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.
This commit is contained in:
Martin Willi
2014-06-04 15:53:12 +02:00
parent 460adb5d09
commit 0c34c1b3af
3 changed files with 62 additions and 62 deletions
+48 -23
View File
@@ -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)
if (has_libtest_linkage())
{
testable_functions_create();
}
if (fn)
{
testable_functions->put(testable_functions, name, fn);
}
else
{
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;
}
+9 -11
View File
@@ -23,13 +23,6 @@
#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.
*
@@ -38,6 +31,14 @@ extern hashtable_t *testable_functions;
*/
void testable_function_register(char *name, void *fn);
/**
* Find a previously registered testable function.
*
* @param name name (namespace/function)
* @return function, NULL if not found
*/
void* testable_function_get(char *name);
/**
* Macro to automatically register/unregister a function that can be called
* from tests.
@@ -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"); \