GCC Code Coverage Report


Directory: ./
File: unit_tests/tests/trigger/test_coil.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 100.0% 79 0 79
Functions: 100.0% 4 0 4
Branches: 33.7% 70 0 208
Decisions: -% 0 - 0

Line Branch Decision Exec Source
1 //
2 // Created by kifir on 5/5/24.
3 //
4
5 #include "pch.h"
6
7 using ::testing::_;
8
9 // Magic below is the simplest way to schedule overdwell sparkDown that I found in
10 // testAssertWeAreNotMissingASpark299.
11 //
12 // eth.smartFireFall(20);
13 //
14 // after this method will schedule over fire spark.
15 // P.S. May be later we will be able to simplify this spell.
16 1 static void prepareToScheduleOverdwellSparkDown(EngineTestHelper& eth) {
17 1 engineConfiguration->ignitionMode = IM_WASTED_SPARK;
18 1 setupSimpleTestEngineWithMafAndTT_ONE_trigger(&eth);
19 1 engineConfiguration->isIgnitionEnabled = true;
20 1 engineConfiguration->isInjectionEnabled = false;
21
22
4/10
✓ Branch 3 taken 1 time.
✓ Branch 8 taken 1 time.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 time.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 25 not taken.
✗ Branch 28 not taken.
✓ Branch 35 taken 1 time.
✗ Branch 36 not taken.
1 ASSERT_EQ( 0u, getRecentWarnings()->getCount()) << "warningCounter#0";
23
24 1 eth.smartFireRise(20);
25
3/9
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✓ Branch 29 taken 1 time.
✗ Branch 30 not taken.
1 ASSERT_EQ( 0u, engine->triggerCentral.triggerState.currentCycle.current_index) << "ci#0";
26
27 1 eth.smartFireFall(20);
28
3/9
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✓ Branch 29 taken 1 time.
✗ Branch 30 not taken.
1 ASSERT_EQ( 1u, engine->triggerCentral.triggerState.currentCycle.current_index) << "ci#1";
29
30 1 eth.smartFireRise(20);
31
3/9
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✓ Branch 29 taken 1 time.
✗ Branch 30 not taken.
1 ASSERT_EQ( 0u, engine->triggerCentral.triggerState.currentCycle.current_index) << "ci#2";
32
33 1 eth.smartFireFall(20);
34
3/9
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✓ Branch 29 taken 1 time.
✗ Branch 30 not taken.
1 ASSERT_EQ( 1u, engine->triggerCentral.triggerState.currentCycle.current_index) << "ci#3";
35
36 1 eth.smartFireRise(20);
37
38 1 eth.smartFireFall(20);
39
3/9
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✓ Branch 29 taken 1 time.
✗ Branch 30 not taken.
1 ASSERT_EQ( 1u, eth.engine.triggerCentral.triggerState.currentCycle.current_index) << "ci#5";
40
41
4/9
✓ Branch 3 taken 1 time.
✓ Branch 7 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 31 taken 1 time.
✗ Branch 32 not taken.
1 ASSERT_EQ(3000, Sensor::getOrZero(SensorType::Rpm));
42
43 // negative advance is rarely used but worth testing considering all out angleWrap.
44 1 setWholeTimingTable(-5);
45 1 eth.engine.periodicFastCallback();
46
47 1 eth.smartFireRise(20);
48 }
49
50 4 TEST(coil, testOverdwellProtection) {
51 extern bool unitTestTaskPrecisionHack;
52 1 unitTestTaskPrecisionHack = true;
53
1/1
✓ Branch 1 taken 1 time.
1 printf("*************************************************** testOverdwellProtection\r\n");
54
55
1/1
✓ Branch 2 taken 1 time.
1 EngineTestHelper eth(engine_type_e::TEST_ENGINE);
56 2 engine->onScheduleOverFireSparkAndPrepareNextSchedule = [&](const IgnitionEvent&, efitick_t) -> void {
57 FAIL() << "Unexpected scheduling of overFireSparkAndPrepareNextSchedule";
58 1 };
59
60
1/1
✓ Branch 1 taken 1 time.
1 prepareToScheduleOverdwellSparkDown(eth);
61
62
1/1
✓ Branch 1 taken 1 time.
1 printf("*************************************************** testOverdwellProtection start\r\n");
63
64 // Magic above is the simpliest way to schedule overdwell sparkDown that I found in
65 // testAssertWeAreNotMissingASpark299. May be later we will be able to simplify this spell.
66
67 1 const IgnitionOutputPin& testCoil = enginePins.coils[0];
68
2/2
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
3 const std::string testOutputName(testCoil.getName());
69
3/9
✓ Branch 3 taken 1 time.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
1 ASSERT_STREQ("Coil 1", testOutputName.c_str()) << "Unexpected test output name";
70
71 1 std::optional<efitick_t> turnSparkPinHighStartChargingTimestamp;
72 1 std::optional<uint32_t> testSparkCounter;
73 1 engine->onScheduleTurnSparkPinHighStartCharging =
74 1 [&](const IgnitionEvent& event, efitick_t, angle_t, efitick_t chargeTime) -> void {
75 if (testOutputName == event.outputs[0]->getName()) {
76 EXPECT_FALSE(turnSparkPinHighStartChargingTimestamp.has_value())
77 << "Extra scheduled overFireSparkAndPrepareNextSchedule";
78 turnSparkPinHighStartChargingTimestamp = chargeTime;
79 testSparkCounter = event.sparkCounter;
80 }
81
1/1
✓ Branch 1 taken 1 time.
1 };
82
83 1 std::optional<efitick_t> overFireSparkAndPrepareNextTimestamp;
84 1 engine->onScheduleOverFireSparkAndPrepareNextSchedule =
85 1 [&](const IgnitionEvent& event, efitick_t fireTime) -> void {
86 EXPECT_STREQ(testOutputName.c_str(), event.outputs[0]->getName())
87 << "overFireSparkAndPrepareNextSchedule is scheduled for unexpected output";
88 EXPECT_FALSE(overFireSparkAndPrepareNextTimestamp.has_value())
89 << "Extra scheduled overFireSparkAndPrepareNextSchedule";
90 overFireSparkAndPrepareNextTimestamp = fireTime;
91 ASSERT_TRUE(testSparkCounter.has_value()) << "Missed scheduled turnSparkPinHighStartCharging";
92 EXPECT_EQ(testSparkCounter.value(), event.sparkCounter)
93 << "Scheduled overFireSparkAndPrepareNextSchedule doesn't match scheduled turnSparkPinHighStartCharging";
94
1/1
✓ Branch 1 taken 1 time.
1 };
95
96
1/1
✓ Branch 1 taken 1 time.
1 eth.smartFireFall(20); // this operation should schedule over fire spark
97
98
1/6
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 ASSERT_TRUE(turnSparkPinHighStartChargingTimestamp.has_value())
99
1/3
✗ Branch 1 not taken.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
1 << "Missed scheduled overFireSparkAndPrepareNextSchedule";
100
1/1
✓ Branch 1 taken 1 time.
1 const efitimeus_t expectedSparkUpTimestampUs = NT2US(turnSparkPinHighStartChargingTimestamp.value());
101
102 1 const efitimeus_t sparkDownOverdwellDurationUs = MS2US(1.5f * engine->ignitionState.sparkDwell);
103
2/7
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
1 EXPECT_EQ(4500, sparkDownOverdwellDurationUs) << "Unexpected sparkDown overdwell duration";
104
105
1/6
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
1 ASSERT_TRUE(overFireSparkAndPrepareNextTimestamp.has_value())
106
1/3
✗ Branch 1 not taken.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
1 << "Missed scheduled overFireSparkAndPrepareNextSchedule";
107
1/1
✓ Branch 2 taken 1 time.
1 const efitimeus_t expectedSparkDownOverdwellTimestampUs = NT2US(overFireSparkAndPrepareNextTimestamp.value());
108
2/6
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
1 EXPECT_EQ(expectedSparkDownOverdwellTimestampUs, expectedSparkUpTimestampUs + sparkDownOverdwellDurationUs);
109
110
2/8
✓ Branch 3 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
1 EXPECT_FALSE(testCoil.getLogicValue()) << "Test coil should be off";
111
112 1 engine->onScheduleTurnSparkPinHighStartCharging =
113 1 [&](const IgnitionEvent&, efitick_t, angle_t, efitick_t) -> void {
114 FAIL() << "Unexpected scheduling of turnSparkPinHighStartCharging";
115 1 };
116
117 1 engine->onScheduleOverFireSparkAndPrepareNextSchedule =
118 1 [&](const IgnitionEvent&, efitick_t) -> void {
119 FAIL() << "Unexpected scheduling of overFireSparkAndPrepareNextSchedule";
120 1 };
121
122 1 std::optional<int> testIgnitionEventState;
123 2 engine->onIgnitionEvent = [&](IgnitionEvent* event, bool state) -> void {
124 if (testOutputName == event->outputs[0]->getName()) {
125 EXPECT_EQ(testSparkCounter.value(), event->sparkCounter) << "Unexpected spark counter in ignition event";
126 testIgnitionEventState = state;
127 }
128
1/1
✓ Branch 1 taken 1 time.
1 };
129
130
1/1
✓ Branch 1 taken 1 time.
1 eth.setTimeAndInvokeEventsUs(expectedSparkUpTimestampUs - 1);
131
2/8
✓ Branch 3 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
1 EXPECT_FALSE(testCoil.getLogicValue()) << "Test still coil should be off";
132
1/7
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
1 EXPECT_FALSE(testIgnitionEventState.has_value()) << "Unexpected ignition event";
133
134
1/1
✓ Branch 1 taken 1 time.
1 eth.setTimeAndInvokeEventsUs(expectedSparkUpTimestampUs);
135
2/8
✓ Branch 3 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
1 EXPECT_TRUE(testCoil.getLogicValue()) << "Test coil should be on";
136
2/9
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
✓ Branch 34 taken 1 time.
✗ Branch 35 not taken.
1 ASSERT_TRUE(testIgnitionEventState.has_value()) << "Missed ignition event";
137
2/8
✓ Branch 2 taken 1 time.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
1 EXPECT_TRUE(testIgnitionEventState.value()) << "Unexpected state in ignition event";
138 1 testIgnitionEventState.reset();
139
140
1/1
✓ Branch 1 taken 1 time.
1 eth.setTimeAndInvokeEventsUs(expectedSparkDownOverdwellTimestampUs - 1);
141
2/8
✓ Branch 3 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
1 EXPECT_TRUE(testCoil.getLogicValue()) << "Test coil still should be on";
142
1/7
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
1 EXPECT_FALSE(testIgnitionEventState.has_value()) << "Unexpected ignition event";
143
144
1/1
✓ Branch 1 taken 1 time.
1 eth.setTimeAndInvokeEventsUs(expectedSparkDownOverdwellTimestampUs);
145
2/8
✓ Branch 3 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
1 EXPECT_FALSE(testCoil.getLogicValue()) << "Test coil should be off";
146
2/9
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
✓ Branch 34 taken 1 time.
✗ Branch 35 not taken.
1 ASSERT_TRUE(testIgnitionEventState.has_value()) << "Missed ignition event";
147
2/8
✓ Branch 3 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
1 EXPECT_FALSE(testIgnitionEventState.value()) << "Unexpected state in ignition event";
148 1 }
149