summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils/test.h
blob: a1b2a2d9b93f5752b7637430ae7d95053e2239a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
 * Copyright (C) 2013 Tobias Brunner
 * Hochschule fuer Technik Rapperswil
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

/**
 * @defgroup test test
 * @{ @ingroup utils
 */

#ifndef TEST_H_
#define TEST_H_

#include "collections/hashtable.h"

/**
 * Collection of testable functions.
 *
 * @note Is initialized only if libtest is loaded.
 */
extern hashtable_t *testable_functions;

/**
 * Register a (possibly static) function so that it can be called from tests.
 *
 * @param name		name (namespace/function)
 * @param fn		function to register (set to NULL to unregister)
 */
void testable_function_register(char *name, void *fn);

/**
 * Macro to automatically register/unregister a function that can be called
 * from tests.
 *
 * @note The constructor has a priority set so that it runs after the
 * constructor that creates the hashtable.  The destructor, on the other hand,
 * does not have a priority set, as test coverage would report that function as
 * untested otherwise.
 *
 * @param ns		namespace
 * @param fn		function to register
 */
#define EXPORT_FUNCTION_FOR_TESTS(ns, fn) \
static void testable_function_register_##fn() __attribute__ ((constructor)); \
static void testable_function_register_##fn() \
{ \
	testable_function_register(#ns "/" #fn, fn); \
} \
static void testable_function_unregister_##fn() __attribute__ ((destructor)); \
static void testable_function_unregister_##fn() \
{ \
	testable_function_register(#ns "/" #fn, NULL); \
}

/**
 * Import a registered function so that it can be called from tests.
 *
 * @param ns		namespace of the function
 * @param name		name of the function
 * @param ret		return type of the function
 * @param ...		arguments of the function
 */
#define IMPORT_FUNCTION_FOR_TESTS(ns, name, ret, ...) \
static ret (*TEST_##ns##name)(__VA_ARGS__);

/**
 * Call a registered function from tests.
 *
 * @param ns		namespace of the function
 * @param name		name of the function
 * @param ...		arguments for the function
 */
#define TEST_FUNCTION(ns, name, ...) \
({ \
	if (testable_functions) \
	{ \
		TEST_##ns##name = testable_functions->get(testable_functions, #ns "/" #name); \
	} \
	if (!TEST_##ns##name) \
	{ \
		test_fail_msg(__FILE__, __LINE__, "function " #name " (" #ns ") not found"); \
	} \
	TEST_##ns##name(__VA_ARGS__); \
})

#endif /** TEST_H_ @}*/