aboutsummaryrefslogtreecommitdiff
path: root/quantum/serial_link/tests
diff options
context:
space:
mode:
authorFred Sundvik <fsundvik@gmail.com>2016-08-27 14:18:49 +0300
committerFred Sundvik <fsundvik@gmail.com>2016-08-27 21:57:49 +0300
commitbcdf9ab76bf3723e6015d4255d53e7c1e7259b61 (patch)
tree90bdb182315b96740da331c3d76c20187bef1f6f /quantum/serial_link/tests
parentb3eba797af74ace19b9f2e762bdd33d9449e3f94 (diff)
downloadqmk_firmware-bcdf9ab76bf3723e6015d4255d53e7c1e7259b61.tar.gz
qmk_firmware-bcdf9ab76bf3723e6015d4255d53e7c1e7259b61.zip
Convert transport_tests to GTest
Diffstat (limited to 'quantum/serial_link/tests')
-rw-r--r--quantum/serial_link/tests/rules.mk7
-rw-r--r--quantum/serial_link/tests/transport_tests.c168
-rw-r--r--quantum/serial_link/tests/transport_tests.cpp188
3 files changed, 194 insertions, 169 deletions
diff --git a/quantum/serial_link/tests/rules.mk b/quantum/serial_link/tests/rules.mk
index 7f2a8f457..bf342c9d2 100644
--- a/quantum/serial_link/tests/rules.mk
+++ b/quantum/serial_link/tests/rules.mk
@@ -10,4 +10,9 @@ serial_link_frame_router_SRC := \
10 10
11serial_link_frame_validator_SRC := \ 11serial_link_frame_validator_SRC := \
12 $(SERIAL_PATH)/tests/frame_validator_tests.cpp \ 12 $(SERIAL_PATH)/tests/frame_validator_tests.cpp \
13 $(SERIAL_PATH)/protocol/frame_validator.c \ No newline at end of file 13 $(SERIAL_PATH)/protocol/frame_validator.c
14
15serial_link_transport_SRC := \
16 $(SERIAL_PATH)/tests/transport_tests.cpp \
17 $(SERIAL_PATH)/protocol/transport.c \
18 $(SERIAL_PATH)/protocol/triple_buffered_object.c \ No newline at end of file
diff --git a/quantum/serial_link/tests/transport_tests.c b/quantum/serial_link/tests/transport_tests.c
deleted file mode 100644
index 358e1b9fd..000000000
--- a/quantum/serial_link/tests/transport_tests.c
+++ /dev/null
@@ -1,168 +0,0 @@
1/*
2The MIT License (MIT)
3
4Copyright (c) 2016 Fred Sundvik
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24
25#include <cgreen/cgreen.h>
26#include <cgreen/mocks.h>
27#include "serial_link/protocol/transport.c"
28#include "serial_link/protocol/triple_buffered_object.c"
29
30void signal_data_written(void) {
31 mock();
32}
33
34static uint8_t sent_data[2048];
35static uint16_t sent_data_size;
36
37void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) {
38 mock(destination);
39 memcpy(sent_data + sent_data_size, data, size);
40 sent_data_size += size;
41}
42
43typedef struct {
44 uint32_t test;
45} test_object1_t;
46
47typedef struct {
48 uint32_t test1;
49 uint32_t test2;
50} test_object2_t;
51
52MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1_t);
53MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1_t);
54SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1_t);
55
56static remote_object_t* test_remote_objects[] = {
57 REMOTE_OBJECT(master_to_slave),
58 REMOTE_OBJECT(master_to_single_slave),
59 REMOTE_OBJECT(slave_to_master),
60};
61
62Describe(Transport);
63BeforeEach(Transport) {
64 add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*));
65 sent_data_size = 0;
66}
67AfterEach(Transport) {}
68
69Ensure(Transport, write_to_local_signals_an_event) {
70 begin_write_master_to_slave();
71 expect(signal_data_written);
72 end_write_master_to_slave();
73 begin_write_slave_to_master();
74 expect(signal_data_written);
75 end_write_slave_to_master();
76 begin_write_master_to_single_slave(1);
77 expect(signal_data_written);
78 end_write_master_to_single_slave(1);
79}
80
81Ensure(Transport, writes_from_master_to_all_slaves) {
82 update_transport();
83 test_object1_t* obj = begin_write_master_to_slave();
84 obj->test = 5;
85 expect(signal_data_written);
86 end_write_master_to_slave();
87 expect(router_send_frame,
88 when(destination, is_equal_to(0xFF)));
89 update_transport();
90 transport_recv_frame(0, sent_data, sent_data_size);
91 test_object1_t* obj2 = read_master_to_slave();
92 assert_that(obj2, is_not_equal_to(NULL));
93 assert_that(obj2->test, is_equal_to(5));
94}
95
96Ensure(Transport, writes_from_slave_to_master) {
97 update_transport();
98 test_object1_t* obj = begin_write_slave_to_master();
99 obj->test = 7;
100 expect(signal_data_written);
101 end_write_slave_to_master();
102 expect(router_send_frame,
103 when(destination, is_equal_to(0)));
104 update_transport();
105 transport_recv_frame(3, sent_data, sent_data_size);
106 test_object1_t* obj2 = read_slave_to_master(2);
107 assert_that(read_slave_to_master(0), is_equal_to(NULL));
108 assert_that(obj2, is_not_equal_to(NULL));
109 assert_that(obj2->test, is_equal_to(7));
110}
111
112Ensure(Transport, writes_from_master_to_single_slave) {
113 update_transport();
114 test_object1_t* obj = begin_write_master_to_single_slave(3);
115 obj->test = 7;
116 expect(signal_data_written);
117 end_write_master_to_single_slave(3);
118 expect(router_send_frame,
119 when(destination, is_equal_to(4)));
120 update_transport();
121 transport_recv_frame(0, sent_data, sent_data_size);
122 test_object1_t* obj2 = read_master_to_single_slave();
123 assert_that(obj2, is_not_equal_to(NULL));
124 assert_that(obj2->test, is_equal_to(7));
125}
126
127Ensure(Transport, ignores_object_with_invalid_id) {
128 update_transport();
129 test_object1_t* obj = begin_write_master_to_single_slave(3);
130 obj->test = 7;
131 expect(signal_data_written);
132 end_write_master_to_single_slave(3);
133 expect(router_send_frame,
134 when(destination, is_equal_to(4)));
135 update_transport();
136 sent_data[sent_data_size - 1] = 44;
137 transport_recv_frame(0, sent_data, sent_data_size);
138 test_object1_t* obj2 = read_master_to_single_slave();
139 assert_that(obj2, is_equal_to(NULL));
140}
141
142Ensure(Transport, ignores_object_with_size_too_small) {
143 update_transport();
144 test_object1_t* obj = begin_write_master_to_slave();
145 obj->test = 7;
146 expect(signal_data_written);
147 end_write_master_to_slave();
148 expect(router_send_frame);
149 update_transport();
150 sent_data[sent_data_size - 2] = 0;
151 transport_recv_frame(0, sent_data, sent_data_size - 1);
152 test_object1_t* obj2 = read_master_to_slave();
153 assert_that(obj2, is_equal_to(NULL));
154}
155
156Ensure(Transport, ignores_object_with_size_too_big) {
157 update_transport();
158 test_object1_t* obj = begin_write_master_to_slave();
159 obj->test = 7;
160 expect(signal_data_written);
161 end_write_master_to_slave();
162 expect(router_send_frame);
163 update_transport();
164 sent_data[sent_data_size + 21] = 0;
165 transport_recv_frame(0, sent_data, sent_data_size + 22);
166 test_object1_t* obj2 = read_master_to_slave();
167 assert_that(obj2, is_equal_to(NULL));
168}
diff --git a/quantum/serial_link/tests/transport_tests.cpp b/quantum/serial_link/tests/transport_tests.cpp
new file mode 100644
index 000000000..21b7b165f
--- /dev/null
+++ b/quantum/serial_link/tests/transport_tests.cpp
@@ -0,0 +1,188 @@
1/*
2The MIT License (MIT)
3
4Copyright (c) 2016 Fred Sundvik
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24
25#include "gtest/gtest.h"
26#include "gmock/gmock.h"
27
28using testing::_;
29using testing::ElementsAreArray;
30using testing::Args;
31
32extern "C" {
33#include "serial_link/protocol/transport.h"
34}
35
36struct test_object1 {
37 uint32_t test;
38};
39
40struct test_object2 {
41 uint32_t test1;
42 uint32_t test2;
43};
44
45MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1);
46MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1);
47SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1);
48
49static remote_object_t* test_remote_objects[] = {
50 REMOTE_OBJECT(master_to_slave),
51 REMOTE_OBJECT(master_to_single_slave),
52 REMOTE_OBJECT(slave_to_master),
53};
54
55class Transport : public testing::Test {
56public:
57 Transport() {
58 Instance = this;
59 add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*));
60 }
61
62 ~Transport() {
63 Instance = nullptr;
64 reinitialize_serial_link_transport();
65 }
66
67 MOCK_METHOD0(signal_data_written, void ());
68 MOCK_METHOD1(router_send_frame, void (uint8_t destination));
69
70 void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) {
71 router_send_frame(destination);
72 std::copy(data, data + size, std::back_inserter(sent_data));
73 }
74
75 static Transport* Instance;
76
77 std::vector<uint8_t> sent_data;
78};
79
80Transport* Transport::Instance = nullptr;
81
82extern "C" {
83void signal_data_written(void) {
84 Transport::Instance->signal_data_written();
85}
86
87void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) {
88 Transport::Instance->router_send_frame(destination, data, size);
89}
90}
91
92TEST_F(Transport, write_to_local_signals_an_event) {
93 begin_write_master_to_slave();
94 EXPECT_CALL(*this, signal_data_written());
95 end_write_master_to_slave();
96 begin_write_slave_to_master();
97 EXPECT_CALL(*this, signal_data_written());
98 end_write_slave_to_master();
99 begin_write_master_to_single_slave(1);
100 EXPECT_CALL(*this, signal_data_written());
101 end_write_master_to_single_slave(1);
102}
103
104TEST_F(Transport, writes_from_master_to_all_slaves) {
105 update_transport();
106 test_object1* obj = begin_write_master_to_slave();
107 obj->test = 5;
108 EXPECT_CALL(*this, signal_data_written());
109 end_write_master_to_slave();
110 EXPECT_CALL(*this, router_send_frame(0xFF));
111 update_transport();
112 transport_recv_frame(0, sent_data.data(), sent_data.size());
113 test_object1* obj2 = read_master_to_slave();
114 EXPECT_NE(obj2, nullptr);
115 EXPECT_EQ(obj2->test, 5);
116}
117
118TEST_F(Transport, writes_from_slave_to_master) {
119 update_transport();
120 test_object1* obj = begin_write_slave_to_master();
121 obj->test = 7;
122 EXPECT_CALL(*this, signal_data_written());
123 end_write_slave_to_master();
124 EXPECT_CALL(*this, router_send_frame(0));
125 update_transport();
126 transport_recv_frame(3, sent_data.data(), sent_data.size());
127 test_object1* obj2 = read_slave_to_master(2);
128 EXPECT_EQ(read_slave_to_master(0), nullptr);
129 EXPECT_NE(obj2, nullptr);
130 EXPECT_EQ(obj2->test, 7);
131}
132
133TEST_F(Transport, writes_from_master_to_single_slave) {
134 update_transport();
135 test_object1* obj = begin_write_master_to_single_slave(3);
136 obj->test = 7;
137 EXPECT_CALL(*this, signal_data_written());
138 end_write_master_to_single_slave(3);
139 EXPECT_CALL(*this, router_send_frame(4));
140 update_transport();
141 transport_recv_frame(0, sent_data.data(), sent_data.size());
142 test_object1* obj2 = read_master_to_single_slave();
143 EXPECT_NE(obj2, nullptr);
144 EXPECT_EQ(obj2->test, 7);
145}
146
147TEST_F(Transport, ignores_object_with_invalid_id) {
148 update_transport();
149 test_object1* obj = begin_write_master_to_single_slave(3);
150 obj->test = 7;
151 EXPECT_CALL(*this, signal_data_written());
152 end_write_master_to_single_slave(3);
153 EXPECT_CALL(*this, router_send_frame(4));
154 update_transport();
155 sent_data[sent_data.size() - 1] = 44;
156 transport_recv_frame(0, sent_data.data(), sent_data.size());
157 test_object1* obj2 = read_master_to_single_slave();
158 EXPECT_EQ(obj2, nullptr);
159}
160
161TEST_F(Transport, ignores_object_with_size_too_small) {
162 update_transport();
163 test_object1* obj = begin_write_master_to_slave();
164 obj->test = 7;
165 EXPECT_CALL(*this, signal_data_written());
166 end_write_master_to_slave();
167 EXPECT_CALL(*this, router_send_frame(_));
168 update_transport();
169 sent_data[sent_data.size() - 2] = 0;
170 transport_recv_frame(0, sent_data.data(), sent_data.size() - 1);
171 test_object1* obj2 = read_master_to_slave();
172 EXPECT_EQ(obj2, nullptr);
173}
174
175TEST_F(Transport, ignores_object_with_size_too_big) {
176 update_transport();
177 test_object1* obj = begin_write_master_to_slave();
178 obj->test = 7;
179 EXPECT_CALL(*this, signal_data_written());
180 end_write_master_to_slave();
181 EXPECT_CALL(*this, router_send_frame(_));
182 update_transport();
183 sent_data.resize(sent_data.size() + 22);
184 sent_data[sent_data.size() - 1] = 0;
185 transport_recv_frame(0, sent_data.data(), sent_data.size());
186 test_object1* obj2 = read_master_to_slave();
187 EXPECT_EQ(obj2, nullptr);
188}