GCC Code Coverage Report


Directory: ./
File: unit_tests/tests/controllers/can/test_can_serial.cpp
Date: 2025-11-16 14:52:24
Warnings: 2 unchecked decisions!
Coverage Exec Excl Total
Lines: 99.2% 132 0 133
Functions: 100.0% 24 0 24
Branches: 66.1% 150 0 227
Decisions: 64.3% 9 - 14

Line Branch Decision Exec Source
1 /*
2 * @file test_can_serial.cpp
3 *
4 * This is more like ISO-TP test really?
5 *
6 * Created on: Nov 26, 2020
7 * @author andreika <prometheus.pcb@gmail.com>
8 * @author Andrey Belomutskiy, (c) 2012-2020
9 */
10
11 #include "pch.h"
12 #include "engine_test_helper.h"
13 #include "serial_can.h"
14
15 #include <array>
16 #include <list>
17 #include <string>
18
19 using namespace std::string_literals;
20
21 // todo: split into TX and RX parts?
22 class TestCanTransport : public ICanTransport {
23 public:
24 52 virtual can_msg_t transmit(CanTxMessage &ctfp, can_sysinterval_t timeout) override {
25 52 const CANTxFrame * frame = ctfp.getFrame();
26 // invoke copy constructor to clone frame
27 52 CANTxFrame localCopy = *frame;
28 52 localCopy.DLC = 8;
29
1/1
✓ Branch 1 taken 52 times.
52 ctfList.emplace_back(localCopy);
30 52 return CAN_MSG_OK;
31 }
32
33 8 virtual void onTpFirstFrame() override {
34 // todo: add coverage?
35 8 }
36
37 44 virtual can_msg_t receive(CANRxFrame *crfp, can_sysinterval_t timeout) override {
38
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 44 times.
44 if (crfList.empty())
39 return CAN_MSG_TIMEOUT;
40 44 *crfp = *crfList.begin();
41 44 crfList.pop_front();
42 44 return CAN_MSG_OK;
43 }
44
45 template<typename T>
46 44 void checkFrame(const T & frame, const std::string & bytes, int frameIndex) {
47
2/6
✓ Branch 5 taken 44 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 44 times.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
44 EXPECT_EQ(bytes.size(), frame.DLC);
48
2/2
✓ Branch 2 taken 352 times.
✓ Branch 3 taken 44 times.
2/2
✓ Decision 'true' taken 352 times.
✓ Decision 'false' taken 44 times.
396 for (size_t i = 0; i < bytes.size(); i++) {
49
2/10
✓ Branch 3 taken 352 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 352 times.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 27 not taken.
✗ Branch 30 not taken.
352 EXPECT_EQ(bytes[i], frame.data8[i]) << "Frame byte #" << i << " differs! Frame " << frameIndex;
50 }
51 44 }
52
53 public:
54 std::list<CANTxFrame> ctfList;
55 std::list<CANRxFrame> crfList;
56 };
57
58 class TestCanStreamerState : public CanStreamerState {
59 public:
60 13 TestCanStreamerState() : CanStreamerState(&streamer, &streamer, 0, 10) {}
61
62 13 void test(const std::vector<std::string> & dataList, const std::vector<std::string> & frames, int fifoLeftoverSize, const std::vector<size_t> & receiveChunks) {
63
1/1
✓ Branch 2 taken 13 times.
13 EngineTestHelper eth(engine_type_e::TEST_ENGINE);
64
65 13 size_t totalSize = 0;
66 13 std::string totalData;
67
3/3
✓ Branch 7 taken 23 times.
✓ Branch 11 taken 23 times.
✓ Branch 12 taken 13 times.
0/1
? Decision couldn't be analyzed.
36 for (auto data : dataList) {
68 23 size_t np = data.size();
69
70 23 totalSize += np;
71
1/1
✓ Branch 1 taken 23 times.
23 totalData += data;
72
73
1/1
✓ Branch 2 taken 23 times.
23 streamAddToTxTimeout(&np, (uint8_t *)data.c_str(), 0);
74 23 }
75
76 // check the FIFO buf size
77
3/7
✓ Branch 3 taken 13 times.
✓ Branch 6 taken 13 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
13 EXPECT_EQ(fifoLeftoverSize, txFifoBuf.getCount());
78
79 // send the rest
80
1/1
✓ Branch 1 taken 13 times.
13 streamFlushTx(0);
81
82 // check if correct the TX frames were sent
83
2/6
✓ Branch 6 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 13 times.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
13 EXPECT_EQ(frames.size(), streamer.ctfList.size());
84
85 13 auto it1 = streamer.ctfList.begin();
86 13 int frameIndex = 0;
87 13 auto it2 = frames.begin();
88
8/10
✓ Branch 5 taken 44 times.
✓ Branch 6 taken 13 times.
✓ Branch 10 taken 44 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 44 times.
✓ Branch 13 taken 13 times.
✓ Branch 15 taken 57 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 44 times.
✓ Branch 19 taken 13 times.
0/1
? Decision couldn't be analyzed.
57 for (; it1 != streamer.ctfList.end() && it2 != frames.end(); it1++, it2++) {
89
1/1
✓ Branch 3 taken 44 times.
44 streamer.checkFrame(*it1, *it2, frameIndex++);
90 }
91
92 // copy transmitted data back into the receive buffer
93
2/2
✓ Branch 7 taken 44 times.
✓ Branch 8 taken 13 times.
2/2
✓ Decision 'true' taken 44 times.
✓ Decision 'false' taken 13 times.
57 for (auto f : streamer.ctfList) {
94 44 CANRxFrame rf;
95 44 rf.DLC = f.DLC;
96 44 rf.RTR = f.RTR;
97 44 rf.IDE = f.IDE;
98 44 rf.EID = f.EID;
99 44 rf.data64[0] = f.data64[0];
100
1/1
✓ Branch 1 taken 44 times.
44 streamer.crfList.push_back(rf);
101 }
102
103 13 size_t totalReceivedSize = 0;
104 26 std::string totalReceivedData;
105
2/2
✓ Branch 8 taken 23 times.
✓ Branch 9 taken 13 times.
2/2
✓ Decision 'true' taken 23 times.
✓ Decision 'false' taken 13 times.
36 for (size_t chunkSize : receiveChunks) {
106 23 size_t nr = chunkSize;
107 23 uint8_t rxbuf[1256];
108
1/1
✓ Branch 1 taken 23 times.
23 streamReceiveTimeout(&nr, rxbuf, 0);
109
2/6
✓ Branch 2 taken 23 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 23 times.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
23 EXPECT_EQ(nr, chunkSize);
110 23 totalReceivedSize += nr;
111
2/2
✓ Branch 3 taken 23 times.
✓ Branch 6 taken 23 times.
69 totalReceivedData += std::string((const char *)rxbuf, nr);
112 }
113 // we should receive the same amount of bytes that we've sent
114
2/6
✓ Branch 2 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
13 EXPECT_EQ(totalSize, totalReceivedSize);
115 // check the data
116
2/2
✓ Branch 1 taken 258 times.
✓ Branch 2 taken 13 times.
2/2
✓ Decision 'true' taken 258 times.
✓ Decision 'false' taken 13 times.
271 for (size_t i = 0; i < totalSize; i++) {
117
2/9
✓ Branch 4 taken 258 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 258 times.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 25 not taken.
✗ Branch 28 not taken.
258 EXPECT_EQ(totalData[i], totalReceivedData[i]) << "Rcv. byte #" << i << " differs!";
118 }
119 // check the FIFO buf size
120
3/7
✓ Branch 3 taken 13 times.
✓ Branch 7 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
13 EXPECT_EQ(0, rxFifoBuf.getCount());
121
122 // clear shared buffer
123
1/1
✓ Branch 1 taken 13 times.
13 txCanBuffer.clear();
124
2/7
✓ Branch 3 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 13 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
13 EXPECT_FALSE(txCanBuffer.getCount());
125 26 }
126
127 protected:
128 TestCanTransport streamer;
129 };
130
131 4 TEST(testCanSerial, test1Frame) {
132
133 {
134
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
135
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
8 state.test({ "1" }, { "\x01"s "1\0\0\0\0\0\0"s }, 1, { 1 }); // 1 byte -> 1 frame, 1 byte in FIFO
136 1 }
137 {
138
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
139
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
8 state.test({ "0123456" }, { "\x07"s "0123456"s }, 7, { 7 }); // 7 bytes -> 1 8-byte frame
140 1 }
141 {
142
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
143
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
8 state.test({ "0123456" }, { "\x07"s "0123456"s }, 7, { 1, 1, 1, 1, 1, 1, 1 }); // 7 bytes -> 1 8-byte frame, split receive test
144 1 }
145 {
146
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
147
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
8 state.test({ "0123456" }, { "\x07"s "0123456"s }, 7, { 3, 4 }); // 7 bytes -> 1 8-byte frame, split receive test
148 1 }
149 {
150
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
151
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
8 state.test({ "0", "1", "2", "3", "4", "5", "6" }, { "\x07"s "0123456"s }, 7, { 7 }); // 7 bytes separately -> 1 8-byte frame
152 1 }
153 6 }
154
155 4 TEST(testCanSerial, test2Frames) {
156 {
157
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
158
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 2 times.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
9 state.test({ "01234567" }, { "\x10"s "\x08"s "012345"s, "\x21"s "67\0\0\0\0\0"s }, 8, { 8 }); // 8 bytes -> 2 8-byte frames, 8 bytes in FIFO
159 1 }
160 {
161
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
162
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 2 times.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
9 state.test({ "0123456789A" }, { "\x10"s "\x0B"s "012345"s, "\x21"s "6789A\0\0"s }, 11, { 2, 5, 4 }); // 11 bytes -> 2 8-byte frames
163 1 }
164 {
165
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
166
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 3 times.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
10 state.test({ "0123456ABCDEFG" }, { "\x10"s "\x0E"s "012345"s, "\x21"s "6ABCDEF"s, "\x22"s "G\0\0\0\0\0\0"s }, 14, { 14 }); // 14 bytes -> 3 8-byte frames, empty FIFO
167 1 }
168 4 }
169
170 4 TEST(testCanSerial, testIrregularSplits) {
171 {
172
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
173
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 3 times.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
10 state.test({ "012", "3456ABCDEFG" }, { "\x10"s "\x0E"s "012345"s, "\x21"s "6ABCDEF"s, "\x22"s "G\0\0\0\0\0\0"s }, 14, { 7, 7 }); // 14 bytes -> 2 8-byte frames, empty FIFO
174 1 }
175 {
176
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
177
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 3 times.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
10 state.test({ "0123456ABC", "DEFG" }, { "\x10"s "\x0E"s "012345"s, "\x21"s "6ABCDEF"s, "\x22"s "G\0\0\0\0\0\0"s }, 14, { 14 }); // 14 bytes -> 2 8-byte frames, empty FIFO
178 1 }
179 3 }
180
181 4 TEST(testCanSerial, testLongMessage) {
182 {
183
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
184
6/8
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 26 taken 4 times.
✓ Branch 27 taken 1 time.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
11 state.test({ "abcdefghijklmnopqrstuvwxyz" }, {
185 "\x10"s "\x1A"s "abcdef"s,
186 "\x21"s "ghijklm"s,
187 "\x22"s "nopqrst"s,
188 "\x23"s "uvwxyz\0"s }, 26, { 26 }); // 26 bytes -> 4 8-byte frames, 5 bytes left in FIFO
189 1 }
190 2 }
191
192 4 TEST(testCanSerial, test64_7Message) {
193 1 std::array<char, 71> buffer;
194
195
1/1
✓ Branch 2 taken 1 time.
3 std::fill(std::begin(buffer), std::end(buffer), 0);
196
197 1 buffer[0] = 1;
198
199 1 buffer[64 + 7 - 1] = 4;
200
1/1
✓ Branch 3 taken 1 time.
4 std::string str(std::begin(buffer),std::end(buffer));
201
202
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
203
8/12
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 17 taken 1 time.
✓ Branch 21 taken 1 time.
✓ Branch 22 taken 1 time.
✓ Branch 28 taken 11 times.
✓ Branch 29 taken 1 time.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
19 state.test({ str }, {
204 /* 0 */
205 "\x10"s "\x47"s "\x01\0\0\0\0\0"s,
206 "\x21"s "\0\0\0\0\0\0\0"s,
207 "\x22"s "\0\0\0\0\0\0\0"s,
208 "\x23"s "\0\0\0\0\0\0\0"s,
209 "\x24"s "\0\0\0\0\0\0\0"s,
210 "\x25"s "\0\0\0\0\0\0\0"s,
211 "\x26"s "\0\0\0\0\0\0\0"s,
212 "\x27"s "\0\0\0\0\0\0\0"s,
213 "\x28"s "\0\0\0\0\0\0\0"s,
214 "\x29"s "\0\0\0\0\0\0\0"s,
215
216 /* 10 */
217 "\x2A"s "\0\4\0\0\0\0\0"s,
218
219 }, 71, { 64 + 7 });
220 4 }
221
222 4 TEST(testCanSerial, test3_64_4Message) {
223 1 std::array<char, 64> buffer64;
224
225
1/1
✓ Branch 2 taken 1 time.
3 std::fill(std::begin(buffer64), std::end(buffer64), 0);
226
227 1 buffer64[0] = 1;
228
229 1 buffer64[64 - 1] = 4;
230
1/1
✓ Branch 3 taken 1 time.
4 std::string str(std::begin(buffer64),std::end(buffer64));
231
232
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
233
8/12
✓ Branch 4 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 17 taken 1 time.
✓ Branch 21 taken 3 times.
✓ Branch 22 taken 1 time.
✓ Branch 28 taken 11 times.
✓ Branch 29 taken 1 time.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
21 state.test({ "123"s, str, "abcd"s }, {
234 /* 0 */
235 "\x10"s "\x47"s "123\1\0\0"s,
236 "\x21"s "\0\0\0\0\0\0\0"s,
237 "\x22"s "\0\0\0\0\0\0\0"s,
238 "\x23"s "\0\0\0\0\0\0\0"s,
239 "\x24"s "\0\0\0\0\0\0\0"s,
240 "\x25"s "\0\0\0\0\0\0\0"s,
241 "\x26"s "\0\0\0\0\0\0\0"s,
242 "\x27"s "\0\0\0\0\0\0\0"s,
243 "\x28"s "\0\0\0\0\0\0\0"s,
244 "\x29"s "\0\0\0\0\4ab"s,
245
246 /* 10 */
247 "\x2A"s "cd\0\0\0\0\0"s,
248
249 }, 71, { 64 + 7 });
250 4 }
251
252