fome-fw/unit_tests/tests/test_util.cpp

466 lines
11 KiB
C++
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
* @file test_util.c
*
* @date Dec 8, 2013
2020-01-13 18:57:43 -08:00
* @author Andrey Belomutskiy, (c) 2012-2020
2015-07-10 06:01:56 -07:00
*/
#include "pch.h"
2015-07-10 06:01:56 -07:00
#include <string.h>
#include "cyclic_buffer.h"
#include "malfunction_central.h"
#include "cli_registry.h"
2020-08-06 19:05:26 -07:00
#include "mmc_card.h"
2015-07-10 06:01:56 -07:00
#include "fl_stack.h"
#include "big_buffer.h"
TEST(util, testitoa) {
char buffer[12];
itoa10(buffer, 239);
ASSERT_TRUE(strEqual(buffer, "239"));
}
TEST(util, negativeZero) {
ASSERT_TRUE(IS_NEGATIVE_ZERO(-0.0));
ASSERT_FALSE(IS_NEGATIVE_ZERO(-10.0));
ASSERT_FALSE(IS_NEGATIVE_ZERO(10.0));
ASSERT_FALSE(IS_NEGATIVE_ZERO(0.0));
}
2021-11-22 11:03:52 -08:00
TEST(util, crc8) {
const uint8_t crc8_tab[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38};
ASSERT_EQ(0xB, crc8(crc8_tab, 8));
}
2019-01-06 04:37:12 -08:00
TEST(util, crc) {
2019-01-14 12:48:47 -08:00
ASSERT_EQ(4, efiRound(4.4, 1));
2019-01-14 15:22:31 -08:00
ASSERT_FLOAT_EQ(1.2, efiRound(1.2345, 0.1));
2021-09-18 19:12:22 -07:00
ASSERT_FLOAT_EQ(0.2, efiRound(0.2345, 0.1));
2015-07-10 06:01:56 -07:00
const char * A = "A";
2015-08-22 11:02:14 -07:00
uint32_t c = crc32(A, 1);
2015-07-10 06:01:56 -07:00
printf("crc32(A)=%x\r\n", c);
2015-08-22 11:02:14 -07:00
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);
2015-07-10 06:01:56 -07:00
}
2019-01-12 11:01:13 -08:00
TEST(util, cyclicBufferContains) {
cyclic_buffer<int> sb;
sb.add(10);
ASSERT_EQ(TRUE, sb.contains(10));
ASSERT_EQ(FALSE, sb.contains(11));
}
2019-01-06 04:37:12 -08:00
TEST(util, cyclicBuffer) {
2019-01-12 11:01:13 -08:00
cyclic_buffer<int> sb;
2019-01-06 04:37:12 -08:00
2015-07-10 06:01:56 -07:00
{
sb.add(10);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(10, sb.sum(3));
2015-07-10 06:01:56 -07:00
sb.add(2);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(12, sb.sum(2));
2015-07-10 06:01:56 -07:00
}
{
sb.clear();
sb.add(1);
sb.add(2);
sb.add(3);
sb.add(4);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(4, sb.maxValue(3));
ASSERT_EQ(4, sb.maxValue(113));
2019-01-14 15:38:20 -08:00
ASSERT_EQ( 2, sb.minValue(3)) << "minValue(3)";
2019-01-14 12:48:47 -08:00
ASSERT_EQ(1, sb.minValue(113));
2015-07-10 06:01:56 -07:00
}
}
static void testMalfunctionCentralRemoveNonExistent() {
2020-03-24 16:50:04 -07:00
clearWarnings();
2015-07-10 06:01:56 -07:00
// this should not crash
removeError(ObdCode::OBD_TPS1_Correlation);
2015-07-10 06:01:56 -07:00
}
static void testMalfunctionCentralSameElementAgain() {
2020-03-24 16:50:04 -07:00
clearWarnings();
2015-07-10 06:01:56 -07:00
error_codes_set_s localCopy;
addError(ObdCode::OBD_TPS1_Correlation);
addError(ObdCode::OBD_TPS1_Correlation);
2015-07-10 06:01:56 -07:00
getErrorCodes(&localCopy);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(1, localCopy.count);
2015-07-10 06:01:56 -07:00
}
static void testMalfunctionCentralRemoveFirstElement() {
2020-03-24 16:50:04 -07:00
clearWarnings();
2015-07-10 06:01:56 -07:00
error_codes_set_s localCopy;
ObdCode firstElement = ObdCode::OBD_TPS1_Correlation;
2015-07-10 06:01:56 -07:00
addError(firstElement);
ObdCode secondElement = ObdCode::OBD_TPS2_Correlation;
2015-07-10 06:01:56 -07:00
addError(secondElement);
getErrorCodes(&localCopy);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(2, localCopy.count);
2015-07-10 06:01:56 -07:00
// let's remove first element - code
removeError(firstElement);
getErrorCodes(&localCopy);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(1, localCopy.count);
ASSERT_EQ(secondElement, localCopy.error_codes[0]);
2015-07-10 06:01:56 -07:00
}
2019-01-14 12:31:56 -08:00
TEST(misc, testMalfunctionCentral) {
2015-07-10 06:01:56 -07:00
testMalfunctionCentralRemoveNonExistent();
testMalfunctionCentralSameElementAgain();
testMalfunctionCentralRemoveFirstElement();
2020-03-24 16:50:04 -07:00
clearWarnings();
2015-07-10 06:01:56 -07:00
error_codes_set_s localCopy;
// on start-up error storage should be empty
getErrorCodes(&localCopy);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(0, localCopy.count);
2015-07-10 06:01:56 -07:00
ObdCode code = ObdCode::OBD_TPS1_Correlation;
2015-07-10 06:01:56 -07:00
// let's add one error and validate
addError(code);
getErrorCodes(&localCopy);
2019-01-14 15:38:20 -08:00
ASSERT_EQ( 1, localCopy.count) << "count #1";
2019-01-14 12:48:47 -08:00
ASSERT_EQ(code, localCopy.error_codes[0]);
2015-07-10 06:01:56 -07:00
// let's remove value which is not in the collection
2023-04-11 16:32:47 -07:00
removeError((ObdCode) 22);
2015-07-10 06:01:56 -07:00
// element not present - nothing to removed
2019-01-14 12:48:47 -08:00
ASSERT_EQ(1, localCopy.count);
ASSERT_EQ(code, localCopy.error_codes[0]);
2015-07-10 06:01:56 -07:00
code = ObdCode::OBD_TPS2_Correlation;
2015-07-10 06:01:56 -07:00
addError(code);
getErrorCodes(&localCopy);
2019-01-14 12:48:47 -08:00
// todo: ASSERT_EQ(2, localCopy.count);
2015-07-10 06:01:56 -07:00
2023-11-01 17:31:08 -07:00
for (int c = 0; c < 100; c++) {
addError((ObdCode) c);
2015-07-10 06:01:56 -07:00
}
getErrorCodes(&localCopy);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(MAX_ERROR_CODES_COUNT, localCopy.count);
2015-07-10 06:01:56 -07:00
// now we have full array and code below present
removeError(code);
getErrorCodes(&localCopy);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(MAX_ERROR_CODES_COUNT - 1, localCopy.count);
2015-07-10 06:01:56 -07:00
}
static int lastInteger = -1;
static int lastInteger2 = -1;
static void testEchoI(int param) {
lastInteger = param;
}
static void testEchoII(int param, int param2) {
lastInteger = param;
lastInteger2 = param2;
}
static const char *lastFirst = NULL;
static const char *lastThird = NULL;
static void testEchoSSS(const char *first, const char *second, const char *third) {
lastFirst = first;
lastThird = third;
}
static float fFirst;
static float fSecond;
static float fThird;
static void testEchoFFF(float first, float second, float third) {
fFirst = first;
fSecond = second;
fThird = third;
}
2015-07-10 06:01:56 -07:00
#define UNKNOWN_COMMAND "dfadasdasd"
// this buffer is needed because on Unix you would not be able to change static char constants
static char buffer[300];
2019-01-14 12:31:56 -08:00
TEST(misc, testConsoleLogic) {
2015-07-10 06:01:56 -07:00
resetConsoleActions();
helpCommand();
char * cmd = "he ha";
2019-01-14 12:48:47 -08:00
ASSERT_EQ(2, findEndOfToken(cmd));
2015-07-10 06:01:56 -07:00
cmd = "\"hee\" ha";
2019-01-14 12:48:47 -08:00
ASSERT_EQ(5, findEndOfToken(cmd));
2015-07-10 06:01:56 -07:00
cmd = "\"h e\" ha";
2019-01-14 12:48:47 -08:00
ASSERT_EQ(5, findEndOfToken(cmd));
2015-07-10 06:01:56 -07:00
strcpy(buffer, "echo");
2019-01-14 12:37:05 -08:00
ASSERT_TRUE(strEqual("echo", unquote(buffer)));
2015-07-10 06:01:56 -07:00
strcpy(buffer, "\"echo\"");
2019-01-14 15:56:32 -08:00
ASSERT_TRUE(strEqual("echo", unquote(buffer))) << "unquote quoted";
2015-07-10 06:01:56 -07:00
2019-01-14 12:48:47 -08:00
ASSERT_EQ(10, tokenLength(UNKNOWN_COMMAND));
2015-07-10 06:01:56 -07:00
// handling invalid token should work
strcpy(buffer, "sdasdafasd asd");
handleConsoleLine(buffer);
printf("\r\naddConsoleActionI\r\n");
2015-07-10 06:01:56 -07:00
addConsoleActionI("echoi", testEchoI);
strcpy(buffer, "echoi 239");
handleConsoleLine(buffer);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(239, lastInteger);
2015-07-10 06:01:56 -07:00
printf("\r\naddConsoleActionI 240 with two spaces\r\n");
2016-06-22 20:01:57 -07:00
strcpy(buffer, "echoi 240");
handleConsoleLine(buffer);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(240, lastInteger);
2016-06-22 20:01:57 -07:00
printf("\r\naddConsoleActionII\r\n");
2015-07-10 06:01:56 -07:00
addConsoleActionII("echoii", testEchoII);
strcpy(buffer, "echoii 22 239");
handleConsoleLine(buffer);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(22, lastInteger);
ASSERT_EQ(239, lastInteger2);
2015-07-10 06:01:56 -07:00
printf("\r\naddConsoleActionII three spaces\r\n");
2016-06-22 20:01:57 -07:00
strcpy(buffer, "echoii 21 220");
handleConsoleLine(buffer);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(21, lastInteger);
ASSERT_EQ(220, lastInteger2);
2016-06-22 20:01:57 -07:00
printf("\r\addConsoleActionSSS\r\n");
2015-07-10 06:01:56 -07:00
addConsoleActionSSS("echosss", testEchoSSS);
strcpy(buffer, "echosss 111 222 333");
handleConsoleLine(buffer);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(111, atoi(lastFirst));
ASSERT_EQ(333, atoi(lastThird));
2015-07-10 06:01:56 -07:00
strcpy(buffer, "echosss \" 1\" 222 333");
handleConsoleLine(buffer);
2019-01-14 12:37:05 -08:00
ASSERT_TRUE(strEqual("\" 1\"", lastFirst));
2015-07-10 06:01:56 -07:00
printf("\r\addConsoleActionFFF\r\n");
addConsoleActionFFF("echofff", testEchoFFF);
strcpy(buffer, "echofff 1.0 2 00003.0");
handleConsoleLine(buffer);
ASSERT_EQ(1.0, fFirst);
ASSERT_EQ(2.0, fSecond);
ASSERT_EQ(3.0, fThird);
2015-07-10 06:01:56 -07:00
}
2019-01-14 12:31:56 -08:00
TEST(misc, testFLStack) {
2015-07-10 06:01:56 -07:00
FLStack<int, 4> stack;
2019-01-14 12:48:47 -08:00
ASSERT_EQ(0, stack.size());
2015-07-10 06:01:56 -07:00
stack.push(123);
stack.push(234);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(2, stack.size());
2015-07-10 06:01:56 -07:00
int v = stack.pop();
2019-01-14 12:48:47 -08:00
ASSERT_EQ(234, v);
ASSERT_EQ(1, stack.size());
ASSERT_EQ(123, stack.get(0));
2015-07-10 06:01:56 -07:00
v = stack.pop();
2019-01-14 12:48:47 -08:00
ASSERT_EQ(123, v);
ASSERT_EQ(0, stack.size());
2015-07-10 06:01:56 -07:00
stack.push(123);
stack.push(234);
stack.push(345);
stack.push(456);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(4, stack.size());
2015-07-10 06:01:56 -07:00
stack.remove(123);
2019-01-14 12:48:47 -08:00
ASSERT_EQ(456, stack.get(0));
ASSERT_EQ(3, stack.size());
2015-07-10 06:01:56 -07:00
}
static char buff[32];
2019-01-14 12:31:56 -08:00
TEST(misc, testMisc) {
2015-07-10 06:01:56 -07:00
strcpy(buff, " ab ");
// we need a mutable array here
2019-01-14 12:37:05 -08:00
ASSERT_TRUE(strEqual("ab", efiTrim(buff)));
2015-07-10 06:01:56 -07:00
2018-09-24 20:54:16 -07:00
2018-11-25 19:20:57 -08:00
{
float v = atoff("1.0");
assertEqualsM("atoff", 1.0, v);
}
2018-09-24 20:54:16 -07:00
{
float v = atoff("nan");
2019-01-14 15:56:32 -08:00
ASSERT_TRUE(cisnan(v)) << "NaN atoff";
2018-09-24 20:54:16 -07:00
}
2018-11-25 19:14:42 -08:00
{
float v = atoff("N");
2019-01-14 15:56:32 -08:00
ASSERT_TRUE(cisnan(v)) << "NaN atoff";
2018-11-25 19:14:42 -08:00
}
2018-09-24 20:54:16 -07:00
2019-01-14 12:48:47 -08:00
// ASSERT_EQ(true, strEqual("spa3", getPinName(SPARKOUT_3_OUTPUT)));
// ASSERT_EQ(SPARKOUT_12_OUTPUT, getPinByName("spa12"));
2015-07-10 06:01:56 -07:00
}
2019-01-11 16:08:15 -08:00
int getRusEfiVersion(void) {
2022-03-15 10:57:40 -07:00
return TS_FILE_VERSION;
2019-01-11 16:08:15 -08:00
}
TEST(util, PeakDetect) {
constexpr int startTime = 50;
constexpr int timeout = 100;
PeakDetect<int, timeout> dut;
// Set a peak
EXPECT_EQ(dut.detect(1000, startTime), 1000);
// Smaller value at the same time is ignored
EXPECT_EQ(dut.detect(500, startTime), 1000);
// Larger value at the same time raises the peak
EXPECT_EQ(dut.detect(1500, startTime), 1500);
// Small value at almost the timeout is ignored
EXPECT_EQ(dut.detect(500, startTime + timeout - 1), 1500);
// Small value past the timeout is used
EXPECT_EQ(dut.detect(500, startTime + timeout + 1), 500);
}
TEST(util, WrapAround62) {
// Random test
{
WrapAround62 t;
uint32_t source = 0;
uint64_t actual = 0;
// Test random progression, positive and negative.
uint32_t seed = time(NULL);
printf("Testing with seed 0x%08x\n", seed);
srand(seed);
for (unsigned i = 0; i < 10000; i++) {
int32_t delta = rand();
if (delta < 0) {
delta = ~delta;
}
delta -= RAND_MAX >> 1;
// Cap negative test
if (delta < 0 && -delta > actual) {
delta = -actual;
}
source += delta;
actual += delta;
uint64_t next = t.update(source);
EXPECT_EQ(actual, next);
}
}
// More pointed test for expected edge conditions
{
WrapAround62 t;
EXPECT_EQ(t.update(0x03453455), 0x003453455LL);
EXPECT_EQ(t.update(0x42342323), 0x042342323LL);
EXPECT_EQ(t.update(0x84356345), 0x084356345LL);
EXPECT_EQ(t.update(0x42342323), 0x042342323LL);
EXPECT_EQ(t.update(0x84356345), 0x084356345LL);
EXPECT_EQ(t.update(0xC5656565), 0x0C5656565LL);
EXPECT_EQ(t.update(0x01122112), 0x101122112LL); // Wrap around!
EXPECT_EQ(t.update(0xC5656565), 0x0C5656565LL);
EXPECT_EQ(t.update(0x84356345), 0x084356345LL);
EXPECT_EQ(t.update(0xC5656565), 0x0C5656565LL);
EXPECT_EQ(t.update(0x01122112), 0x101122112LL); // Wrap around!
EXPECT_EQ(t.update(0x42342323), 0x142342323LL);
EXPECT_EQ(t.update(0x84356345), 0x184356345LL);
EXPECT_EQ(t.update(0x42342323), 0x142342323LL);
EXPECT_EQ(t.update(0x84356345), 0x184356345LL);
EXPECT_EQ(t.update(0xC5656565), 0x1C5656565LL);
EXPECT_EQ(t.update(0x01122112), 0x201122112LL); // Wrap around!
EXPECT_EQ(t.update(0xC5656565), 0x1C5656565LL);
EXPECT_EQ(t.update(0x84356345), 0x184356345LL);
EXPECT_EQ(t.update(0xC5656565), 0x1C5656565LL);
EXPECT_EQ(t.update(0x01122112), 0x201122112LL); // Wrap around!
EXPECT_EQ(t.update(0xC5656565), 0x1C5656565LL);
EXPECT_EQ(t.update(0x84356345), 0x184356345LL);
EXPECT_EQ(t.update(0x42342323), 0x142342323LL);
EXPECT_EQ(t.update(0x01122112), 0x101122112LL);
EXPECT_EQ(t.update(0x84356345), 0x084356345LL);
EXPECT_EQ(t.update(0x42342323), 0x042342323LL);
EXPECT_EQ(t.update(0x03453455), 0x003453455LL);
}
}
TEST(util, isInRange) {
EXPECT_FALSE(isInRange(5, 4, 10));
EXPECT_TRUE(isInRange(5, 5, 10));
EXPECT_TRUE(isInRange(5, 7, 10));
EXPECT_TRUE(isInRange(5, 10, 10));
EXPECT_FALSE(isInRange(5, 11, 10));
}
2023-10-24 01:03:02 -07:00
TEST(util, wrapAngle) {
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
// Test within range
EXPECT_EQ(0, wrapAngleMethod(0));
EXPECT_EQ(20, wrapAngleMethod(20));
EXPECT_EQ(710, wrapAngleMethod(710));
// Test off the top of the range
EXPECT_EQ(1, wrapAngleMethod(721));
EXPECT_EQ(20, wrapAngleMethod(740));
EXPECT_EQ(719, wrapAngleMethod(720 + 719));
EXPECT_EQ(0, wrapAngleMethod(720 + 720));
EXPECT_EQ(5, wrapAngleMethod(10 * 720 + 5));
// Test off the bottom of the range
EXPECT_EQ(719, wrapAngleMethod(-1));
EXPECT_EQ(360, wrapAngleMethod(-360));
EXPECT_EQ(1, wrapAngleMethod(-719));
}
BigBufferUser getBigBufferCurrentUser();
TEST(BigBuffer, CppMagic) {
BigBufferHandle h = getBigBuffer(BigBufferUser::ToothLogger);
ASSERT_EQ(getBigBufferCurrentUser(), BigBufferUser::ToothLogger);
h = {};
ASSERT_EQ(getBigBufferCurrentUser(), BigBufferUser::None);
}