1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

unittests: Add ztimer test suite

This commit is contained in:
Joakim Nohlgård 2018-09-03 08:40:05 +02:00 committed by Kaspar Schleiser
parent 6dd79366bb
commit 39980d5ea3
6 changed files with 564 additions and 0 deletions

View File

@ -0,0 +1,6 @@
# avoid clang warning in tests-ztimer/tests-ztimer-extend.c:141
ifeq (llvm,$(TOOLCHAIN))
CFLAGS += -Wno-gnu-folding-constant
endif
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,3 @@
USEMODULE += ztimer_core
USEMODULE += ztimer_mock
USEMODULE += ztimer_convert_muldiv64

View File

@ -0,0 +1,216 @@
/*
* Copyright (C) 2018 Eistec AB
*
* 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.
*/
/**
* @{
*
* @file
* @brief Unittests for ztimer_convert_muldiv64
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/
#include "ztimer.h"
#include "ztimer/mock.h"
#include "ztimer/convert_muldiv64.h"
#include "embUnit/embUnit.h"
#include "tests-ztimer.h"
#include <stdio.h>
static void test_ztimer_convert_muldiv64_now_helper(uint32_t div, uint32_t mul)
{
ztimer_mock_t zmock;
ztimer_convert_muldiv64_t zc;
ztimer_clock_t *z = &zc.super.super;
ztimer_mock_init(&zmock, 16);
ztimer_convert_muldiv64_init(&zc, &zmock.super, div, mul);
uint32_t last = 0;
for (uint32_t i = 0; i <= 0xfffff; i++) {
uint32_t now = ztimer_now(z);
uint64_t should = (uint64_t)i * div;
should /= mul;
TEST_ASSERT(now >= last);
TEST_ASSERT_EQUAL_INT(should, now);
ztimer_mock_advance(&zmock, 1);
last = now;
}
}
/**
* @brief Basic checks for ztimer_convert_muldiv64
*/
static void test_ztimer_convert_muldiv64_now(void)
{
test_ztimer_convert_muldiv64_now_helper(15625, 512);
}
static void _set_cb(void *arg)
{
int *val = arg;
*val = 1;
}
static void test_ztimer_convert_muldiv64_set_speedup(void)
{
ztimer_mock_t zmock;
ztimer_convert_muldiv64_t zc;
ztimer_clock_t *z = &zc.super.super;
unsigned val = 0;
/* initialize 32bit mock timer */
ztimer_mock_init(&zmock, 32);
/* initialize convert to do "speedup" of the mock timer
* (all now() values multiplied by 1000, all set() will be divided by
* the same) */
ztimer_convert_muldiv64_init(&zc, &zmock.super, 1000, 1);
ztimer_t t = { .callback=_set_cb, .arg=&val };
/* mock now() starts at 0, convert at 0 * 1000 = 0 */
TEST_ASSERT_EQUAL_INT(0, ztimer_now(&zmock.super));
TEST_ASSERT_EQUAL_INT(0, ztimer_now(z));
/* set convert to 1 (integer divide would set this to 0 on lower timer, but
* convert is supposed to do divide with ceiling) */
ztimer_set(z, &t, 1);
/* advance mock to 1 (convert should be at 1000) */
ztimer_mock_advance(&zmock, 1);
TEST_ASSERT_EQUAL_INT(1, ztimer_now(&zmock.super));
TEST_ASSERT_EQUAL_INT(1000, ztimer_now(z));
/* convert must have triggered t, as 1000 is > 1 */
TEST_ASSERT_EQUAL_INT(1, val);
/* reset helper variable */
val = 0;
/* set t to +500 (absolute: 1500) */
ztimer_set(z, &t, 500);
/* advance mock to 2 (convert: 2000) */
ztimer_mock_advance(&zmock, 1);
TEST_ASSERT_EQUAL_INT(2, ztimer_now(&zmock.super));
TEST_ASSERT_EQUAL_INT(2000, ztimer_now(z));
/* assert that timer triggered */
TEST_ASSERT_EQUAL_INT(1, val);
val = 0;
/* set t to 4294967000 (absolute: 4294969000) */
/* 4294967000 == (UINT32_MAX // 1000 * 1000) */
ztimer_set(z, &t, 4294967000);
/* advance mock to just before t's trigger time */
/* this has overflowed convert */
ztimer_mock_advance(&zmock, 4294966LU);
TEST_ASSERT_EQUAL_INT(4294968LU, ztimer_now(&zmock.super));
/* convert has overflowed ((2000 + 4294966000) % 2**32 = 704U)*/
TEST_ASSERT_EQUAL_INT(704LU, ztimer_now(z));
/* assert t hasn't triggered yet */
TEST_ASSERT_EQUAL_INT(0, val);
/* advance mock to 4294969 (convert to 4294969000) */
ztimer_mock_advance(&zmock, 0x1);
/* assert t has triggered */
TEST_ASSERT_EQUAL_INT(1, val);
}
static void test_ztimer_convert_muldiv64_set_slowdown(void)
{
ztimer_mock_t zmock;
ztimer_convert_muldiv64_t zc;
ztimer_clock_t *z = &zc.super.super;
unsigned val = 0;
/* initialize 32bit mock timer */
ztimer_mock_init(&zmock, 32);
/* initialize convert to do "slowdown" of the mock timer
* (all now() values divided by 1000, all set() will be multiplied by
* the same) */
ztimer_convert_muldiv64_init(&zc, &zmock.super, 1, 1000);
ztimer_t t = { .callback=_set_cb, .arg=&val };
/* mock now() starts at 0, convert at 0 / 1000 = 0 */
TEST_ASSERT_EQUAL_INT(0, ztimer_now(&zmock.super));
TEST_ASSERT_EQUAL_INT(0, ztimer_now(z));
/* set t on convert to 1 (should be 1000 on mock) */
ztimer_set(z, &t, 1);
/* advance mock to 999 (convert should be at (999/1000)==1 */
ztimer_mock_advance(&zmock, 999);
TEST_ASSERT_EQUAL_INT(999, ztimer_now(&zmock.super));
TEST_ASSERT_EQUAL_INT(0, ztimer_now(z));
/* convert must not have triggered */
TEST_ASSERT_EQUAL_INT(0, val);
/* advance mock to 1000 (convert: 1) */
ztimer_mock_advance(&zmock, 1);
TEST_ASSERT_EQUAL_INT(1000, ztimer_now(&zmock.super));
TEST_ASSERT_EQUAL_INT(1, ztimer_now(z));
/* assert that timer triggered */
TEST_ASSERT_EQUAL_INT(1, val);
val = 0;
/* testing intermediate timer and (lack of) quantization */
/* max value mock overflows at 4294967.xxx * 1000, so there will
* be some intermediate timers.
* when setting z at (mock=1000, z=1) to +4294968,
* it should trigger at (mock=1704) */
ztimer_set(z, &t, 4294968);
ztimer_mock_advance(&zmock, UINT32_MAX);
TEST_ASSERT_EQUAL_INT(999, ztimer_now(&zmock.super));
/* ztimer_now(z) is now at (UINT32_MAX + 1000)/1000) == 4294968 */
TEST_ASSERT_EQUAL_INT(4294968, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(0, val);
ztimer_mock_advance(&zmock, 704);
TEST_ASSERT_EQUAL_INT(1703, ztimer_now(&zmock.super));
TEST_ASSERT_EQUAL_INT(4294969, ztimer_now(z));
/* assert that this has not triggered yet. */
TEST_ASSERT_EQUAL_INT(0, val);
ztimer_mock_advance(&zmock, 1);
TEST_ASSERT_EQUAL_INT(1704, ztimer_now(&zmock.super));
TEST_ASSERT_EQUAL_INT(4294969, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(1, val);
val = 0;
}
Test *tests_ztimer_convert_muldiv64_tests(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_ztimer_convert_muldiv64_set_speedup),
new_TestFixture(test_ztimer_convert_muldiv64_set_slowdown),
new_TestFixture(test_ztimer_convert_muldiv64_now),
};
EMB_UNIT_TESTCALLER(ztimer_tests, NULL, NULL, fixtures);
return (Test *)&ztimer_tests;
}
/** @} */

