GCC Code Coverage Report


Directory: ./
File: unit_tests/tests/trigger/test_injection_scheduling.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 100.0% 125 0 125
Functions: 100.0% 16 0 16
Branches: 100.0% 166 0 166
Decisions: -% 0 - 0

Line Branch Decision Exec Source
1 #include "pch.h"
2 #include "main_trigger_callback.h"
3 #include "injector_model.h"
4
5 using ::testing::_;
6 using ::testing::StrictMock;
7 using ::testing::InSequence;
8
9 using ::testing::Eq;
10 using ::testing::Not;
11 using ::testing::Property;
12 using ::testing::Truly;
13
14 4 static bool ActionArgumentHasLowBitSet(const action_s& a) {
15 4 auto const tmp{ TaggedPointer<InjectionEvent>::fromRaw(a.getArgumentRaw()) };
16 4 return tmp.getFlag() != 0;
17 }
18
19 4 TEST(injectionScheduling, InjectionIsScheduled) {
20
1/1
✓ Branch 2 taken 1 time.
1 StrictMock<MockExecutor> mockExec;
21
22
1/1
✓ Branch 2 taken 1 time.
1 EngineTestHelper eth(engine_type_e::TEST_ENGINE);
23
1/1
✓ Branch 1 taken 1 time.
1 engine->scheduler.setMockExecutor(&mockExec);
24
25 1 efitick_t nowNt = 1000000;
26
27 1 InjectionEvent event;
28
1/1
✓ Branch 2 taken 1 time.
1 InjectorOutputPin pin;
29 1 pin.injectorIndex = 0;
30 1 event.outputs[0] = &pin;
31
32 // Injection duration of 20ms
33
1/1
✓ Branch 2 taken 1 time.
1 MockInjectorModel2 im;
34
7/7
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 22 taken 1 time.
✓ Branch 25 taken 1 time.
1 EXPECT_CALL(im, getInjectionDuration(_)).WillOnce(Return(20.0f));
35
1/1
✓ Branch 1 taken 1 time.
1 engine->module<InjectorModelPrimary>().set(&im);
36
37 1 engine->rpmCalculator.oneDegreeUs = 100;
38
39 {
40
1/1
✓ Branch 2 taken 1 time.
1 InSequence is;
41
42 // Should schedule one normal injection:
43 // rising edge 5 degrees from now
44 1 float nt5deg = USF2NT(engine->rpmCalculator.oneDegreeUs * 5);
45 1 efitick_t startTime = nowNt + nt5deg;
46
10/10
✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 23 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 29 taken 1 time.
✓ Branch 33 taken 1 time.
✓ Branch 37 taken 1 time.
1 EXPECT_CALL(mockExec, schedule(testing::NotNull(), _, startTime, Not(Truly(ActionArgumentHasLowBitSet))));
47 // falling edge 20ms later
48
10/10
✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 24 taken 1 time.
✓ Branch 27 taken 1 time.
✓ Branch 30 taken 1 time.
✓ Branch 34 taken 1 time.
✓ Branch 38 taken 1 time.
1 EXPECT_CALL(mockExec, schedule(testing::NotNull(), _, startTime + MS2NT(20), Property(&action_s::getArgumentRaw, Eq(reinterpret_cast<uintptr_t>(&event)))));
49 1 }
50
51 // Event scheduled at 125 degrees
52 1 event.injectionStartAngle = 125;
53
54 // We are at 120 degrees now, next tooth 130
55
1/1
✓ Branch 1 taken 1 time.
1 event.onTriggerTooth(nowNt, 120, 130);
56 2 }
57
58 4 TEST(injectionScheduling, InjectionIsScheduledDualStage) {
59
1/1
✓ Branch 2 taken 1 time.
1 StrictMock<MockExecutor> mockExec;
60
1/1
✓ Branch 2 taken 1 time.
1 StrictMock<MockInjectorModel2> im;
61
62
1/1
✓ Branch 2 taken 1 time.
1 EngineTestHelper eth(engine_type_e::TEST_ENGINE);
63
1/1
✓ Branch 1 taken 1 time.
1 engine->scheduler.setMockExecutor(&mockExec);
64
1/1
✓ Branch 1 taken 1 time.
1 engine->module<InjectorModelPrimary>().set(&im);
65
1/1
✓ Branch 1 taken 1 time.
1 engine->module<InjectorModelSecondary>().set(&im);
66
67 1 efitick_t nowNt = 1000000;
68
69 1 InjectionEvent event;
70
1/1
✓ Branch 2 taken 1 time.
1 InjectorOutputPin pin;
71 1 pin.injectorIndex = 0;
72 1 event.outputs[0] = &pin;
73
74 1 engine->rpmCalculator.oneDegreeUs = 100;
75
76 // Some nonzero fuel quantity on both stages
77 1 engine->engineState.injectionMass[0] = 50;
78 1 engine->engineState.injectionStage2Fraction = 0.2;
79
80 {
81
1/1
✓ Branch 2 taken 1 time.
1 InSequence is;
82
83 // Primary injection duration of 20ms, secondary 10ms
84
7/7
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 22 taken 1 time.
✓ Branch 25 taken 1 time.
1 EXPECT_CALL(im, getInjectionDuration(40)).WillOnce(Return(20.0f));
85
7/7
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 22 taken 1 time.
✓ Branch 25 taken 1 time.
1 EXPECT_CALL(im, getInjectionDuration(10)).WillOnce(Return(10.0f));
86 1 }
87
88 {
89
1/1
✓ Branch 2 taken 1 time.
1 InSequence is;
90
91 // Should schedule one normal injection:
92 // rising edge 5 degrees from now
93 1 float nt5deg = USF2NT(engine->rpmCalculator.oneDegreeUs * 5);
94 1 efitick_t startTime = nowNt + nt5deg;
95
9/9
✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 11 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 20 taken 1 time.
✓ Branch 23 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 30 taken 1 time.
✓ Branch 34 taken 1 time.
1 EXPECT_CALL(mockExec, schedule(testing::NotNull(), _, startTime, Truly(ActionArgumentHasLowBitSet)));
96 // falling edge (primary) 20ms later
97
10/10
✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 24 taken 1 time.
✓ Branch 27 taken 1 time.
✓ Branch 30 taken 1 time.
✓ Branch 34 taken 1 time.
✓ Branch 38 taken 1 time.
1 EXPECT_CALL(mockExec, schedule(testing::NotNull(), _, startTime + MS2NT(20), Property(&action_s::getArgumentRaw, Eq(reinterpret_cast<uintptr_t>(&event)))));
98 // falling edge (secondary) 10ms later
99
10/10
✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 24 taken 1 time.
✓ Branch 27 taken 1 time.
✓ Branch 30 taken 1 time.
✓ Branch 34 taken 1 time.
✓ Branch 38 taken 1 time.
1 EXPECT_CALL(mockExec, schedule(testing::NotNull(), _, startTime + MS2NT(10), Property(&action_s::getArgumentRaw, Eq(reinterpret_cast<uintptr_t>(&event)))));
100 1 }
101
102 // Event scheduled at 125 degrees
103 1 event.injectionStartAngle = 125;
104
105 // We are at 120 degrees now, next tooth 130
106
1/1
✓ Branch 1 taken 1 time.
1 event.onTriggerTooth(nowNt, 120, 130);
107 2 }
108
109 4 TEST(injectionScheduling, InjectionIsScheduledBeforeWraparound) {
110
1/1
✓ Branch 2 taken 1 time.
1 StrictMock<MockExecutor> mockExec;
111
112
1/1
✓ Branch 2 taken 1 time.
1 EngineTestHelper eth(engine_type_e::TEST_ENGINE);
113
1/1
✓ Branch 1 taken 1 time.
1 engine->scheduler.setMockExecutor(&mockExec);
114
115 1 efitick_t nowNt = 1000000;
116
117 1 InjectionEvent event;
118
1/1
✓ Branch 2 taken 1 time.
1 InjectorOutputPin pin;
119 1 pin.injectorIndex = 0;
120 1 event.outputs[0] = &pin;
121
122 // Injection duration of 20ms
123
1/1
✓ Branch 2 taken 1 time.
1 MockInjectorModel2 im;
124
7/7
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 22 taken 1 time.
✓ Branch 25 taken 1 time.
1 EXPECT_CALL(im, getInjectionDuration(_)).WillOnce(Return(20.0f));
125
1/1
✓ Branch 1 taken 1 time.
1 engine->module<InjectorModelPrimary>().set(&im);
126
127 1 engine->rpmCalculator.oneDegreeUs = 100;
128
129 {
130
1/1
✓ Branch 2 taken 1 time.
1 InSequence is;
131
132 // Should schedule one normal injection:
133 // rising edge 5 degrees from now
134 1 float nt5deg = USF2NT(engine->rpmCalculator.oneDegreeUs * 5);
135 1 efitick_t startTime = nowNt + nt5deg;
136
10/10
✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 23 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 29 taken 1 time.
✓ Branch 33 taken 1 time.
✓ Branch 37 taken 1 time.
1 EXPECT_CALL(mockExec, schedule(testing::NotNull(), _, startTime, Not(Truly(ActionArgumentHasLowBitSet))));
137 // falling edge 20ms later
138
10/10
✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 24 taken 1 time.
✓ Branch 27 taken 1 time.
✓ Branch 30 taken 1 time.
✓ Branch 34 taken 1 time.
✓ Branch 38 taken 1 time.
1 EXPECT_CALL(mockExec, schedule(testing::NotNull(), _, startTime + MS2NT(20), Property(&action_s::getArgumentRaw, Eq(reinterpret_cast<uintptr_t>(&event)))));
139 1 }
140
141 // Event scheduled at 715 degrees
142 1 event.injectionStartAngle = 715;
143
144 // We are at 710 degrees now, next tooth 010
145
1/1
✓ Branch 1 taken 1 time.
1 event.onTriggerTooth(nowNt, 710, 010);
146 2 }
147
148 4 TEST(injectionScheduling, InjectionIsScheduledAfterWraparound) {
149
1/1
✓ Branch 2 taken 1 time.
1 StrictMock<MockExecutor> mockExec;
150
151
1/1
✓ Branch 2 taken 1 time.
1 EngineTestHelper eth(engine_type_e::TEST_ENGINE);
152
1/1
✓ Branch 1 taken 1 time.
1 engine->scheduler.setMockExecutor(&mockExec);
153
154 1 efitick_t nowNt = 1000000;
155
156 1 InjectionEvent event;
157
1/1
✓ Branch 2 taken 1 time.
1 InjectorOutputPin pin;
158 1 pin.injectorIndex = 0;
159 1 event.outputs[0] = &pin;
160
161 // Injection duration of 20ms
162
1/1
✓ Branch 2 taken 1 time.
1 MockInjectorModel2 im;
163
7/7
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 22 taken 1 time.
✓ Branch 25 taken 1 time.
1 EXPECT_CALL(im, getInjectionDuration(_)).WillOnce(Return(20.0f));
164
1/1
✓ Branch 1 taken 1 time.
1 engine->module<InjectorModelPrimary>().set(&im);
165
166 1 engine->rpmCalculator.oneDegreeUs = 100;
167
168 {
169
1/1
✓ Branch 2 taken 1 time.
1 InSequence is;
170
171 // Should schedule one normal injection:
172 // rising edge 15 degrees from now
173 1 float nt5deg = USF2NT(engine->rpmCalculator.oneDegreeUs * 15);
174 1 efitick_t startTime = nowNt + nt5deg;
175
10/10
✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 23 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 29 taken 1 time.
✓ Branch 33 taken 1 time.
✓ Branch 37 taken 1 time.
1 EXPECT_CALL(mockExec, schedule(testing::NotNull(), _, startTime, Not(Truly(ActionArgumentHasLowBitSet))));
176 // falling edge 20ms later
177
10/10
✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
✓ Branch 15 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 24 taken 1 time.
✓ Branch 27 taken 1 time.
✓ Branch 30 taken 1 time.
✓ Branch 34 taken 1 time.
✓ Branch 38 taken 1 time.
1 EXPECT_CALL(mockExec, schedule(testing::NotNull(), _, startTime + MS2NT(20), Property(&action_s::getArgumentRaw, Eq(reinterpret_cast<uintptr_t>(&event)))));
178 1 }
179
180 // Event scheduled at 5 degrees
181 1 event.injectionStartAngle = 5;
182
183 // We are at 710 degrees now, next tooth 010
184
1/1
✓ Branch 1 taken 1 time.
1 event.onTriggerTooth(nowNt, 710, 010);
185 2 }
186
187 4 TEST(injectionScheduling, InjectionNotScheduled) {
188 // StrictMock since we expect no scheduler calls!
189
1/1
✓ Branch 2 taken 1 time.
1 StrictMock<MockExecutor> mockExec;
190
191
1/1
✓ Branch 2 taken 1 time.
1 EngineTestHelper eth(engine_type_e::TEST_ENGINE);
192
1/1
✓ Branch 1 taken 1 time.
1 engine->scheduler.setMockExecutor(&mockExec);
193
194 1 efitick_t nowNt = 1000000;
195
196 1 InjectionEvent event;
197
1/1
✓ Branch 2 taken 1 time.
1 InjectorOutputPin pin;
198 1 pin.injectorIndex = 0;
199 1 event.outputs[0] = &pin;
200
201 // Expect no calls to injector model
202
1/1
✓ Branch 2 taken 1 time.
1 StrictMock<MockInjectorModel2> im;
203
1/1
✓ Branch 1 taken 1 time.
1 engine->module<InjectorModelPrimary>().set(&im);
204
205 1 engine->rpmCalculator.oneDegreeUs = 100;
206
207 {
208
1/1
✓ Branch 2 taken 1 time.
1 InSequence is;
209
210 // Expect no scheduler calls!
211 1 }
212
213
214 // Event scheduled at 125 degrees
215 1 event.injectionStartAngle = 125;
216
217 // We are at 130 degrees now, next tooth 140
218
1/1
✓ Branch 1 taken 1 time.
1 event.onTriggerTooth(nowNt, 130, 140);
219 2 }
220