diff options
author | Martin Willi <martin@revosec.ch> | 2014-04-03 12:25:38 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2014-06-04 15:53:12 +0200 |
commit | 0c34c1b3afb82bc4a4fabf6a4b3d90b5906e4885 (patch) | |
tree | a4faa209e1520e7a975ad236dc87f0c5037125ef /src | |
parent | 460adb5d0925f4af807b09434b771545d1f62b47 (diff) | |
download | strongswan-0c34c1b3afb82bc4a4fabf6a4b3d90b5906e4885.tar.bz2 strongswan-0c34c1b3afb82bc4a4fabf6a4b3d90b5906e4885.tar.xz |
unit-tests: Support testable functions on Windows, avoid weak GCC symbols
Instead of using weak symbols, we use dlsym() on Windows to find an arbitrary
symbol in libtest to detect its linkage. Instead of creating the associated
hashtable in the test runner, we maintain it in libstrongswan, making it
significantly simpler.
Diffstat (limited to 'src')
-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"); \ |