View File

@ -0,0 +1,272 @@
/*
* Copyright (C) 2018 Eistec AB
*
* 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.
*/
/**
* @{
*
* @file
* @brief Unittests for ztimer
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/
#include "ztimer.h"
#include "ztimer/mock.h"
#include "embUnit/embUnit.h"
#include "tests-ztimer.h"
#include <stdio.h>
/**
* @brief Simple callback for counting alarms
*/
static void cb_incr(void *arg)
{
uint32_t *ptr = arg;
*ptr += 1;
}
/**
* @brief Testing 32 bit wide mock clock now functionality
*/
static void test_ztimer_mock_now32(void)
{
ztimer_mock_t zmock;
ztimer_clock_t *z = &zmock.super;
/* Basic sanity test of the mock implementation */
ztimer_mock_init(&zmock, 32);
uint32_t now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(0, now);
ztimer_mock_advance(&zmock, 123);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(123, now);
ztimer_mock_jump(&zmock, 0x10000000ul);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(0x10000000ul, now);
ztimer_mock_advance(&zmock, 0x98765432ul);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(0xa8765432ul, now);
ztimer_mock_advance(&zmock, 0x41234567ul);
ztimer_mock_advance(&zmock, 0x40000000ul);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(0x29999999ul, now);
}
/**
* @brief Testing 16 bit wide mock clock now functionality
*/
static void test_ztimer_mock_now16(void)
{
ztimer_mock_t zmock;
ztimer_clock_t *z = &zmock.super;
/* testing a 16 bit counter */
ztimer_mock_init(&zmock, 16);
uint32_t now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(0, now);
ztimer_mock_advance(&zmock, 123);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(123, now);
ztimer_mock_advance(&zmock, 30000ul);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(30123ul, now);
ztimer_mock_advance(&zmock, 0x10000ul);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(30123ul + 0x10000, now);
ztimer_mock_advance(&zmock, 0x8000ul);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(30123ul + 0x10000 + 0x8000, now);
}
/**
* @brief Testing 8 bit wide mock clock now functionality
*/
static void test_ztimer_mock_now8(void)
{
ztimer_mock_t zmock;
ztimer_clock_t *z = &zmock.super;
/* testing a small counter */
ztimer_mock_init(&zmock, 8);
uint32_t now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(0, now);
ztimer_mock_advance(&zmock, 123);
puts("advanced 123");
now = ztimer_now(z);
puts("advanced 123 now");
TEST_ASSERT_EQUAL_INT(123, now);
ztimer_mock_advance(&zmock, 0x100);
puts("advanced");
now = ztimer_now(z);
puts("now");
TEST_ASSERT_EQUAL_INT(0x100 + 123, now);
ztimer_mock_advance(&zmock, 180);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(0x100 + 123 + 180, now);
}
/**
* @brief Testing 3 bit wide mock clock now functionality
*/
static void test_ztimer_mock_now3(void)
{
ztimer_mock_t zmock;
ztimer_clock_t *z = &zmock.super;
/* testing a tiny counter */
ztimer_mock_init(&zmock, 3);
uint32_t now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(0, now);
ztimer_mock_advance(&zmock, 7);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(7, now);
ztimer_mock_advance(&zmock, 8);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(7 + 8, now);
ztimer_mock_advance(&zmock, 10);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(7 + 8 + 10, now);
}
/**
* @brief Testing 32 bit wide mock clock set functionality
*/
static void test_ztimer_mock_set32(void)
{
ztimer_mock_t zmock;
ztimer_clock_t *z = &zmock.super;
ztimer_mock_init(&zmock, 32);
uint32_t now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(0, now);
uint32_t count = 0;
ztimer_t alarm = { .callback = cb_incr, .arg = &count, };
ztimer_set(z, &alarm, 1000);
ztimer_mock_advance(&zmock, 1); /* now = 1*/
TEST_ASSERT_EQUAL_INT(0, count);
ztimer_mock_advance(&zmock, 100); /* now = 101 */
TEST_ASSERT_EQUAL_INT(0, count);
ztimer_mock_advance(&zmock, 898); /* now = 999 */
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(999, now);
TEST_ASSERT_EQUAL_INT(0, count);
ztimer_mock_advance(&zmock, 1); /* now = 1000*/
TEST_ASSERT_EQUAL_INT(1, count);
ztimer_mock_advance(&zmock, 1); /* now = 1001*/
TEST_ASSERT_EQUAL_INT(1, count);
ztimer_mock_advance(&zmock, 1000); /* now = 2001*/
TEST_ASSERT_EQUAL_INT(1, count);
ztimer_set(z, &alarm, 3);
ztimer_mock_advance(&zmock, 999); /* now = 3000*/
TEST_ASSERT_EQUAL_INT(2, count);
ztimer_set(z, &alarm, 4000001000ul);
ztimer_mock_advance(&zmock, 1000); /* now = 4000*/
TEST_ASSERT_EQUAL_INT(2, count);
ztimer_mock_advance(&zmock, 4000000000ul); /* now = 4000004000*/
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(4000004000ul, now);
TEST_ASSERT_EQUAL_INT(3, count);
ztimer_set(z, &alarm, 15);
ztimer_mock_advance(&zmock, 14);
ztimer_remove(z, &alarm);
ztimer_mock_advance(&zmock, 1000);
TEST_ASSERT_EQUAL_INT(3, count);
}
/**
* @brief Testing 16 bit wide mock clock set functionality
*/
static void test_ztimer_mock_set16(void)
{
ztimer_mock_t zmock;
ztimer_clock_t *z = &zmock.super;
ztimer_mock_init(&zmock, 16);
uint32_t now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(0, now);
uint32_t count = 0;
ztimer_t alarm = { .callback = cb_incr, .arg = &count, };
ztimer_set(z, &alarm, 1000);
ztimer_mock_advance(&zmock, 1);
TEST_ASSERT_EQUAL_INT(1, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(0, count);
ztimer_mock_advance(&zmock, 100);
TEST_ASSERT_EQUAL_INT(1 + 100, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(0, count);
ztimer_mock_advance(&zmock, 898);
now = ztimer_now(z);
TEST_ASSERT_EQUAL_INT(1 + 100 + 898, now);
TEST_ASSERT_EQUAL_INT(0, count);
ztimer_mock_advance(&zmock, 1);
TEST_ASSERT_EQUAL_INT(1 + 100 + 898 + 1, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(1, count);
ztimer_mock_advance(&zmock, 1);
TEST_ASSERT_EQUAL_INT(1 + 100 + 898 + 1 + 1, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(1, count);
ztimer_mock_advance(&zmock, 1000);
TEST_ASSERT_EQUAL_INT(1 + 100 + 898 + 1 + 1 + 1000, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(1, count);
ztimer_set(z, &alarm, UINT16_MAX);
ztimer_mock_advance(&zmock, 0x10000ul);
/* 1 + 100 + 898 + 1 + 1 + 1000 + 0x10000 = 67537 */
TEST_ASSERT_EQUAL_INT(67537ul, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(2, count);
ztimer_set(z, &alarm, UINT16_MAX);
ztimer_mock_advance(&zmock, 0x10000000ul);
TEST_ASSERT_EQUAL_INT(67537ul + 0x10000000ul, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(3, count);
ztimer_set(z, &alarm, 0x10001ul);
ztimer_mock_advance(&zmock, 1);
TEST_ASSERT_EQUAL_INT(67537ul + 0x10000000ul + 1, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(3, count);
ztimer_mock_advance(&zmock, UINT16_MAX);
TEST_ASSERT_EQUAL_INT(67537ul + 0x10000000ul + 1 + UINT16_MAX, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(3, count);
ztimer_mock_advance(&zmock, 0x1);
TEST_ASSERT_EQUAL_INT(67537ul + 0x10000000ul + 1 + UINT16_MAX + 1, ztimer_now(z));
TEST_ASSERT_EQUAL_INT(4, count);
now = ztimer_now(z);
/* 67537ul + 0x10000000ul + 1 + UINT16_MAX + 1 = 0x100207d2 */
TEST_ASSERT_EQUAL_INT(0x100207d2, now);
}
Test *tests_ztimer_mock_tests(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_ztimer_mock_now32),
new_TestFixture(test_ztimer_mock_now16),
new_TestFixture(test_ztimer_mock_now8),
new_TestFixture(test_ztimer_mock_now3),
new_TestFixture(test_ztimer_mock_set32),
new_TestFixture(test_ztimer_mock_set16),
};
EMB_UNIT_TESTCALLER(ztimer_tests, NULL, NULL, fixtures);
return (Test *)&ztimer_tests;
}
/** @} */

View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2018 Eistec AB
*
* 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.
*/
/**
* @{
*
* @file
* @brief Unittest entry point for the ztimer test group
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/
#include "embUnit/embUnit.h"
#include "tests-ztimer.h"
Test *tests_ztimer_mock_tests(void);
Test *tests_ztimer_convert_muldiv64_tests(void);
void tests_ztimer(void)
{
TESTS_RUN(tests_ztimer_mock_tests());
TESTS_RUN(tests_ztimer_convert_muldiv64_tests());
}
/** @} */

View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2018 Eistec AB
*
* 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.
*/
/**
* @addtogroup unittests
* @{
*
* @file
* @brief Unittests for ztimer
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/
#ifndef TESTS_ZTIMER_H
#define TESTS_ZTIMER_H
#include "embUnit.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief The entry point of this test suite.
*/
void tests_ztimer(void);
#ifdef __cplusplus
}
#endif
#endif /* TESTS_ZTIMER_H */
/** @} */