diff --git a/tests/sys/ztimer_mbox_get_timeout/Makefile b/tests/sys/ztimer_mbox_get_timeout/Makefile new file mode 100644 index 0000000000000..1e51f832b346d --- /dev/null +++ b/tests/sys/ztimer_mbox_get_timeout/Makefile @@ -0,0 +1,7 @@ +include ../Makefile.sys_common + +USEMODULE += ztimer_usec +USEMODULE += core_thread_flags +USEMODULE += core_mbox + +include $(RIOTBASE)/Makefile.include diff --git a/tests/sys/ztimer_mbox_get_timeout/app.config.test b/tests/sys/ztimer_mbox_get_timeout/app.config.test new file mode 100644 index 0000000000000..8d7e31b1901e6 --- /dev/null +++ b/tests/sys/ztimer_mbox_get_timeout/app.config.test @@ -0,0 +1,6 @@ +# this file enables modules defined in Kconfig. Do not use this file for +# application configuration. This is only needed during migration. +CONFIG_MODULE_ZTIMER=y +CONFIG_ZTIMER_USEC=y +CONFIG_MODULE_CORE_THREAD_FLAGS=y +CONFIG_MODULE_CORE_MBOX=y diff --git a/tests/sys/ztimer_mbox_get_timeout/main.c b/tests/sys/ztimer_mbox_get_timeout/main.c new file mode 100644 index 0000000000000..5f650d69a2d1f --- /dev/null +++ b/tests/sys/ztimer_mbox_get_timeout/main.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2023 Otto-von-Guericke-Universität Magdeburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief testing ztimer_mbox_get_timeout function + * + * + * @author Marian Buschsieweke + * + */ + +#include +#include +#include + +#include "mbox.h" +#include "test_utils/expect.h" +#include "time_units.h" +#include "ztimer.h" + +#define MSG_TYPE 42 +#define MSG_VAL 1337 + +static msg_t queue[4]; +static mbox_t mbox = MBOX_INIT(queue, ARRAY_SIZE(queue)); + +static void cb_mbox_put(void *arg) +{ + mbox_try_put(&mbox, arg); +} + +static void test_mbox_already_full(void) +{ + printf("testing mbox already full prior call: "); + msg_t msg = { .type = MSG_TYPE, .content.value = MSG_VAL }; + mbox_put(&mbox, &msg); + uint32_t start = ztimer_now(ZTIMER_USEC); + expect(ztimer_mbox_get_timeout(ZTIMER_USEC, &mbox, &msg, US_PER_SEC) == 0); + uint32_t stop = ztimer_now(ZTIMER_USEC); + /* Returning immediately should with nothing else running in this test app + * should not take more than a millisecond */ + expect(stop - start < US_PER_MS); + printf("OK\n"); +} + +static void test_timeout_reached(void) +{ + const uint32_t timeout_us = 10 * US_PER_MS; + printf("testing timeout is reached: "); + msg_t msg = { .type = MSG_TYPE - 1, .content.value = MSG_VAL - 1 }; + uint32_t start = ztimer_now(ZTIMER_USEC); + expect(ztimer_mbox_get_timeout(ZTIMER_USEC, &mbox, &msg, timeout_us) == -ECANCELED); + uint32_t stop = ztimer_now(ZTIMER_USEC); + /* This may take longer than the timeout due to overhead, background tasks, + * etc. But it MUST NOT return early. */ + expect(stop - start >= timeout_us); + /* But it should also not take way too long */ + expect(stop - start < 2 * timeout_us); + /* msg must not be changed */ + expect((msg.type == MSG_TYPE - 1) && (msg.content.value == MSG_VAL - 1)) ; + printf("OK\n"); +} + +static void test_msg_prior_timeout(void) +{ + const uint32_t msg_timeout_us = 10 * US_PER_MS; + const uint32_t wait_timeout_us = 20 * US_PER_MS; + + msg_t msg = { .type = MSG_TYPE, .content.value = MSG_VAL }; + msg_t got = { .type = 0 }; + ztimer_t t = { + .callback = cb_mbox_put, + .arg = &msg, + }; + + ztimer_set(ZTIMER_USEC, &t, msg_timeout_us); + uint32_t start = ztimer_now(ZTIMER_USEC); + expect(ztimer_mbox_get_timeout(ZTIMER_USEC, &mbox, &got, wait_timeout_us) == 0); + uint32_t stop = ztimer_now(ZTIMER_USEC); + + /* the function should return AFTER the message was send, but BEFORE the + * timeout was triggered */ + expect(stop - start >= msg_timeout_us); + expect(stop - start < wait_timeout_us); + + /* we should have gotten the correct message */ + expect((got.type == msg.type) && (got.content.value == msg.content.value)); +} + +int main(void) +{ + printf("Testing ztimer_mbox_get_timeout()\n" + "=================================\n"); + test_mbox_already_full(); + test_timeout_reached(); + printf("repeating test, but with sporadic THREAD_FLAG_TIMEOUT set...\n"); + thread_flags_set(thread_get_active(), THREAD_FLAG_TIMEOUT); + test_timeout_reached(); + test_msg_prior_timeout(); + + printf("ALL TESTS SUCCEEDED\n"); + return 0; +} diff --git a/tests/sys/ztimer_mbox_get_timeout/tests/01-run.py b/tests/sys/ztimer_mbox_get_timeout/tests/01-run.py new file mode 100755 index 0000000000000..80df7e90d2e09 --- /dev/null +++ b/tests/sys/ztimer_mbox_get_timeout/tests/01-run.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2023 Otto-von-Guericke-Universität Magdeburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +# @author Marian Buschsieweke + +import sys +from testrunner import run + + +def testfunc(child): + child.expect("Testing ztimer_mbox_get_timeout()") + child.expect("ALL TESTS SUCCEEDED") + + +if __name__ == "__main__": + sys.exit(run(testfunc))