GCC Code Coverage Report


Directory: ./
File: unit_tests/tests/controllers/can/test_can_serial.cpp
Date: 2025-10-03 00:57:22
Warnings: 2 unchecked decisions!
Coverage Exec Excl Total
Lines: 99.2% 130 0 131
Functions: 100.0% 23 0 23
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 class TestCanStreamer : public ICanStreamer {
22 public:
23 52 virtual can_msg_t transmit(canmbx_t mailbox, const CanTxMessage *ctfp, can_sysinterval_t timeout) override {
24 52 const CANTxFrame * frame = ctfp->getFrame();
25 // invoke copy constructor to clone frame
26 52 CANTxFrame localCopy = *frame;
27 52 localCopy.DLC = 8;
28
1/1
✓ Branch 1 taken 52 times.
52 ctfList.emplace_back(localCopy);
29 52 return CAN_MSG_OK;
30 }
31
32 44 virtual can_msg_t receive(canmbx_t mailbox, CANRxFrame *crfp, can_sysinterval_t timeout) override {
33
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())
34 return CAN_MSG_TIMEOUT;
35 44 *crfp = *crfList.begin();
36 44 crfList.pop_front();
37 44 return CAN_MSG_OK;
38 }
39
40 template<typename T>
41 44 void checkFrame(const T & frame, const std::string & bytes, int frameIndex) {
42
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);
43
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++) {
44
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;
45 }
46 44 }
47
48 public:
49 std::list<CANTxFrame> ctfList;
50 std::list<CANRxFrame> crfList;
51 };
52
53 class TestCanStreamerState : public CanStreamerState {
54 public:
55 13 TestCanStreamerState() : CanStreamerState(&streamer) {}
56
57 13 void test(const std::vector<std::string> & dataList, const std::vector<std::string> & frames, int fifoLeftoverSize, const std::vector<size_t> & receiveChunks) {
58
1/1
✓ Branch 2 taken 13 times.
13 EngineTestHelper eth(engine_type_e::TEST_ENGINE);
59
60 13 size_t totalSize = 0;
61 13 std::string totalData;
62
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) {
63 23 size_t np = data.size();
64
65 23 totalSize += np;
66
1/1
✓ Branch 1 taken 23 times.
23 totalData += data;
67
68
1/1
✓ Branch 2 taken 23 times.
23 streamAddToTxTimeout(&np, (uint8_t *)data.c_str(), 0);
69 23 }
70
71 // check the FIFO buf size
72
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());
73
74 // send the rest
75
1/1
✓ Branch 1 taken 13 times.
13 streamFlushTx(0);
76
77 // check if correct the TX frames were sent
78
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());
79
80 13 auto it1 = streamer.ctfList.begin();
81 13 int frameIndex = 0;
82 13 auto it2 = frames.begin();
83
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++) {
84
1/1
✓ Branch 3 taken 44 times.
44 streamer.checkFrame(*it1, *it2, frameIndex++);
85 }
86
87 // copy transmitted data back into the receive buffer
88
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) {
89 44 CANRxFrame rf;
90 44 rf.DLC = f.DLC;
91 44 rf.RTR = f.RTR;
92 44 rf.IDE = f.IDE;
93 44 rf.EID = f.EID;
94 44 rf.data64[0] = f.data64[0];
95
1/1
✓ Branch 1 taken 44 times.
44 streamer.crfList.push_back(rf);
96 }
97
98 13 size_t totalReceivedSize = 0;
99 26 std::string totalReceivedData;
100
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) {
101 23 size_t nr = chunkSize;
102 23 uint8_t rxbuf[1256];
103
1/1
✓ Branch 1 taken 23 times.
23 streamReceiveTimeout(&nr, rxbuf, 0);
104
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);
105 23 totalReceivedSize += nr;
106
2/2
✓ Branch 3 taken 23 times.
✓ Branch 6 taken 23 times.
69 totalReceivedData += std::string((const char *)rxbuf, nr);
107 }
108 // we should receive the same amount of bytes that we've sent
109
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);
110 // check the data
111
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++) {
112
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!";
113 }
114 // check the FIFO buf size
115
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());
116
117 // clear shared buffer
118
1/1
✓ Branch 1 taken 13 times.
13 txCanBuffer.clear();
119
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());
120 26 }
121
122 protected:
123 TestCanStreamer streamer;
124 };
125
126 4 TEST(testCanSerial, test1Frame) {
127
128 {
129
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
130
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
131 1 }
132 {
133
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
134
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
135 1 }
136 {
137
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
138
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
139 1 }
140 {
141
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
142
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
143 1 }
144 {
145
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
146
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
147 1 }
148 6 }
149
150 4 TEST(testCanSerial, test2Frames) {
151 {
152
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
153
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
154 1 }
155 {
156
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
157
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
158 1 }
159 {
160
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
161
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
162 1 }
163 4 }
164
165 4 TEST(testCanSerial, testIrregularSplits) {
166 {
167
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
168
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
169 1 }
170 {
171
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
172
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
173 1 }
174 3 }
175
176 4 TEST(testCanSerial, testLongMessage) {
177 {
178
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
179
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" }, {
180 "\x10"s "\x1A"s "abcdef"s,
181 "\x21"s "ghijklm"s,
182 "\x22"s "nopqrst"s,
183 "\x23"s "uvwxyz\0"s }, 26, { 26 }); // 26 bytes -> 4 8-byte frames, 5 bytes left in FIFO
184 1 }
185 2 }
186
187 4 TEST(testCanSerial, test64_7Message) {
188 1 std::array<char, 71> buffer;
189
190
1/1
✓ Branch 2 taken 1 time.
3 std::fill(std::begin(buffer), std::end(buffer), 0);
191
192 1 buffer[0] = 1;
193
194 1 buffer[64 + 7 - 1] = 4;
195
1/1
✓ Branch 3 taken 1 time.
4 std::string str(std::begin(buffer),std::end(buffer));
196
197
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
198
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 }, {
199 /* 0 */
200 "\x10"s "\x47"s "\x01\0\0\0\0\0"s,
201 "\x21"s "\0\0\0\0\0\0\0"s,
202 "\x22"s "\0\0\0\0\0\0\0"s,
203 "\x23"s "\0\0\0\0\0\0\0"s,
204 "\x24"s "\0\0\0\0\0\0\0"s,
205 "\x25"s "\0\0\0\0\0\0\0"s,
206 "\x26"s "\0\0\0\0\0\0\0"s,
207 "\x27"s "\0\0\0\0\0\0\0"s,
208 "\x28"s "\0\0\0\0\0\0\0"s,
209 "\x29"s "\0\0\0\0\0\0\0"s,
210
211 /* 10 */
212 "\x2A"s "\0\4\0\0\0\0\0"s,
213
214 }, 71, { 64 + 7 });
215 4 }
216
217 4 TEST(testCanSerial, test3_64_4Message) {
218 1 std::array<char, 64> buffer64;
219
220
1/1
✓ Branch 2 taken 1 time.
3 std::fill(std::begin(buffer64), std::end(buffer64), 0);
221
222 1 buffer64[0] = 1;
223
224 1 buffer64[64 - 1] = 4;
225
1/1
✓ Branch 3 taken 1 time.
4 std::string str(std::begin(buffer64),std::end(buffer64));
226
227
1/1
✓ Branch 2 taken 1 time.
1 TestCanStreamerState state;
228
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 }, {
229 /* 0 */
230 "\x10"s "\x47"s "123\1\0\0"s,
231 "\x21"s "\0\0\0\0\0\0\0"s,
232 "\x22"s "\0\0\0\0\0\0\0"s,
233 "\x23"s "\0\0\0\0\0\0\0"s,
234 "\x24"s "\0\0\0\0\0\0\0"s,
235 "\x25"s "\0\0\0\0\0\0\0"s,
236 "\x26"s "\0\0\0\0\0\0\0"s,
237 "\x27"s "\0\0\0\0\0\0\0"s,
238 "\x28"s "\0\0\0\0\0\0\0"s,
239 "\x29"s "\0\0\0\0\4ab"s,
240
241 /* 10 */
242 "\x2A"s "cd\0\0\0\0\0"s,
243
244 }, 71, { 64 + 7 });
245 4 }
246
247