Line data Source code
1 : // SPDX-License-Identifier: GPL-3.0-or-later
2 : // Copyright 2021, CZ.NIC z.s.p.o. (http://www.nic.cz/)
3 : #ifndef _UNITTESTS_H_
4 : #define _UNITTESTS_H_
5 : #include <check.h>
6 : #include <math.h>
7 : #include "fixtures.h"
8 :
9 : void unittests_add_suite(Suite*);
10 :
11 : #ifndef SUITE
12 : #error Missing SUITE definition to name suite
13 : #endif
14 2 : static void unittests_add_tcase(TCase *tcase) {
15 2 : static Suite *suite = NULL;
16 2 : if (suite == NULL) {
17 2 : suite = suite_create(SUITE);
18 2 : unittests_add_suite(suite);
19 : }
20 2 : suite_add_tcase(suite, tcase);
21 2 : }
22 :
23 :
24 : #ifndef DEFAULT_SETUP
25 : #define DEFAULT_SETUP basic_setup
26 : #endif
27 : #ifndef DEFAULT_TEARDOWN
28 : #define DEFAULT_TEARDOWN basic_teardown
29 : #endif
30 :
31 : #define _TEST_CASE(name, setup, teardown, timeout) \
32 : static void _tcase_##name(TCase *tcase); \
33 : static TCase *unittests_tcase_##name() { \
34 : static TCase *tcase = NULL; \
35 : if (tcase == NULL) { \
36 : tcase = tcase_create(#name); \
37 : tcase_add_checked_fixture(tcase, setup, teardown); \
38 : if (!isnan(timeout)) \
39 : tcase_set_timeout(tcase, timeout); \
40 : unittests_add_tcase(tcase); \
41 : _tcase_##name(tcase); \
42 : } \
43 : return tcase; \
44 : } \
45 : static void _tcase_##name(TCase *tcase)
46 : #define __test_case1(name) _TEST_CASE(name, DEFAULT_SETUP, DEFAULT_TEARDOWN, NAN)
47 : #define __test_case2(name, setup) _TEST_CASE(name, setup, DEFAULT_TEARDOWN, NAN)
48 : #define __test_case3(name, setup, teardown) _TEST_CASE(name, setup, teardown, NAN)
49 : #define __test_case_select(_1, _2, _3, _4, X, ...) X
50 : #define TEST_CASE(...) \
51 : __test_case_select(__VA_ARGS__, _TEST_CASE, __test_case3, __test_case2, __test_case1)(__VA_ARGS__)
52 :
53 :
54 : #define _TEST(tcase_add, tcase, name, ...) \
55 : static const TTest *name; \
56 : __attribute__((constructor)) static void _test_##name() { \
57 : tcase_add(unittests_tcase_##tcase(), __VA_ARGS__); \
58 : } \
59 : START_TEST(name)
60 :
61 : #define TEST(tcase, name) \
62 : _TEST(tcase_add_test, tcase, name, name)
63 : #define TEST_RAISE_SIGNAL(tcase, name, signal) \
64 : _TEST(tcase_add_test_raise_signal, tcase, name, name, signal)
65 : #define TEST_EXIT(tcase, name, exit_value) \
66 : _TEST(tcase_add_exit_test, tcase, name, name, exit_value)
67 :
68 : #define LOOP_TEST(tcase, name, s, e) \
69 : _TEST(tcase_add_loop_test, tcase, name, name, s, e)
70 : #define LOOP_TEST_RAISE_SIGNAL(tcase, name, signal, s, e) \
71 : _TEST(tcase_add_test_raise_signal, tcase, name, name, signal, s, e)
72 : #define LOOP_TEST_EXIT(tcase, name, exit_value, s, e) \
73 : _TEST(tcase_add_exit_test, tcase, name, name, exit_value, s, e)
74 :
75 : #define _ARRAY_TEST(tcase_add, tcase, name, array, ...) \
76 : static void name##_array_fn(__typeof__(*array) _d CK_ATTRIBUTE_UNUSED); \
77 : _TEST(tcase_add, tcase, name, __VA_ARGS__, 0, sizeof(array) / sizeof(*(array))) { \
78 : name##_array_fn(array[_i]); \
79 : } \
80 : static void name##_array_fn(__typeof__(*array) _d CK_ATTRIBUTE_UNUSED)
81 :
82 : #define ARRAY_TEST(tcase, name, array) \
83 : _ARRAY_TEST(tcase_add_loop_test, tcase, name, array, name)
84 : #define ARRAY_TEST_RAISE_SIGNAL(tcase, name, signal, array) \
85 : _ARRAY_TEST(tcase_add_loop_test_raise_signal, tcase, name, array, name, signal)
86 : #define ARRAY_TEST_EXIT(tcase, name, exit_value, array) \
87 : _ARRAY_TEST(tcase_add_loop_exit_test, tcase, name, array, name, exit_value)
88 :
89 : #endif
|