Files
relay_chn/test_apps/main/test_relay_chn_tilt_multi.c
ismail 497f45e336 Fix and optimize tilt test case issues
Tilt tests started to fail after the latest changes. Had to make
some fixes and optimizations so that the test code resets the
tilt controls correctly and aligns with relay_chn's timing requirements.

Fixes #1115
2025-09-13 09:54:12 +03:00

504 lines
21 KiB
C

/*
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
*
* SPDX-License-Identifier: MIT
*/
#include "test_common.h"
// ### Tilt Functionality Tests (Conditional)
// This section will only be compiled if **`CONFIG_RELAY_CHN_ENABLE_TILTING`** is defined as **`1`** in `sdkconfig`.
#ifndef CONFIG_RELAY_CHN_ENABLE_TILTING
#error "This test requires CONFIG_RELAY_CHN_ENABLE_TILTING"
#endif
#define RELAY_CHN_CMD_FORWARD 1
#define RELAY_CHN_CMD_REVERSE 2
void check_all_channels_for_state(relay_chn_state_t state)
{
for (int i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
// ESP_LOGI(TEST_TAG, "Checking channel %d for state %d", i, state);
TEST_ASSERT_EQUAL(state, relay_chn_get_state(i));
}
}
// Helper function to prepare channel for tilt tests
void prepare_channels_for_tilt_with_mixed_runs() {
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
// Ensure the channel has had a 'last_run_cmd'
for (int i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
if (i % 2 == 0) {
relay_chn_run_forward(i);
} else { // Assuming initial_cmd is RELAY_CHN_CMD_REVERSE
relay_chn_run_reverse(i);
}
}
for (int i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
relay_chn_state_t expect_state;
if (i % 2 == 0) {
expect_state = RELAY_CHN_STATE_FORWARD;
} else { // Assuming initial_cmd is RELAY_CHN_CMD_REVERSE
expect_state = RELAY_CHN_STATE_REVERSE;
}
TEST_ASSERT_EQUAL(expect_state, relay_chn_get_state(i));
}
}
// Helper function to prepare channel for tilt tests
void prepare_all_channels_for_tilt(int initial_cmd) {
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
// If the channels are not IDLE yet, wait more
bool not_idle = false;
for (int i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
if (relay_chn_get_state(i) != RELAY_CHN_STATE_IDLE) {
not_idle = true;
break;
}
}
if (not_idle) {
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS));
}
// Ensure all channels are IDLE
check_all_channels_for_state(RELAY_CHN_STATE_IDLE);
// Ensure the channel has had a 'last_run_cmd'
if (initial_cmd == RELAY_CHN_CMD_FORWARD) {
relay_chn_run_forward_all();
} else { // Assuming initial_cmd is RELAY_CHN_CMD_REVERSE
relay_chn_run_reverse_all();
}
relay_chn_state_t expect_state = initial_cmd == RELAY_CHN_CMD_FORWARD
? RELAY_CHN_STATE_FORWARD : RELAY_CHN_STATE_REVERSE;
check_all_channels_for_state(expect_state);
ESP_LOGI(TEST_TAG, "All channels prepared for tilt test");
}
// TEST_CASE: Test transition from running forward to tilt forward
// Scenario: RELAY_CHN_STATE_FORWARD -> (relay_chn_tilt_forward) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_FORWARD
TEST_CASE("Run Forward to Tilt Forward transition with inertia", "[relay_chn][tilt][inertia]")
{
// 1. Start in forward direction
relay_chn_run_forward_all();
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_FORWARD);
// 2. Issue tilt forward command
relay_chn_tilt_forward_all();
// After tilt command, it should immediately stop and then trigger inertia.
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_STOPPED);
// Wait for the inertia period (after which the tilt command will be dispatched)
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
// TEST_CASE: Test transition from running reverse to tilt reverse
// Scenario: RELAY_CHN_STATE_REVERSE -> (relay_chn_tilt_reverse) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_REVERSE
TEST_CASE("Run Reverse to Tilt Reverse transition with inertia", "[relay_chn][tilt][inertia]")
{
// 1. Start in reverse direction
relay_chn_run_reverse_all();
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_REVERSE);
// 2. Issue tilt reverse command
relay_chn_tilt_reverse_all();
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_STOPPED);
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_REVERSE);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
// TEST_CASE: Test transition from FREE state to tilt forward (now with preparation)
// Scenario: RELAY_CHN_STATE_IDLE -> (prepare) -> RELAY_CHN_STATE_IDLE -> (relay_chn_tilt_forward) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_FORWARD
TEST_CASE("FREE to Tilt Forward transition with inertia (prepared)", "[relay_chn][tilt][inertia]")
{
// Prepare channel by running forward first to set last_run_cmd
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_stop_all(); // Stop to trigger IDLE
// Wait for the channel to transition to IDLE
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_IDLE); // Ensure we are back to IDLE
// Issue tilt forward command
relay_chn_tilt_forward_all();
// From FREE state, tilt command should still incur the inertia due to the internal timer logic
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
// TEST_CASE: Test transition from FREE state to tilt reverse (now with preparation)
// Scenario: RELAY_CHN_STATE_IDLE -> (prepare) -> RELAY_CHN_STATE_IDLE -> (relay_chn_tilt_reverse) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_REVERSE
TEST_CASE("FREE to Tilt Reverse transition with inertia (prepared)", "[relay_chn][tilt][inertia]")
{
// Prepare channel by running reverse first to set last_run_cmd
prepare_all_channels_for_tilt(RELAY_CHN_CMD_REVERSE);
relay_chn_stop_all(); // Stop to trigger IDLE
// Wait for the channel to transition to IDLE
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_IDLE); // Ensure we are back to IDLE
// Issue tilt reverse command
relay_chn_tilt_reverse_all();
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_REVERSE);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
// TEST_CASE: Test transition from tilt forward to run forward (inertia expected for run)
// Scenario: RELAY_CHN_STATE_TILT_FORWARD -> (relay_chn_run_forward) -> RELAY_CHN_STATE_FORWARD
TEST_CASE("Tilt Forward to Run Forward transition with inertia", "[relay_chn][tilt][inertia]")
{
// Prepare channel by running forward first to set last_run_cmd, then tilt
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward_all(); // Go to tilt state
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// 2. Issue run forward command
relay_chn_run_forward_all();
// From Tilt to Run in the same logical name but in the opposite direction, inertia is expected.
check_all_channels_for_state(RELAY_CHN_STATE_FORWARD_PENDING);
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_FORWARD);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
// TEST_CASE: Test transition from tilt reverse to run reverse (no inertia expected for run)
// Scenario: RELAY_CHN_STATE_TILT_REVERSE -> (relay_chn_run_reverse) -> RELAY_CHN_STATE_REVERSE
TEST_CASE("Tilt Reverse to Run Reverse transition with inertia", "[relay_chn][tilt][inertia]")
{
// Prepare channel by running reverse first to set last_run_cmd, then tilt
prepare_all_channels_for_tilt(RELAY_CHN_CMD_REVERSE);
relay_chn_tilt_reverse_all(); // Go to tilt state
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_REVERSE);
// 2. Issue run reverse command
relay_chn_run_reverse_all();
check_all_channels_for_state(RELAY_CHN_STATE_REVERSE_PENDING);
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_REVERSE);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
// TEST_CASE: Test transition from tilt forward to run reverse (without inertia)
// Scenario: RELAY_CHN_STATE_TILT_FORWARD -> (relay_chn_run_reverse) -> RELAY_CHN_STATE_REVERSE
TEST_CASE("Tilt Forward to Run Reverse transition without inertia", "[relay_chn][tilt][inertia]")
{
// Prepare channel by running forward first to set last_run_cmd, then tilt
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward_all(); // Go to tilt state
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// 2. Issue run reverse command (opposite direction)
relay_chn_run_reverse_all();
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_REVERSE);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
// TEST_CASE: Test stopping from a tilt state (no inertia for stop command itself)
// Scenario: RELAY_CHN_STATE_TILT_FORWARD -> (relay_chn_tilt_stop) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_IDLE
TEST_CASE("Tilt to Stop transition without immediate inertia for stop", "[relay_chn][tilt][inertia]")
{
// Prepare all channels by running forward first to set last_run_cmd, then tilt
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward_all(); // Go to tilt state
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
// Verify all channels are tilting forward
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// 2. Issue stop command
relay_chn_tilt_stop_all();
// Stop command should apply immediately, setting state to FREE since last state was tilt.
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
// Verify all channels are IDLE
check_all_channels_for_state(RELAY_CHN_STATE_IDLE);
}
// ### Batch Tilt Control Tests
TEST_CASE("tilt_forward_all sets all channels to TILT_FORWARD", "[relay_chn][tilt][batch]")
{
// 1. Prepare all channels.
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
// 2. Issue tilt forward to all channels
relay_chn_tilt_forward_all();
// Should incur inertia timer
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
// 3. Verify all channels are tilting forward
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
TEST_CASE("tilt_reverse_all sets all channels to TILT_REVERSE", "[relay_chn][tilt][batch]")
{
// 1. Prepare all channels.
prepare_all_channels_for_tilt(RELAY_CHN_CMD_REVERSE);
// 2. Issue tilt reverse to all channels
relay_chn_tilt_reverse_all();
// Should incur inertia timer
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
// 3. Verify all channels are tilting reverse
check_all_channels_for_state(RELAY_CHN_STATE_TILT_REVERSE);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
TEST_CASE("tilt_stop_all stops all tilting channels", "[relay_chn][tilt][batch]")
{
// 1. Prepare and start all channels tilting forward
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward_all();
// Should incur inertia timer
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
// 3. Verify all channels are tilting forward
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// 2. Stop tilting on all channels
relay_chn_tilt_stop_all();
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
// 3. Verify all channels are free
check_all_channels_for_state(RELAY_CHN_STATE_IDLE);
}
TEST_CASE("tilt_auto_all tilts channels based on last run direction", "[relay_chn][tilt][batch]")
{
// 1. Prepare channel 0 with last run FORWARD and channel 1 with last run REVERSE
prepare_channels_for_tilt_with_mixed_runs();
// 2. Issue auto tilt command to all channels
relay_chn_tilt_auto_all();
// Should incur inertia timer
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
// 3. Verify even channels tilt forward (last run was forward) and odd channels tilt reverse (last run was reverse)
for (int i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
relay_chn_state_t state = i % 2 == 0 ?
RELAY_CHN_STATE_TILT_FORWARD : RELAY_CHN_STATE_TILT_REVERSE;
TEST_ASSERT_EQUAL(state, relay_chn_get_state(i));
}
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
// Test relay_chn_tilt_auto() chooses correct tilt direction
TEST_CASE("relay_chn_tilt_auto chooses correct direction", "[relay_chn][tilt][auto]")
{
// Prepare FORWARD
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_auto_all();
// Should incur inertia timer
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
// Verify all tilt forward
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
// Prepare REVERSE
prepare_all_channels_for_tilt(RELAY_CHN_CMD_REVERSE);
relay_chn_tilt_auto_all();
// Should incur inertia timer
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
// Verify all tilt reverse
check_all_channels_for_state(RELAY_CHN_STATE_TILT_REVERSE);
// Ensure the channel reset tilt control
relay_chn_tilt_stop_all();
}
// Test sensitivity set/get
TEST_CASE("relay_chn_tilt_set_sensitivity and get", "[relay_chn][tilt][sensitivity]")
{
uint8_t ch = 0;
relay_chn_tilt_set_sensitivity(ch, 0);
TEST_ASSERT_EQUAL_UINT8(0, relay_chn_tilt_get_sensitivity(ch));
relay_chn_tilt_set_sensitivity(ch, 50);
TEST_ASSERT_EQUAL_UINT8(50, relay_chn_tilt_get_sensitivity(ch));
relay_chn_tilt_set_sensitivity(ch, 100);
TEST_ASSERT_EQUAL_UINT8(100, relay_chn_tilt_get_sensitivity(ch));
// Set all channels
relay_chn_tilt_set_sensitivity_all_with(42);
uint8_t vals[CONFIG_RELAY_CHN_COUNT] = {0};
uint8_t expect[CONFIG_RELAY_CHN_COUNT];
memset(expect, 42, CONFIG_RELAY_CHN_COUNT);
TEST_ESP_OK(relay_chn_tilt_get_sensitivity_all(vals));
TEST_ASSERT_EQUAL_UINT8_ARRAY(expect, vals, CONFIG_RELAY_CHN_COUNT);
}
TEST_CASE("relay_chn_tilt_get_default_sensitivity returns correct value", "[relay_chn][tilt][sensitivity]")
{
// The default sensitivity is calculated from default timing values.
// Default run time: 15ms, Min run time: 50ms, Max run time: 10ms.
// Formula: ( (DEFAULT_RUN - MIN_RUN) * 100 ) / (MAX_RUN - MIN_RUN)
// ( (15 - 50) * 100 ) / (10 - 50) = (-35 * 100) / -40 = -3500 / -40 = 87.5
// As integer arithmetic, this is 87.
uint8_t expected_sensitivity = 87;
TEST_ASSERT_EQUAL_UINT8(expected_sensitivity, relay_chn_tilt_get_default_sensitivity());
}
// Test sensitivity upper boundary for all set functions
TEST_CASE("relay_chn_tilt_set_sensitivity functions handle upper boundary", "[relay_chn][tilt][sensitivity]")
{
// 1. Test relay_chn_tilt_set_sensitivity() for each channel
for (uint8_t ch = 0; ch < CONFIG_RELAY_CHN_COUNT; ch++) {
relay_chn_tilt_set_sensitivity(ch, 101);
TEST_ASSERT_EQUAL_UINT8(100, relay_chn_tilt_get_sensitivity(ch));
relay_chn_tilt_set_sensitivity(ch, 255);
TEST_ASSERT_EQUAL_UINT8(100, relay_chn_tilt_get_sensitivity(ch));
}
// 2. Test relay_chn_tilt_set_sensitivity_all_with()
relay_chn_tilt_set_sensitivity_all_with(150);
for (int i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
TEST_ASSERT_EQUAL_UINT8(100, relay_chn_tilt_get_sensitivity(i));
}
// 3. Test relay_chn_tilt_set_sensitivity_all()
uint8_t sensitivities[CONFIG_RELAY_CHN_COUNT];
for (int i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
sensitivities[i] = 100 + i * 10; // Values like 100, 110, 120...
}
TEST_ESP_OK(relay_chn_tilt_set_sensitivity_all(sensitivities));
for (int i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
TEST_ASSERT_EQUAL_UINT8(100, relay_chn_tilt_get_sensitivity(i));
}
}
// Test tilt counter logic: forward x3, reverse x3, extra reverse fails
TEST_CASE("tilt counter logic: forward and reverse consumption", "[relay_chn][tilt][counter]")
{
// Tilt execution time at 100% sensitivity in milliseconds (10 + 90)
#define TEST_TILT_EXECUTION_TIME_MS 100
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_set_sensitivity_all_with(100); // Set sentivity to max for fastest execution
// Ensure sensitivities are set correctly
uint8_t sensitivities[CONFIG_RELAY_CHN_COUNT];
uint8_t expect[CONFIG_RELAY_CHN_COUNT];
memset(expect, 100, CONFIG_RELAY_CHN_COUNT);
relay_chn_tilt_get_sensitivity_all(sensitivities);
TEST_ASSERT_EQUAL_UINT8_ARRAY(expect, sensitivities, CONFIG_RELAY_CHN_COUNT);
// Tilt forward 3 times
relay_chn_tilt_forward_all();
vTaskDelay(pdMS_TO_TICKS(TEST_TILT_EXECUTION_TIME_MS * 3 + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// Stop tilt on all channels
relay_chn_tilt_stop_all();
#if CONFIG_RELAY_CHN_ENABLE_NVS
// Tilt stop should save the latest tilt count to the NVS
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS + 300));
#else
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
#endif
// Now tilt reverse 3 times (should succeed)
relay_chn_tilt_reverse_all();
vTaskDelay(pdMS_TO_TICKS(TEST_TILT_EXECUTION_TIME_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_REVERSE);
// Let it execute 2 at least, or more
vTaskDelay(pdMS_TO_TICKS(TEST_TILT_EXECUTION_TIME_MS * 3));
// More reverse tilt should fail (counter exhausted)
check_all_channels_for_state(RELAY_CHN_STATE_IDLE);
}
// Test run command during TILT state
TEST_CASE("run command during TILT state transitions correctly", "[relay_chn][tilt][run-during-tilt]")
{
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward_all();
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// Issue run reverse while in TILT_FORWARD
relay_chn_run_reverse_all();
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
// Should transition to REVERSE
check_all_channels_for_state(RELAY_CHN_STATE_REVERSE);
}
// Test run command during active tilt cycle (move/pause)
TEST_CASE("run_all command during active tilt cycle stops tilt", "[relay_chn][tilt][interrupt]")
{
// Set a known sensitivity for predictable timing.
// For sensitivity=50, move_time=30ms, pause_time=270ms.
relay_chn_tilt_set_sensitivity_all_with(50);
// --- Test interrupting during MOVE step ---
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward_all();
// Should incur inertia timer
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// Interrupt with run_reverse_all while in the MOVE part of the cycle
relay_chn_run_reverse_all();
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
// Should stop tilting and go to REVERSE immediately (no inertia from TILT_FORWARD)
check_all_channels_for_state(RELAY_CHN_STATE_REVERSE);
// --- Test interrupting during PAUSE step ---
relay_chn_stop_all(); // Stop the reverse runs
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward_all();
// Should incur inertia timer
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS)); // Wait past MOVE, into PAUSE
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// Interrupt with run_forward_all while in the PAUSE part of the cycle
relay_chn_run_forward_all();
// Should stop tilting and go to FORWARD_PENDING (inertia from TILT_FORWARD)
check_all_channels_for_state(RELAY_CHN_STATE_FORWARD_PENDING);
}