| Line | Branch | Decision | Exec | Source |
|---|---|---|---|---|
| 1 | /** | |||
| 2 | * @file engine_test_helper.h | |||
| 3 | * | |||
| 4 | * @date Jun 26, 2014 | |||
| 5 | * @author Andrey Belomutskiy, (c) 2012-2020 | |||
| 6 | */ | |||
| 7 | ||||
| 8 | #pragma once | |||
| 9 | ||||
| 10 | #include "trigger_central.h" | |||
| 11 | #include "main_trigger_callback.h" | |||
| 12 | #include "unit_test_framework.h" | |||
| 13 | #include "engine.h" | |||
| 14 | ||||
| 15 | #include <unordered_map> | |||
| 16 | ||||
| 17 | extern EnginePins enginePins; | |||
| 18 | ||||
| 19 | class EngineTestHelperBase | |||
| 20 | { | |||
| 21 | public: | |||
| 22 | // we have the base method and base constructor in order to better control order if initialization | |||
| 23 | // base constructor contains things which need to be executed first | |||
| 24 | EngineTestHelperBase(Engine * eng, engine_configuration_s * config, persistent_config_s * pers); | |||
| 25 | ~EngineTestHelperBase(); | |||
| 26 | }; | |||
| 27 | ||||
| 28 | /** | |||
| 29 | * Mock engine with trigger signal simulation infrastructure | |||
| 30 | */ | |||
| 31 | class EngineTestHelper : public EngineTestHelperBase { | |||
| 32 | public: | |||
| 33 | explicit EngineTestHelper(engine_type_e engineType); | |||
| 34 | EngineTestHelper(engine_type_e engineType, const std::unordered_map<SensorType, float>& sensorValues); | |||
| 35 | EngineTestHelper(engine_type_e engineType, configuration_callback_t boardCallback); | |||
| 36 | EngineTestHelper(engine_type_e engineType, configuration_callback_t boardCallback, const std::unordered_map<SensorType, float>& sensorValues); | |||
| 37 | ~EngineTestHelper(); | |||
| 38 | ||||
| 39 | // convert ms time to angle at current RPM | |||
| 40 | angle_t timeToAngle(float timeMs); | |||
| 41 | 18 | float angleToTimeUs(angle_t angle) { | ||
| 42 | 18 | return angle * engine.rpmCalculator.oneDegreeUs; | ||
| 43 | } | |||
| 44 | ||||
| 45 | float angleToTimeMs(angle_t angle) { | |||
| 46 | return US2MS(angleToTimeUs(angle)); | |||
| 47 | } | |||
| 48 | ||||
| 49 | warningBuffer_t *recentWarnings(); | |||
| 50 | int getWarningCounter(); | |||
| 51 | ||||
| 52 | void applyTriggerWaveform(); | |||
| 53 | void setTriggerType(trigger_type_e trigger); | |||
| 54 | /** | |||
| 55 | * DEPRECATED these methods do not execute events on the queue | |||
| 56 | */ | |||
| 57 | void fireRise(float delayMs); | |||
| 58 | void fireFall(float delayMs); | |||
| 59 | void moveTimeForwardUs(int deltaTimeUs); | |||
| 60 | void fireTriggerEvents2(int count, float delayMs); | |||
| 61 | ||||
| 62 | /** | |||
| 63 | * these methods execute events while moving time forward | |||
| 64 | * todo: better naming convention? | |||
| 65 | */ | |||
| 66 | void smartFireRise(float delayMs); | |||
| 67 | void smartFireFall(float delayMs); | |||
| 68 | void moveTimeForwardAndInvokeEventsUs(int deltaTimeUs); | |||
| 69 | void setTimeAndInvokeEventsUs(int timeNowUs); | |||
| 70 | void moveTimeForwardAndInvokeEventsSec(int deltaTimeSeconds); | |||
| 71 | /** | |||
| 72 | * both Rise and Fall | |||
| 73 | */ | |||
| 74 | void smartFireTriggerEvents2(int count, float delayMs); | |||
| 75 | ||||
| 76 | /** | |||
| 77 | * See also #fireRise() which would also move time forward | |||
| 78 | */ | |||
| 79 | void firePrimaryTriggerRise(); | |||
| 80 | /** | |||
| 81 | * See also #fireFall() which would also move time forward | |||
| 82 | */ | |||
| 83 | void firePrimaryTriggerFall(); | |||
| 84 | void fireTriggerEvents(int count); | |||
| 85 | void fireTriggerEventsWithDuration(float delayMs); | |||
| 86 | /** | |||
| 87 | * todo: better method name since this method executes events in the FUTURE | |||
| 88 | * looks like such a method should be used only in some pretty narrow circumstances | |||
| 89 | * a healthy test should probably use executeActions instead? | |||
| 90 | */ | |||
| 91 | void clearQueue(); | |||
| 92 | ||||
| 93 | scheduling_s * assertEvent5(const char *msg, int index, action_s const& action, efitimeus_t expectedTimestamp); | |||
| 94 | scheduling_s * assertScheduling(const char *msg, int index, scheduling_s *expected, action_s const& action, efitimeus_t expectedTimestamp); | |||
| 95 | ||||
| 96 | const AngleBasedEvent* assertTriggerEvent(const char *msg, int index, AngleBasedEvent *expected, action_s const& action, angle_t enginePhase); | |||
| 97 | ||||
| 98 | void assertEvent(const char *msg, int index, action_s const& action, efitimeus_t momentUs, InjectionEvent *event); | |||
| 99 | void assertInjectorUpEvent(const char *msg, int eventIndex, efitimeus_t momentUs, long injectorIndex); | |||
| 100 | void assertInjectorDownEvent(const char *msg, int eventIndex, efitimeus_t momentUs, long injectorIndex); | |||
| 101 | // todo: open question if this is worth a helper method or should be inlined? | |||
| 102 | void assertRpm(int expectedRpm, const char *msg = "RPM"); | |||
| 103 | ||||
| 104 | // read all scheluder queue and search for the requested callback, then asserts the expected angle, return true if we found the callback | |||
| 105 | bool assertEventExistsAtEnginePhase(const char *msg, action_s const& action, angle_t expectedEventEnginePhase); | |||
| 106 | ||||
| 107 | // spins the engine using 60-2 trigger pattern, at target RPM, by X crank degree, not engine phase degree | |||
| 108 | void spin60_2UntilDeg(struct testSpinEngineUntilData& spinInfo, int targetRpm, float targetDegree); | |||
| 109 | ||||
| 110 | int executeActions(); | |||
| 111 | void moveTimeForwardMs(float deltaTimeMs); | |||
| 112 | void moveTimeForwardSec(float deltaTimeSec); | |||
| 113 | ||||
| 114 | Engine engine; | |||
| 115 | persistent_config_s persistentConfig; | |||
| 116 | ||||
| 117 | std::unique_ptr<::testing::NiceMock<MockAirmass>> mockAirmass; | |||
| 118 | ||||
| 119 | private: | |||
| 120 | void writeEventsLogicData(const char *fileName); | |||
| 121 | void writeEvents2(const char *fileName); | |||
| 122 | }; | |||
| 123 | ||||
| 124 | void setupSimpleTestEngineWithMafAndTT_ONE_trigger(EngineTestHelper *eth, injection_mode_e injMode = IM_BATCH); | |||
| 125 | void setupSimpleTestEngineWithMaf(EngineTestHelper *eth, injection_mode_e injectionMode, trigger_type_e trigger); | |||
| 126 | ||||
| 127 | void setVerboseTrigger(bool isEnabled); | |||
| 128 | ||||
| 129 | warningBuffer_t * getRecentWarnings(); | |||
| 130 | ||||
| 131 | // used by EngineTestHelper::spin60_2UntilDeg func | |||
| 132 | struct testSpinEngineUntilData { | |||
| 133 | float currentDegree; | |||
| 134 | int currentTooth; | |||
| 135 | int toothCount; | |||
| 136 | }; | |||
| 137 |