GCC Code Coverage Report


Directory: ./
File: unit_tests/tests/ignition_injection/injection_mode_transition.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 100.0% 52 0 52
Functions: 100.0% 4 0 4
Branches: 50.6% 42 0 83
Decisions: 100.0% 2 - 2

Line Branch Decision Exec Source
1 /*
2 * @file injection_mode_transition.cpp
3 *
4 * Created on: Jul 19, 2020
5 * @author Andrey Belomutskiy, (c) 2012-2020
6 */
7
8 #include "pch.h"
9
10 using ::testing::_;
11
12 11 static void doRevolution(EngineTestHelper& eth, int periodMs) {
13 11 float halfToothTime = (periodMs / 6.0f) / 2;
14
15 11 eth.smartFireRise(halfToothTime);
16 11 eth.fireFall(halfToothTime);
17 11 eth.smartFireRise(halfToothTime);
18 11 eth.fireFall(halfToothTime);
19 11 eth.smartFireRise(halfToothTime);
20 11 eth.fireFall(halfToothTime);
21
22 // now missing tooth
23 11 eth.smartFireRise(halfToothTime);
24 11 eth.fireFall(3 * halfToothTime);
25
26 // This tooth is the sync point!
27 11 eth.smartFireRise(halfToothTime);
28 11 eth.fireFall(halfToothTime);
29 11 }
30
31 // https://github.com/rusefi/rusefi/issues/1592
32 4 TEST(fuelControl, transitionIssue1592) {
33 extern bool unitTestTaskPrecisionHack;
34 1 unitTestTaskPrecisionHack = true;
35
1/1
✓ Branch 2 taken 1 time.
1 EngineTestHelper eth(engine_type_e::TEST_ENGINE);
36 1 engine->tdcMarkEnabled = false;
37
1/1
✓ Branch 1 taken 1 time.
1 setupSimpleTestEngineWithMafAndTT_ONE_trigger(&eth, IM_SEQUENTIAL);
38
39
5/5
✓ Branch 3 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 13 taken 1 time.
✓ Branch 17 taken 1 time.
3 EXPECT_CALL(*eth.mockAirmass, getAirmass(500, _))
40
3/3
✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
3 .WillRepeatedly(Return(AirmassResult{0.1008f, 50.0f}));
41
42 // This is easiest to trip on a wheel that requires sync
43 1 engineConfiguration->trigger.customTotalToothCount = 6;
44 1 engineConfiguration->trigger.customSkippedToothCount = 1;
45
1/1
✓ Branch 1 taken 1 time.
1 eth.setTriggerType(trigger_type_e::TT_TOOTHED_WHEEL);
46
1/1
✓ Branch 1 taken 1 time.
1 setCamOperationMode();
47 1 engineConfiguration->isFasterEngineSpinUpEnabled = true;
48
49 1 setTable(config->injectionPhase, 0.0f);
50 1 setArrayValues(config->crankingFuelCoef, 1.0f);
51
52
53 1 engineConfiguration->globalTriggerAngleOffset = 20;
54
55 // Yes, this is a ton of fuel but it makes the repro easier
56 1 setTable(config->crankingCycleBaseFuel, 213.6);
57 1 engineConfiguration->cranking.rpm = 501;
58
59 // Test the transition from batch cranking to sequential running
60 1 engineConfiguration->crankingInjectionMode = IM_BATCH;
61
62 // First sync point will schedule cranking pulse since we're in "faster spin up" mode
63
1/1
✓ Branch 1 taken 1 time.
1 doRevolution(eth, 240);
64
65 {
66 // Injector 2 should be scheduled to open then close
67 1 auto inj2 = &engine->injectionEvents.elements[1];
68 1 auto const taggedPointer{TaggedPointer<decltype(this)>::make(inj2, false)};
69 1 auto const aHigh{ action_s::make<turnInjectionPinHigh>( taggedPointer.getRaw() ) };
70 1 auto const aLow{ action_s::make<turnInjectionPinLow>( inj2 ) };
71
72
4/9
✓ Branch 4 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(engine->scheduler.size(), 2);
73
74 // Check that the action is correct - we don't care about the timing necessarily
75
1/1
✓ Branch 1 taken 1 time.
1 auto sched_open = engine->scheduler.getForUnitTest(0);
76
3/8
✓ Branch 5 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
1 ASSERT_EQ(sched_open->action.getArgumentRaw(), taggedPointer.getRaw());
77
3/8
✓ Branch 6 taken 1 time.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 time.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 1 time.
✗ Branch 31 not taken.
1 ASSERT_EQ(sched_open->action.getCallback(), aHigh.getCallback());
78
79
1/1
✓ Branch 1 taken 1 time.
1 auto sched_close = engine->scheduler.getForUnitTest(1);
80 // Next action should be closing the same injector
81
3/8
✓ Branch 5 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
1 ASSERT_EQ(sched_close->action.getArgumentRaw(), taggedPointer.getRaw());
82
3/8
✓ Branch 6 taken 1 time.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 time.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 1 time.
✗ Branch 31 not taken.
1 ASSERT_EQ(sched_close->action.getCallback(), aLow.getCallback());
83 }
84
85 // Run the engine for some revs
86
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
2/2
✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
11 for (size_t i = 0; i < 10; i++) {
87
1/1
✓ Branch 1 taken 10 times.
10 doRevolution(eth, 150);
88 }
89
90 // Check that no injectors are stuck open
91 // Injectors 1/3 should be open
92
2/6
✓ Branch 5 taken 1 time.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 time.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
1 EXPECT_EQ(enginePins.injectors[0].getOverlappingCounter(), 1);
93
2/6
✓ Branch 5 taken 1 time.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 time.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
1 EXPECT_EQ(enginePins.injectors[1].getOverlappingCounter(), 0);
94
2/6
✓ Branch 5 taken 1 time.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 time.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
1 EXPECT_EQ(enginePins.injectors[2].getOverlappingCounter(), 1);
95
2/6
✓ Branch 5 taken 1 time.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 time.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
1 EXPECT_EQ(enginePins.injectors[3].getOverlappingCounter(), 0);
96 1 }
97