The tilt sensitivity values were passed to the NVS module without the boundaries being checked, even though the maximum percent value is 100. This commit fixes this issue. Also test cases are added to cover the upper boundary checks for the tilt sensitivity settings. Fixes #1086
267 lines
12 KiB
C
267 lines
12 KiB
C
#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
|
|
|
|
// Helper function to prepare channel for tilt tests
|
|
void prepare_channel_for_tilt(int initial_cmd) {
|
|
// Ensure the channel reset tilt control
|
|
relay_chn_tilt_stop();
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
|
|
// Ensure the channel has had a 'last_run_cmd'
|
|
if (initial_cmd == RELAY_CHN_CMD_FORWARD) {
|
|
relay_chn_run_forward();
|
|
} else { // Assuming initial_cmd is RELAY_CHN_CMD_REVERSE
|
|
relay_chn_run_reverse();
|
|
}
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS)); // Allow command to process
|
|
relay_chn_stop(); // Stop it to set last_run_cmd but return to FREE for next test
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
|
|
}
|
|
|
|
// 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]")
|
|
{
|
|
// Prepare channel by running forward first to set last_run_cmd
|
|
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
|
|
// 1. Start in forward direction
|
|
relay_chn_run_forward();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
|
|
// 2. Issue tilt forward command
|
|
relay_chn_tilt_forward();
|
|
// After tilt command, it should immediately stop and then trigger inertia.
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state());
|
|
|
|
// Wait for the inertia period (after which the tilt command will be dispatched)
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
}
|
|
|
|
// 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]")
|
|
{
|
|
// Prepare channel by running reverse first to set last_run_cmd
|
|
prepare_channel_for_tilt(RELAY_CHN_CMD_REVERSE);
|
|
|
|
// 1. Start in reverse direction
|
|
relay_chn_run_reverse();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state());
|
|
|
|
// 2. Issue tilt reverse command
|
|
relay_chn_tilt_reverse();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state());
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_REVERSE, relay_chn_get_state());
|
|
}
|
|
|
|
// 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_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); // Ensure we are back to FREE
|
|
|
|
// Issue tilt forward command
|
|
relay_chn_tilt_forward();
|
|
// From FREE state, tilt command should still incur the inertia due to the internal timer logic
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
}
|
|
|
|
// 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_channel_for_tilt(RELAY_CHN_CMD_REVERSE);
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); // Ensure we are back to FREE
|
|
|
|
// Issue tilt reverse command
|
|
relay_chn_tilt_reverse();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_REVERSE, relay_chn_get_state());
|
|
}
|
|
|
|
// 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_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
relay_chn_tilt_forward(); // Go to tilt state
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
|
|
// 2. Issue run forward command
|
|
relay_chn_run_forward();
|
|
// From Tilt to Run in the same logical name but in the opposite direction, inertia is expected.
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD_PENDING, relay_chn_get_state());
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
}
|
|
|
|
// 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_channel_for_tilt(RELAY_CHN_CMD_REVERSE);
|
|
relay_chn_tilt_reverse(); // Go to tilt state
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_REVERSE, relay_chn_get_state());
|
|
|
|
// 2. Issue run reverse command
|
|
relay_chn_run_reverse();
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE_PENDING, relay_chn_get_state());
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state());
|
|
}
|
|
|
|
// 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_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
relay_chn_tilt_forward(); // Go to tilt state
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
|
|
// 2. Issue run reverse command (opposite direction)
|
|
relay_chn_run_reverse();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state());
|
|
}
|
|
|
|
// TEST_CASE: Test stopping from a tilt state (no inertia for stop command itself)
|
|
// Scenario: RELAY_CHN_STATE_TILT_FORWARD -> (relay_chn_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 channel by running forward first to set last_run_cmd, then tilt
|
|
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
relay_chn_tilt_forward(); // Go to tilt state
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
|
|
// 2. Issue stop command
|
|
relay_chn_stop();
|
|
// Stop command should apply immediately, setting state to FREE since last state was tilt.
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
|
|
}
|
|
|
|
// 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_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
relay_chn_tilt_auto();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
relay_chn_tilt_stop();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
|
|
// Prepare REVERSE
|
|
prepare_channel_for_tilt(RELAY_CHN_CMD_REVERSE);
|
|
relay_chn_tilt_auto();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_REVERSE, relay_chn_get_state());
|
|
}
|
|
|
|
// Test sensitivity set/get
|
|
TEST_CASE("relay_chn_tilt_set_sensitivity and get", "[relay_chn][tilt][sensitivity]")
|
|
{
|
|
relay_chn_tilt_set_sensitivity(0);
|
|
TEST_ASSERT_EQUAL_UINT8(0, relay_chn_tilt_get_sensitivity());
|
|
|
|
relay_chn_tilt_set_sensitivity(50);
|
|
TEST_ASSERT_EQUAL_UINT8(50, relay_chn_tilt_get_sensitivity());
|
|
|
|
relay_chn_tilt_set_sensitivity(100);
|
|
TEST_ASSERT_EQUAL_UINT8(100, relay_chn_tilt_get_sensitivity());
|
|
|
|
relay_chn_tilt_set_sensitivity(42);
|
|
TEST_ASSERT_EQUAL_UINT8(42, relay_chn_tilt_get_sensitivity());
|
|
}
|
|
|
|
// Test sensitivity upper boundary
|
|
TEST_CASE("relay_chn_tilt_set_sensitivity handles upper boundary", "[relay_chn][tilt][sensitivity]")
|
|
{
|
|
// Set sensitivity to a value greater than 100
|
|
relay_chn_tilt_set_sensitivity(101);
|
|
// It should be capped at 100
|
|
TEST_ASSERT_EQUAL_UINT8(100, relay_chn_tilt_get_sensitivity());
|
|
|
|
relay_chn_tilt_set_sensitivity(200);
|
|
TEST_ASSERT_EQUAL_UINT8(100, relay_chn_tilt_get_sensitivity());
|
|
}
|
|
|
|
// Test tilt counter logic: forward x3, reverse x3, extra reverse fails
|
|
TEST_CASE("tilt counter logic: forward and reverse consumption", "[relay_chn][tilt][counter]")
|
|
{
|
|
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
|
|
// Tilt forward 3 times
|
|
for (int i = 0; i < 3; ++i) {
|
|
relay_chn_tilt_forward();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
relay_chn_tilt_stop();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
}
|
|
|
|
// Now tilt reverse 3 times (should succeed)
|
|
for (int i = 0; i < 3; ++i) {
|
|
relay_chn_tilt_reverse();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
if (i < 3) {
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_REVERSE, relay_chn_get_state());
|
|
relay_chn_tilt_stop();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
}
|
|
}
|
|
|
|
// Extra reverse tilt should fail (counter exhausted)
|
|
relay_chn_tilt_reverse();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
// Should not enter TILT_REVERSE, should remain FREE or STOPPED
|
|
relay_chn_state_t state = relay_chn_get_state();
|
|
TEST_ASSERT(state != RELAY_CHN_STATE_TILT_REVERSE);
|
|
}
|
|
|
|
// Test run command during TILT state
|
|
TEST_CASE("run command during TILT state transitions correctly", "[relay_chn][tilt][run-during-tilt]")
|
|
{
|
|
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
relay_chn_tilt_forward();
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
|
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
|
|
// Issue run reverse while in TILT_FORWARD
|
|
relay_chn_run_reverse();
|
|
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
|
|
// Should transition to REVERSE or REVERSE_PENDING depending on inertia logic
|
|
relay_chn_state_t state = relay_chn_get_state();
|
|
TEST_ASSERT(state == RELAY_CHN_STATE_REVERSE || state == RELAY_CHN_STATE_REVERSE_PENDING);
|
|
} |