TEST(util, crc) { ASSERT_EQ(4, efiRound(4.4, 1)); ASSERT_FLOAT_EQ(1.2, efiRound(1.2345, 0.1)); print("*************************************** testCrc\r\n"); const char * A = "A"; ASSERT_EQ( 168, calc_crc((const crc_t *) A, 1)) << "crc8"; uint32_t c = crc32(A, 1); printf("crc32(A)=%x\r\n", c); assertEqualsM("crc32 1", 0xd3d99e8b, c); const char * line = "AbcDEFGF"; c = crc32(line, 8); printf("crc32(line)=%x\r\n", c); assertEqualsM("crc32 line", 0x4775a7b1, c); c = crc32(line, 1); c = crc32inc(line + 1, c, 8 - 1); assertEqualsM("crc32 line inc", 0x4775a7b1, c); }
void testSpeedDensity(void) { printf("*************************************************** testSpeedDensity\r\n"); EngineTestHelper eth(FORD_INLINE_6_1995); eth.ec->triggerConfig.customTotalToothCount = 8; eth.initTriggerShapeAndRpmCalculator(); eth.fireTriggerEvents(); assertEqualsM("RPM", 1500, eth.rpmState.rpm()); // 427 cubic inches, that's a LOT of engine eth.ec->displacement = 6.99728; eth.ec->cylindersCount = 8; eth.ec->injectorFlow = gramm_second_to_cc_minute(5.303); // 0.01414 sec or 14.14 ms assertEquals(0.01414, sdMath(eth.ec, 0.92, 98, 12.5, 293.16)); }
TEST(misc, testMisc) { print("******************************************* testMisc\r\n"); strcpy(buff, " ab "); // we need a mutable array here ASSERT_TRUE(strEqual("ab", efiTrim(buff))); { float v = atoff("1.0"); assertEqualsM("atoff", 1.0, v); } { float v = atoff("nan"); ASSERT_TRUE(cisnan(v)) << "NaN atoff"; } { float v = atoff("N"); ASSERT_TRUE(cisnan(v)) << "NaN atoff"; } // ASSERT_EQ(true, strEqual("spa3", getPinName(SPARKOUT_3_OUTPUT))); // ASSERT_EQ(SPARKOUT_12_OUTPUT, getPinByName("spa12")); }
void testAngleResolver(void) { printf("*************************************************** testAngleResolver\r\n"); EngineTestHelper eth(FORD_ASPIRE_1996); Engine *engine = ð.engine; engine_configuration_s *engineConfiguration = eth.engine.engineConfiguration; engineConfiguration->globalTriggerAngleOffset = 175; assertTrue(engine->engineConfiguration2!=NULL); trigger_shape_s * ts = &engine->triggerShape; confgiureFordAspireTriggerShape(ts); ts->calculateTriggerSynchPoint(engineConfiguration, engine); assertEqualsM("index 2", 228.0450, ts->eventAngles[3]); // this angle is relation to synch point assertEqualsM("time 2", 0.3233, ts->wave.getSwitchTime(2)); assertEqualsM("index 5", 413.7470, ts->eventAngles[6]); assertEqualsM("time 5", 0.5692, ts->wave.getSwitchTime(5)); assertEquals(4, ts->getTriggerShapeSynchPointIndex()); assertEqualsM("shape size", 10, ts->getSize()); OutputSignalList list; ae.resetEventList(); printf("*************************************************** testAngleResolver 0\r\n"); findTriggerPosition(&ae.getNextActuatorEvent()->position, 53 - 175 PASS_ENGINE_PARAMETER); assertEqualsM("size", 1, ae.size); assertEquals(1, ae.events[0].position.eventIndex); assertEquals(3.1588, ae.events[0].position.angleOffset); printf("*************************************************** testAngleResolver 2\r\n"); ae.resetEventList(); findTriggerPosition(&ae.getNextActuatorEvent()->position, 51 + 180 - 175 PASS_ENGINE_PARAMETER); assertEquals(2, ae.events[0].position.eventIndex); assertEquals(112.3495, ae.events[0].position.angleOffset); }
static void testNoiselessDecoderProcedure(EngineTestHelper ð, int errorToleranceCnt DECLARE_ENGINE_PARAMETER_SUFFIX) { printf("*** (bc->useNoiselessTriggerDecoder = %s)\r\n", CONFIGB(useNoiselessTriggerDecoder) ? "true" : "false"); resetTrigger(eth); // first, no noise fireNoisyCycle60_2(ð, 2, 1000, -1, 0, 0, 0); // should be no errors anyway ASSERT_EQ( 0, engine->triggerCentral.triggerState.totalTriggerErrorCounter) << "testNoiselessDecoderProcedure totalTriggerErrorCounter"; // check if we're imitating the 60-2 signal correctly ASSERT_EQ( 0, eth.engine.triggerCentral.triggerState.getCurrentIndex()) << "index #1"; // check rpm (60secs / (1000us * 60teeth)) = 1000rpm ASSERT_EQ( 1000, GET_RPM()) << "testNoiselessDecoder RPM"; // add noise1 - 1 spike in the middle of the 2nd rising pulse fireNoisyCycle60_2(ð, 2, 1000, 2, 10, 500, 1); assertEqualsM("testNoiselessDecoder noise#1", errorToleranceCnt, engine->triggerCentral.triggerState.totalTriggerErrorCounter); resetTrigger(eth); // add noise2 - 1 spike in the middle of the 2nd falling pulse fireNoisyCycle60_2(ð, 2, 1000, 3, 10, 500, 1); //assertEqualsM("noise#2", errorToleranceCnt, engine->triggerCentral.triggerState.totalTriggerErrorCounter); resetTrigger(eth); // add noise3 - in the middle of the sync.gap, // so that we cannot tell for sure if it's a start of another 'extra' tooth or just a noise inside the gap, // that's why we used expectedEventCount[] in our filtering algo to make a prediction about gap fireNoisyCycle60_2(ð, 2, 1000, 114, 10, 1500, 1); // so everything runs smoothly! assertEqualsM("noise#3", errorToleranceCnt, engine->triggerCentral.triggerState.totalTriggerErrorCounter); resetTrigger(eth); // add noise4 - too close to the start of the real next signal, so the noise spike is accepted as a signal // but when the real signal comes shortly afterwards, it we be treated as a noise spike, fireNoisyCycle60_2(ð, 2, 1000, 4, 10, 980, 1); // and we won't get out of sync! assertEqualsM("noise#4", errorToleranceCnt, engine->triggerCentral.triggerState.totalTriggerErrorCounter); resetTrigger(eth); // add noise5 - one very long 333us noise spike fireNoisyCycle60_2(ð, 2, 1000, 4, 333, 10, 1); // still ok assertEqualsM("noise#5", errorToleranceCnt, engine->triggerCentral.triggerState.totalTriggerErrorCounter); resetTrigger(eth); // add noise6 - 10 short spikes across the entire signal pulse const int failProofNumSpikes = 10; fireNoisyCycle60_2(ð, 2, 1000, 4, 5, 10, failProofNumSpikes); // we barely survived this time assertEqualsM("testNoiselessDecoder noise#6", errorToleranceCnt, engine->triggerCentral.triggerState.totalTriggerErrorCounter); resetTrigger(eth); // add noise7 - 34 short spikes across the entire signal pulse fireNoisyCycle60_2(ð, 2, 1000, 2, 10, 10, failProofNumSpikes + 1); // alas, this is a hard case even for noiseless decoder, and it fails... // but still we're close to 33% signal-noise ratio threshold - not bad! // so here's an error anyway! ASSERT_EQ( 1, engine->triggerCentral.triggerState.totalTriggerErrorCounter) << "testNoiselessDecoder noise#7_fail_test"; }
A_Test void whenComparingZeroAndZero_thenReturnsZero(void) { int n1 = 0; int n2 = 0; assertEqualsM("Comparing two equal numbers must return 0.", 0, compareInt(&n1, &n2)); }
void testFuelMap(void) { printf("*************************************************** testFuelMap\r\n"); EngineTestHelper eth(FORD_ASPIRE_1996); for (int k = 0; k < FUEL_LOAD_COUNT; k++) { for (int r = 0; r < FUEL_RPM_COUNT; r++) { eth.engine.engineConfiguration->fuelTable[k][r] = k * 200 + r; } } for (int i = 0; i < FUEL_LOAD_COUNT; i++) eth.engine.engineConfiguration->fuelLoadBins[i] = i; for (int i = 0; i < FUEL_RPM_COUNT; i++) eth.engine.engineConfiguration->fuelRpmBins[i] = i; assertEqualsM("base fuel table", 1005, getBaseTableFuel(eth.engine.engineConfiguration, 5, 5)); printf("*************************************************** initThermistors\r\n"); Engine *engine = ð.engine; engine_configuration_s *engineConfiguration = engine->engineConfiguration; initThermistors(engine); printf("*** getInjectorLag\r\n"); assertEquals(1.0, getInjectorLag(12 PASS_ENGINE_PARAMETER)); eth.engine.engineConfiguration->injectorLag = 0.5; for (int i = 0; i < VBAT_INJECTOR_CURVE_SIZE; i++) { eth.engine.engineConfiguration->battInjectorLagCorrBins[i] = i; eth.engine.engineConfiguration->battInjectorLagCorr[i] = 2 * i; } // because all the correction tables are zero printf("*************************************************** getRunningFuel 1\r\n"); float baseFuel = getBaseTableFuel(eth.engine.engineConfiguration, 5, getEngineLoadT(PASS_ENGINE_PARAMETER_F)); assertEqualsM("base fuel", 5.05, getRunningFuel(baseFuel, 5 PASS_ENGINE_PARAMETER)); printf("*************************************************** setting IAT table\r\n"); for (int i = 0; i < IAT_CURVE_SIZE; i++) { eth.engine.engineConfiguration->iatFuelCorrBins[i] = i; eth.engine.engineConfiguration->iatFuelCorr[i] = 2 * i; } eth.engine.engineConfiguration->iatFuelCorr[0] = 2; printf("*************************************************** setting CLT table\r\n"); for (int i = 0; i < CLT_CURVE_SIZE; i++) { eth.engine.engineConfiguration->cltFuelCorrBins[i] = i; eth.engine.engineConfiguration->cltFuelCorr[i] = 1; } eth.engine.engineConfiguration->injectorLag = 0; assertEquals(NAN, getIntakeAirTemperature(ð.engine)); float iatCorrection = getIatCorrection(-KELV PASS_ENGINE_PARAMETER); assertEqualsM("IAT", 2, iatCorrection); float cltCorrection = getCltCorrection(getCoolantTemperature(ð.engine) PASS_ENGINE_PARAMETER); assertEqualsM("CLT", 1, cltCorrection); float injectorLag = getInjectorLag(getVBatt(engineConfiguration) PASS_ENGINE_PARAMETER); assertEquals(0, injectorLag); testMafValue = 5; // 1005 * 2 for IAT correction printf("*************************************************** getRunningFuel 2\r\n"); baseFuel = getBaseTableFuel(eth.engine.engineConfiguration, 5, getEngineLoadT(PASS_ENGINE_PARAMETER_F)); assertEqualsM("v1", 30150, getRunningFuel(baseFuel, 5 PASS_ENGINE_PARAMETER)); testMafValue = 0; engineConfiguration->crankingSettings.baseCrankingFuel = 4; printf("*************************************************** getStartingFuel\r\n"); // NAN in case we have issues with the CLT sensor assertEqualsM("getStartingFuel nan", 4, getCrankingFuel3(engineConfiguration, NAN, 0)); assertEqualsM("getStartingFuel#1", 23.7333, getCrankingFuel3(engineConfiguration, 0, 4)); assertEqualsM("getStartingFuel#2", 18.0419, getCrankingFuel3(engineConfiguration, 8, 15)); assertEqualsM("getStartingFuel#3", 11.2000, getCrankingFuel3(engineConfiguration, 70, 0)); assertEqualsM("getStartingFuel#3", 5.6000, getCrankingFuel3(engineConfiguration, 70, 50)); }
static void confgiureFordAspireTriggerShape(trigger_shape_s * s) { s->reset(FOUR_STROKE_CAM_SENSOR); s->addEvent(53.747, T_SECONDARY, TV_HIGH); s->addEvent(121.90, T_SECONDARY, TV_LOW); s->addEvent(232.76, T_SECONDARY, TV_HIGH); s->addEvent(300.54, T_SECONDARY, TV_LOW); s->addEvent(360, T_PRIMARY, TV_HIGH); s->addEvent(409.8412, T_SECONDARY, TV_HIGH); s->addEvent(478.6505, T_SECONDARY, TV_LOW); s->addEvent(588.045, T_SECONDARY, TV_HIGH); s->addEvent(657.03, T_SECONDARY, TV_LOW); s->addEvent(720, T_PRIMARY, TV_LOW); assertEquals(53.747 / 720, s->wave.getSwitchTime(0)); assertEqualsM("@0", 1, s->wave.getChannelState(1, 0)); assertEqualsM("@0", 1, s->wave.getChannelState(1, 0)); assertEqualsM("@1", 0, s->wave.getChannelState(0, 1)); assertEqualsM("@1", 0, s->wave.getChannelState(1, 1)); assertEqualsM("@2", 0, s->wave.getChannelState(0, 2)); assertEqualsM("@2", 1, s->wave.getChannelState(1, 2)); assertEqualsM("@3", 0, s->wave.getChannelState(0, 3)); assertEqualsM("@3", 0, s->wave.getChannelState(1, 3)); assertEqualsM("@4", 1, s->wave.getChannelState(0, 4)); assertEqualsM("@5", 1, s->wave.getChannelState(1, 5)); assertEqualsM("@8", 0, s->wave.getChannelState(1, 8)); assertEquals(121.90 / 720, s->wave.getSwitchTime(1)); assertEquals(657.03 / 720, s->wave.getSwitchTime(8)); assertEqualsM("expecting 0", 0, s->wave.findAngleMatch(53.747 / 720.0, s->getSize())); assertEqualsM("expecting not found", -1, s->wave.findAngleMatch(53 / 720.0, s->getSize())); assertEquals(7, s->wave.findAngleMatch(588.045 / 720.0, s->getSize())); assertEqualsM("expecting 0", 0, s->wave.waveIndertionAngle(23.747 / 720.0, s->getSize())); assertEqualsM("expecting 1", 1, s->wave.waveIndertionAngle(63.747 / 720.0, s->getSize())); }
void assertFalseM(const char *msg, float actual) { assertEqualsM(msg, FALSE, actual); }
void assertTrueM(const char *msg, float actual) { assertEqualsM(msg, TRUE, actual); }
void assertEquals(float expected, float actual) { assertEqualsM("", expected, actual); }
void testSignalExecutor(void) { testSignalExecutor3(); print("*************************************** testSignalExecutor\r\n"); eq.clear(); assertEquals(EMPTY_QUEUE, eq.getNextEventTime(0)); scheduling_s s1; scheduling_s s2; scheduling_s s3; scheduling_s s4; eq.insertTask(&s1, 10, callback, NULL); eq.insertTask(&s4, 10, callback, NULL); eq.insertTask(&s3, 12, callback, NULL); eq.insertTask(&s2, 11, callback, NULL); assertEquals(4, eq.size()); assertEquals(10, eq.getHead()->momentX); assertEquals(10, eq.getHead()->next->momentX); assertEquals(11, eq.getHead()->next->next->momentX); assertEquals(12, eq.getHead()->next->next->next->momentX); callbackCounter = 0; eq.executeAll(10); assertEqualsM("callbackCounter/2", 2, callbackCounter); callbackCounter = 0; eq.executeAll(11); assertEqualsM("callbackCounter/1#1", 1, callbackCounter); eq.executeAll(100); assertEquals(0, eq.size()); eq.insertTask(&s1, 12, callback, NULL); eq.insertTask(&s2, 11, callback, NULL); eq.insertTask(&s3, 10, callback, NULL); callbackCounter = 0; eq.executeAll(10); assertEqualsM("callbackCounter/1#2", 1, callbackCounter); callbackCounter = 0; eq.executeAll(11); assertEquals(1, callbackCounter); eq.executeAll(100); assertEquals(0, eq.size()); callbackCounter = 0; eq.insertTask(&s1, 10, callback, NULL); assertEquals(10, eq.getNextEventTime(0)); eq.executeAll(1); assertEqualsM("callbacks not expected", 0, callbackCounter); eq.executeAll(11); assertEquals(1, callbackCounter); assertEquals(EMPTY_QUEUE, eq.getNextEventTime(0)); eq.insertTask(&s1, 10, callback, NULL); eq.insertTask(&s2, 13, callback, NULL); assertEquals(10, eq.getNextEventTime(0)); eq.executeAll(1); assertEquals(10, eq.getNextEventTime(0)); eq.executeAll(100); assertEquals(0, eq.size()); callbackCounter = 0; // both events are scheduled for the same time eq.insertTask(&s1, 10, callback, NULL); eq.insertTask(&s2, 10, callback, NULL); eq.executeAll(11); assertEquals(2, callbackCounter); testSignalExecutor2(); }
void testFuelMap(void) { chDbgCheck(engineConfiguration!=NULL, "engineConfiguration"); printf("*************************************************** testFuelMap\r\n"); for (int k = 0; k < FUEL_LOAD_COUNT; k++) { for (int r = 0; r < FUEL_RPM_COUNT; r++) { engineConfiguration->fuelTable[k][r] = k * 200 + r; } } printf("*************************************************** initThermistors\r\n"); initThermistors(); printf("*** getInjectorLag\r\n"); assertEquals(0, getInjectorLag(12)); for (int i = 0; i < FUEL_LOAD_COUNT; i++) engineConfiguration->fuelLoadBins[i] = i; for (int i = 0; i < FUEL_RPM_COUNT; i++) engineConfiguration->fuelRpmBins[i] = i; printf("*************************************************** prepareFuelMap\r\n"); assertEquals(1005, getBaseTableFuel(5, 5)); engineConfiguration->injectorLag = 0.5; for (int i = 0; i < VBAT_INJECTOR_CURVE_SIZE; i++) { engineConfiguration->battInjectorLagCorrBins[i] = i; engineConfiguration->battInjectorLagCorr[i] = 2 * i; } EngineTestHelper eth(FORD_ASPIRE_1996); // because all the correction tables are zero printf("*************************************************** getRunningFuel\r\n"); float baseFuel = getBaseTableFuel(5, getEngineLoadT(ð.engine)); assertEqualsM("value", 0.5, getRunningFuel(baseFuel, ð.engine, 5)); printf("*************************************************** setting IAT table\r\n"); for (int i = 0; i < IAT_CURVE_SIZE; i++) { engineConfiguration->iatFuelCorrBins[i] = i; engineConfiguration->iatFuelCorr[i] = 2 * i; } engineConfiguration->iatFuelCorr[0] = 2; printf("*************************************************** setting CLT table\r\n"); for (int i = 0; i < CLT_CURVE_SIZE; i++) { engineConfiguration->cltFuelCorrBins[i] = i; engineConfiguration->cltFuelCorr[i] = 1; } engineConfiguration->injectorLag = 0; assertEquals(NAN, getIntakeAirTemperature()); float iatCorrection = getIatCorrection(-KELV); assertEqualsM("IAT", 2, iatCorrection); float cltCorrection = getCltCorrection(getCoolantTemperature()); assertEqualsM("CLT", 1, cltCorrection); float injectorLag = getInjectorLag(getVBatt()); assertEquals(0, injectorLag); testMafValue = 5; // 1005 * 2 for IAT correction printf("*************************************************** getRunningFuel\r\n"); baseFuel = getBaseTableFuel(5, getEngineLoadT(ð.engine)); assertEqualsM("v1", 30150, getRunningFuel(baseFuel, ð.engine, 5)); testMafValue = 0; engineConfiguration->crankingSettings.coolantTempMaxC = 65; // 8ms at 65C engineConfiguration->crankingSettings.fuelAtMaxTempMs = 8; engineConfiguration->crankingSettings.coolantTempMinC = 0; // 20ms at 0C engineConfiguration->crankingSettings.fuelAtMinTempMs = 20; printf("*************************************************** getStartingFuel\r\n"); // NAN in case we have issues with the CLT sensor // assertEquals(16, getStartingFuel(NAN)); assertEquals(20, getStartingFuel(0)); assertEquals(18.5231, getStartingFuel(8)); assertEquals(8, getStartingFuel(70)); }
void testLogicExpressions(void) { printf("*************************************************** testLogicExpressions\r\n"); testParsing(); LECalculator c; LEElement value1; value1.init(LE_NUMERIC_VALUE, 123.0); c.add(&value1); assertEqualsM("123", 123.0, c.getValue(0, NULL)); LEElement value2; value2.init(LE_NUMERIC_VALUE, 321.0); c.add(&value2); LEElement value3; value3.init(LE_OPERATOR_AND); c.add(&value3); assertEqualsM("123 and 321", 1.0, c.getValue(0, NULL)); /** * fuel_pump = (time_since_boot < 4 seconds) OR (rpm > 0) * fuel_pump = time_since_boot 4 less rpm 0 > OR */ c.reset(); LEElement thepool[TEST_POOL_SIZE]; LEElementPool pool(thepool, TEST_POOL_SIZE); LEElement *e = pool.next(); e->init(LE_METHOD_TIME_SINCE_BOOT); e = pool.next(); e->init(LE_NUMERIC_VALUE, 4); e = pool.next(); e->init(LE_OPERATOR_LESS); e = pool.next(); e->init(LE_METHOD_RPM); e = pool.next(); e->init(LE_NUMERIC_VALUE, 0); e = pool.next(); e->init(LE_OPERATOR_MORE); e = pool.next(); e->init(LE_OPERATOR_OR); pool.reset(); LEElement *element; element = pool.parseExpression("fan no_such_method"); assertTrueM("NULL expected", element == NULL); /** * fan = (not fan && coolant > 90) OR (fan && coolant > 85) * fan = fan NOT coolant 90 AND more fan coolant 85 more AND OR */ mockFan = 0; mockCoolant = 100; testExpression("coolant", 100); testExpression("fan", 0); testExpression("fan not", 1); testExpression("coolant 90 >", 1); testExpression("fan not coolant 90 > and", 1); testExpression("100 200 1 if", 200); testExpression("10 99 max", 99); testExpression2(123, "10 self max", 123); testExpression("fan NOT coolant 90 > AND fan coolant 85 > AND OR", 1); { LEElement thepool[TEST_POOL_SIZE]; LEElementPool pool(thepool, TEST_POOL_SIZE); LEElement * element = pool.parseExpression("fan NOT coolant 90 > AND fan coolant 85 > AND OR"); assertTrueM("Not NULL expected", element != NULL); LECalculator c; assertEqualsM("that expression", 1, c.getValue2(0, element, NULL)); assertEquals(12, c.currentCalculationLogPosition); assertEquals(102, c.calcLogAction[0]); assertEquals(0, c.calcLogValue[0]); } testExpression("coolant", 100); testExpression("fan_off_setting", 0); testExpression("coolant fan_off_setting >", 1); testExpression("0 1 &", 0); testExpression("0 1 |", 1); testExpression("0 1 >", 0); testExpression(FAN_CONTROL_LOGIC, 1); mockRpm = 900; testExpression(FUEL_PUMP_LOGIC, 1); }