tests: Make more tests run

This commit is contained in:
2026-01-06 17:01:31 +01:00
parent 118291f8ab
commit 348a1a1e14
11 changed files with 228 additions and 39 deletions
+1
View File
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.16)
if(TgtEnv STREQUAL "Host") if(TgtEnv STREQUAL "Host")
message("Using Host-Branch") message("Using Host-Branch")
enable_testing()
add_subdirectory("test/unitOnHost") add_subdirectory("test/unitOnHost")
elseif(TgtEnv STREQUAL "Target") elseif(TgtEnv STREQUAL "Target")
# add_subdirectory("test/unitOnTarget") # add_subdirectory("test/unitOnTarget")
+182 -8
View File
@@ -27,7 +27,7 @@ class ClientMock {
cbEvents.push(fmt::format("{}: {} {} {} {}", (int)event, isRemote, sType.getID(), sType.Name.get(), sType.GroupName.get())); cbEvents.push(fmt::format("{}: {} {} {} {}", (int)event, isRemote, sType.getID(), sType.Name.get(), sType.GroupName.get()));
} }
void onSpitObject(SProcessor::ObjectEvent event, bool isRemote, const SType &sType, const SObject &sObject) { void onSpitObject(SProcessor::ObjectEvent event, bool isRemote, const SType &sType, const SObject &sObject) {
cbEvents.push(fmt::format("{}: {} {} {} {} {}", (int)event, isRemote, sType.getID(), sType.Name.get(), sObject.Name.get(), sObject.getID())); cbEvents.push(fmt::format("{}: {} {} {} {} {}", (int)event, isRemote, sType.getID(), sType.Name.get(), sObject.Name.get(), sObject.getID()));
} }
void onPlay(string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) { void onPlay(string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) {
} }
@@ -46,6 +46,8 @@ class ClientMock {
class SpitClientFix { class SpitClientFix {
protected: protected:
std::vector<string> messages;
ClientMock client; ClientMock client;
SProcessor::Callbacks callbacks{ SProcessor::Callbacks callbacks{
.onServerEvent = [&](SProcessor::ServerEvent event, const SadDetectedServer &detectedServer) { client.onServerEvent(event, detectedServer); }, .onServerEvent = [&](SProcessor::ServerEvent event, const SadDetectedServer &detectedServer) { client.onServerEvent(event, detectedServer); },
@@ -58,17 +60,18 @@ class SpitClientFix {
.onPlayRemoteObjectStatus = [&](const SType &t, const SObject &o, uint64_t p_FrameInsideObject, int value) { client.onPlayRemoteObjectStatus(t, o, p_FrameInsideObject, value); }, .onPlayRemoteObjectStatus = [&](const SType &t, const SObject &o, uint64_t p_FrameInsideObject, int value) { client.onPlayRemoteObjectStatus(t, o, p_FrameInsideObject, value); },
.onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient) { return client.onCheckSpitTypeVeto(knownType, createdByClient); }, .onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient) { return client.onCheckSpitTypeVeto(knownType, createdByClient); },
.onCheckSpitObjectVeto = [&](bool knownType) { return client.onCheckSpitObjectVeto(knownType); }}; .onCheckSpitObjectVeto = [&](bool knownType) { return client.onCheckSpitObjectVeto(knownType); }};
SProcessor::InternalCallbacks intCallbacks { SProcessor::InternalCallbacks intCallbacks{
.delay = [&](int ms){ return ; }, .delay = [&](int ms) { return; },
.sendMessage = [&](Message::OPPart &msg){ return 0; }, .sendMessage = [&](Message::OPPart &msg) { return 0; },
.sendTypeInternal = [&](SType &sType) { return 0; }, .parseMessage = [&](Message &msg) {
.sendObjectInternal = [&](SObject *sObject) { return 0; } // auto o = fmt::format("msg-{}", msg.getHeader()->getMessageNumber());
}; // messages.push_back(o);
},
};
SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks, intCallbacks}; SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks, intCallbacks};
}; };
TEST_CASE_FIXTURE(SpitClientFix, "Spit types") { TEST_CASE_FIXTURE(SpitClientFix, "Spit types") {
{ {
Message::ReportType t; Message::ReportType t;
t.setConfirmed(false); t.setConfirmed(false);
@@ -174,3 +177,174 @@ TEST_CASE_FIXTURE(SpitClientFix, "Spit types") {
cbEvents.pop(); cbEvents.pop();
CHECK(cbEvents.empty()); CHECK(cbEvents.empty());
} }
TEST_CASE_FIXTURE(SpitClientFix, "Message Counter") {
Message::ReportType t1;
t1.setID("type#1");
t1.setServerRemote(true);
auto m1 = sut.createMessage(t1);
Message::ReportType t2;
t2.setID("type#2");
t2.setServerRemote(true);
auto m2 = sut.createMessage(t2);
Message::ReportType t3;
t3.setID("type#3");
t3.setServerRemote(true);
auto m3 = sut.createMessage(t3);
Message::ReportType t4;
t4.setID("type#4");
t4.setServerRemote(true);
auto m4 = sut.createMessage(t4);
Message::ReportType t5;
t5.setID("type#5");
t5.setServerRemote(true);
auto m5 = sut.createMessage(t5);
Message::ReportType t6;
t6.setID("type#6");
t6.setServerRemote(true);
auto m6 = sut.createMessage(t6);
CHECK(cbEvents.empty());
SUBCASE("Normal order") {
REQUIRE(cbEvents.size() == 0);
sut.checkParseMessageData(m1);
CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
sut.checkParseMessageData(m2);
CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
sut.checkParseMessageData(m3);
CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
sut.checkParseMessageData(m4);
CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
}
CHECK(cbEvents.empty());
SUBCASE("overtakes one") {
REQUIRE(cbEvents.size() == 0);
sut.checkParseMessageData(m1);
CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
sut.checkParseMessageData(m3);
CHECK(cbEvents.empty());
sut.checkParseMessageData(m2);
CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front());
cbEvents.pop();
CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
sut.checkParseMessageData(m4);
CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
}
CHECK(cbEvents.empty());
SUBCASE("overtakes two") {
REQUIRE(cbEvents.size() == 0);
sut.checkParseMessageData(m1);
CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
sut.checkParseMessageData(m4);
CHECK(cbEvents.empty());
sut.checkParseMessageData(m2);
CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
sut.checkParseMessageData(m3);
CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front());
cbEvents.pop();
CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
sut.checkParseMessageData(m5);
CHECK_MESSAGE(cbEvents.front() == "0: true type#5 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
}
CHECK(cbEvents.empty());
SUBCASE("many overtakes") {
REQUIRE(cbEvents.size() == 0);
sut.checkParseMessageData(m1);
CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
sut.checkParseMessageData(m5);
CHECK(cbEvents.empty());
sut.checkParseMessageData(m6);
CHECK(cbEvents.empty());
sut.checkParseMessageData(m4);
CHECK(cbEvents.empty());
sut.checkParseMessageData(m3);
CHECK(cbEvents.empty());
sut.checkParseMessageData(m2);
CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front());
cbEvents.pop();
CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front());
cbEvents.pop();
CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front());
cbEvents.pop();
CHECK_MESSAGE(cbEvents.front() == "0: true type#5 ", cbEvents.front());
cbEvents.pop();
CHECK_MESSAGE(cbEvents.front() == "0: true type#6 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
}
CHECK(cbEvents.empty());
SUBCASE("reverse order") {
REQUIRE(cbEvents.size() == 0);
sut.checkParseMessageData(m1);
CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
sut.checkParseMessageData(m6);
CHECK(cbEvents.empty());
sut.checkParseMessageData(m5);
CHECK(cbEvents.empty());
sut.checkParseMessageData(m4);
CHECK(cbEvents.empty());
sut.checkParseMessageData(m3);
CHECK(cbEvents.empty());
sut.checkParseMessageData(m2);
CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front());
cbEvents.pop();
CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front());
cbEvents.pop();
CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front());
cbEvents.pop();
CHECK_MESSAGE(cbEvents.front() == "0: true type#5 ", cbEvents.front());
cbEvents.pop();
CHECK_MESSAGE(cbEvents.front() == "0: true type#6 ", cbEvents.front());
cbEvents.pop();
CHECK(cbEvents.empty());
}
}
@@ -61,8 +61,7 @@ class SpitClientCmplsFix {
SProcessor::InternalCallbacks intCallbacks { SProcessor::InternalCallbacks intCallbacks {
.delay = [&](int ms){ return ; }, .delay = [&](int ms){ return ; },
.sendMessage = [&](Message::OPPart &msg){ return 0; }, .sendMessage = [&](Message::OPPart &msg){ return 0; },
.sendTypeInternal = [&](SType &sType) { return 0; }, .parseMessage = [&](Message &msg) { },
.sendObjectInternal = [&](SObject *sObject) { return 0; }
}; };
SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks, intCallbacks}; SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks, intCallbacks};
}; };
+7 -5
View File
@@ -3,16 +3,17 @@
#include "stepperDrv.hpp" #include "stepperDrv.hpp"
#include "stepperMotor.hpp" #include "stepperMotor.hpp"
#include <cmath> #include <cmath>
#include "syslog.hpp" #include "logging.hpp"
class WatchMotor { class WatchMotor {
static constexpr uint8_t Positions = 6; static constexpr uint8_t Positions = 6;
public: public:
using AlmostFinishedCb = void (*)(uint8_t newIdx); using AlmostFinishedCb = void (*)(uint8_t newIdx);
WatchMotor(IStepperMotor &stepper, AlmostFinishedCb onDone) WatchMotor(IStepperMotor &stepper, AlmostFinishedCb onDone, ILogging &logger)
: _stepper(stepper), : _stepper(stepper),
_onFinCb(onDone) { _onFinCb(onDone),
_logger(logger) {
} }
void moveTo(uint8_t position, uint8_t profile, int minJumps, float accel, float speed) { void moveTo(uint8_t position, uint8_t profile, int minJumps, float accel, float speed) {
@@ -46,9 +47,9 @@ class WatchMotor {
ESP_LOGD("MV", "Moving to %d by %.2f + %.2f", sign, delta, corr); ESP_LOGD("MV", "Moving to %d by %.2f + %.2f", sign, delta, corr);
_stepper.moveBy(delta + corr, profile, accel, speed, [&](int diff) { _stepper.moveBy(delta + corr, profile, accel, speed, [&](int diff) {
Syslog::logv(Syslog::Severity::Debug,"Almost done with head=%i",diff); _logger.logv(ILogging::Severity::Debug,"Almost done with head=%i",diff);
if (diff < 6) { if (diff < 6) {
Syslog::logv(Syslog::Severity::Warning,"Low headroom in Profile pipeline=%i",diff); _logger.logv(ILogging::Severity::Warning,"Low headroom in Profile pipeline=%i",diff);
} }
if (_onFinCb) { if (_onFinCb) {
@@ -65,4 +66,5 @@ class WatchMotor {
IStepperMotor &_stepper; IStepperMotor &_stepper;
uint8_t _currentIndex{}; uint8_t _currentIndex{};
AlmostFinishedCb _onFinCb{}; AlmostFinishedCb _onFinCb{};
ILogging &_logger;
}; };
@@ -1,4 +1,5 @@
UnitTestsFrame() UnitTestsFrame()
target_link_libraries(${moduleName} PUBLIC target_link_libraries(${moduleName} PUBLIC
devHal devHal
bases
) )
@@ -37,6 +37,12 @@ class StepperMotorMock : public IStepperMotor {
float nextPos{}; float nextPos{};
}; };
class LoggerMock : public ILogging {
void output(Severity severity, std::string message) override {
// do nothing
}
};
void onFin(uint8_t idx) { void onFin(uint8_t idx) {
} }
@@ -47,7 +53,8 @@ class WatchFaceFixture {
protected: protected:
static constexpr int MicroSteps = 32; static constexpr int MicroSteps = 32;
StepperMotorMock motor; StepperMotorMock motor;
WatchMotor sut{motor, onFin}; LoggerMock logger;
WatchMotor sut{motor, onFin, logger};
private: private:
}; };
+1 -1
Submodule core updated: 14491fb9c7...37e288c012
+4 -3
View File
@@ -513,7 +513,7 @@ void LightingTask() {
}; };
while (true) { while (true) {
auto onPos = pictoIllumQue.dequeue(0); auto onPos = pictoIllumQue.tryDequeue();
if (onPos) { if (onPos) {
ESP_LOGI(TAG, "Changing picto-Illum to pos = %i", onPos->pos); ESP_LOGI(TAG, "Changing picto-Illum to pos = %i", onPos->pos);
ESP_LOGI(TAG, "Current color set r%i g%i b%i ", ESP_LOGI(TAG, "Current color set r%i g%i b%i ",
@@ -585,10 +585,11 @@ void MovementTask() {
StepperMotor stepper(stepperCfg, stepperDriver, initSens); StepperMotor stepper(stepperCfg, stepperDriver, initSens);
SyslogInst logger;
WatchMotor watch(stepper, [](uint8_t newPos) { WatchMotor watch(stepper, [](uint8_t newPos) {
pictoIllumQue.enqueue(std::make_unique<PictoIllumCommand>(newPos)); pictoIllumQue.enqueue(std::make_unique<PictoIllumCommand>(newPos));
responseQueue.enqueue(std::make_unique<WatchIndex>(ResponseType::StepAt, newPos)); responseQueue.enqueue(std::make_unique<WatchIndex>(ResponseType::StepAt, newPos));
}); }, logger);
ESP_LOGI("Stepper", "Find Home"); ESP_LOGI("Stepper", "Find Home");
stepper.findRef(); stepper.findRef();
@@ -653,7 +654,7 @@ void MovementTask() {
int delay = Random::randomWithIn(2000,3000)/portTICK_PERIOD_MS; int delay = Random::randomWithIn(2000,3000)/portTICK_PERIOD_MS;
Syslog::logv(Syslog::Severity::Informational, Syslog::logv(Syslog::Severity::Informational,
"ShuffleMode Wait for %i", delay); "ShuffleMode Wait for %i", delay);
auto cmd = commandQueue.dequeue(delay); auto cmd = commandQueue.tryDequeueFor(delay);
if (cmd) { if (cmd) {
if (cmd->type != MoveType::Shuffle) { if (cmd->type != MoveType::Shuffle) {
commandQueue.enqueue(std::move(cmd)); commandQueue.enqueue(std::move(cmd));
-16
View File
@@ -41,22 +41,6 @@
#include "mqttClient.hpp" #include "mqttClient.hpp"
#include "watchFace.hpp" #include "watchFace.hpp"
#include "random.hpp" #include "random.hpp"
// #include "esp_chip_info.h"
// #include "esp_flash.h"
// #include "esp_ota_ops.h"
// #include "esp_partition.h"
// #include "esp_random.h"
// #include "esp_system.h"
// #include "fileSystem.hpp"
// #include "lwip/apps/netbiosns.h"
// #include "mdns.h"
// #include "soc/soc_caps.h"
// #include "systemFunctions.hpp"
// #include <inttypes.h>
// #include <sys/param.h>
// #include <unistd.h>
#include "sad_DetectedServer.hpp" #include "sad_DetectedServer.hpp"
#include "spit_object.hpp" #include "spit_object.hpp"
#include "spit_player.hpp" #include "spit_player.hpp"
+20
View File
@@ -0,0 +1,20 @@
.PHONY: start test clean
start:
./startCode
# testConfig: buildTestOnTarget
test:
cmake -DTgtEnv:STRING=Target -S . -B buildTestOnTarget
cmake --build buildTestOnTarget --parallel
idf.py -B buildTestOnTarget -p /dev/ttyACM0 flash monitor
uTest:
cmake -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++ -DTgtEnv:STRING=Host -S . -B buildUTest
cmake --build buildUTest --parallel
ctest --test-dir buildUTest
clean:
rm -rf build buildTestOnTarget
+3 -3
View File
@@ -1,12 +1,12 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(UnitTests)
include(../../core/test/unitOnHost/test_core.cmake) include(../../core/test/unitOnHost/test_core.cmake)
UnitTestSetup() UnitTestSetup()
enable_testing()
project(UnitTests)
addSubDirs_ofRoot("${CMAKE_CURRENT_LIST_DIR}/../../components") addSubDirs_ofRoot("${CMAKE_CURRENT_LIST_DIR}/../../components")
addSubDirs_ofRoot("${CMAKE_CURRENT_LIST_DIR}/../../core/components") addSubDirs_ofRoot("${CMAKE_CURRENT_LIST_DIR}/../../core/components")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../core/test/unitOnHost/hwMock" hwMock) add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../core/test/unitOnHost/hwMock" hwMock)
# add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../core/test/unitOnHost/freeRtos" freeRtos) add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../core/test/unitOnHost/netMock" netMock)
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../core/test/unitOnHost/osMock" osMock)