]> git.ipfire.org Git - people/ms/strongswan.git/blame - src/libstrongswan/utils/test.h
unit-tests: Don't use priority for destructor that unregisters testable functions
[people/ms/strongswan.git] / src / libstrongswan / utils / test.h
CommitLineData
4cea186b
TB
1/*
2 * Copyright (C) 2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16/**
17 * @defgroup test test
18 * @{ @ingroup utils
19 */
20
21#ifndef TEST_H_
22#define TEST_H_
23
24#include "collections/hashtable.h"
25
26/**
27 * Collection of testable functions.
28 *
29 * @note Is initialized only if libtest is loaded.
30 */
31extern hashtable_t *testable_functions;
32
33/**
34 * Register a (possibly static) function so that it can be called from tests.
35 *
36 * @param name name (namespace/function)
37 * @param fn function to register (set to NULL to unregister)
38 */
39void testable_function_register(char *name, void *fn);
40
41/**
42 * Macro to automatically register/unregister a function that can be called
43 * from tests.
44 *
f1e12da7
TB
45 * @note The constructor has a priority set so that it runs after the
46 * constructor that creates the hashtable. The destructor, on the other hand,
47 * does not have a priority set, as test coverage would report that function as
48 * untested otherwise.
49 *
4cea186b
TB
50 * @param ns namespace
51 * @param fn function to register
52 */
53#define EXPORT_FUNCTION_FOR_TESTS(ns, fn) \
54static void testable_function_register_##fn() __attribute__ ((constructor(2000))); \
55static void testable_function_register_##fn() \
56{ \
57 testable_function_register(#ns "/" #fn, fn); \
58} \
f1e12da7 59static void testable_function_unregister_##fn() __attribute__ ((destructor)); \
4cea186b
TB
60static void testable_function_unregister_##fn() \
61{ \
62 testable_function_register(#ns "/" #fn, NULL); \
63}
64
65/**
66 * Import a registered function so that it can be called from tests.
67 *
68 * @note If the imported function is static (or no conflicting header files
69 * are included) ret can be prefixed with static to declare the function static.
70 *
71 * @note We allocate an arbitrary amount of stack space, hopefully enough for
72 * all arguments.
73 *
74 * @param ns namespace of the function
75 * @param name name of the function
76 * @param ret return type of the function
77 * @param ... arguments of the function
78 */
79#define IMPORT_FUNCTION_FOR_TESTS(ns, name, ret, ...) \
80ret name(__VA_ARGS__) \
81{ \
82 void (*fn)() = NULL; \
83 if (testable_functions) \
84 { \
85 fn = testable_functions->get(testable_functions, #ns "/" #name); \
86 } \
87 if (fn) \
88 { \
89 void *args = __builtin_apply_args(); \
90 __builtin_return(__builtin_apply(fn, args, 16*sizeof(void*))); \
91 } \
92 test_fail_msg(__FILE__, __LINE__, "function " #name " (" #ns ") not found"); \
93 __builtin_return(NULL); \
94}
95
96#endif /** TEST_H_ @}*/