1 /*
2 * Copyright (c) 2024 Nordic Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/drivers/watchdog.h>
9 #include <zephyr/ztest_error_hook.h>
10
11 /*
12 * To use this test, either the devicetree's /aliases must have a
13 * 'watchdog0' property, or one of the following watchdog compatibles
14 * must have an enabled node.
15 */
16 #if DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(watchdog0))
17 #define WDT_NODE DT_ALIAS(watchdog0)
18 #elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_wdt)
19 #define WDT_NODE DT_INST(0, nordic_nrf_wdt)
20 #elif DT_HAS_COMPAT_STATUS_OKAY(zephyr_counter_watchdog)
21 #define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_counter_watchdog)
22 #endif
23
24 #if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_dtcm))
25 #define NOINIT_SECTION ".dtcm_noinit.test_wdt"
26 #else
27 #define NOINIT_SECTION ".noinit.test_wdt"
28 #endif
29
30 /* Bit fields used to select tests to be run on the target */
31 #define WDT_DISABLE_SUPPORTED BIT(0)
32 #define WDT_FLAG_RESET_NONE_SUPPORTED BIT(1)
33 #define WDT_FLAG_RESET_CPU_CORE_SUPPORTED BIT(2)
34 #define WDT_FLAG_RESET_SOC_SUPPORTED BIT(3)
35 #define WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED BIT(4)
36 #define WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED BIT(5)
37 #define WDT_OPT_PAUSE_HALTED_BY_DBG_SUPPORTED BIT(6)
38 #define WDT_FEED_CAN_STALL BIT(7)
39
40 /* Common for all targets: */
41 #define DEFAULT_WINDOW_MAX (500U)
42 #define DEFAULT_WINDOW_MIN (0U)
43
44 /* Align tests to the specific target: */
45 #if defined(CONFIG_SOC_SERIES_NRF54LX) || defined(CONFIG_SOC_NRF54H20) || \
46 defined(CONFIG_SOC_NRF9280)
47 #define WDT_TEST_FLAGS \
48 (WDT_DISABLE_SUPPORTED | WDT_FLAG_RESET_SOC_SUPPORTED | \
49 WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED | WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED | \
50 WDT_OPT_PAUSE_HALTED_BY_DBG_SUPPORTED)
51 #define DEFAULT_FLAGS (WDT_FLAG_RESET_SOC)
52 #define MAX_INSTALLABLE_TIMEOUTS (8)
53 #define WDT_WINDOW_MAX_ALLOWED (0x07CFFFFFU)
54 #define DEFAULT_OPTIONS (WDT_OPT_PAUSE_IN_SLEEP | WDT_OPT_PAUSE_HALTED_BY_DBG)
55 #else
56 /* By default run most of the error checks.
57 * See Readme.txt on how to align test scope for the specific target.
58 */
59 #define WDT_TEST_FLAGS \
60 (WDT_DISABLE_SUPPORTED | WDT_FLAG_RESET_SOC_SUPPORTED | \
61 WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED)
62 #define DEFAULT_FLAGS (WDT_FLAG_RESET_SOC)
63 #define MAX_INSTALLABLE_TIMEOUTS (8)
64 #define WDT_WINDOW_MAX_ALLOWED (0xFFFFFFFFU)
65 #define DEFAULT_OPTIONS (WDT_OPT_PAUSE_IN_SLEEP)
66 #endif
67
68 static const struct device *const wdt = DEVICE_DT_GET(WDT_NODE);
69 static struct wdt_timeout_cfg m_cfg_wdt0;
70
71 /* Following variables are incremented in WDT callbacks
72 * to indicate whether interrupt was fired or not.
73 */
74 volatile uint32_t m_test_06b_value __attribute__((section(NOINIT_SECTION)));
75 #define TEST_06B_TAG (0x12345678U)
76 volatile uint32_t m_test_08b_value __attribute__((section(NOINIT_SECTION)));
77 #define TEST_08B_TAG (0x23456789U)
78 volatile uint32_t m_test_08d_A_value __attribute__((section(NOINIT_SECTION)));
79 #define TEST_08D_A_TAG (0x3456789AU)
80 volatile uint32_t m_test_08d_B_value __attribute__((section(NOINIT_SECTION)));
81 #define TEST_08D_B_TAG (0x456789ABU)
82
wdt_test_06b_cb(const struct device * wdt_dev,int channel_id)83 static void wdt_test_06b_cb(const struct device *wdt_dev, int channel_id)
84 {
85 ARG_UNUSED(wdt_dev);
86 ARG_UNUSED(channel_id);
87 m_test_06b_value = TEST_06B_TAG;
88 }
89
wdt_test_08b_cb(const struct device * wdt_dev,int channel_id)90 static void wdt_test_08b_cb(const struct device *wdt_dev, int channel_id)
91 {
92 ARG_UNUSED(wdt_dev);
93 ARG_UNUSED(channel_id);
94 m_test_08b_value = TEST_08B_TAG;
95 }
96
wdt_test_08d_A_cb(const struct device * wdt_dev,int channel_id)97 static void wdt_test_08d_A_cb(const struct device *wdt_dev, int channel_id)
98 {
99 ARG_UNUSED(wdt_dev);
100 ARG_UNUSED(channel_id);
101 m_test_08d_A_value = TEST_08D_A_TAG;
102 }
103
wdt_test_08d_B_cb(const struct device * wdt_dev,int channel_id)104 static void wdt_test_08d_B_cb(const struct device *wdt_dev, int channel_id)
105 {
106 ARG_UNUSED(wdt_dev);
107 ARG_UNUSED(channel_id);
108 m_test_08d_B_value = TEST_08D_B_TAG;
109 }
110
111 /**
112 * @brief wdt_disable() negative test
113 *
114 * Confirm that wdt_disable() returns
115 * -EFAULT when watchdog instance is not enabled.
116 *
117 */
ZTEST(wdt_coverage,test_01_wdt_disable_before_wdt_setup)118 ZTEST(wdt_coverage, test_01_wdt_disable_before_wdt_setup)
119 {
120 int ret;
121
122 if (!(WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED)) {
123 /* Skip this test because wdt_disable() is NOT supported. */
124 ztest_test_skip();
125 }
126
127 /* Call wdt_disable before enabling wdt */
128 ret = wdt_disable(wdt);
129 zassert_true(ret == -EFAULT,
130 "Calling wdt_disable before watchdog was started should return -EFAULT (-14), "
131 "got unexpected value of %d",
132 ret);
133 }
134
135 /**
136 * @brief wdt_setup() negative test
137 *
138 * Confirm that wdt_setup() returns error value or ASSERTION FAIL
139 * when it's called before wdt_install_timeouts().
140 *
141 */
ZTEST(wdt_coverage,test_02_wdt_setup_before_setting_timeouts)142 ZTEST(wdt_coverage, test_02_wdt_setup_before_setting_timeouts)
143 {
144 int ret;
145
146 /* Call wdt_setup before wdt_install_timeouts() */
147 ztest_set_assert_valid(true);
148 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
149 zassert_true(ret < 0,
150 "Calling wdt_setup before installing timeouts should fail, got unexpected "
151 "value of %d",
152 ret);
153 }
154
155 /**
156 * @brief wdt_feed() negative test
157 *
158 * Confirm that wdt_feed() returns error value
159 * when it's called before wdt_setup().
160 * Test scenario where none of timeout channels is configured.
161 *
162 */
ZTEST(wdt_coverage,test_03_wdt_feed_before_wdt_setup_channel_not_configured)163 ZTEST(wdt_coverage, test_03_wdt_feed_before_wdt_setup_channel_not_configured)
164 {
165 int ret;
166
167 /* Call wdt_feed() before wdt_setup() (channel wasn't configured) */
168 ret = wdt_feed(wdt, 0);
169 zassert_true(ret == -EINVAL,
170 "wdt_feed() shall return error value when called before wdt_setup(), got "
171 "unexpected value of %d",
172 ret);
173 }
174
175 /**
176 * @brief wdt_install_timeout() negative test
177 *
178 * Confirm that wdt_install_timeout() returns
179 * -ENOTSUP when flag WDT_FLAG_RESET_NONE is not supported
180 *
181 */
ZTEST(wdt_coverage,test_04a_wdt_install_timeout_WDT_FLAG_RESET_NONE_not_supported)182 ZTEST(wdt_coverage, test_04a_wdt_install_timeout_WDT_FLAG_RESET_NONE_not_supported)
183 {
184 int ret;
185
186 if (WDT_TEST_FLAGS & WDT_FLAG_RESET_NONE_SUPPORTED) {
187 /* Skip this test because WDT_FLAG_RESET_NONE is supported. */
188 ztest_test_skip();
189 }
190
191 m_cfg_wdt0.callback = NULL;
192 m_cfg_wdt0.flags = WDT_FLAG_RESET_NONE;
193 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
194 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
195
196 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
197 zassert_true(ret == -ENOTSUP,
198 "WDT_FLAG_RESET_NONE is not supported on this target and should fail, got "
199 "unexpected value of %d",
200 ret);
201 }
202
203 /**
204 * @brief wdt_install_timeout() negative test
205 *
206 * Confirm that wdt_install_timeout() returns
207 * -ENOTSUP when flag WDT_FLAG_RESET_CPU_CORE is not supported
208 *
209 */
ZTEST(wdt_coverage,test_04b_wdt_install_timeout_WDT_FLAG_RESET_CPU_CORE_not_supported)210 ZTEST(wdt_coverage, test_04b_wdt_install_timeout_WDT_FLAG_RESET_CPU_CORE_not_supported)
211 {
212 int ret;
213
214 if (WDT_TEST_FLAGS & WDT_FLAG_RESET_CPU_CORE_SUPPORTED) {
215 /* Skip this test because WDT_FLAG_RESET_CPU_CORE is supported. */
216 ztest_test_skip();
217 }
218
219 m_cfg_wdt0.callback = NULL;
220 m_cfg_wdt0.flags = WDT_FLAG_RESET_CPU_CORE;
221 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
222 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
223
224 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
225 zassert_true(ret == -ENOTSUP,
226 "WDT_FLAG_RESET_CPU_CORE is not supported on this target and should fail, got "
227 "unexpected value of %d",
228 ret);
229 }
230
231 /**
232 * @brief wdt_install_timeout() negative test
233 *
234 * Confirm that wdt_install_timeout() returns
235 * -ENOTSUP when flag WDT_FLAG_RESET_SOC is not supported
236 *
237 */
ZTEST(wdt_coverage,test_04c_wdt_install_timeout_WDT_FLAG_RESET_SOC_not_supported)238 ZTEST(wdt_coverage, test_04c_wdt_install_timeout_WDT_FLAG_RESET_SOC_not_supported)
239 {
240 int ret;
241
242 if (WDT_TEST_FLAGS & WDT_FLAG_RESET_SOC_SUPPORTED) {
243 /* Skip this test because WDT_FLAG_RESET_SOC is supported. */
244 ztest_test_skip();
245 }
246
247 m_cfg_wdt0.callback = NULL;
248 m_cfg_wdt0.flags = WDT_FLAG_RESET_SOC;
249 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
250 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
251
252 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
253 zassert_true(ret == -ENOTSUP,
254 "WDT_FLAG_RESET_SOC is not supported on this target and should fail, got "
255 "unexpected value of %d",
256 ret);
257 }
258
259 /**
260 * @brief wdt_install_timeout() negative test
261 *
262 * Confirm that wdt_install_timeout() returns
263 * -EINVAL when window timeout is out of possible range
264 *
265 */
ZTEST(wdt_coverage,test_04w_wdt_install_timeout_with_invalid_window)266 ZTEST(wdt_coverage, test_04w_wdt_install_timeout_with_invalid_window)
267 {
268 int ret;
269
270 /* set defaults */
271 m_cfg_wdt0.callback = NULL;
272 m_cfg_wdt0.flags = DEFAULT_FLAGS;
273 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
274 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
275
276 /* ----------------- window.min
277 * Check that window.min can't be different than 0
278 */
279 m_cfg_wdt0.window.min = 1U;
280 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
281 zassert_true(ret == -EINVAL,
282 "Calling wdt_install_timeout with window.min = 1 should return -EINVAL (-22), "
283 "got unexpected value of %d",
284 ret);
285
286 /* Set default window.min */
287 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
288
289 /* ----------------- window.max
290 * Check that window.max can't be equal to 0
291 */
292 m_cfg_wdt0.window.max = 0U;
293 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
294 zassert_true(ret == -EINVAL,
295 "Calling wdt_install_timeout with window.max = 0 should return -EINVAL (-22), "
296 "got unexpected value of %d",
297 ret);
298
299 /* Check that window.max can't exceed maximum allowed value */
300 m_cfg_wdt0.window.max = WDT_WINDOW_MAX_ALLOWED + 1;
301 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
302 zassert_true(ret == -EINVAL,
303 "Calling wdt_install_timeout with window.max = %d should return -EINVAL "
304 "(-22), got unexpected value of %d",
305 WDT_WINDOW_MAX_ALLOWED + 1, ret);
306 }
307
308 /**
309 * @brief wdt_install_timeout() negative test
310 *
311 * Confirm that wdt_install_timeout() returns
312 * -EINVAL when watchdog supports only one timeout value
313 * for all timeouts and the supplied timeout window differs
314 * from windows for alarms installed so far.
315 *
316 */
ZTEST(wdt_coverage,test_04wm_wdt_install_timeout_with_multiple_timeout_values)317 ZTEST(wdt_coverage, test_04wm_wdt_install_timeout_with_multiple_timeout_values)
318 {
319 int ret;
320
321 if (!(WDT_TEST_FLAGS & WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED)) {
322 /* Skip this test because timeouts with different values are supported */
323 ztest_test_skip();
324 }
325
326 m_cfg_wdt0.callback = NULL;
327 m_cfg_wdt0.flags = DEFAULT_FLAGS;
328 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
329 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
330
331 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
332 zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
333 TC_PRINT("Configured WDT channel %d\n", ret);
334
335 /* Call wdt_install_timeout again with different window */
336 m_cfg_wdt0.window.max = WDT_WINDOW_MAX_ALLOWED >> 1;
337 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
338 zassert_true(ret == -EINVAL,
339 "wdt_install_timeout should return -EINVAL (-22), got unexpected value of %d",
340 ret);
341 }
342
343 /**
344 * @brief wdt_install_timeout() negative test
345 *
346 * Confirm that wdt_install_timeout() returns ASSERTION FAIL or
347 * -EBUSY when called after the watchdog instance has been already setup.
348 *
349 */
ZTEST(wdt_coverage,test_05_wdt_install_timeout_after_wdt_setup)350 ZTEST(wdt_coverage, test_05_wdt_install_timeout_after_wdt_setup)
351 {
352 int ret;
353
354 m_cfg_wdt0.callback = NULL;
355 m_cfg_wdt0.flags = DEFAULT_FLAGS;
356 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
357 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
358
359 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
360 zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
361 TC_PRINT("Configured WDT channel %d\n", ret);
362
363 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
364 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
365
366 /* Call wdt_install_timeout again to test invalid use */
367 ztest_set_assert_valid(true);
368 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
369 zassert_true(ret == -EBUSY,
370 "Calling wdt_install_timeout after wdt_setup should return -EBUSY (-16), got "
371 "unexpected value of %d",
372 ret);
373
374 /* Assumption: wdt_disable() is called after this test */
375 }
376
377 /**
378 * @brief wdt_setup() negative test
379 *
380 * Confirm that wdt_setup() returns
381 * -ENOTSUP when option WDT_OPT_PAUSE_IN_SLEEP is not supported
382 *
383 */
ZTEST(wdt_coverage,test_06a_wdt_setup_WDT_OPT_PAUSE_IN_SLEEP_not_supported)384 ZTEST(wdt_coverage, test_06a_wdt_setup_WDT_OPT_PAUSE_IN_SLEEP_not_supported)
385 {
386 int ret;
387
388 if (WDT_TEST_FLAGS & WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED) {
389 /* Skip this test because WDT_OPT_PAUSE_IN_SLEEP is supported. */
390 ztest_test_skip();
391 }
392
393 m_cfg_wdt0.callback = NULL;
394 m_cfg_wdt0.flags = DEFAULT_FLAGS;
395 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
396 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
397
398 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
399 zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
400 TC_PRINT("Configured WDT channel %d\n", ret);
401
402 ret = wdt_setup(wdt, WDT_OPT_PAUSE_IN_SLEEP);
403 zassert_true(ret == -ENOTSUP,
404 "WDT_OPT_PAUSE_IN_SLEEP is not supported on this target and should fail, got "
405 "unexpected value of %d",
406 ret);
407
408 ret = wdt_setup(wdt, WDT_OPT_PAUSE_IN_SLEEP | WDT_OPT_PAUSE_HALTED_BY_DBG);
409 zassert_true(ret == -ENOTSUP,
410 "WDT_OPT_PAUSE_IN_SLEEP is not supported on this target and should fail, got "
411 "unexpected value of %d",
412 ret);
413 }
414
415 /**
416 * @brief Test that wdt_setup(device, WDT_OPT_PAUSE_IN_SLEEP) works as expected
417 *
418 * Confirm that when WDT_OPT_PAUSE_IN_SLEEP is set,
419 * watchdog will not fire when thread is sleeping.
420 *
421 */
ZTEST(wdt_coverage,test_06b_wdt_setup_WDT_OPT_PAUSE_IN_SLEEP_functional)422 ZTEST(wdt_coverage, test_06b_wdt_setup_WDT_OPT_PAUSE_IN_SLEEP_functional)
423 {
424 int ret;
425
426 if (!(WDT_TEST_FLAGS & WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED)) {
427 /* Skip this test because WDT_OPT_PAUSE_IN_SLEEP can NOT be used. */
428 ztest_test_skip();
429 }
430
431 /* When test fails, watchdog sets m_test_06b_value to TEST_06B_TAG in WDT callback
432 * wdt_test_06b_cb. Then, target is reset. Check value of m_test_06b_value to prevent reset
433 * loop on this test.
434 */
435 if (m_test_06b_value == TEST_06B_TAG) {
436 m_test_06b_value = 0U;
437 zassert_true(false, "Watchod has fired while it shouldn't");
438 }
439
440 /* Clear flag that is set when the watchdog fires */
441 m_test_06b_value = 0U;
442
443 m_cfg_wdt0.callback = wdt_test_06b_cb;
444 m_cfg_wdt0.flags = DEFAULT_FLAGS;
445 /* Set timeout window to ~500 ms */
446 m_cfg_wdt0.window.max = 500U;
447 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
448
449 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
450 zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
451 TC_PRINT("Configured WDT channel %d\n", ret);
452
453 ret = wdt_setup(wdt, WDT_OPT_PAUSE_IN_SLEEP);
454 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
455 TC_PRINT("Test has failed if there is reset after this line\n");
456
457 /* Sleep for longer time than watchdog timeout */
458 k_sleep(K_SECONDS(1));
459
460 /* m_test_06b_value is set to TEST_06B_TAG in WDT callback */
461 zassert_equal(m_test_06b_value, 0, "Watchod has fired while it shouldn't");
462
463 /* Assumption: wdt_disable() is called after each test */
464 }
465
466 /**
467 * @brief wdt_setup() negative test
468 *
469 * Confirm that wdt_setup() returns
470 * -ENOTSUP when option WDT_OPT_PAUSE_HALTED_BY_DBG is not supported
471 *
472 */
ZTEST(wdt_coverage,test_06c_wdt_setup_WDT_OPT_PAUSE_HALTED_BY_DBG_not_supported)473 ZTEST(wdt_coverage, test_06c_wdt_setup_WDT_OPT_PAUSE_HALTED_BY_DBG_not_supported)
474 {
475 int ret;
476
477 if (WDT_TEST_FLAGS & WDT_OPT_PAUSE_HALTED_BY_DBG_SUPPORTED) {
478 /* Skip this test because WDT_OPT_PAUSE_HALTED_BY_DBG is supported. */
479 ztest_test_skip();
480 }
481
482 m_cfg_wdt0.callback = NULL;
483 m_cfg_wdt0.flags = DEFAULT_FLAGS;
484 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
485 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
486
487 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
488 zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
489 TC_PRINT("Configured WDT channel %d\n", ret);
490
491 ret = wdt_setup(wdt, WDT_OPT_PAUSE_HALTED_BY_DBG);
492 zassert_true(ret == -ENOTSUP,
493 "WDT_OPT_PAUSE_HALTED_BY_DBG is not supported on this target and should fail, "
494 "got unexpected value of %d",
495 ret);
496
497 ret = wdt_setup(wdt, WDT_OPT_PAUSE_IN_SLEEP | WDT_OPT_PAUSE_HALTED_BY_DBG);
498 zassert_true(ret == -ENOTSUP,
499 "WDT_OPT_PAUSE_HALTED_BY_DBG is not supported on this target and should fail, "
500 "got unexpected value of %d",
501 ret);
502 }
503
504 /**
505 * @brief wdt_setup() corner case
506 *
507 * Confirm that wdt_setup() returns
508 * 0 - success, when no option is provided
509 *
510 */
ZTEST(wdt_coverage,test_06d_wdt_setup_without_any_OPT)511 ZTEST(wdt_coverage, test_06d_wdt_setup_without_any_OPT)
512 {
513 int ret;
514
515 m_cfg_wdt0.callback = NULL;
516 m_cfg_wdt0.flags = DEFAULT_FLAGS;
517 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
518 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
519
520 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
521 zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
522 TC_PRINT("Configured WDT channel %d\n", ret);
523
524 ret = wdt_setup(wdt, 0x0);
525 zassert_true(ret == 0, "Got unexpected value of %d, while expected is 0", ret);
526 }
527
528 /**
529 * @brief wdt_setup() negative test
530 *
531 * Confirm that wdt_setup() returns
532 * -EBUSY when watchdog instance has been already setup.
533 *
534 */
ZTEST(wdt_coverage,test_07_wdt_setup_already_done)535 ZTEST(wdt_coverage, test_07_wdt_setup_already_done)
536 {
537 int ret;
538
539 m_cfg_wdt0.callback = NULL;
540 m_cfg_wdt0.flags = DEFAULT_FLAGS;
541 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
542 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
543
544 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
545 zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
546 TC_PRINT("Configured WDT channel %d\n", ret);
547
548 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
549 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
550
551 /* Call wdt_setup again to test invalid use */
552 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
553 zassert_true(ret == -EBUSY,
554 "Calling wdt_setup for the second time should return -EBUSY (-16), got "
555 "unexpected value of %d",
556 ret);
557
558 /* Assumption: wdt_disable() is called after this test */
559 }
560
561 /**
562 * @brief wdt_setup() negative test
563 *
564 * Confirm that wdt_disable() returns
565 * -EPERM when watchdog can not be disabled directly by application code.
566 *
567 */
ZTEST(wdt_coverage,test_08a_wdt_disable_not_supported)568 ZTEST(wdt_coverage, test_08a_wdt_disable_not_supported)
569 {
570 int ret;
571
572 if (WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED) {
573 /* Skip this test because wdt_disable() is supported. */
574 ztest_test_skip();
575 }
576
577 m_cfg_wdt0.callback = NULL;
578 m_cfg_wdt0.flags = DEFAULT_FLAGS;
579 /* Assumption - test suite execution finishes before WDT timeout will fire */
580 m_cfg_wdt0.window.max = WDT_WINDOW_MAX_ALLOWED;
581 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
582
583 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
584 zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
585 TC_PRINT("Configured WDT channel %d\n", ret);
586
587 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
588 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
589
590 /* Call wdt_disable to test not allowed use */
591 ret = wdt_disable(wdt);
592 zassert_true(ret == -EPERM,
593 "Disabling WDT is not supported on this target and should return -EPERM (-1), "
594 "got unexpected value of %d",
595 ret);
596 }
597
598 /**
599 * @brief Test that wdt_disable() stops watchdog
600 *
601 * Confirm that wdt_disable() prevents previously configured
602 * watchdog from resetting the core.
603 *
604 */
ZTEST(wdt_coverage,test_08b_wdt_disable_check_not_firing)605 ZTEST(wdt_coverage, test_08b_wdt_disable_check_not_firing)
606 {
607 int ret;
608
609 if (!(WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED)) {
610 /* Skip this test because wdt_disable() is NOT supported. */
611 ztest_test_skip();
612 }
613
614 /* When test fails, watchdog sets m_test_08b_value to TEST_08B_TAG in WDT callback
615 * wdt_test_08b_cb. Then, target is reset. Check value of m_test_08b_value to prevent reset
616 * loop on this test.
617 */
618 if (m_test_08b_value == TEST_08B_TAG) {
619 m_test_08b_value = 0U;
620 zassert_true(false, "Watchod has fired while it shouldn't");
621 }
622
623 /* Clear flag that is set when the watchdog fires */
624 m_test_08b_value = 0U;
625
626 m_cfg_wdt0.callback = wdt_test_08b_cb;
627 m_cfg_wdt0.flags = DEFAULT_FLAGS;
628 /* Set timeout window to ~500 ms */
629 m_cfg_wdt0.window.max = 500U;
630 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
631
632 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
633 zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
634 TC_PRINT("Configured WDT channel %d\n", ret);
635
636 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
637 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
638 TC_PRINT("Test has failed if there is reset after this line\n");
639
640 /* Wait for 450 ms, then disable the watchdog
641 * Don't change to k_sleep() because use of WDT_OPT_PAUSE_IN_SLEEP
642 * will break test scenario.
643 */
644 k_busy_wait(450000);
645 ret = wdt_disable(wdt);
646 zassert_true(ret == 0, "Watchdog disable error, got unexpected value of %d", ret);
647
648 /* Wait a bit more to see if watchdog fires
649 * Don't change to k_sleep() because use of WDT_OPT_PAUSE_IN_SLEEP
650 * will break test scenario.
651 */
652 k_busy_wait(300000);
653
654 /* m_test_08b_value is set to TEST_08B_TAG in WDT callback */
655 zassert_equal(m_test_08b_value, 0, "Watchod has fired while it shouldn't");
656 }
657
658 /**
659 * @brief Test that after wdt_disable() timeouts can be reconfigured
660 *
661 * Confirm that after wdt_disable() it is possible to configure
662 * timeout channel that was configured previously.
663 *
664 */
ZTEST(wdt_coverage,test_08c_wdt_disable_check_timeouts_reusable)665 ZTEST(wdt_coverage, test_08c_wdt_disable_check_timeouts_reusable)
666 {
667 int ret, id1, id2;
668
669 if (!(WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED)) {
670 /* Skip this test because wdt_disable() is NOT supported. */
671 ztest_test_skip();
672 }
673
674 m_cfg_wdt0.callback = NULL;
675 m_cfg_wdt0.flags = DEFAULT_FLAGS;
676 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
677 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
678
679 id1 = wdt_install_timeout(wdt, &m_cfg_wdt0);
680 zassert_true(id1 >= 0, "Watchdog install error, got unexpected value of %d", id1);
681 TC_PRINT("Configured WDT channel %d\n", id1);
682
683 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
684 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
685
686 ret = wdt_disable(wdt);
687 zassert_true(ret == 0, "Watchdog disable error, got unexpected value of %d", ret);
688
689 id2 = wdt_install_timeout(wdt, &m_cfg_wdt0);
690 zassert_true(id2 >= 0, "Watchdog install error, got unexpected value of %d", id2);
691 TC_PRINT("Configured WDT channel %d\n", id2);
692
693 /* test that timeout channel id2 is NOT greater than previously returned channel id1 */
694 zassert_true(id2 <= id1,
695 "First usable timeout channel after wdt_disable() is %d, expected number no "
696 "greater than %d",
697 id2, id1);
698 }
699
700 /**
701 * @brief Test that after wdt_disable() uninstalled timeouts don't have to be feed
702 *
703 * Confirm that wdt_disable() uninstalls all timeouts.
704 * When new timeout is configured, only this one has to be feed.
705 *
706 */
ZTEST(wdt_coverage,test_08d_wdt_disable_check_timeouts_uninstalled)707 ZTEST(wdt_coverage, test_08d_wdt_disable_check_timeouts_uninstalled)
708 {
709 int ret, id_A, id_B, i;
710
711 if (!(WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED)) {
712 /* Skip this test because wdt_disable() is NOT supported. */
713 ztest_test_skip();
714 }
715
716 /* m_test_08d_A_value is set to TEST_08D_A_TAG in callback wdt_test_08d_A_cb */
717 if (m_test_08d_A_value == TEST_08D_A_TAG) {
718 m_test_08d_A_value = 0U;
719 zassert_true(false, "Timeout A has fired while it shouldn't");
720 }
721
722 /* m_test_08d_B_value is set to TEST_08D_B_TAG in callback wdt_test_08d_B_cb */
723 if (m_test_08d_B_value == TEST_08D_B_TAG) {
724 m_test_08d_B_value = 0U;
725 zassert_true(false, "Timeout B has fired while it shouldn't");
726 }
727
728 /* Clear flags that are set when the watchdog fires */
729 m_test_08d_A_value = 0U;
730 m_test_08d_B_value = 0U;
731
732 /* Configure Timeout A */
733 m_cfg_wdt0.callback = wdt_test_08d_A_cb;
734 m_cfg_wdt0.flags = DEFAULT_FLAGS;
735 /* Set timeout window to ~500 ms */
736 m_cfg_wdt0.window.max = 500U;
737 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
738
739 id_A = wdt_install_timeout(wdt, &m_cfg_wdt0);
740 zassert_true(id_A >= 0, "Watchdog install error, got unexpected value of %d", id_A);
741 TC_PRINT("Configured WDT channel %d\n", id_A);
742
743 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
744 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
745
746 ret = wdt_disable(wdt);
747 zassert_true(ret == 0, "Watchdog disable error, got unexpected value of %d", ret);
748
749 /* Configure Timeout B */
750 m_cfg_wdt0.callback = wdt_test_08d_B_cb;
751 m_cfg_wdt0.flags = DEFAULT_FLAGS;
752 /* Set timeout window to ~500 ms */
753 m_cfg_wdt0.window.max = 500U;
754 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
755
756 id_B = wdt_install_timeout(wdt, &m_cfg_wdt0);
757 zassert_true(id_B >= 0, "Watchdog install error, got unexpected value of %d", id_B);
758 TC_PRINT("Configured WDT channel %d\n", id_B);
759
760 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
761 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
762 TC_PRINT("Test has failed if there is reset after this line\n");
763
764 /* Confirm that only Timeout B has to be feed */
765 for (i = 0; i < 4; i++) {
766 k_busy_wait(450000);
767 wdt_feed(wdt, id_B);
768 }
769
770 ret = wdt_disable(wdt);
771 zassert_true(ret == 0, "Watchdog disable error, got unexpected value of %d", ret);
772
773 /* m_test_08d_A_value is set to TEST_08D_A_TAG in callback wdt_test_08d_A_cb */
774 zassert_equal(m_test_08d_A_value, 0, "Timeout A has fired while it shouldn't");
775
776 /* m_test_08d_B_value is set to TEST_08D_B_TAG in callback wdt_test_08d_B_cb */
777 zassert_equal(m_test_08d_B_value, 0, "Timeout B has fired while it shouldn't");
778 }
779
780 /**
781 * @brief Test error code when wdt_setup() is called after wdt_disable()
782 *
783 * Confirm that wdt_setup() returns error value or ASSERTION FAIL
784 * when it's called before any timeout was configured with wdt_install_timeouts().
785 * All timeouts were uninstalled by calling wdt_disable().
786 *
787 */
ZTEST(wdt_coverage,test_08e_wdt_setup_immediately_after_wdt_disable)788 ZTEST(wdt_coverage, test_08e_wdt_setup_immediately_after_wdt_disable)
789 {
790 int ret;
791
792 if (!(WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED)) {
793 /* Skip this test because wdt_disable() is NOT supported. */
794 ztest_test_skip();
795 }
796
797 m_cfg_wdt0.callback = NULL;
798 m_cfg_wdt0.flags = DEFAULT_FLAGS;
799 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
800 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
801
802 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
803 zassert_true(ret >= 0, "Watchdog install error, got unexpected value of %d", ret);
804 TC_PRINT("Configured WDT channel %d\n", ret);
805
806 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
807 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
808
809 ret = wdt_disable(wdt);
810 zassert_true(ret == 0, "Watchdog disable error, got unexpected value of %d", ret);
811
812 /* Call wdt_setup when no timeouts are configured. */
813 /* Timeouts were removed by calling wdt_disable(). */
814 ztest_set_assert_valid(true);
815 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
816 zassert_true(ret < 0,
817 "Calling wdt_setup before installing timeouts should fail, got unexpected "
818 "value of %d",
819 ret);
820 }
821
822 /**
823 * @brief wdt_feed() negative test
824 *
825 * Confirm that wdt_feed() returns error or ASSERTION FAIL
826 * when it's called before wdt_setup().
827 * Test scenario where timeout channel is configured.
828 *
829 */
ZTEST(wdt_coverage,test_09a_wdt_feed_before_wdt_setup_channel_configured)830 ZTEST(wdt_coverage, test_09a_wdt_feed_before_wdt_setup_channel_configured)
831 {
832 int ret, ch_id;
833
834 m_cfg_wdt0.callback = NULL;
835 m_cfg_wdt0.flags = DEFAULT_FLAGS;
836 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
837 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
838
839 ch_id = wdt_install_timeout(wdt, &m_cfg_wdt0);
840 zassert_true(ch_id >= 0, "Watchdog install error, got unexpected value of %d", ch_id);
841 TC_PRINT("Configured WDT channel %d\n", ch_id);
842
843 /* Call wdt_feed() before wdt_setup() (channel was configured) */
844 ztest_set_assert_valid(true);
845 ret = wdt_feed(wdt, ch_id);
846 zassert_true(ret < 0,
847 "wdt_feed() shall return error value when called before wdt_setup(), got "
848 "unexpected value of %d",
849 ret);
850 }
851
852 /**
853 * @brief wdt_feed() negative test
854 *
855 * Confirm that wdt_feed() returns
856 * -EINVAL when there is no installed timeout for supplied channel.
857 *
858 */
ZTEST(wdt_coverage,test_09b_wdt_feed_invalid_channel)859 ZTEST(wdt_coverage, test_09b_wdt_feed_invalid_channel)
860 {
861 int ret, ch_id, ch_invalid;
862
863 m_cfg_wdt0.callback = NULL;
864 m_cfg_wdt0.flags = DEFAULT_FLAGS;
865 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
866 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
867
868 ch_id = wdt_install_timeout(wdt, &m_cfg_wdt0);
869 zassert_true(ch_id >= 0, "Watchdog install error, got unexpected value of %d", ch_id);
870 TC_PRINT("Configured WDT channel %d\n", ch_id);
871
872 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
873 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
874 TC_PRINT("Test has failed if there is reset after this line\n");
875
876 /* Call wdt_feed() on not configured channel */
877 ch_invalid = ch_id + 2;
878 ret = wdt_feed(wdt, ch_invalid);
879 zassert_true(ret == -EINVAL,
880 "wdt_feed(%d) shall return -EINVAL (-22), got unexpected value of %d",
881 ch_invalid, ret);
882
883 /* Call wdt_feed() on not configured channel */
884 ch_invalid = ch_id + 1;
885 ret = wdt_feed(wdt, ch_invalid);
886 zassert_true(ret == -EINVAL,
887 "wdt_feed(%d) shall return -EINVAL (-22), got unexpected value of %d",
888 ch_invalid, ret);
889
890 /* Call wdt_feed() on invalid channel (no such channel) */
891 ret = wdt_feed(wdt, -1);
892 zassert_true(ret == -EINVAL,
893 "wdt_feed(-1) shall return -EINVAL (-22), got unexpected value of %d", ret);
894
895 /* Call wdt_feed() on invalid channel (no such channel) */
896 ret = wdt_feed(wdt, MAX_INSTALLABLE_TIMEOUTS);
897 zassert_true(ret == -EINVAL,
898 "wdt_feed(%d) shall return -EINVAL (-22), got unexpected value of %d",
899 MAX_INSTALLABLE_TIMEOUTS, ret);
900
901 /* Assumption: wdt_disable() is called after each test */
902 }
903
904 /**
905 * @brief wdt_feed() negative test
906 *
907 * Confirm that wdt_feed() returns
908 * -EAGAIN when completing the feed operation would stall the caller, for example
909 * due to an in-progress watchdog operation such as a previous wdt_feed() call.
910 *
911 */
ZTEST(wdt_coverage,test_09c_wdt_feed_stall)912 ZTEST(wdt_coverage, test_09c_wdt_feed_stall)
913 {
914 int ret, ch_id, i;
915
916 if (!(WDT_TEST_FLAGS & WDT_FEED_CAN_STALL)) {
917 /* Skip this test because wdt_feed() can NOT stall. */
918 ztest_test_skip();
919 }
920
921 m_cfg_wdt0.callback = NULL;
922 m_cfg_wdt0.flags = DEFAULT_FLAGS;
923 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
924 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
925
926 ch_id = wdt_install_timeout(wdt, &m_cfg_wdt0);
927 zassert_true(ch_id >= 0, "Watchdog install error, got unexpected value of %d", ch_id);
928 TC_PRINT("Configured WDT channel %d\n", ch_id);
929
930 ret = wdt_setup(wdt, DEFAULT_OPTIONS);
931 zassert_true(ret == 0, "Watchdog setup error, got unexpected value of %d", ret);
932 TC_PRINT("Test has failed if there is reset after this line\n");
933
934 for (i = 0; i < 5; i++) {
935 ret = wdt_feed(wdt, ch_id);
936 if (i == 0) {
937 zassert_true(ret == 0, "wdt_feed error, got unexpected value of %d", ret);
938 } else {
939 zassert_true(
940 ret == -EAGAIN,
941 "wdt_feed shall return -EAGAIN (-11), got unexpected value of %d",
942 ret);
943 }
944 }
945 }
946
947 /**
948 * @brief wdt_install_timeout() negative test
949 *
950 * Confirm that wdt_install_timeout() returns
951 * -ENOMEM when no more timeouts can be installed.
952 *
953 */
ZTEST(wdt_coverage,test_10_wdt_install_timeout_max_number_of_timeouts)954 ZTEST(wdt_coverage, test_10_wdt_install_timeout_max_number_of_timeouts)
955 {
956 int i, ret;
957
958 m_cfg_wdt0.callback = NULL;
959 m_cfg_wdt0.flags = DEFAULT_FLAGS;
960 m_cfg_wdt0.window.max = DEFAULT_WINDOW_MAX;
961 m_cfg_wdt0.window.min = DEFAULT_WINDOW_MIN;
962
963 for (i = 0; i < MAX_INSTALLABLE_TIMEOUTS; i++) {
964 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
965 /* Assumption - timeouts are counted from 0 to (MAX_INSTALLABLE_TIMEOUTS - 1) */
966 zassert_true(ret < MAX_INSTALLABLE_TIMEOUTS,
967 "Watchdog install error, got unexpected value of %d", ret);
968 TC_PRINT("Configured WDT channel %d\n", ret);
969 }
970
971 /* Call wdt_install_timeout again to test if error value is returned */
972 ret = wdt_install_timeout(wdt, &m_cfg_wdt0);
973 zassert_true(ret == -ENOMEM,
974 "wdt_install_timeout shall return -ENOMEM (-12), got unexpected value of %d",
975 ret);
976 }
977
suite_setup(void)978 static void *suite_setup(void)
979 {
980 TC_PRINT("Test executed on %s\n", CONFIG_BOARD_TARGET);
981 TC_PRINT("===================================================================\n");
982
983 return NULL;
984 }
985
before_test(void * not_used)986 static void before_test(void *not_used)
987 {
988 ARG_UNUSED(not_used);
989 int ret_val;
990
991 ret_val = device_is_ready(wdt);
992 zassert_true(ret_val, "WDT device is not ready, got unexpected value of %d", ret_val);
993 }
994
cleanup_after_test(void * f)995 static void cleanup_after_test(void *f)
996 {
997 if (WDT_TEST_FLAGS & WDT_DISABLE_SUPPORTED) {
998 /* Disable watchdog so it doesn't break other tests */
999 wdt_disable(wdt);
1000 }
1001 }
1002
1003 ZTEST_SUITE(wdt_coverage, NULL, suite_setup, before_test, cleanup_after_test, NULL);
1004