summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/dll/test/shared_library_load_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/dll/test/shared_library_load_test.cpp')
-rw-r--r--src/boost/libs/dll/test/shared_library_load_test.cpp528
1 files changed, 528 insertions, 0 deletions
diff --git a/src/boost/libs/dll/test/shared_library_load_test.cpp b/src/boost/libs/dll/test/shared_library_load_test.cpp
new file mode 100644
index 000000000..de7e619ee
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_load_test.cpp
@@ -0,0 +1,528 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2015-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/core/lightweight_test.hpp>
+// Unit Tests
+
+namespace boost { namespace dll { namespace fs {
+
+#ifdef BOOST_DLL_USE_STD_FS
+using std::filesystem::remove;
+using std::filesystem::copy;
+#else
+using boost::filesystem::remove;
+using boost::filesystem::copy;
+#endif
+
+}}}
+
+inline boost::dll::fs::path drop_version(const boost::dll::fs::path& lhs) {
+ boost::dll::fs::path ext = lhs.filename().extension();
+ if (ext.native().size() > 1 && std::isdigit(ext.string()[1])) {
+ ext = lhs;
+ ext.replace_extension().replace_extension().replace_extension();
+ return ext;
+ }
+
+ return lhs;
+}
+
+inline bool lib_path_equal(const boost::dll::fs::path& lhs, const boost::dll::fs::path& rhs) {
+ const bool res = (drop_version(lhs).filename() == drop_version(rhs).filename());
+ if (!res) {
+ std::cerr << "lhs != rhs: " << lhs << " != " << rhs << '\n';
+ }
+ return res;
+}
+
+struct fs_copy_guard {
+ const boost::dll::fs::path actual_path_;
+ const bool same_;
+
+ inline explicit fs_copy_guard(const boost::dll::fs::path& shared_library_path)
+ : actual_path_( drop_version(shared_library_path) )
+ , same_(actual_path_ == shared_library_path)
+ {
+ if (!same_) {
+ boost::dll::fs::error_code ignore;
+ boost::dll::fs::remove(actual_path_, ignore);
+ boost::dll::fs::copy(shared_library_path, actual_path_, ignore);
+ }
+ }
+
+ inline ~fs_copy_guard() {
+ if (!same_) {
+ boost::dll::fs::error_code ignore;
+ boost::dll::fs::remove(actual_path_, ignore);
+ }
+ }
+};
+
+// Disgusting workarounds for b2 on Windows platform
+inline boost::dll::fs::path do_find_correct_libs_path(int argc, char* argv[], const char* lib_name) {
+ boost::dll::fs::path ret;
+
+ for (int i = 1; i < argc; ++i) {
+ ret = argv[i];
+ if (ret.string().find(lib_name) != std::string::npos && b2_workarounds::is_shared_library(ret)) {
+ return ret;
+ }
+ }
+
+ return lib_name;
+}
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+
+ BOOST_TEST(argc >= 3);
+ boost::dll::fs::path shared_library_path = do_find_correct_libs_path(argc, argv, "test_library");
+ std::cout << "Library: " << shared_library_path;
+
+ {
+ shared_library sl(shared_library_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ shared_library sl2;
+ BOOST_TEST(!sl2.is_loaded());
+ BOOST_TEST(!sl2);
+
+ swap(sl, sl2);
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+
+ sl.assign(sl2);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ sl.assign(sl2);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ sl2.assign(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ // Assigning an empty shared library
+ sl2.assign(shared_library());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!sl2.is_loaded());
+ BOOST_TEST(!sl2);
+ boost::dll::fs::error_code ec;
+ BOOST_TEST(sl2.location(ec) != sl.location());
+ BOOST_TEST(ec);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ BOOST_TEST(!ec);
+
+ // Checking self assignment #1
+ sl.assign(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+
+ // Checking self assignment #2
+ sl.assign(sl, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ BOOST_TEST(!sl.is_loaded());
+
+ sl.assign(sl);
+ BOOST_TEST(!sl);
+
+ shared_library sl2(sl);
+ BOOST_TEST(!sl);
+ BOOST_TEST(!sl2);
+
+ sl2.assign(sl);
+ BOOST_TEST(!sl);
+ BOOST_TEST(!sl2);
+ }
+
+ {
+ shared_library sl;
+ sl.load(shared_library_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(shared_library_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::load_with_altered_search_path );
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::load_with_altered_search_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ BOOST_TEST(!ec);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::search_system_folders, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ BOOST_TEST(!ec);
+ }
+
+ {
+ try {
+#if BOOST_OS_WINDOWS
+ boost::dll::shared_library("winmm.dll");
+#elif BOOST_OS_LINUX
+ boost::dll::shared_library("libdl.so");
+#endif
+ BOOST_TEST(false);
+ } catch (...) {}
+ }
+
+ {
+ try {
+#if BOOST_OS_WINDOWS
+ boost::dll::shared_library("winmm", load_mode::search_system_folders | load_mode::append_decorations);
+#elif BOOST_OS_LINUX
+ boost::dll::shared_library("dl", boost::dll::load_mode::search_system_folders | load_mode::append_decorations);
+#endif
+ } catch (...) {
+ BOOST_TEST(false);
+ }
+ }
+
+ {
+ shared_library sl;
+ sl.load(shared_library_path, load_mode::load_with_altered_search_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(shared_library_path, load_mode::load_with_altered_search_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_local);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_now);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ fs_copy_guard guard(shared_library_path);
+
+ boost::dll::fs::path platform_independent_path = guard.actual_path_;
+ platform_independent_path.replace_extension();
+ if (platform_independent_path.filename().wstring().find(L"lib") == 0) {
+ platform_independent_path
+ = platform_independent_path.parent_path() / platform_independent_path.filename().wstring().substr(3);
+ }
+ std::cerr << "platform_independent_path: " << platform_independent_path << '\n';
+
+ shared_library sl(platform_independent_path, load_mode::append_decorations);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ sl.unload();
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_now | load_mode::rtld_global | load_mode::load_with_altered_search_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ sl.load(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+
+ { // Non-default flags with assignment
+ shared_library sl(shared_library_path,
+ load_mode::rtld_now | load_mode::rtld_global | load_mode::load_with_altered_search_path
+
+// `load_mode::rtld_deepbind` is incompatible with sanitizers:
+// You are trying to dlopen a libtest_library.so shared library with RTLD_DEEPBIND flag which is incompatibe with sanitizer runtime
+// (see https://github.com/google/sanitizers/issues/611 for details).
+#ifndef BOOST_TRAVISCI_BUILD
+ | load_mode::rtld_deepbind
+#endif
+
+ );
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+
+ boost::dll::fs::error_code ec;
+ shared_library sl2(sl, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ shared_library sl3(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl3.is_loaded());
+ BOOST_TEST(sl3);
+
+ shared_library sl4;
+ sl4.assign(sl, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl4.is_loaded());
+ BOOST_TEST(sl4);
+ }
+
+ { // Non-default flags with assignment and error_code
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ shared_library sl2(sl, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ shared_library sl3(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl3.is_loaded());
+ BOOST_TEST(sl3);
+ BOOST_TEST(sl3.location() == sl.location());
+ }
+
+ { // self_load
+ shared_library sl(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ std::cout << "\nProgram location: " << program_location();
+ std::cout << "\nLibrary location: " << sl.location();
+ BOOST_TEST( boost::dll::fs::equivalent(sl.location(), program_location()) );
+
+ boost::dll::fs::error_code ec;
+ shared_library sl2(program_location());
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST( boost::dll::fs::equivalent(sl2.location(), program_location()) );
+ BOOST_TEST(sl2);
+ BOOST_TEST(!ec);
+
+ BOOST_TEST(sl == sl2);
+ BOOST_TEST(!(sl < sl2 || sl2 <sl));
+ BOOST_TEST(!(sl != sl2));
+
+ sl.load(shared_library_path);
+ BOOST_TEST(sl != sl2);
+ BOOST_TEST(sl < sl2 || sl2 <sl);
+ BOOST_TEST(!(sl == sl2));
+
+ sl.unload();
+ BOOST_TEST(!sl);
+ BOOST_TEST(sl != sl2);
+ BOOST_TEST(sl < sl2 || sl2 <sl);
+ BOOST_TEST(!(sl == sl2));
+
+ sl2.unload();
+ BOOST_TEST(!sl2);
+ BOOST_TEST(sl == sl2);
+ BOOST_TEST(!(sl < sl2 || sl2 <sl));
+ BOOST_TEST(!(sl != sl2));
+
+ // assigning self
+ sl.load(program_location());
+ sl2 = sl;
+ BOOST_TEST(sl == sl2);
+ BOOST_TEST(sl.location() == sl2.location());
+ }
+
+ {
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ sl.load(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+
+ sl.load(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ }
+
+ { // self_load
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ }
+
+ { // unload
+ shared_library sl(shared_library_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ sl.unload();
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ }
+
+
+ { // error_code load calls test
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path / "dir_that_does_not_exist", ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+
+ boost::dll::fs::path bad_path(shared_library_path);
+ bad_path += ".1.1.1.1.1.1";
+ sl.load(bad_path, ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+
+ sl.load(shared_library_path, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+
+ shared_library sl2(bad_path, ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(!sl2.is_loaded());
+ BOOST_TEST(!sl2);
+
+ shared_library sl3(shared_library_path, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl3.is_loaded());
+ BOOST_TEST(sl3);
+
+ sl.load("", ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ }
+
+
+ shared_library_path = do_find_correct_libs_path(argc, argv, "library1");
+ fs_copy_guard guard(shared_library_path);
+ shared_library starts_with_lib(
+ boost::dll::fs::path(guard.actual_path_).replace_extension(),
+ load_mode::append_decorations
+ );
+
+ starts_with_lib.load(
+ boost::dll::fs::path(guard.actual_path_).replace_extension(),
+ load_mode::append_decorations
+ );
+
+ return boost::report_errors();
+}