Fist commit
This commit is contained in:
153
test/test_native_pattern_engine/test_main.cpp
Executable file
153
test/test_native_pattern_engine/test_main.cpp
Executable file
@@ -0,0 +1,153 @@
|
||||
#include <unity.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PatternEngine.h"
|
||||
|
||||
using namespace timbre_core;
|
||||
|
||||
void setUp(void) {}
|
||||
void tearDown(void) {}
|
||||
|
||||
struct OutputEvent {
|
||||
RelayId relay;
|
||||
bool on;
|
||||
};
|
||||
|
||||
static void test_absolute_deadlines_and_final_off(void) {
|
||||
std::vector<OutputEvent> events;
|
||||
PatternEngine engine([&events](RelayId relay, bool on) {
|
||||
events.push_back(OutputEvent{relay, on});
|
||||
});
|
||||
const Pattern pattern{PatternId::A, {2, 1, 1, 1}};
|
||||
|
||||
TEST_ASSERT_TRUE(engine.start(pattern, 1000));
|
||||
TEST_ASSERT_TRUE(engine.running());
|
||||
TEST_ASSERT_TRUE(engine.outputOn());
|
||||
TEST_ASSERT_EQUAL_UINT64(3000, engine.deadlineMs());
|
||||
TEST_ASSERT_EQUAL_size_t(1, events.size());
|
||||
TEST_ASSERT_TRUE(events[0].on);
|
||||
TEST_ASSERT_EQUAL_UINT8(static_cast<std::uint8_t>(RelayId::Main),
|
||||
static_cast<std::uint8_t>(events[0].relay));
|
||||
|
||||
TEST_ASSERT_FALSE(engine.update(2999));
|
||||
TEST_ASSERT_TRUE(engine.outputOn());
|
||||
TEST_ASSERT_TRUE(engine.update(3000));
|
||||
TEST_ASSERT_FALSE(engine.outputOn());
|
||||
TEST_ASSERT_EQUAL_UINT8(1, engine.activePhase());
|
||||
TEST_ASSERT_EQUAL_UINT64(4000, engine.deadlineMs());
|
||||
|
||||
TEST_ASSERT_TRUE(engine.update(5000));
|
||||
// At 5000 ms the third phase has also reached its boundary; the
|
||||
// absolute-deadline engine therefore advances to the final OFF phase.
|
||||
TEST_ASSERT_FALSE(engine.outputOn());
|
||||
TEST_ASSERT_EQUAL_UINT8(3, engine.activePhase());
|
||||
TEST_ASSERT_EQUAL_UINT64(6000, engine.deadlineMs());
|
||||
|
||||
TEST_ASSERT_TRUE(engine.update(7000));
|
||||
TEST_ASSERT_FALSE(engine.running());
|
||||
TEST_ASSERT_FALSE(engine.outputOn());
|
||||
TEST_ASSERT_EQUAL_UINT8(PatternEngine::kNoPhase, engine.activePhase());
|
||||
TEST_ASSERT_EQUAL_size_t(4, events.size());
|
||||
TEST_ASSERT_FALSE(events.back().on);
|
||||
}
|
||||
|
||||
static void test_clock_regression_turns_output_off(void) {
|
||||
std::vector<OutputEvent> events;
|
||||
PatternEngine engine([&events](RelayId relay, bool on) {
|
||||
events.push_back({relay, on});
|
||||
});
|
||||
const Pattern pattern{PatternId::A, {2, 1}};
|
||||
|
||||
TEST_ASSERT_TRUE(engine.start(pattern, 1000));
|
||||
TEST_ASSERT_TRUE(engine.outputOn());
|
||||
TEST_ASSERT_TRUE(engine.update(500));
|
||||
TEST_ASSERT_FALSE(engine.running());
|
||||
TEST_ASSERT_FALSE(engine.outputOn());
|
||||
TEST_ASSERT_FALSE(events.empty());
|
||||
TEST_ASSERT_FALSE(events.back().on);
|
||||
}
|
||||
|
||||
static void test_late_poll_does_not_accumulate_or_leave_on(void) {
|
||||
std::vector<OutputEvent> events;
|
||||
PatternEngine engine([&events](RelayId, bool on) { events.push_back({RelayId::Main, on}); });
|
||||
const Pattern pattern{PatternId::B, {1, 1, 1, 1, 1, 1}};
|
||||
|
||||
TEST_ASSERT_TRUE(engine.start(pattern, 10));
|
||||
TEST_ASSERT_TRUE(engine.update(1000000));
|
||||
TEST_ASSERT_FALSE(engine.running());
|
||||
TEST_ASSERT_FALSE(engine.outputOn());
|
||||
TEST_ASSERT_EQUAL_UINT64(0, engine.deadlineMs());
|
||||
TEST_ASSERT_FALSE(events.empty());
|
||||
TEST_ASSERT_FALSE(events.back().on);
|
||||
}
|
||||
|
||||
static void test_fixed_queue_capacity_and_absolute_request_time(void) {
|
||||
std::vector<OutputEvent> events;
|
||||
PatternEngine engine([&events](RelayId relay, bool on) {
|
||||
events.push_back({relay, on});
|
||||
});
|
||||
const Pattern pattern{PatternId::C, {1, 1}};
|
||||
|
||||
for (std::size_t i = 0; i < 8; ++i) {
|
||||
TEST_ASSERT_TRUE(engine.enqueue(pattern, 1000));
|
||||
}
|
||||
TEST_ASSERT_EQUAL_size_t(8, engine.queueSize());
|
||||
TEST_ASSERT_FALSE(engine.enqueue(pattern, 1000));
|
||||
TEST_ASSERT_EQUAL_size_t(8, engine.queueSize());
|
||||
TEST_ASSERT_FALSE(engine.running());
|
||||
|
||||
engine.update(999);
|
||||
TEST_ASSERT_FALSE(engine.running());
|
||||
TEST_ASSERT_EQUAL_size_t(8, engine.queueSize());
|
||||
engine.update(1000);
|
||||
TEST_ASSERT_TRUE(engine.running());
|
||||
TEST_ASSERT_EQUAL_size_t(7, engine.queueSize());
|
||||
TEST_ASSERT_TRUE(engine.outputOn());
|
||||
TEST_ASSERT_EQUAL_UINT64(2000, engine.deadlineMs());
|
||||
}
|
||||
|
||||
static void test_invalid_pattern_id_and_zero_phase_are_safe(void) {
|
||||
std::vector<OutputEvent> events;
|
||||
PatternEngine engine([&events](RelayId relay, bool on) {
|
||||
events.push_back({relay, on});
|
||||
});
|
||||
|
||||
TEST_ASSERT_FALSE(engine.start(static_cast<PatternId>(99), 0));
|
||||
TEST_ASSERT_FALSE(engine.running());
|
||||
TEST_ASSERT_TRUE(events.empty());
|
||||
|
||||
const Pattern silent{PatternId::A, {0, 0}};
|
||||
TEST_ASSERT_TRUE(engine.start(silent, 0));
|
||||
TEST_ASSERT_FALSE(engine.running());
|
||||
TEST_ASSERT_FALSE(engine.outputOn());
|
||||
TEST_ASSERT_EQUAL_size_t(0, events.size());
|
||||
}
|
||||
|
||||
static void test_reserved_gpio_is_never_driven(void) {
|
||||
std::vector<OutputEvent> events;
|
||||
PatternEngine engine([&events](RelayId relay, bool on) {
|
||||
events.push_back({relay, on});
|
||||
});
|
||||
const Pattern pattern{PatternId::A, {1, 1}};
|
||||
TEST_ASSERT_TRUE(engine.start(pattern, 0));
|
||||
TEST_ASSERT_TRUE(engine.update(2000));
|
||||
TEST_ASSERT_FALSE(engine.reservedRelayDriven());
|
||||
TEST_ASSERT_EQUAL_UINT8(static_cast<std::uint8_t>(RelayId::Main),
|
||||
static_cast<std::uint8_t>(engine.lastOutputRelay()));
|
||||
for (const OutputEvent& event : events) {
|
||||
TEST_ASSERT_EQUAL_UINT8(static_cast<std::uint8_t>(RelayId::Main),
|
||||
static_cast<std::uint8_t>(event.relay));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_absolute_deadlines_and_final_off);
|
||||
RUN_TEST(test_clock_regression_turns_output_off);
|
||||
RUN_TEST(test_late_poll_does_not_accumulate_or_leave_on);
|
||||
RUN_TEST(test_fixed_queue_capacity_and_absolute_request_time);
|
||||
RUN_TEST(test_invalid_pattern_id_and_zero_phase_are_safe);
|
||||
RUN_TEST(test_reserved_gpio_is_never_driven);
|
||||
return UNITY_END();
|
||||
}
|
||||
Reference in New Issue
Block a user