mirror of https://github.com/FOME-Tech/fome-fw.git
allow logging multiple warnings at once (#4414)
* allow logging multiple warnings at once * comment * .Code * Revert ".Code" This reverts commit 2b986bd50035aeec051d11aafd83fdbc1694351c. * add a better comparison operator instead of conversion * dot code * Revert "dot code" This reverts commit 35f6ae1007c41e3b30ea129a324f33ab4205036d. * force gcc-10 maybe? * Revert "force gcc-10 maybe?" This reverts commit 4ddf8bcefddd354ccdc1da682c5fff1e68d44273. * vq * dot code * dead * dot code * return may be null * static_vector; maybe cyclic_buffer is broken or wrong tool for the job? * move static vector * put cyclic buffer back how it was since we don't use it now
This commit is contained in:
parent
1343699a2f
commit
6218edd040
|
@ -797,7 +797,7 @@ void updateTunerStudioState() {
|
||||||
tsOutputChannels->hasCriticalError = hasFirmwareError();
|
tsOutputChannels->hasCriticalError = hasFirmwareError();
|
||||||
#endif // HW_CHECK_MODE
|
#endif // HW_CHECK_MODE
|
||||||
|
|
||||||
tsOutputChannels->isWarnNow = engine->engineState.warnings.isWarningNow(timeSeconds, true);
|
tsOutputChannels->isWarnNow = engine->engineState.warnings.isWarningNow();
|
||||||
#if EFI_HIP_9011_DEBUG
|
#if EFI_HIP_9011_DEBUG
|
||||||
tsOutputChannels->isKnockChipOk = (instance.invalidResponsesCount == 0);
|
tsOutputChannels->isKnockChipOk = (instance.invalidResponsesCount == 0);
|
||||||
#endif /* EFI_HIP_9011 */
|
#endif /* EFI_HIP_9011 */
|
||||||
|
@ -818,7 +818,7 @@ void updateTunerStudioState() {
|
||||||
tsOutputChannels->warningCounter = engine->engineState.warnings.warningCounter;
|
tsOutputChannels->warningCounter = engine->engineState.warnings.warningCounter;
|
||||||
tsOutputChannels->lastErrorCode = engine->engineState.warnings.lastErrorCode;
|
tsOutputChannels->lastErrorCode = engine->engineState.warnings.lastErrorCode;
|
||||||
for (int i = 0; i < 8;i++) {
|
for (int i = 0; i < 8;i++) {
|
||||||
tsOutputChannels->recentErrorCode[i] = engine->engineState.warnings.recentWarnings.get(i);
|
tsOutputChannels->recentErrorCode[i] = engine->engineState.warnings.recentWarnings.get(i).Code;
|
||||||
}
|
}
|
||||||
|
|
||||||
tsOutputChannels->startStopStateToggleCounter = engine->startStopStateToggleCounter;
|
tsOutputChannels->startStopStateToggleCounter = engine->startStopStateToggleCounter;
|
||||||
|
|
|
@ -34,27 +34,51 @@ WarningCodeState::WarningCodeState() {
|
||||||
void WarningCodeState::clear() {
|
void WarningCodeState::clear() {
|
||||||
warningCounter = 0;
|
warningCounter = 0;
|
||||||
lastErrorCode = 0;
|
lastErrorCode = 0;
|
||||||
timeOfPreviousWarning = DEEP_IN_THE_PAST_SECONDS;
|
|
||||||
recentWarnings.clear();
|
recentWarnings.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WarningCodeState::addWarningCode(obd_code_e code) {
|
void WarningCodeState::addWarningCode(obd_code_e code) {
|
||||||
warningCounter++;
|
warningCounter++;
|
||||||
lastErrorCode = code;
|
lastErrorCode = code;
|
||||||
if (!recentWarnings.contains(code)) {
|
|
||||||
|
warning_t* existing = recentWarnings.find(code);
|
||||||
|
|
||||||
|
if (!existing) {
|
||||||
chibios_rt::CriticalSectionLocker csl;
|
chibios_rt::CriticalSectionLocker csl;
|
||||||
|
|
||||||
// We don't bother double checking
|
// Add the code to the list
|
||||||
recentWarnings.add((int)code);
|
existing = recentWarnings.add(warning_t(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (existing) {
|
||||||
|
// Reset the timer on the code to now
|
||||||
|
existing->LastTriggered.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the "any warning" timer too
|
||||||
|
timeSinceLastWarning.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param forIndicator if we want to retrieving value for TS indicator, this case a minimal period is applued
|
* @param forIndicator if we want to retrieving value for TS indicator, this case a minimal period is applued
|
||||||
*/
|
*/
|
||||||
bool WarningCodeState::isWarningNow(efitimesec_t now, bool forIndicator) const {
|
bool WarningCodeState::isWarningNow() const {
|
||||||
int period = forIndicator ? maxI(3, engineConfiguration->warningPeriod) : engineConfiguration->warningPeriod;
|
int period = maxI(3, engineConfiguration->warningPeriod);
|
||||||
return absI(now - timeOfPreviousWarning) < period;
|
|
||||||
|
return !timeSinceLastWarning.hasElapsedSec(period);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether a particular warning is active
|
||||||
|
bool WarningCodeState::isWarningNow(obd_code_e code) const {
|
||||||
|
warning_t* warn = recentWarnings.find(code);
|
||||||
|
|
||||||
|
// No warning found at all
|
||||||
|
if (!warn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the warning is old, it is not active
|
||||||
|
return !warn->LastTriggered.hasElapsedSec(maxI(3, engineConfiguration->warningPeriod));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuelConsumptionState::consumeFuel(float grams, efitick_t nowNt) {
|
void FuelConsumptionState::consumeFuel(float grams, efitick_t nowNt) {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "cyclic_buffer.h"
|
#include "static_vector.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
#define MOCK_ADC_SIZE 26
|
#define MOCK_ADC_SIZE 26
|
||||||
|
@ -43,17 +43,42 @@ public:
|
||||||
gear_e gearSelectorPosition;
|
gear_e gearSelectorPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef cyclic_buffer<int, 8> warningBuffer_t;
|
struct warning_t {
|
||||||
|
Timer LastTriggered;
|
||||||
|
obd_code_e Code = OBD_None;
|
||||||
|
|
||||||
|
warning_t() { }
|
||||||
|
|
||||||
|
explicit warning_t(obd_code_e code)
|
||||||
|
: Code(code)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equality just checks the code, timer doesn't matter
|
||||||
|
bool operator ==(const warning_t& other) const {
|
||||||
|
return other.Code == Code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare against a plain OBD code
|
||||||
|
bool operator ==(const obd_code_e other) const {
|
||||||
|
return other == Code;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef static_vector<warning_t, 8> warningBuffer_t;
|
||||||
|
|
||||||
class WarningCodeState {
|
class WarningCodeState {
|
||||||
public:
|
public:
|
||||||
WarningCodeState();
|
WarningCodeState();
|
||||||
void addWarningCode(obd_code_e code);
|
void addWarningCode(obd_code_e code);
|
||||||
bool isWarningNow(efitimesec_t now, bool forIndicator) const;
|
bool isWarningNow() const;
|
||||||
|
bool isWarningNow(obd_code_e code) const;
|
||||||
void clear();
|
void clear();
|
||||||
int warningCounter;
|
int warningCounter;
|
||||||
int lastErrorCode;
|
int lastErrorCode;
|
||||||
efitimesec_t timeOfPreviousWarning;
|
|
||||||
|
Timer timeSinceLastWarning;
|
||||||
|
|
||||||
// todo: we need a way to post multiple recent warnings into TS
|
// todo: we need a way to post multiple recent warnings into TS
|
||||||
warningBuffer_t recentWarnings;
|
warningBuffer_t recentWarnings;
|
||||||
};
|
};
|
||||||
|
|
|
@ -144,13 +144,12 @@ bool warning(obd_code_e code, const char *fmt, ...) {
|
||||||
#endif /* EFI_SIMULATOR */
|
#endif /* EFI_SIMULATOR */
|
||||||
|
|
||||||
#if EFI_SIMULATOR || EFI_PROD_CODE
|
#if EFI_SIMULATOR || EFI_PROD_CODE
|
||||||
engine->engineState.warnings.addWarningCode(code);
|
// we just had this same warning, let's not spam
|
||||||
|
if (engine->engineState.warnings.isWarningNow(code) || !warningEnabled) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// todo: move this logic into WarningCodeState?
|
engine->engineState.warnings.addWarningCode(code);
|
||||||
efitimesec_t now = getTimeNowSeconds();
|
|
||||||
if (engine->engineState.warnings.isWarningNow(now, false) || !warningEnabled)
|
|
||||||
return true; // we just had another warning, let's not spam
|
|
||||||
engine->engineState.warnings.timeOfPreviousWarning = now;
|
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
template <typename T, int TSlots>
|
||||||
|
struct static_vector {
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
m_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TSearch>
|
||||||
|
T* find(const TSearch& search) const {
|
||||||
|
for (size_t i = 0; i < m_size; i++) {
|
||||||
|
if (m_storage[i] == search) {
|
||||||
|
return const_cast<T*>(&m_storage[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* add(const T& value) {
|
||||||
|
if (m_size >= TSlots) {
|
||||||
|
// vector full, discard
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& location = m_storage[m_size];
|
||||||
|
|
||||||
|
location = value;
|
||||||
|
m_size++;
|
||||||
|
|
||||||
|
return &location;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& get(size_t i) {
|
||||||
|
return m_storage[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getCount() const {
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_size = 0;
|
||||||
|
T m_storage[TSlots];
|
||||||
|
};
|
|
@ -42,12 +42,6 @@
|
||||||
// See USF2NT above for when to use MSF2NT
|
// See USF2NT above for when to use MSF2NT
|
||||||
#define MSF2NT(msTimeFloat) USF2NT(MS2US(msTimeFloat))
|
#define MSF2NT(msTimeFloat) USF2NT(MS2US(msTimeFloat))
|
||||||
|
|
||||||
/**
|
|
||||||
* We use this 'deep in past, before ECU has ever started' value as a way to unify
|
|
||||||
* handling of first ever event and an event which has happened after a large pause in engine activity
|
|
||||||
*/
|
|
||||||
#define DEEP_IN_THE_PAST_SECONDS -10
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
/**
|
/**
|
||||||
* Provide a 62-bit counter from a 32-bit counter source that wraps around.
|
* Provide a 62-bit counter from a 32-bit counter source that wraps around.
|
||||||
|
|
|
@ -54,7 +54,7 @@ TEST(trigger, testNoStartUpWarnings) {
|
||||||
eth.fireFall(150);
|
eth.fireFall(150);
|
||||||
}
|
}
|
||||||
EXPECT_EQ( 1, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#testNoStartUpWarnings CUSTOM_SYNC_COUNT_MISMATCH expected";
|
EXPECT_EQ( 1, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#testNoStartUpWarnings CUSTOM_SYNC_COUNT_MISMATCH expected";
|
||||||
EXPECT_EQ(CUSTOM_SYNC_ERROR, unitTestWarningCodeState.recentWarnings.get(0));
|
EXPECT_EQ(CUSTOM_SYNC_ERROR, unitTestWarningCodeState.recentWarnings.get(0).Code);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(trigger, testNoisyInput) {
|
TEST(trigger, testNoisyInput) {
|
||||||
|
@ -74,8 +74,8 @@ TEST(trigger, testNoisyInput) {
|
||||||
ASSERT_EQ(NOISY_RPM, Sensor::getOrZero(SensorType::Rpm)) << "testNoisyInput RPM should be noisy";
|
ASSERT_EQ(NOISY_RPM, Sensor::getOrZero(SensorType::Rpm)) << "testNoisyInput RPM should be noisy";
|
||||||
|
|
||||||
ASSERT_EQ( 2, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#testNoisyInput";
|
ASSERT_EQ( 2, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#testNoisyInput";
|
||||||
ASSERT_EQ(CUSTOM_SYNC_COUNT_MISMATCH, unitTestWarningCodeState.recentWarnings.get(0)) << "@0";
|
ASSERT_EQ(CUSTOM_SYNC_COUNT_MISMATCH, unitTestWarningCodeState.recentWarnings.get(0).Code) << "@0";
|
||||||
ASSERT_EQ(OBD_Crankshaft_Position_Sensor_A_Circuit_Malfunction, unitTestWarningCodeState.recentWarnings.get(1)) << "@0";
|
ASSERT_EQ(OBD_Crankshaft_Position_Sensor_A_Circuit_Malfunction, unitTestWarningCodeState.recentWarnings.get(1).Code) << "@0";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(trigger, testCamInput) {
|
TEST(trigger, testCamInput) {
|
||||||
|
@ -105,7 +105,7 @@ TEST(trigger, testCamInput) {
|
||||||
|
|
||||||
// asserting that lack of camshaft signal would be detecting
|
// asserting that lack of camshaft signal would be detecting
|
||||||
ASSERT_EQ(1, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#testCamInput #2";
|
ASSERT_EQ(1, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#testCamInput #2";
|
||||||
ASSERT_EQ(OBD_Camshaft_Position_Sensor_Circuit_Range_Performance, unitTestWarningCodeState.recentWarnings.get(0)) << "@0";
|
ASSERT_EQ(OBD_Camshaft_Position_Sensor_Circuit_Range_Performance, unitTestWarningCodeState.recentWarnings.get(0).Code) << "@0";
|
||||||
unitTestWarningCodeState.recentWarnings.clear();
|
unitTestWarningCodeState.recentWarnings.clear();
|
||||||
|
|
||||||
for (int i = 0; i < 600;i++) {
|
for (int i = 0; i < 600;i++) {
|
||||||
|
|
|
@ -19,6 +19,6 @@ TEST(issues, issue898) {
|
||||||
ASSERT_EQ(TRUE, engine->triggerCentral.triggerShape.shapeDefinitionError) << "MRE_MIATA_NA6 shapeDefinitionError";
|
ASSERT_EQ(TRUE, engine->triggerCentral.triggerShape.shapeDefinitionError) << "MRE_MIATA_NA6 shapeDefinitionError";
|
||||||
|
|
||||||
ASSERT_EQ( 2, eth.recentWarnings()->getCount()) << "warningCounter#testFuelSchedulerBug299smallAndMedium";
|
ASSERT_EQ( 2, eth.recentWarnings()->getCount()) << "warningCounter#testFuelSchedulerBug299smallAndMedium";
|
||||||
ASSERT_EQ(CUSTOM_ERR_BOTH_FRONTS_REQUIRED, eth.recentWarnings()->get(0));
|
ASSERT_EQ(CUSTOM_ERR_BOTH_FRONTS_REQUIRED, eth.recentWarnings()->get(0).Code);
|
||||||
ASSERT_EQ(CUSTOM_ERR_TRIGGER_SYNC, eth.recentWarnings()->get(1));
|
ASSERT_EQ(CUSTOM_ERR_TRIGGER_SYNC, eth.recentWarnings()->get(1).Code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ TEST(realCrankingVQ40, normalCranking) {
|
||||||
|
|
||||||
// TODO: why warnings?
|
// TODO: why warnings?
|
||||||
ASSERT_EQ(3, eth.recentWarnings()->getCount());
|
ASSERT_EQ(3, eth.recentWarnings()->getCount());
|
||||||
ASSERT_EQ(CUSTOM_SYNC_COUNT_MISMATCH, eth.recentWarnings()->get(0));
|
ASSERT_EQ(CUSTOM_SYNC_COUNT_MISMATCH, eth.recentWarnings()->get(0).Code);
|
||||||
ASSERT_EQ(CUSTOM_OUT_OF_ORDER_COIL, eth.recentWarnings()->get(1)); // this is from a coil being protected by overdwell protection
|
ASSERT_EQ(CUSTOM_OUT_OF_ORDER_COIL, eth.recentWarnings()->get(1).Code); // this is from a coil being protected by overdwell protection
|
||||||
ASSERT_EQ(CUSTOM_SYNC_ERROR, eth.recentWarnings()->get(2));
|
ASSERT_EQ(CUSTOM_SYNC_ERROR, eth.recentWarnings()->get(2).Code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,9 @@ TEST(realCrankingNB2, normalCranking) {
|
||||||
ASSERT_EQ(942, round(Sensor::getOrZero(SensorType::Rpm)));
|
ASSERT_EQ(942, round(Sensor::getOrZero(SensorType::Rpm)));
|
||||||
|
|
||||||
ASSERT_EQ(3, eth.recentWarnings()->getCount());
|
ASSERT_EQ(3, eth.recentWarnings()->getCount());
|
||||||
ASSERT_EQ(CUSTOM_OUT_OF_ORDER_COIL, eth.recentWarnings()->get(0));
|
ASSERT_EQ(CUSTOM_OUT_OF_ORDER_COIL, eth.recentWarnings()->get(0).Code);
|
||||||
ASSERT_EQ(CUSTOM_SYNC_ERROR, eth.recentWarnings()->get(1));
|
ASSERT_EQ(CUSTOM_SYNC_ERROR, eth.recentWarnings()->get(1).Code);
|
||||||
ASSERT_EQ(CUSTOM_SYNC_COUNT_MISMATCH, eth.recentWarnings()->get(2));
|
ASSERT_EQ(CUSTOM_SYNC_COUNT_MISMATCH, eth.recentWarnings()->get(2).Code);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(realCrankingNB2, crankingMissingInjector) {
|
TEST(realCrankingNB2, crankingMissingInjector) {
|
||||||
|
@ -51,7 +51,7 @@ TEST(realCrankingNB2, crankingMissingInjector) {
|
||||||
ASSERT_EQ(668, round(Sensor::getOrZero(SensorType::Rpm)));
|
ASSERT_EQ(668, round(Sensor::getOrZero(SensorType::Rpm)));
|
||||||
|
|
||||||
ASSERT_EQ(3, eth.recentWarnings()->getCount());
|
ASSERT_EQ(3, eth.recentWarnings()->getCount());
|
||||||
ASSERT_EQ(CUSTOM_OUT_OF_ORDER_COIL, eth.recentWarnings()->get(0));
|
ASSERT_EQ(CUSTOM_OUT_OF_ORDER_COIL, eth.recentWarnings()->get(0).Code);
|
||||||
ASSERT_EQ(CUSTOM_SYNC_ERROR, eth.recentWarnings()->get(1));
|
ASSERT_EQ(CUSTOM_SYNC_ERROR, eth.recentWarnings()->get(1).Code);
|
||||||
ASSERT_EQ(CUSTOM_SYNC_COUNT_MISMATCH, eth.recentWarnings()->get(2));
|
ASSERT_EQ(CUSTOM_SYNC_COUNT_MISMATCH, eth.recentWarnings()->get(2).Code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -867,7 +867,7 @@ void doTestFuelSchedulerBug299smallAndMedium(int startUpDelayMs) {
|
||||||
|
|
||||||
ASSERT_EQ( 0, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#testFuelSchedulerBug299smallAndMedium";
|
ASSERT_EQ( 0, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#testFuelSchedulerBug299smallAndMedium";
|
||||||
/*
|
/*
|
||||||
ASSERT_EQ(CUSTOM_OBD_SKIPPED_FUEL, unitTestWarningCodeState.recentWarnings.get(0));
|
ASSERT_EQ(CUSTOM_OBD_SKIPPED_FUEL, unitTestWarningCodeState.recentWarnings.get(0).Code);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1048,7 +1048,7 @@ TEST(big, testFuelSchedulerBug299smallAndLarge) {
|
||||||
eth.executeActions();
|
eth.executeActions();
|
||||||
ASSERT_EQ( 0, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#testFuelSchedulerBug299smallAndLarge";
|
ASSERT_EQ( 0, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#testFuelSchedulerBug299smallAndLarge";
|
||||||
/*
|
/*
|
||||||
ASSERT_EQ(CUSTOM_OBD_SKIPPED_FUEL, unitTestWarningCodeState.recentWarnings.get(0));
|
ASSERT_EQ(CUSTOM_OBD_SKIPPED_FUEL, unitTestWarningCodeState.recentWarnings.get(0).Code);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1154,8 +1154,8 @@ TEST(big, testSparkReverseOrderBug319) {
|
||||||
eth.executeActions();
|
eth.executeActions();
|
||||||
ASSERT_EQ( 0, enginePins.coils[3].outOfOrder) << "out-of-order #8";
|
ASSERT_EQ( 0, enginePins.coils[3].outOfOrder) << "out-of-order #8";
|
||||||
ASSERT_EQ( 2, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#SparkReverseOrderBug319";
|
ASSERT_EQ( 2, unitTestWarningCodeState.recentWarnings.getCount()) << "warningCounter#SparkReverseOrderBug319";
|
||||||
ASSERT_EQ(CUSTOM_DWELL_TOO_LONG, unitTestWarningCodeState.recentWarnings.get(0)) << "warning @0";
|
ASSERT_EQ(CUSTOM_DWELL_TOO_LONG, unitTestWarningCodeState.recentWarnings.get(0).Code) << "warning @0";
|
||||||
ASSERT_EQ(CUSTOM_OUT_OF_ORDER_COIL, unitTestWarningCodeState.recentWarnings.get(1));
|
ASSERT_EQ(CUSTOM_OUT_OF_ORDER_COIL, unitTestWarningCodeState.recentWarnings.get(1).Code);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(big, testMissedSpark299) {
|
TEST(big, testMissedSpark299) {
|
||||||
|
|
Loading…
Reference in New Issue