From 5cf116024c855e9cd8863e7f3dd33d22a0878f2a Mon Sep 17 00:00:00 2001 From: Paul Nykiel Date: Thu, 29 Dec 2022 21:39:59 +0100 Subject: [PATCH] #45: Tests for mode handler timeout and active handling --- Src/Application/mode_handler.c | 10 +- Tests/LowLevel/Application/mode_handler.cpp | 286 +++++++++++++++++--- 2 files changed, 257 insertions(+), 39 deletions(-) diff --git a/Src/Application/mode_handler.c b/Src/Application/mode_handler.c index 698135d..9531884 100644 --- a/Src/Application/mode_handler.c +++ b/Src/Application/mode_handler.c @@ -11,8 +11,8 @@ enum { IMU_TIMEOUT = (uint16_t) (100 / 16.384), - FLIGHTCOMPUTER_TIMOUT = (uint16_t) ((2 * 100) / 16.384), - REMOTE_TIMEOUT = (uint16_t) (200 / 16.384), + FLIGHTCOMPUTER_TIMEOUT = (uint16_t) ((2 * 100) / 16.384), + REMOTE_TIMEOUT = (uint16_t) (100 / 16.384), }; static uint8_t imu_timeout_counter; @@ -21,7 +21,7 @@ static uint8_t remote_timeout_counter; void mode_handler_init(void) { imu_timeout_counter = IMU_TIMEOUT; - flightcomputer_timeout_counter = FLIGHTCOMPUTER_TIMOUT; + flightcomputer_timeout_counter = FLIGHTCOMPUTER_TIMEOUT; remote_timeout_counter = REMOTE_TIMEOUT; } @@ -60,8 +60,8 @@ mode_handler_mode_t mode_handler_handle(imu_data_t *imu_data, remote_data_t *rem flightcomputer_timeout_counter = 0; } bool flightcomputer_active = true; - if (flightcomputer_timeout_counter >= FLIGHTCOMPUTER_TIMOUT) { - flightcomputer_timeout_counter = FLIGHTCOMPUTER_TIMOUT; + if (flightcomputer_timeout_counter >= FLIGHTCOMPUTER_TIMEOUT) { + flightcomputer_timeout_counter = FLIGHTCOMPUTER_TIMEOUT; flightcomputer_active = false; } *flightcomputer_setpoint = flightcomputer_get_setpoint(); diff --git a/Tests/LowLevel/Application/mode_handler.cpp b/Tests/LowLevel/Application/mode_handler.cpp index 930877e..ce00051 100644 --- a/Tests/LowLevel/Application/mode_handler.cpp +++ b/Tests/LowLevel/Application/mode_handler.cpp @@ -29,15 +29,9 @@ TEST(TEST_NAME, all_ok) { flightcomputer_setpoint_t flightcomputerSetpoint; EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); - EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_IMU_DATA)); - EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_REMOTE_DATA)); - EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_FCP_DATA)); } -TEST(TEST_NAME, imu_initial_nok) { +TEST(TEST_NAME, imu_initial_timeout) { auto imuHandle = mock::imu.getHandle(); auto flightcomputerHandle = mock::flightcomputer.getHandle(); auto remoteHandle = mock::remote.getHandle(); @@ -60,10 +54,31 @@ TEST(TEST_NAME, imu_initial_nok) { EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_REMOTE); EXPECT_TRUE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_IMU_DATA)); - EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_REMOTE_DATA)); - EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_FCP_DATA)); +} + +TEST(TEST_NAME, imu_initial_nok) { + auto imuHandle = mock::imu.getHandle(); + auto flightcomputerHandle = mock::flightcomputer.getHandle(); + auto remoteHandle = mock::remote.getHandle(); + auto errorHandlerHandle = mock::error_handler.getHandle(); + + imuHandle.overrideFunc([]() { return true; }); + imuHandle.overrideFunc([]() { return imu_data_t{.imu_ok = false}; }); + remoteHandle.overrideFunc([]() { return true; }); + remoteHandle.overrideFunc( + []() { return remote_data_t{.is_armed = true, .override_active = false, .remote_ok = true}; }); + flightcomputerHandle.overrideFunc([]() { return true; }); + flightcomputerHandle.overrideFunc([]() { return flightcomputer_setpoint_t{}; }); + + mode_handler_init(); + + imu_data_t imuData; + remote_data_t remoteData; + flightcomputer_setpoint_t flightcomputerSetpoint; + + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_REMOTE); + EXPECT_TRUE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_IMU_DATA)); } TEST(TEST_NAME, imu_timeout) { @@ -75,7 +90,7 @@ TEST(TEST_NAME, imu_timeout) { std::size_t frameCounter = 0; imuHandle.overrideFunc([&frameCounter]() { frameCounter += 1; - return not(2 <= frameCounter and frameCounter <= 7); + return frameCounter < 2 or frameCounter > 7; }); imuHandle.overrideFunc([]() { return imu_data_t{.imu_ok = true}; }); remoteHandle.overrideFunc([]() { return true; }); @@ -93,72 +108,275 @@ TEST(TEST_NAME, imu_timeout) { // 1 - data available EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_IMU_DATA)); + MODE_HANDLER_ERROR_NO_IMU_DATA)); + + // 2 - no data available (1. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + MODE_HANDLER_ERROR_NO_IMU_DATA)); + + // 3 - no data available (2. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_FCP_DATA)); + MODE_HANDLER_ERROR_NO_IMU_DATA)); - // 2 - no data available (1. frame) + // 4 - no data available (3. frame) EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_IMU_DATA)); + + // 5 - no data available (4. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + MODE_HANDLER_ERROR_NO_IMU_DATA)); + + // 6 - no data available (5. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_FCP_DATA)); + MODE_HANDLER_ERROR_NO_IMU_DATA)); - // 3 - no data available (2. frame) + // 7 - no data available (6. frame) -> timeout + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_REMOTE); + EXPECT_TRUE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_IMU_DATA)); + + // 8 - data available EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_IMU_DATA)); +} + +TEST(TEST_NAME, remote_initial_timeout) { + auto imuHandle = mock::imu.getHandle(); + auto flightcomputerHandle = mock::flightcomputer.getHandle(); + auto remoteHandle = mock::remote.getHandle(); + auto errorHandlerHandle = mock::error_handler.getHandle(); + + imuHandle.overrideFunc([]() { return true; }); + imuHandle.overrideFunc([]() { return imu_data_t{.imu_ok = true}; }); + remoteHandle.overrideFunc([]() { return false; }); + remoteHandle.overrideFunc( + []() { return remote_data_t{.is_armed = true, .override_active = false, .remote_ok = true}; }); + flightcomputerHandle.overrideFunc([]() { return true; }); + flightcomputerHandle.overrideFunc([]() { return flightcomputer_setpoint_t{}; }); + + mode_handler_init(); + + imu_data_t imuData; + remote_data_t remoteData; + flightcomputer_setpoint_t flightcomputerSetpoint; + + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_STABILISED_FAILSAVE); + EXPECT_TRUE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_REMOTE_DATA)); +} + +TEST(TEST_NAME, remote_initial_nok) { + auto imuHandle = mock::imu.getHandle(); + auto flightcomputerHandle = mock::flightcomputer.getHandle(); + auto remoteHandle = mock::remote.getHandle(); + auto errorHandlerHandle = mock::error_handler.getHandle(); + + imuHandle.overrideFunc([]() { return true; }); + imuHandle.overrideFunc([]() { return imu_data_t{.imu_ok = true}; }); + remoteHandle.overrideFunc([]() { return true; }); + remoteHandle.overrideFunc( + []() { return remote_data_t{.is_armed = true, .override_active = false, .remote_ok = false}; }); + flightcomputerHandle.overrideFunc([]() { return true; }); + flightcomputerHandle.overrideFunc([]() { return flightcomputer_setpoint_t{}; }); + + mode_handler_init(); + + imu_data_t imuData; + remote_data_t remoteData; + flightcomputer_setpoint_t flightcomputerSetpoint; + + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_STABILISED_FAILSAVE); + EXPECT_TRUE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_REMOTE_DATA)); +} + +TEST(TEST_NAME, remote_timeout) { + auto imuHandle = mock::imu.getHandle(); + auto flightcomputerHandle = mock::flightcomputer.getHandle(); + auto remoteHandle = mock::remote.getHandle(); + auto errorHandlerHandle = mock::error_handler.getHandle(); + + std::size_t frameCounter = 0; + imuHandle.overrideFunc([]() { return true; }); + imuHandle.overrideFunc([]() { return imu_data_t{.imu_ok = true}; }); + remoteHandle.overrideFunc([&frameCounter]() { + frameCounter += 1; + return frameCounter < 2 or frameCounter > 7; + }); + remoteHandle.overrideFunc( + []() { return remote_data_t{.is_armed = true, .override_active = false, .remote_ok = true}; }); + flightcomputerHandle.overrideFunc([]() { return true; }); + flightcomputerHandle.overrideFunc([]() { return flightcomputer_setpoint_t{}; }); + + mode_handler_init(); + + imu_data_t imuData; + remote_data_t remoteData; + flightcomputer_setpoint_t flightcomputerSetpoint; + + // 1 - data available + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); + EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + + // 2 - no data available (1. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + + // 3 - no data available (2. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_FCP_DATA)); + MODE_HANDLER_ERROR_NO_REMOTE_DATA)); // 4 - no data available (3. frame) EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_IMU_DATA)); + MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + + // 5 - no data available (4. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); + EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + + // 6 - no data available (5. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + + // 7 - no data available (6. frame) -> timeout + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_STABILISED_FAILSAVE); + EXPECT_TRUE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + + // 8 - data available + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); + EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_REMOTE_DATA)); +} + +TEST(TEST_NAME, fcp_initial_timeout) { + auto imuHandle = mock::imu.getHandle(); + auto flightcomputerHandle = mock::flightcomputer.getHandle(); + auto remoteHandle = mock::remote.getHandle(); + auto errorHandlerHandle = mock::error_handler.getHandle(); + + imuHandle.overrideFunc([]() { return true; }); + imuHandle.overrideFunc([]() { return imu_data_t{.imu_ok = true}; }); + remoteHandle.overrideFunc([]() { return true; }); + remoteHandle.overrideFunc( + []() { return remote_data_t{.is_armed = true, .override_active = false, .remote_ok = true}; }); + flightcomputerHandle.overrideFunc([]() { return false; }); + flightcomputerHandle.overrideFunc([]() { return flightcomputer_setpoint_t{}; }); + + mode_handler_init(); + + imu_data_t imuData; + remote_data_t remoteData; + flightcomputer_setpoint_t flightcomputerSetpoint; + + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_REMOTE); + EXPECT_TRUE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_FCP_DATA)); +} + +TEST(TEST_NAME, fcp_timeout) { + auto imuHandle = mock::imu.getHandle(); + auto flightcomputerHandle = mock::flightcomputer.getHandle(); + auto remoteHandle = mock::remote.getHandle(); + auto errorHandlerHandle = mock::error_handler.getHandle(); + + std::size_t frameCounter = 0; + imuHandle.overrideFunc([]() { return true; }); + imuHandle.overrideFunc([]() { return imu_data_t{.imu_ok = true}; }); + remoteHandle.overrideFunc([]() { return true; }); + remoteHandle.overrideFunc( + []() { return remote_data_t{.is_armed = true, .override_active = false, .remote_ok = true}; }); + flightcomputerHandle.overrideFunc([&frameCounter]() { + frameCounter += 1; + return frameCounter < 2 or frameCounter > 13; + }); + flightcomputerHandle.overrideFunc([]() { return flightcomputer_setpoint_t{}; }); + + mode_handler_init(); + + imu_data_t imuData; + remote_data_t remoteData; + flightcomputer_setpoint_t flightcomputerSetpoint; + + // 1 - data available + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_FCP_DATA)); - // 5 - no data available (4. frame) + // 2 - no data available (1. frame) EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_IMU_DATA)); + MODE_HANDLER_ERROR_NO_FCP_DATA)); + + // 3 - no data available (2. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + MODE_HANDLER_ERROR_NO_FCP_DATA)); + + // 4 - no data available (3. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); + EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_FCP_DATA)); + + // 5 - no data available (4. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_FCP_DATA)); // 6 - no data available (5. frame) EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_IMU_DATA)); + MODE_HANDLER_ERROR_NO_FCP_DATA)); + + // 7 - no data available (6. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + MODE_HANDLER_ERROR_NO_FCP_DATA)); + + // 8 - no data available (7. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_FCP_DATA)); - // 7 - no data available (6. frame) -> timeout - EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_REMOTE); - EXPECT_TRUE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_IMU_DATA)); + // 9 - no data available (8. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + MODE_HANDLER_ERROR_NO_FCP_DATA)); + + // 10 - no data available (9. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_FCP_DATA)); - // 8 - data available + // 11 - no data available (10. frame) EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_IMU_DATA)); + MODE_HANDLER_ERROR_NO_FCP_DATA)); + + // 12 - no data available (11. frame) + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, - MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + MODE_HANDLER_ERROR_NO_FCP_DATA)); + + // 13 - no data available (12. frame) -> timeout + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_REMOTE); + EXPECT_TRUE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, + MODE_HANDLER_ERROR_NO_FCP_DATA)); + + // 14 - data available + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_FCP_DATA)); }