diff options
-rw-r--r-- | src/libstrongswan/tests/test_runner.c | 33 | ||||
-rw-r--r-- | src/libstrongswan/utils/test.c | 71 | ||||
-rw-r--r-- | src/libstrongswan/utils/test.h | 18 |
3 files changed, 61 insertions, 61 deletions
diff --git a/src/libstrongswan/tests/test_runner.c b/src/libstrongswan/tests/test_runner.c index 63d79199f..443c0ae13 100644 --- a/src/libstrongswan/tests/test_runner.c +++ b/src/libstrongswan/tests/test_runner.c @@ -35,35 +35,12 @@ #define TTY(color) tty_escape_get(2, TTY_FG_##color) /** - * Initialize the lookup table for testable functions (defined in - * libstrongswan). We don't use the constructor attribute as the order can't - * really be defined (clang does not support it and gcc does not adhere to it in - * the monolithic build). The function here is a weak symbol in libstrongswan. + * A global symbol indicating libtest linkage */ -void testable_functions_create() -{ - if (!testable_functions) - { - /* as this is executed before chunk_hash() seed initialization used - * by hashtables, we enforce seeding it here. */ - chunk_hash_seed(); - testable_functions = hashtable_create(hashtable_hash_str, - hashtable_equals_str, 8); - } -} - -/** - * Destroy the lookup table for testable functions - */ -static void testable_functions_destroy() __attribute__ ((destructor)); -static void testable_functions_destroy() -{ - DESTROY_IF(testable_functions); - /* if leak detective is enabled plugins are not actually unloaded, which - * means their destructor is called AFTER this one when the process - * terminates, make sure this does not crash */ - testable_functions = NULL; -} +#ifdef WIN32 +__declspec(dllexport) +#endif +bool test_runner_available = TRUE; /** * Destroy a single test suite and associated data diff --git a/src/libstrongswan/utils/test.c b/src/libstrongswan/utils/test.c index 624ac4b34..0b0a80f42 100644 --- a/src/libstrongswan/utils/test.c +++ b/src/libstrongswan/utils/test.c @@ -20,13 +20,23 @@ /** * A collection of testable functions */ -hashtable_t *testable_functions; +static hashtable_t *functions = NULL; + +#ifndef WIN32 +bool test_runner_available __attribute__((weak)); +#endif /** - * The function that actually initializes the hash table above. Provided - * by the test runner. + * Check if we have libtest linkage and need testable functions */ -void testable_functions_create() __attribute__((weak)); +static bool has_libtest_linkage() +{ +#ifdef WIN32 + return dlsym(RTLD_DEFAULT, "test_runner_available"); +#else + return test_runner_available; +#endif +} /* * Described in header. @@ -35,33 +45,48 @@ void testable_function_register(char *name, void *fn) { bool old = FALSE; - if (!testable_functions_create) - { /* not linked to the test runner */ - return; - } - else if (!fn && !testable_functions) - { /* ignore as testable_functions has already been destroyed */ - return; - } - if (lib && lib->leak_detective) { old = lib->leak_detective->set_state(lib->leak_detective, FALSE); } - if (!testable_functions) - { - testable_functions_create(); - } - if (fn) - { - testable_functions->put(testable_functions, name, fn); - } - else + + if (has_libtest_linkage()) { - testable_functions->remove(testable_functions, name); + if (!functions) + { + chunk_hash_seed(); + functions = hashtable_create(hashtable_hash_str, + hashtable_equals_str, 8); + } + if (fn) + { + functions->put(functions, name, fn); + } + else + { + functions->remove(functions, name); + if (functions->get_count(functions) == 0) + { + functions->destroy(functions); + functions = NULL; + } + } } + if (lib && lib->leak_detective) { lib->leak_detective->set_state(lib->leak_detective, old); } } + +/* + * Described in header. + */ +void* testable_function_get(char *name) +{ + if (functions) + { + return functions->get(functions, name); + } + return NULL; +} diff --git a/src/libstrongswan/utils/test.h b/src/libstrongswan/utils/test.h index a1b2a2d9b..f9a84713e 100644 --- a/src/libstrongswan/utils/test.h +++ b/src/libstrongswan/utils/test.h @@ -24,19 +24,20 @@ #include "collections/hashtable.h" /** - * Collection of testable functions. + * Register a (possibly static) function so that it can be called from tests. * - * @note Is initialized only if libtest is loaded. + * @param name name (namespace/function) + * @param fn function to register (set to NULL to unregister) */ -extern hashtable_t *testable_functions; +void testable_function_register(char *name, void *fn); /** - * Register a (possibly static) function so that it can be called from tests. + * Find a previously registered testable function. * * @param name name (namespace/function) - * @param fn function to register (set to NULL to unregister) + * @return function, NULL if not found */ -void testable_function_register(char *name, void *fn); +void* testable_function_get(char *name); /** * Macro to automatically register/unregister a function that can be called @@ -82,10 +83,7 @@ static ret (*TEST_##ns##name)(__VA_ARGS__); */ #define TEST_FUNCTION(ns, name, ...) \ ({ \ - if (testable_functions) \ - { \ - TEST_##ns##name = testable_functions->get(testable_functions, #ns "/" #name); \ - } \ + TEST_##ns##name = testable_function_get( #ns "/" #name); \ if (!TEST_##ns##name) \ { \ test_fail_msg(__FILE__, __LINE__, "function " #name " (" #ns ") not found"); \ |