blob: b16daccb2e37e31d6501a2fd988bd049ef087eff [file] [log] [blame]
/*
* Copyright (c) 2024 Nordic Semiconductor
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/drivers/watchdog.h>
#include <zephyr/ztest_error_hook.h>
/*
* To use this test, either the devicetree's /aliases must have a
* 'watchdog0' property, or one of the following watchdog compatibles
* must have an enabled node.
*/
#if DT_NODE_HAS_STATUS(DT_ALIAS(watchdog0), okay)
#define WDT_NODE DT_ALIAS(watchdog0)
#elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_wdt)
#define WDT_NODE DT_INST(0, nordic_nrf_wdt)
#elif DT_HAS_COMPAT_STATUS_OKAY(zephyr_counter_watchdog)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_counter_watchdog)
#endif
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay)
#define NOINIT_SECTION ".dtcm_noinit.test_wdt"
#else
#define NOINIT_SECTION ".noinit.test_wdt"
#endif
/* Bit fields used to select tests to be run on the target */
#define WDT_DISABLE_SUPPORTED BIT(0)
#define WDT_FLAG_RESET_NONE_SUPPORTED BIT(1)
#define WDT_FLAG_RESET_CPU_CORE_SUPPORTED BIT(2)
#define WDT_FLAG_RESET_SOC_SUPPORTED BIT(3)
#define WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED BIT(4)
#define WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED BIT(5)
#define WDT_OPT_PAUSE_HALTED_BY_DBG_SUPPORTED BIT(6)
#define WDT_FEED_CAN_STALL BIT(7)
/* Common for all targets: */
#define DEFAULT_WINDOW_MAX (500U)
#define DEFAULT_WINDOW_MIN (0U)
/* Align tests to the specific target: */
#if defined(CONFIG_SOC_NRF54L15) || defined(CONFIG_SOC_NRF54H20)
#define WDT_TEST_FLAGS \
(WDT_DISABLE_SUPPORTED | WDT_FLAG_RESET_SOC_SUPPORTED | \
WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED | WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED | \
WDT_OPT_PAUSE_HALTED_BY_DBG_SUPPORTED)
#define DEFAULT_FLAGS (WDT_FLAG_RESET_SOC)
#define MAX_INSTALLABLE_TIMEOUTS (8)
#define WDT_WINDOW_MAX_ALLOWED (0x07CFFFFFU)
#define DEFAULT_OPTIONS (WDT_OPT_PAUSE_IN_SLEEP | WDT_OPT_PAUSE_HALTED_BY_DBG)
#else
/* By default run most of the error checks.
* See Readme.txt on how to align test scope for the specific target.
*/
#define WDT_TEST_FLAGS \
(WDT_DISABLE_SUPPORTED | WDT_FLAG_RESET_SOC_SUPPORTED | \
WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED)
#define DEFAULT_FLAGS (WDT_FLAG_RESET_SOC)
#define MAX_INSTALLABLE_TIMEOUTS (8)
#define WDT_WINDOW_MAX_ALLOWED (0xFFFFFFFFU)
#define DEFAULT_OPTIONS (WDT_OPT_PAUSE_IN_SLEEP)
#endif
static const struct device *const wdt = DEVICE_DT_GET(WDT_NODE);
static struct wdt_timeout_cfg m_cfg_wdt0;
/* Following variables are incremented in WDT callbacks
* to indicate whether interrupt was fired or not.
*/
volatile uint32_t m_test_06b_value __attribute__((section(NOINIT_SECTION)));
#define TEST_06B_TAG (0x12345678U)
volatile uint32_t m_test_08b_value __attribute__((section(NOINIT_SECTION)));
#define TEST_08B_TAG (0x23456789U)
volatile uint32_t m_test_08d_A_value __attribute__((section(NOINIT_SECTION)));
#define TEST_08D_A_TAG (0x3456789AU)
volatile uint32_t m_test_08d_B_value __attribute__((section(NOINIT_SECTION)));
#define TEST_08D_B_TAG (0x456789ABU)
static void wdt_test_06b_cb(const struct device *wdt_dev, int channel_id)
{
ARG_UNUSED(wdt_dev);
ARG_UNUSED(channel_id);
m_test_06b_value = TEST_06B_TAG;
}
static void wdt_test_08b_cb(const struct device *wdt_dev, int channel_id)
{
ARG_UNUSED(wdt_dev);
ARG_UNUSED(channel_id);
m_test_08b_value = TEST_08B_TAG;
}
static void wdt_test_08d_A_cb(const struct device *wdt_dev, int channel_id)
{
ARG_UNUSED(wdt_dev);
ARG_UNUSED(channel_id);
m_test_08d_A_value = TEST_08D_A_TAG;
}
static void wdt_test_08d_B_cb(const struct device *wdt_dev, int channel_id)
{
ARG_UNUSED(wdt_dev);
ARG_UNUSED(channel_id);
m_test_08d_B_value = TEST_08D_B_TAG;
}
/**
* @brief wdt_disable() negative test
*
* Confirm that wdt_disable() returns
* -EFAULT when watchdog instance is not enabled.
*
*/
ZTEST(wdt_coverage, test_01_wdt_disable_before_wdt_setup)
{
int ret;
if (!(WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED)) {
/* Skip this test because wdt_disable() is NOT supported. */
ztest_test_skip();
}
/* Call wdt_disable before enabling wdt */
ret = wdt_disable(wdt);
zassert_true(ret == -EFAULT,
"Calling wdt_disable before watchdog was started should return -EFAULT (-14), "
"got unexpected value of %d",
ret);
}
/**
* @brief wdt_setup() negative test
*
* Confirm that wdt_setup() returns error value or ASSERTION FAIL
* when it's called before wdt_install_timeouts().
*
*/
ZTEST(wdt_coverage, test_02_wdt_setup_before_setting_timeouts)
{
int ret;
/* Call wdt_setup before wdt_install_timeouts() */
ztest_set_assert_valid(true);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret < 0,
"Calling wdt_setup before installing timeouts should fail, got unexpected "
"value of %d",
ret);
}
/**
* @brief wdt_feed() negative test
*
* Confirm that wdt_feed() returns error value
* when it's called before wdt_setup().
* Test scenario where none of timeout channels is configured.
*
*/
ZTEST(wdt_coverage, test_03_wdt_feed_before_wdt_setup_channel_not_configured)
{
int ret;
/* Call wdt_feed() before wdt_setup() (channel wasn't configured) */
ret = wdt_feed(wdt, 0);
zassert_true(ret == -EINVAL,
"wdt_feed() shall return error value when called before wdt_setup(), got "
"unexpected value of %d",
ret);
}
/**
* @brief wdt_install_timeout() negative test
*
* Confirm that wdt_install_timeout() returns
* -ENOTSUP when flag WDT_FLAG_RESET_NONE is not supported
*
*/
ZTEST(wdt_coverage, test_04a_wdt_install_timeout_WDT_FLAG_RESET_NONE_not_supported)
{
int ret;
if (WDT_TEST_FLAGS & WDT_FLAG_RESET_NONE_SUPPORTED) {
/* Skip this test because WDT_FLAG_RESET_NONE is supported. */
ztest_test_skip();
}
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = WDT_FLAG_RESET_NONE;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret == -ENOTSUP,
"WDT_FLAG_RESET_NONE is not supported on this target and should fail, got "
"unexpected value of %d",
ret);
}
/**
* @brief wdt_install_timeout() negative test
*
* Confirm that wdt_install_timeout() returns
* -ENOTSUP when flag WDT_FLAG_RESET_CPU_CORE is not supported
*
*/
ZTEST(wdt_coverage, test_04b_wdt_install_timeout_WDT_FLAG_RESET_CPU_CORE_not_supported)
{
int ret;
if (WDT_TEST_FLAGS & WDT_FLAG_RESET_CPU_CORE_SUPPORTED) {
/* Skip this test because WDT_FLAG_RESET_CPU_CORE is supported. */
ztest_test_skip();
}
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = WDT_FLAG_RESET_CPU_CORE;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret == -ENOTSUP,
"WDT_FLAG_RESET_CPU_CORE is not supported on this target and should fail, got "
"unexpected value of %d",
ret);
}
/**
* @brief wdt_install_timeout() negative test
*
* Confirm that wdt_install_timeout() returns
* -ENOTSUP when flag WDT_FLAG_RESET_SOC is not supported
*
*/
ZTEST(wdt_coverage, test_04c_wdt_install_timeout_WDT_FLAG_RESET_SOC_not_supported)
{
int ret;
if (WDT_TEST_FLAGS & WDT_FLAG_RESET_SOC_SUPPORTED) {
/* Skip this test because WDT_FLAG_RESET_SOC is supported. */
ztest_test_skip();
}
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = WDT_FLAG_RESET_SOC;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret == -ENOTSUP,
"WDT_FLAG_RESET_SOC is not supported on this target and should fail, got "
"unexpected value of %d",
ret);
}
/**
* @brief wdt_install_timeout() negative test
*
* Confirm that wdt_install_timeout() returns
* -EINVAL when window timeout is out of possible range
*
*/
ZTEST(wdt_coverage, test_04w_wdt_install_timeout_with_invalid_window)
{
int ret;
/* set defaults */
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
/* ----------------- window.min
* Check that window.min can't be different than 0
*/
m_cfg_wdt0.window.min = 1U;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret == -EINVAL,
"Calling wdt_install_timeout with window.min = 1 should return -EINVAL (-22), "
"got unexpected value of %d",
ret);
/* Set default window.min */
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
/* ----------------- window.max
* Check that window.max can't be equal to 0
*/
m_cfg_wdt0.window.max = 0U;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret == -EINVAL,
"Calling wdt_install_timeout with window.max = 0 should return -EINVAL (-22), "
"got unexpected value of %d",
ret);
/* Check that window.max can't exceed maximum allowed value */
m_cfg_wdt0.window.max = WDT_WINDOW_MAX_ALLOWED + 1;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret == -EINVAL,
"Calling wdt_install_timeout with window.max = %d should return -EINVAL "
"(-22), got unexpected value of %d",
WDT_WINDOW_MAX_ALLOWED + 1, ret);
}
/**
* @brief wdt_install_timeout() negative test
*
* Confirm that wdt_install_timeout() returns
* -EINVAL when watchdog supports only one timeout value
* for all timeouts and the supplied timeout window differs
* from windows for alarms installed so far.
*
*/
ZTEST(wdt_coverage, test_04wm_wdt_install_timeout_with_multiple_timeout_values)
{
int ret;
if (!(WDT_TEST_FLAGS & WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED)) {
/* Skip this test because timeouts with different values are supported */
ztest_test_skip();
}
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
/* Call wdt_install_timeout again with different window */
m_cfg_wdt0.window.max = WDT_WINDOW_MAX_ALLOWED >> 1;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret == -EINVAL,
"wdt_install_timeout should return -EINVAL (-22), got unexpected value of %d",
ret);
}
/**
* @brief wdt_install_timeout() negative test
*
* Confirm that wdt_install_timeout() returns ASSERTION FAIL or
* -EBUSY when called after the watchdog instance has been already setup.
*
*/
ZTEST(wdt_coverage, test_05_wdt_install_timeout_after_wdt_setup)
{
int ret;
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
/* Call wdt_install_timeout again to test invalid use */
ztest_set_assert_valid(true);
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret == -EBUSY,
"Calling wdt_install_timeout after wdt_setup should return -EBUSY (-16), got "
"unexpected value of %d",
ret);
/* Assumption: wdt_disable() is called after this test */
}
/**
* @brief wdt_setup() negative test
*
* Confirm that wdt_setup() returns
* -ENOTSUP when option WDT_OPT_PAUSE_IN_SLEEP is not supported
*
*/
ZTEST(wdt_coverage, test_06a_wdt_setup_WDT_OPT_PAUSE_IN_SLEEP_not_supported)
{
int ret;
if (WDT_TEST_FLAGS & WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED) {
/* Skip this test because WDT_OPT_PAUSE_IN_SLEEP is supported. */
ztest_test_skip();
}
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
ret = wdt_setup(wdt, WDT_OPT_PAUSE_IN_SLEEP);
zassert_true(ret == -ENOTSUP,
"WDT_OPT_PAUSE_IN_SLEEP is not supported on this target and should fail, got "
"unexpected value of %d",
ret);
ret = wdt_setup(wdt, WDT_OPT_PAUSE_IN_SLEEP | WDT_OPT_PAUSE_HALTED_BY_DBG);
zassert_true(ret == -ENOTSUP,
"WDT_OPT_PAUSE_IN_SLEEP is not supported on this target and should fail, got "
"unexpected value of %d",
ret);
}
/**
* @brief Test that wdt_setup(device, WDT_OPT_PAUSE_IN_SLEEP) works as expected
*
* Confirm that when WDT_OPT_PAUSE_IN_SLEEP is set,
* watchdog will not fire when thread is sleeping.
*
*/
ZTEST(wdt_coverage, test_06b_wdt_setup_WDT_OPT_PAUSE_IN_SLEEP_functional)
{
int ret;
if (!(WDT_TEST_FLAGS & WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED)) {
/* Skip this test because WDT_OPT_PAUSE_IN_SLEEP can NOT be used. */
ztest_test_skip();
}
/* When test fails, watchdog sets m_test_06b_value to TEST_06B_TAG in WDT callback
* wdt_test_06b_cb. Then, target is reset. Check value of m_test_06b_value to prevent reset
* loop on this test.
*/
if (m_test_06b_value == TEST_06B_TAG) {
m_test_06b_value = 0U;
zassert_true(false, "Watchod has fired while it shouldn't");
}
/* Clear flag that is set when the watchdog fires */
m_test_06b_value = 0U;
m_cfg_wdt0.callback = wdt_test_06b_cb;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
/* Set timeout window to ~500 ms */
m_cfg_wdt0.window.max = 500U;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
ret = wdt_setup(wdt, WDT_OPT_PAUSE_IN_SLEEP);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
TC_PRINT("Test has failed if there is reset after this line\n");
/* Sleep for longer time than watchdog timeout */
k_sleep(K_SECONDS(1));
/* m_test_06b_value is set to TEST_06B_TAG in WDT callback */
zassert_equal(m_test_06b_value, 0, "Watchod has fired while it shouldn't");
/* Assumption: wdt_disable() is called after each test */
}
/**
* @brief wdt_setup() negative test
*
* Confirm that wdt_setup() returns
* -ENOTSUP when option WDT_OPT_PAUSE_HALTED_BY_DBG is not supported
*
*/
ZTEST(wdt_coverage, test_06c_wdt_setup_WDT_OPT_PAUSE_HALTED_BY_DBG_not_supported)
{
int ret;
if (WDT_TEST_FLAGS & WDT_OPT_PAUSE_HALTED_BY_DBG_SUPPORTED) {
/* Skip this test because WDT_OPT_PAUSE_HALTED_BY_DBG is supported. */
ztest_test_skip();
}
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
ret = wdt_setup(wdt, WDT_OPT_PAUSE_HALTED_BY_DBG);
zassert_true(ret == -ENOTSUP,
"WDT_OPT_PAUSE_HALTED_BY_DBG is not supported on this target and should fail, "
"got unexpected value of %d",
ret);
ret = wdt_setup(wdt, WDT_OPT_PAUSE_IN_SLEEP | WDT_OPT_PAUSE_HALTED_BY_DBG);
zassert_true(ret == -ENOTSUP,
"WDT_OPT_PAUSE_HALTED_BY_DBG is not supported on this target and should fail, "
"got unexpected value of %d",
ret);
}
/**
* @brief wdt_setup() corner case
*
* Confirm that wdt_setup() returns
* 0 - success, when no option is provided
*
*/
ZTEST(wdt_coverage, test_06d_wdt_setup_without_any_OPT)
{
int ret;
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
ret = wdt_setup(wdt, 0x0);
zassert_true(ret == 0, "Got unexpected value of %d, while expected is 0", ret);
}
/**
* @brief wdt_setup() negative test
*
* Confirm that wdt_setup() returns
* -EBUSY when watchdog instance has been already setup.
*
*/
ZTEST(wdt_coverage, test_07_wdt_setup_already_done)
{
int ret;
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
/* Call wdt_setup again to test invalid use */
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == -EBUSY,
"Calling wdt_setup for the second time should return -EBUSY (-16), got "
"unexpected value of %d",
ret);
/* Assumption: wdt_disable() is called after this test */
}
/**
* @brief wdt_setup() negative test
*
* Confirm that wdt_disable() returns
* -EPERM when watchdog can not be disabled directly by application code.
*
*/
ZTEST(wdt_coverage, test_08a_wdt_disable_not_supported)
{
int ret;
if (WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED) {
/* Skip this test because wdt_disable() is supported. */
ztest_test_skip();
}
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
/* Assumption - test suite execution finishes before WDT timeout will fire */
m_cfg_wdt0.window.max = WDT_WINDOW_MAX_ALLOWED;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
/* Call wdt_disable to test not allowed use */
ret = wdt_disable(wdt);
zassert_true(ret == -EPERM,
"Disabling WDT is not supported on this target and should return -EPERM (-1), "
"got unexpected value of %d",
ret);
}
/**
* @brief Test that wdt_disable() stops watchdog
*
* Confirm that wdt_disable() prevents previously configured
* watchdog from resetting the core.
*
*/
ZTEST(wdt_coverage, test_08b_wdt_disable_check_not_firing)
{
int ret;
if (!(WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED)) {
/* Skip this test because wdt_disable() is NOT supported. */
ztest_test_skip();
}
/* When test fails, watchdog sets m_test_08b_value to TEST_08B_TAG in WDT callback
* wdt_test_08b_cb. Then, target is reset. Check value of m_test_08b_value to prevent reset
* loop on this test.
*/
if (m_test_08b_value == TEST_08B_TAG) {
m_test_08b_value = 0U;
zassert_true(false, "Watchod has fired while it shouldn't");
}
/* Clear flag that is set when the watchdog fires */
m_test_08b_value = 0U;
m_cfg_wdt0.callback = wdt_test_08b_cb;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
/* Set timeout window to ~500 ms */
m_cfg_wdt0.window.max = 500U;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
TC_PRINT("Test has failed if there is reset after this line\n");
/* Wait for 450 ms, then disable the watchdog
* Don't change to k_sleep() because use of WDT_OPT_PAUSE_IN_SLEEP
* will break test scenario.
*/
k_busy_wait(450000);
ret = wdt_disable(wdt);
zassert_true(ret == 0, "Watchdog disable error, got unexpected value of %d", ret);
/* Wait a bit more to see if watchdog fires
* Don't change to k_sleep() because use of WDT_OPT_PAUSE_IN_SLEEP
* will break test scenario.
*/
k_busy_wait(300000);
/* m_test_08b_value is set to TEST_08B_TAG in WDT callback */
zassert_equal(m_test_08b_value, 0, "Watchod has fired while it shouldn't");
}
/**
* @brief Test that after wdt_disable() timeouts can be reconfigured
*
* Confirm that after wdt_disable() it is possible to configure
* timeout channel that was configured previously.
*
*/
ZTEST(wdt_coverage, test_08c_wdt_disable_check_timeouts_reusable)
{
int ret, id1, id2;
if (!(WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED)) {
/* Skip this test because wdt_disable() is NOT supported. */
ztest_test_skip();
}
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
id1 = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(id1 >= 0, "Watchdog install error, got unexpected value of %d", id1);
TC_PRINT("Configured WDT channel %d\n", id1);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
ret = wdt_disable(wdt);
zassert_true(ret == 0, "Watchdog disable error, got unexpected value of %d", ret);
id2 = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(id2 >= 0, "Watchdog install error, got unexpected value of %d", id2);
TC_PRINT("Configured WDT channel %d\n", id2);
/* test that timeout channel id2 is NOT greater than previously returned channel id1 */
zassert_true(id2 <= id1,
"First usable timeout channel after wdt_disable() is %d, expected number no "
"greater than %d",
id2, id1);
}
/**
* @brief Test that after wdt_disable() uninstalled timeouts don't have to be feed
*
* Confirm that wdt_disable() uninstalls all timeouts.
* When new timeout is configured, only this one has to be feed.
*
*/
ZTEST(wdt_coverage, test_08d_wdt_disable_check_timeouts_uninstalled)
{
int ret, id_A, id_B, i;
if (!(WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED)) {
/* Skip this test because wdt_disable() is NOT supported. */
ztest_test_skip();
}
/* m_test_08d_A_value is set to TEST_08D_A_TAG in callback wdt_test_08d_A_cb */
if (m_test_08d_A_value == TEST_08D_A_TAG) {
m_test_08d_A_value = 0U;
zassert_true(false, "Timeout A has fired while it shouldn't");
}
/* m_test_08d_B_value is set to TEST_08D_B_TAG in callback wdt_test_08d_B_cb */
if (m_test_08d_B_value == TEST_08D_B_TAG) {
m_test_08d_B_value = 0U;
zassert_true(false, "Timeout B has fired while it shouldn't");
}
/* Clear flags that are set when the watchdog fires */
m_test_08d_A_value = 0U;
m_test_08d_B_value = 0U;
/* Configure Timeout A */
m_cfg_wdt0.callback = wdt_test_08d_A_cb;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
/* Set timeout window to ~500 ms */
m_cfg_wdt0.window.max = 500U;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
id_A = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(id_A >= 0, "Watchdog install error, got unexpected value of %d", id_A);
TC_PRINT("Configured WDT channel %d\n", id_A);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
ret = wdt_disable(wdt);
zassert_true(ret == 0, "Watchdog disable error, got unexpected value of %d", ret);
/* Configure Timeout B */
m_cfg_wdt0.callback = wdt_test_08d_B_cb;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
/* Set timeout window to ~500 ms */
m_cfg_wdt0.window.max = 500U;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
id_B = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(id_B >= 0, "Watchdog install error, got unexpected value of %d", id_B);
TC_PRINT("Configured WDT channel %d\n", id_B);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
TC_PRINT("Test has failed if there is reset after this line\n");
/* Confirm that only Timeout B has to be feed */
for (i = 0; i < 4; i++) {
k_busy_wait(450000);
wdt_feed(wdt, id_B);
}
ret = wdt_disable(wdt);
zassert_true(ret == 0, "Watchdog disable error, got unexpected value of %d", ret);
/* m_test_08d_A_value is set to TEST_08D_A_TAG in callback wdt_test_08d_A_cb */
zassert_equal(m_test_08d_A_value, 0, "Timeout A has fired while it shouldn't");
/* m_test_08d_B_value is set to TEST_08D_B_TAG in callback wdt_test_08d_B_cb */
zassert_equal(m_test_08d_B_value, 0, "Timeout B has fired while it shouldn't");
}
/**
* @brief Test error code when wdt_setup() is called after wdt_disable()
*
* Confirm that wdt_setup() returns error value or ASSERTION FAIL
* when it's called before any timeout was configured with wdt_install_timeouts().
* All timeouts were uninstalled by calling wdt_disable().
*
*/
ZTEST(wdt_coverage, test_08e_wdt_setup_immediately_after_wdt_disable)
{
int ret;
if (!(WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED)) {
/* Skip this test because wdt_disable() is NOT supported. */
ztest_test_skip();
}
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
ret = wdt_disable(wdt);
zassert_true(ret == 0, "Watchdog disable error, got unexpected value of %d", ret);
/* Call wdt_setup when no timeouts are configured. */
/* Timeouts were removed by calling wdt_disable(). */
ztest_set_assert_valid(true);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret < 0,
"Calling wdt_setup before installing timeouts should fail, got unexpected "
"value of %d",
ret);
}
/**
* @brief wdt_feed() negative test
*
* Confirm that wdt_feed() returns error or ASSERTION FAIL
* when it's called before wdt_setup().
* Test scenario where timeout channel is configured.
*
*/
ZTEST(wdt_coverage, test_09a_wdt_feed_before_wdt_setup_channel_configured)
{
int ret, ch_id;
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ch_id = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ch_id >= 0, "Watchdog install error, got unexpected value of %d", ch_id);
TC_PRINT("Configured WDT channel %d\n", ch_id);
/* Call wdt_feed() before wdt_setup() (channel was configured) */
ztest_set_assert_valid(true);
ret = wdt_feed(wdt, ch_id);
zassert_true(ret < 0,
"wdt_feed() shall return error value when called before wdt_setup(), got "
"unexpected value of %d",
ret);
}
/**
* @brief wdt_feed() negative test
*
* Confirm that wdt_feed() returns
* -EINVAL when there is no installed timeout for supplied channel.
*
*/
ZTEST(wdt_coverage, test_09b_wdt_feed_invalid_channel)
{
int ret, ch_id, ch_invalid;
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ch_id = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ch_id >= 0, "Watchdog install error, got unexpected value of %d", ch_id);
TC_PRINT("Configured WDT channel %d\n", ch_id);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
TC_PRINT("Test has failed if there is reset after this line\n");
/* Call wdt_feed() on not configured channel */
ch_invalid = ch_id + 2;
ret = wdt_feed(wdt, ch_invalid);
zassert_true(ret == -EINVAL,
"wdt_feed(%d) shall return -EINVAL (-22), got unexpected value of %d",
ch_invalid, ret);
/* Call wdt_feed() on not configured channel */
ch_invalid = ch_id + 1;
ret = wdt_feed(wdt, ch_invalid);
zassert_true(ret == -EINVAL,
"wdt_feed(%d) shall return -EINVAL (-22), got unexpected value of %d",
ch_invalid, ret);
/* Call wdt_feed() on invalid channel (no such channel) */
ret = wdt_feed(wdt, -1);
zassert_true(ret == -EINVAL,
"wdt_feed(-1) shall return -EINVAL (-22), got unexpected value of %d", ret);
/* Call wdt_feed() on invalid channel (no such channel) */
ret = wdt_feed(wdt, MAX_INSTALLABLE_TIMEOUTS);
zassert_true(ret == -EINVAL,
"wdt_feed(%d) shall return -EINVAL (-22), got unexpected value of %d",
MAX_INSTALLABLE_TIMEOUTS, ret);
/* Assumption: wdt_disable() is called after each test */
}
/**
* @brief wdt_feed() negative test
*
* Confirm that wdt_feed() returns
* -EAGAIN when completing the feed operation would stall the caller, for example
* due to an in-progress watchdog operation such as a previous wdt_feed() call.
*
*/
ZTEST(wdt_coverage, test_09c_wdt_feed_stall)
{
int ret, ch_id, i;
if (!(WDT_TEST_FLAGS & WDT_FEED_CAN_STALL)) {
/* Skip this test because wdt_feed() can NOT stall. */
ztest_test_skip();
}
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
ch_id = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ch_id >= 0, "Watchdog install error, got unexpected value of %d", ch_id);
TC_PRINT("Configured WDT channel %d\n", ch_id);
ret = wdt_setup(wdt, DEFAULT_OPTIONS);
zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
TC_PRINT("Test has failed if there is reset after this line\n");
for (i = 0; i < 5; i++) {
ret = wdt_feed(wdt, ch_id);
if (i == 0) {
zassert_true(ret == 0, "wdt_feed error, got unexpected value of %d", ret);
} else {
zassert_true(
ret == -EAGAIN,
"wdt_feed shall return -EAGAIN (-11), got unexpected value of %d",
ret);
}
}
}
/**
* @brief wdt_install_timeout() negative test
*
* Confirm that wdt_install_timeout() returns
* -ENOMEM when no more timeouts can be installed.
*
*/
ZTEST(wdt_coverage, test_10_wdt_install_timeout_max_number_of_timeouts)
{
int i, ret;
m_cfg_wdt0.callback = NULL;
m_cfg_wdt0.flags = DEFAULT_FLAGS;
m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
for (i = 0; i < MAX_INSTALLABLE_TIMEOUTS; i++) {
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
/* Assumption - timeouts are counted from 0 to (MAX_INSTALLABLE_TIMEOUTS - 1) */
zassert_true(ret < MAX_INSTALLABLE_TIMEOUTS,
"Watchdog install error, got unexpected value of %d", ret);
TC_PRINT("Configured WDT channel %d\n", ret);
}
/* Call wdt_install_timeout again to test if error value is returned */
ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
zassert_true(ret == -ENOMEM,
"wdt_install_timeout shall return -ENOMEM (-12), got unexpected value of %d",
ret);
}
static void *suite_setup(void)
{
TC_PRINT("Test executed on %s\n", CONFIG_BOARD_TARGET);
TC_PRINT("===================================================================\n");
return NULL;
}
static void before_test(void *not_used)
{
ARG_UNUSED(not_used);
int ret_val;
ret_val = device_is_ready(wdt);
zassert_true(ret_val, "WDT device is not ready, got unexpected value of %d", ret_val);
}
static void cleanup_after_test(void *f)
{
if (WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED) {
/* Disable watchdog so it doesn't break other tests */
wdt_disable(wdt);
}
}
ZTEST_SUITE(wdt_coverage, NULL, suite_setup, before_test, cleanup_after_test, NULL);