-
-
Save ashjas/2f3d365c6edefff52589f1a7bbd83588 to your computer and use it in GitHub Desktop.
implementing a BOOST_TEST test_runner for running multiple tests from different shared libraries containing testcases
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef BOOST_TEST_DYN_LINK | |
#define BOOST_TEST_DYN_LINK | |
#endif | |
#include "boost/test/unit_test.hpp" | |
#include <boost/program_options.hpp> | |
#include <boost/variant.hpp> | |
#include <iostream> | |
#include <vector> | |
namespace dyn_lib { | |
#if defined(BOOST_WINDOWS) && !defined(BOOST_DISABLE_WIN32) // WIN32 API | |
#include <windows.h> | |
typedef HINSTANCE handle; | |
inline handle | |
open(std::string const& file_name) | |
{ | |
return LoadLibrary(file_name.c_str()); | |
} | |
template<typename TargType> | |
inline TargType | |
locate_symbol(handle h, std::string const& symbol) | |
{ | |
return reinterpret_cast<TargType>(GetProcAddress(h, symbol.c_str())); | |
} | |
inline void close(handle h) | |
{ | |
if (h) | |
FreeLibrary(h); | |
} | |
inline std::string error() | |
{ | |
LPTSTR msg = NULL; | |
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, | |
NULL, | |
GetLastError(), | |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
(LPTSTR)&msg, | |
0, NULL); | |
std::string res(msg); | |
if (msg) | |
LocalFree(msg); | |
return res; | |
} | |
#elif defined(BOOST_HAS_UNISTD_H) // POSIX API | |
#include <dlfcn.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
typedef void* handle; | |
inline handle open(std::string const& file_name) | |
{ | |
return dlopen(file_name.c_str(), RTLD_LOCAL | RTLD_LAZY); | |
} | |
template<typename TargType> | |
inline TargType | |
locate_symbol(handle h, std::string const& symbol) | |
{ | |
return reinterpret_cast<TargType>(dlsym(h, symbol.c_str())); | |
} | |
inline void | |
close(handle h) | |
{ | |
if (h) | |
dlclose(h); | |
} | |
inline std::string | |
error() | |
{ | |
return dlerror(); | |
} | |
#else | |
#error "Dynamic library API is unknown" | |
#endif | |
} // namespace dyn_lib | |
static std::string test_lib_name; | |
static std::string init_func_name("init_unit_test"); | |
dyn_lib::handle test_lib_handle; | |
bool load_test_lib() | |
{ | |
typedef bool(*init_func_ptr)(); | |
init_func_ptr init_func; | |
test_lib_handle = dyn_lib::open(test_lib_name);//there is an undefined behaviour at this point, at 2nd iteration. | |
if (!test_lib_handle) | |
throw std::logic_error(std::string("Fail to load test library: ") | |
.append(dyn_lib::error())); | |
init_func = dyn_lib::locate_symbol<init_func_ptr>(test_lib_handle, init_func_name); | |
if (!init_func) | |
throw std::logic_error(std::string("Can't locate test initilization function ") | |
.append(init_func_name) | |
.append(": ") | |
.append(dyn_lib::error())); | |
return (*init_func)(); | |
} | |
int main(int argc, char* argv[]) | |
{ | |
std::string desc_str; | |
std::vector<std::string> dllsToTest{"abc","def"}; | |
try { | |
for (int i = 0; i < dllsToTest.size(); ++i) | |
{ | |
test_lib_name = dllsToTest[i]; | |
int res = ::boost::unit_test::unit_test_main(&load_test_lib, argc, argv); | |
::boost::unit_test::framework::clear(); | |
dyn_lib::close(test_lib_handle); | |
test_lib_handle = NULL; | |
} | |
//return res; | |
} | |
catch (std::exception& ex){ | |
std::cout << ex.what() << std::endl << desc_str; | |
return -1; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef BOOST_TEST_DYN_LINK | |
#define BOOST_TEST_DYN_LINK | |
#endif | |
#define BOOST_TEST_NO_MAIN | |
#define BOOST_TEST_ALTERNATIVE_INIT_API | |
#include <boost/test/unit_test.hpp> | |
extern "C" { | |
__declspec(dllexport) bool init_unit_test() | |
{ | |
return true; | |
} | |
} | |
BOOST_AUTO_TEST_CASE(test1) | |
{ | |
BOOST_TEST(false); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment