GCC Code Coverage Report


Directory: ./
File: unit_tests/tests/sensor/redundant.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 100.0% 200 0 200
Functions: 100.0% 63 0 63
Branches: 28.8% 89 0 309
Decisions: -% 0 - 0

Line Branch Decision Exec Source
1 #include "pch.h"
2
3 #include "redundant_sensor.h"
4 #include "redundant_ford_tps.h"
5
6 class SensorRedundant : public ::testing::Test
7 {
8 protected:
9 RedundantSensor dut;
10 MockSensor m1, m2;
11
12 7 SensorRedundant()
13 14 : dut(SensorType::Tps1, SensorType::Tps1Primary, SensorType::Tps1Secondary)
14
1/1
✓ Branch 1 taken 7 times.
7 , m1(SensorType::Tps1Primary)
15
2/2
✓ Branch 2 taken 7 times.
✓ Branch 5 taken 7 times.
14 , m2(SensorType::Tps1Secondary)
16 {
17 7 }
18
19 7 void SetUp() override
20 {
21 7 Sensor::resetRegistry();
22
23 // Other tests verify registry function - don't re-test it here
24
3/9
✓ Branch 3 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 33 taken 7 times.
✗ Branch 34 not taken.
7 ASSERT_TRUE(dut.Register());
25
3/9
✓ Branch 3 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 33 taken 7 times.
✗ Branch 34 not taken.
7 ASSERT_TRUE(m1.Register());
26
3/9
✓ Branch 3 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 33 taken 7 times.
✗ Branch 34 not taken.
7 ASSERT_TRUE(m2.Register());
27
28 7 dut.configure(5.0f, false);
29 }
30
31 7 void TearDown() override
32 {
33 7 Sensor::resetRegistry();
34 7 }
35 };
36
37 4 TEST_F(SensorRedundant, CheckIsRedundant)
38 {
39 // Expect isRedundant
40 {
41
1/6
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
1 EXPECT_TRUE(dut.isRedundant());
42 }
43 1 }
44
45 4 TEST_F(SensorRedundant, SetOnlyOneSensor)
46 {
47 // Don't set any sensors - expect invalid
48 {
49 1 auto result = dut.get();
50
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
51 }
52
53 // Set one sensor
54 1 m1.set(24.0f);
55
56 // Should still be invalid - only one is set!
57 {
58 1 auto result = dut.get();
59
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
60 }
61 1 }
62
63 4 TEST_F(SensorRedundant, SetTwoSensors)
64 {
65 // Don't set any sensors - expect invalid
66 {
67 1 auto result = dut.get();
68
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
69 }
70
71 // Set one sensor
72 1 m1.set(24.0f);
73 // Set the other sensor
74 1 m2.set(26.0f);
75
76 // Should now be valid - and the average of the two input
77 {
78
1/1
✓ Branch 2 taken 1 time.
1 auto result = dut.get();
79
1/6
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 7 not taken.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
1 EXPECT_TRUE(result.Valid);
80
2/6
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
1 EXPECT_FLOAT_EQ(result.Value, 25.0f);
81 }
82 1 }
83
84 4 TEST_F(SensorRedundant, DifferenceNone)
85 {
86 // Set both sensors to the same value
87 1 m1.set(10);
88 1 m2.set(10);
89
90 // Expect valid, and 10 output
91 {
92
1/1
✓ Branch 2 taken 1 time.
1 auto result = dut.get();
93
1/6
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 7 not taken.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
1 EXPECT_TRUE(result.Valid);
94
2/6
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
1 EXPECT_FLOAT_EQ(result.Value, 10.0f);
95 }
96 1 }
97
98 4 TEST_F(SensorRedundant, DifferenceNearLimit)
99 {
100 // Set both sensors to nearly the limit (4.998 apart)
101 1 m1.set(7.501f);
102 1 m2.set(12.499f);
103
104 // Expect valid, and 10 output
105 {
106
1/1
✓ Branch 2 taken 1 time.
1 auto result = dut.get();
107
1/6
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 7 not taken.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
1 EXPECT_TRUE(result.Valid);
108
2/6
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
1 EXPECT_FLOAT_EQ(result.Value, 10.0f);
109 }
110 1 }
111
112 4 TEST_F(SensorRedundant, DifferenceOverLimit)
113 {
114 // Set both sensors barely over the limit (5.002 apart)
115 1 m1.set(7.499f);
116 1 m2.set(12.501f);
117
118 // Expect invalid
119 {
120 1 auto result = dut.get();
121
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
122 }
123 1 }
124
125 4 TEST_F(SensorRedundant, DifferenceOverLimitSwapped)
126 {
127 // Now try it the other way (m1 > m2)
128 1 m1.set(12.501f);
129 1 m2.set(7.499f);
130
131 // Expect invalid
132 {
133 1 auto result = dut.get();
134
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
135 }
136 1 }
137
138
139 class SensorRedundantIgnoreSecond : public ::testing::Test
140 {
141 protected:
142 RedundantSensor dut;
143 MockSensor m1, m2;
144
145 4 SensorRedundantIgnoreSecond()
146 8 : dut(SensorType::Tps1, SensorType::Tps1Primary, SensorType::Tps1Secondary)
147
1/1
✓ Branch 1 taken 4 times.
4 , m1(SensorType::Tps1Primary)
148
2/2
✓ Branch 2 taken 4 times.
✓ Branch 5 taken 4 times.
8 , m2(SensorType::Tps1Secondary)
149 {
150 4 }
151
152 4 void SetUp() override
153 {
154 4 Sensor::resetRegistry();
155
156 // Other tests verify registry function - don't re-test it here
157
3/9
✓ Branch 3 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 33 taken 4 times.
✗ Branch 34 not taken.
4 ASSERT_TRUE(dut.Register());
158
3/9
✓ Branch 3 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 33 taken 4 times.
✗ Branch 34 not taken.
4 ASSERT_TRUE(m1.Register());
159
3/9
✓ Branch 3 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 33 taken 4 times.
✗ Branch 34 not taken.
4 ASSERT_TRUE(m2.Register());
160
161 4 dut.configure(5.0f, true);
162 }
163
164 4 void TearDown() override
165 {
166 4 Sensor::resetRegistry();
167 4 }
168 };
169
170 4 TEST_F(SensorRedundantIgnoreSecond, CheckIsRedundant)
171 {
172 // Expect not isRedundant
173 {
174
1/6
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
1 EXPECT_FALSE(dut.isRedundant());
175 }
176 1 }
177 4 TEST_F(SensorRedundantIgnoreSecond, OnlyFirst)
178 {
179 // Don't set any sensors - expect invalid
180 {
181 1 auto result = dut.get();
182
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
183 }
184
185 // Set one sensor
186 1 m1.set(44.0f);
187
188 // Should be valid - we don't care about second sensor
189 {
190
1/1
✓ Branch 2 taken 1 time.
1 auto result = dut.get();
191
1/6
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 7 not taken.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
1 EXPECT_TRUE(result.Valid);
192
2/6
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
1 EXPECT_FLOAT_EQ(result.Value, 44.0f);
193 }
194 1 }
195
196 4 TEST_F(SensorRedundantIgnoreSecond, OnlySecond)
197 {
198 // Don't set any sensors - expect invalid
199 {
200 1 auto result = dut.get();
201
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
202 }
203
204 // Set second sensor only
205 1 m2.set(66.0f);
206
207 // Should be invalid - should ignore second sensor
208 {
209 1 auto result = dut.get();
210
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
211 }
212 1 }
213
214 4 TEST_F(SensorRedundantIgnoreSecond, SetBothIgnoreSecond)
215 {
216 // Don't set any sensors - expect invalid
217 {
218 1 auto result = dut.get();
219
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
220 }
221
222 // Set both sensors
223 1 m1.set(74.0f);
224 1 m2.set(76.0f);
225
226 // Should be valid, but only get the value from m1
227 {
228
1/1
✓ Branch 2 taken 1 time.
1 auto result = dut.get();
229
1/6
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 7 not taken.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
1 EXPECT_TRUE(result.Valid);
230
2/6
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
1 EXPECT_FLOAT_EQ(result.Value, 74.0f);
231 }
232 1 }
233
234 class SensorFordRedundantTps : public ::testing::Test
235 {
236 protected:
237 RedundantFordTps dut;
238 MockSensor m1, m2;
239
240 7 SensorFordRedundantTps()
241 14 : dut(SensorType::Tps1, SensorType::Tps1Primary, SensorType::Tps1Secondary)
242
1/1
✓ Branch 1 taken 7 times.
7 , m1(SensorType::Tps1Primary)
243
2/2
✓ Branch 2 taken 7 times.
✓ Branch 5 taken 7 times.
14 , m2(SensorType::Tps1Secondary)
244 {
245 7 }
246
247 7 void SetUp() override
248 {
249 7 Sensor::resetRegistry();
250
251 // Other tests verify registry function - don't re-test it here
252
3/9
✓ Branch 3 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 33 taken 7 times.
✗ Branch 34 not taken.
7 ASSERT_TRUE(dut.Register());
253
3/9
✓ Branch 3 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 33 taken 7 times.
✗ Branch 34 not taken.
7 ASSERT_TRUE(m1.Register());
254
3/9
✓ Branch 3 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 33 taken 7 times.
✗ Branch 34 not taken.
7 ASSERT_TRUE(m2.Register());
255
256 7 dut.configure(5.0f, 50);
257 }
258
259 7 void TearDown() override
260 {
261 7 Sensor::resetRegistry();
262 7 }
263 };
264
265 4 TEST_F(SensorFordRedundantTps, SetOnlyOneSensor)
266 {
267 // Don't set any sensors - expect invalid
268 {
269 1 auto result = dut.get();
270
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
271 }
272
273 // Set one sensor
274 1 m1.set(24.0f);
275
276 // Should still be invalid - only one is set!
277 {
278 1 auto result = dut.get();
279
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
280 }
281 1 }
282
283 4 TEST_F(SensorFordRedundantTps, SetTwoSensors)
284 {
285 // Don't set any sensors - expect invalid
286 {
287 1 auto result = dut.get();
288
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
289 }
290
291 // Set one sensor
292 1 m1.set(12.0f);
293 // Set the other sensor at double the first
294 1 m2.set(28.0f);
295
296 // Should now be valid - and the average of the two input
297 {
298
1/1
✓ Branch 2 taken 1 time.
1 auto result = dut.get();
299
1/6
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 7 not taken.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
1 EXPECT_TRUE(result.Valid);
300
2/6
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
1 EXPECT_FLOAT_EQ(result.Value, 13.0f);
301
302
1/6
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
1 EXPECT_TRUE(dut.isRedundant());
303 }
304 1 }
305
306 4 TEST_F(SensorFordRedundantTps, DifferenceNone)
307 {
308 // Set both sensors to the same value
309 1 m1.set(10);
310 1 m2.set(20);
311
312 // Expect valid, and 10 output
313 {
314
1/1
✓ Branch 2 taken 1 time.
1 auto result = dut.get();
315
1/6
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 7 not taken.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
1 EXPECT_TRUE(result.Valid);
316
2/6
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
1 EXPECT_FLOAT_EQ(result.Value, 10.0f);
317 }
318 1 }
319
320 4 TEST_F(SensorFordRedundantTps, DifferenceNearLimit)
321 {
322 // Set both sensors to nearly the limit (4.998 apart)
323 1 m1.set(7.501f);
324 1 m2.set(2 * 12.499f);
325
326 // Expect valid, and 10 output
327 {
328
1/1
✓ Branch 2 taken 1 time.
1 auto result = dut.get();
329
1/6
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 7 not taken.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
1 EXPECT_TRUE(result.Valid);
330
2/6
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
1 EXPECT_FLOAT_EQ(result.Value, 10.0f);
331 }
332 1 }
333
334 4 TEST_F(SensorFordRedundantTps, DifferenceOverLimit)
335 {
336 // Set both sensors barely over the limit (5.002 apart)
337 1 m1.set(7.499f);
338 1 m2.set(2 * 12.501f);
339
340 // Expect invalid
341 {
342 1 auto result = dut.get();
343
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
344 }
345 1 }
346
347 4 TEST_F(SensorFordRedundantTps, DifferenceOverLimitSwapped)
348 {
349 // Now try it the other way (m1 > m2)
350 1 m1.set(12.501f);
351 1 m2.set(2 * 7.499f);
352
353 // Expect invalid
354 {
355 1 auto result = dut.get();
356
1/6
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 EXPECT_FALSE(result.Valid);
357 }
358 1 }
359
360 4 TEST_F(SensorFordRedundantTps, HighRange)
361 {
362 // Set the throttle like it's at 75%
363 1 m1.set(75);
364 1 m2.set(100);
365
366 // expect valid, at 75%
367 {
368
1/1
✓ Branch 2 taken 1 time.
1 auto result = dut.get();
369
1/6
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 7 not taken.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
1 EXPECT_TRUE(result.Valid);
370
2/6
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
1 EXPECT_FLOAT_EQ(result.Value, 75.0f);
371 }
372 1 }
373