diff --git a/tests/xtimer_usleep/README.md b/tests/xtimer_usleep/README.md new file mode 100644 index 0000000000000000000000000000000000000000..75e46c32c259ed6d96150e889e749d9481d5bc6c --- /dev/null +++ b/tests/xtimer_usleep/README.md @@ -0,0 +1,10 @@ +# xtimer_usleep test application + +This test tests `xtimer_usleep()` both against the timings of +`xtimer_now_usec()` and by providing capabilities to compare against an external +timer. + +## Usage +``` +make flash test +``` diff --git a/tests/xtimer_usleep/main.c b/tests/xtimer_usleep/main.c index 6564a507b67499a25ff0b15bb4fbf58cbb95c4db..5117aa274e5b69efca12343008f35de74a9d07f0 100644 --- a/tests/xtimer_usleep/main.c +++ b/tests/xtimer_usleep/main.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2017 Inria + * 2017 Freie Universität Berlin * * 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 @@ -14,35 +15,44 @@ * @brief xtimer_usleep test application * * @author Francisco Acosta <francisco.acosta@inria.fr> + * @author Martine Lenders <m.lenders@fu-berlin.de> * @} */ +#include <inttypes.h> #include <stdio.h> #include "xtimer.h" #include "timex.h" -#define ONE_SEC_SLEEP (1 * US_PER_SEC) -#define FIVE_SEC_SLEEP (5 * US_PER_SEC) -#define TEN_SEC_SLEEP (10 * US_PER_SEC) +#define RUNS (5U) +#define SLEEP_TIMES_NUMOF (sizeof(sleep_times) / sizeof(sleep_times[0])) + +static const uint32_t sleep_times[] = { 10000, 50000, 100000 }; int main(void) { - int t = 9; - - printf("This test will print \"Slept for X sec...\" every 1, 5 and 10 seconds.\n"); - printf("\n<======== If using pyterm, this is the time when started.\n\n"); - - while (t) { - xtimer_usleep(ONE_SEC_SLEEP); - printf("Slept for 1 sec...\n"); - xtimer_usleep(FIVE_SEC_SLEEP); - printf("Slept for 5 sec...\n"); - xtimer_usleep(TEN_SEC_SLEEP); - printf("Slept for 10 sec...\n"); - t--; + uint32_t start_test, testtime; + + printf("Running test %u times with %u distinct sleep times\n", RUNS, + (unsigned)SLEEP_TIMES_NUMOF); + puts("Please hit any key and then ENTER to continue"); + getchar(); + start_test = xtimer_now_usec(); + for (unsigned m = 0; m < RUNS; m++) { + for (unsigned n = 0; + n < sizeof(sleep_times) / sizeof(sleep_times[0]); + n++) { + uint32_t diff, start; + start = xtimer_now_usec(); + xtimer_usleep(sleep_times[n]); + diff = xtimer_now_usec() - start; + printf("Slept for %" PRIu32 " us (expected: %" PRIu32 " us)\n", + diff, sleep_times[n]); + } } - printf("Test end.\n"); + testtime = xtimer_now_usec() - start_test; + printf("Test ran for %" PRIu32 " us\n", testtime); return 0; } diff --git a/tests/xtimer_usleep/tests/01-run.py b/tests/xtimer_usleep/tests/01-run.py index 7899a5bdde16d09b7c88fd67cae52466a3c33201..827f2c6dc906338161bf31ea22c84e7926aec850 100755 --- a/tests/xtimer_usleep/tests/01-run.py +++ b/tests/xtimer_usleep/tests/01-run.py @@ -1,6 +1,9 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 # Copyright (C) 2017 Francisco Acosta <francisco.acosta@inria.fr> +# 2017 Freie Universität Berlin # # 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 @@ -8,48 +11,46 @@ import os import sys +import time sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner')) import testrunner -from datetime import datetime +US_PER_SEC = 1000000 +INTERNAL_JITTER = 0.05 +EXTERNAL_JITTER = 0.15 class InvalidTimeout(Exception): pass def testfunc(child): - exp_diff1 = 1000000 - exp_diff5 = 5000000 - exp_diff10 = 10000000 - child.expect(u"This test will print \"Slept for X sec...\" every 1, 5 and 10 seconds.\r\n") - child.expect(u"\r\n") - child.expect(u"<======== If using pyterm, this is the time when started.") - child.expect(u"\r\n") - m = 9 - while (m): - n = 3 - while (n): - if n == 3: - exp_diff = exp_diff1 - if n == 2: - exp_diff = exp_diff5 - elif n == 1: - exp_diff = exp_diff10 - start = datetime.now() - child.expect(u"Slept for \\d+ sec...", timeout=11) - stop = datetime.now() - diff = (stop - start) - diff = (diff.seconds * 1000000) + diff.microseconds - # fail within 5% of expected - if diff > (exp_diff + (exp_diff1 * 0.05)) or \ - diff < (exp_diff - (exp_diff1 * 0.05)): - raise InvalidTimeout("Invalid timeout %d (expected %d)" % (diff, exp_diff)); - else: - print("Timed out correctly: %d (expected %d)" % (diff, exp_diff)) - n = n - 1 - m = m -1 - - child.expect(u"Test end.", timeout=15) + child.expect(u"Running test (\\d+) times with (\\d+) distinct sleep times") + RUNS = int(child.match.group(1)) + SLEEP_TIMES_NUMOF = int(child.match.group(2)) + try: + child.expect_exact(u"Please hit any key and then ENTER to continue") + child.sendline(u"a") + start_test = time.time() + for m in range(RUNS): + for n in range(SLEEP_TIMES_NUMOF): + child.expect(u"Slept for (\\d+) us \\(expected: (\\d+) us\\)") + sleep_time = int(child.match.group(1)) + exp = int(child.match.group(2)) + lower_bound = exp - (exp * INTERNAL_JITTER) + upper_bound = exp + (exp * INTERNAL_JITTER) + if not (lower_bound < sleep_time < upper_bound): + raise InvalidTimeout("Invalid timeout %d (expected %d)" % (sleep_time, exp)); + testtime = (time.time() - start_test) * US_PER_SEC + child.expect(u"Test ran for (\\d+) us") + exp = int(child.match.group(1)) + lower_bound = exp - (exp * EXTERNAL_JITTER) + upper_bound = exp + (exp * EXTERNAL_JITTER) + if not (lower_bound < testtime < upper_bound): + raise InvalidTimeout("Host timer measured %d us (client measured %d us)" % \ + (testtime, exp)); + except InvalidTimeout as e: + print(e) + sys.exit(1) if __name__ == "__main__": - sys.exit(testrunner.run(testfunc)) + sys.exit(testrunner.run(testfunc, echo=True))