]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/dll/test/shared_library_load_test.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / dll / test / shared_library_load_test.cpp
1 // Copyright 2011-2012 Renato Tegon Forti
2 // Copyright Antony Polukhin, 2015-2022
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 // For more information, see http://www.boost.org
9
10 #include "../example/b2_workarounds.hpp"
11 #include <boost/dll.hpp>
12 #include <boost/core/lightweight_test.hpp>
13 // Unit Tests
14
15 namespace boost { namespace dll { namespace fs {
16
17 #ifdef BOOST_DLL_USE_STD_FS
18 using std::filesystem::remove;
19 using std::filesystem::copy;
20 #else
21 using boost::filesystem::remove;
22 using boost::filesystem::copy;
23 #endif
24
25 }}}
26
27 inline boost::dll::fs::path drop_version(const boost::dll::fs::path& lhs) {
28 boost::dll::fs::path ext = lhs.filename().extension();
29 if (ext.native().size() > 1 && std::isdigit(ext.string()[1])) {
30 ext = lhs;
31 ext.replace_extension().replace_extension().replace_extension();
32 return ext;
33 }
34
35 return lhs;
36 }
37
38 inline bool lib_path_equal(const boost::dll::fs::path& lhs, const boost::dll::fs::path& rhs) {
39 const bool res = (drop_version(lhs).filename() == drop_version(rhs).filename());
40 if (!res) {
41 std::cerr << "lhs != rhs: " << lhs << " != " << rhs << '\n';
42 }
43 return res;
44 }
45
46 struct fs_copy_guard {
47 const boost::dll::fs::path actual_path_;
48 const bool same_;
49
50 inline explicit fs_copy_guard(const boost::dll::fs::path& shared_library_path)
51 : actual_path_( drop_version(shared_library_path) )
52 , same_(actual_path_ == shared_library_path)
53 {
54 if (!same_) {
55 boost::dll::fs::error_code ignore;
56 boost::dll::fs::remove(actual_path_, ignore);
57 boost::dll::fs::copy(shared_library_path, actual_path_, ignore);
58 }
59 }
60
61 inline ~fs_copy_guard() {
62 if (!same_) {
63 boost::dll::fs::error_code ignore;
64 boost::dll::fs::remove(actual_path_, ignore);
65 }
66 }
67 };
68
69 // Disgusting workarounds for b2 on Windows platform
70 inline boost::dll::fs::path do_find_correct_libs_path(int argc, char* argv[], const char* lib_name) {
71 boost::dll::fs::path ret;
72
73 for (int i = 1; i < argc; ++i) {
74 ret = argv[i];
75 if (ret.string().find(lib_name) != std::string::npos && b2_workarounds::is_shared_library(ret)) {
76 return ret;
77 }
78 }
79
80 return lib_name;
81 }
82
83 int main(int argc, char* argv[])
84 {
85 using namespace boost::dll;
86
87 BOOST_TEST(argc >= 3);
88 boost::dll::fs::path shared_library_path = do_find_correct_libs_path(argc, argv, "test_library");
89 std::cout << "Library: " << shared_library_path;
90
91 {
92 shared_library sl(shared_library_path);
93 BOOST_TEST(sl.is_loaded());
94 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
95
96 shared_library sl2;
97 BOOST_TEST(!sl2.is_loaded());
98 BOOST_TEST(!sl2);
99
100 swap(sl, sl2);
101 BOOST_TEST(!sl.is_loaded());
102 BOOST_TEST(!sl);
103 BOOST_TEST(sl2.is_loaded());
104 BOOST_TEST(sl2);
105
106 sl.assign(sl2);
107 BOOST_TEST(sl.is_loaded());
108 BOOST_TEST(sl);
109 BOOST_TEST(sl2.is_loaded());
110 BOOST_TEST(sl2);
111 BOOST_TEST(sl2.location() == sl.location());
112
113 sl.assign(sl2);
114 BOOST_TEST(sl.is_loaded());
115 BOOST_TEST(sl);
116 BOOST_TEST(sl2.is_loaded());
117 BOOST_TEST(sl2);
118 BOOST_TEST(sl2.location() == sl.location());
119
120 sl2.assign(sl);
121 BOOST_TEST(sl.is_loaded());
122 BOOST_TEST(sl);
123 BOOST_TEST(sl2.is_loaded());
124 BOOST_TEST(sl2);
125 BOOST_TEST(sl2.location() == sl.location());
126
127 // Assigning an empty shared library
128 sl2.assign(shared_library());
129 BOOST_TEST(sl.is_loaded());
130 BOOST_TEST(sl);
131 BOOST_TEST(!sl2.is_loaded());
132 BOOST_TEST(!sl2);
133 boost::dll::fs::error_code ec;
134 BOOST_TEST(sl2.location(ec) != sl.location());
135 BOOST_TEST(ec);
136 }
137
138 {
139 boost::dll::fs::error_code ec;
140 shared_library sl(shared_library_path, ec);
141 BOOST_TEST(sl.is_loaded());
142 BOOST_TEST(sl);
143 BOOST_TEST(!ec);
144 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
145 BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
146 BOOST_TEST(!ec);
147
148 // Checking self assignment #1
149 sl.assign(sl);
150 BOOST_TEST(sl.is_loaded());
151 BOOST_TEST(sl);
152 BOOST_TEST(!ec);
153 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
154 BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
155
156 // Checking self assignment #2
157 sl.assign(sl, ec);
158 BOOST_TEST(sl.is_loaded());
159 BOOST_TEST(sl);
160 BOOST_TEST(!ec);
161 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
162 BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
163 }
164
165 {
166 shared_library sl;
167 BOOST_TEST(!sl.is_loaded());
168
169 sl.assign(sl);
170 BOOST_TEST(!sl);
171
172 shared_library sl2(sl);
173 BOOST_TEST(!sl);
174 BOOST_TEST(!sl2);
175
176 sl2.assign(sl);
177 BOOST_TEST(!sl);
178 BOOST_TEST(!sl2);
179 }
180
181 {
182 shared_library sl;
183 sl.load(shared_library_path);
184 BOOST_TEST(sl.is_loaded());
185 BOOST_TEST(sl);
186 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
187 }
188
189 {
190 shared_library sl;
191 boost::dll::fs::error_code ec;
192 sl.load(shared_library_path, ec);
193 BOOST_TEST(sl.is_loaded());
194 BOOST_TEST(sl);
195 BOOST_TEST(!ec);
196 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
197 }
198
199 {
200 shared_library sl(shared_library_path, load_mode::load_with_altered_search_path );
201 BOOST_TEST(sl.is_loaded());
202 BOOST_TEST(sl);
203 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
204 }
205
206 {
207 boost::dll::fs::error_code ec;
208 shared_library sl(shared_library_path, load_mode::load_with_altered_search_path, ec);
209 BOOST_TEST(sl.is_loaded());
210 BOOST_TEST(sl);
211 BOOST_TEST(!ec);
212 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
213 BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
214 BOOST_TEST(!ec);
215 }
216
217 {
218 boost::dll::fs::error_code ec;
219 shared_library sl(shared_library_path, load_mode::search_system_folders, ec);
220 BOOST_TEST(sl.is_loaded());
221 BOOST_TEST(sl);
222 BOOST_TEST(!ec);
223 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
224 BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
225 BOOST_TEST(!ec);
226 }
227
228 {
229 try {
230 #if BOOST_OS_WINDOWS
231 boost::dll::shared_library("winmm.dll");
232 BOOST_TEST(false);
233 #elif BOOST_OS_LINUX
234 boost::dll::shared_library("libdl.so");
235 BOOST_TEST(false);
236 #endif
237 } catch (...) {}
238 }
239
240 {
241 try {
242 #if BOOST_OS_WINDOWS
243 boost::dll::shared_library("winmm", load_mode::search_system_folders | load_mode::append_decorations);
244 #elif BOOST_OS_LINUX
245 boost::dll::shared_library("dl", boost::dll::load_mode::search_system_folders | load_mode::append_decorations);
246 #endif
247 } catch (...) {
248 BOOST_TEST(false);
249 }
250 }
251
252 {
253 shared_library sl;
254 sl.load(shared_library_path, load_mode::load_with_altered_search_path);
255 BOOST_TEST(sl.is_loaded());
256 BOOST_TEST(sl);
257 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
258 }
259
260 {
261 shared_library sl;
262 boost::dll::fs::error_code ec;
263 sl.load(shared_library_path, load_mode::load_with_altered_search_path, ec);
264 BOOST_TEST(sl.is_loaded());
265 BOOST_TEST(sl);
266 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
267 }
268
269 {
270 shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global);
271 BOOST_TEST(sl.is_loaded());
272 BOOST_TEST(sl);
273 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
274 }
275
276 {
277 shared_library sl(shared_library_path, load_mode::rtld_local);
278 BOOST_TEST(sl.is_loaded());
279 BOOST_TEST(sl);
280 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
281 }
282
283 {
284 shared_library sl(shared_library_path, load_mode::rtld_now);
285 BOOST_TEST(sl.is_loaded());
286 BOOST_TEST(sl);
287 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
288 }
289
290 {
291 fs_copy_guard guard(shared_library_path);
292
293 boost::dll::fs::path platform_independent_path = guard.actual_path_;
294 platform_independent_path.replace_extension();
295 if (platform_independent_path.filename().wstring().find(L"lib") == 0) {
296 platform_independent_path
297 = platform_independent_path.parent_path() / platform_independent_path.filename().wstring().substr(3);
298 }
299 std::cerr << "platform_independent_path: " << platform_independent_path << '\n';
300
301 shared_library sl(platform_independent_path, load_mode::append_decorations);
302 BOOST_TEST(sl.is_loaded());
303 BOOST_TEST(sl);
304 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
305
306 sl.unload();
307 BOOST_TEST(!sl.is_loaded());
308 BOOST_TEST(!sl);
309 }
310
311 {
312 shared_library sl(shared_library_path, load_mode::rtld_now | load_mode::rtld_global | load_mode::load_with_altered_search_path);
313 BOOST_TEST(sl.is_loaded());
314 BOOST_TEST(sl);
315 }
316
317 {
318 boost::dll::fs::error_code ec;
319 shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
320 BOOST_TEST(sl.is_loaded());
321 BOOST_TEST(sl);
322 BOOST_TEST(!ec);
323 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
324 }
325
326 {
327 shared_library sl;
328 sl.load(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global);
329 BOOST_TEST(sl.is_loaded());
330 BOOST_TEST(sl);
331 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
332 }
333
334
335 { // Non-default flags with assignment
336 shared_library sl(shared_library_path,
337 load_mode::rtld_now | load_mode::rtld_global | load_mode::load_with_altered_search_path
338
339 // `load_mode::rtld_deepbind` is incompatible with sanitizers:
340 // You are trying to dlopen a libtest_library.so shared library with RTLD_DEEPBIND flag which is incompatibe with sanitizer runtime
341 // (see https://github.com/google/sanitizers/issues/611 for details).
342 #ifndef BOOST_TRAVISCI_BUILD
343 | load_mode::rtld_deepbind
344 #endif
345
346 );
347 BOOST_TEST(sl.is_loaded());
348 BOOST_TEST(sl);
349
350 boost::dll::fs::error_code ec;
351 shared_library sl2(sl, ec);
352 BOOST_TEST(!ec);
353 BOOST_TEST(sl.is_loaded());
354 BOOST_TEST(sl);
355 BOOST_TEST(sl2.is_loaded());
356 BOOST_TEST(sl2);
357 BOOST_TEST(sl2.location() == sl.location());
358
359 shared_library sl3(sl);
360 BOOST_TEST(sl.is_loaded());
361 BOOST_TEST(sl);
362 BOOST_TEST(sl3.is_loaded());
363 BOOST_TEST(sl3);
364
365 shared_library sl4;
366 sl4.assign(sl, ec);
367 BOOST_TEST(!ec);
368 BOOST_TEST(sl.is_loaded());
369 BOOST_TEST(sl);
370 BOOST_TEST(sl4.is_loaded());
371 BOOST_TEST(sl4);
372 }
373
374 { // Non-default flags with assignment and error_code
375 boost::dll::fs::error_code ec;
376 shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
377 BOOST_TEST(sl.is_loaded());
378 BOOST_TEST(sl);
379 BOOST_TEST(!ec);
380 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
381
382 shared_library sl2(sl, ec);
383 BOOST_TEST(!ec);
384 BOOST_TEST(sl.is_loaded());
385 BOOST_TEST(sl);
386 BOOST_TEST(sl2.is_loaded());
387 BOOST_TEST(sl2);
388 BOOST_TEST(sl2.location() == sl.location());
389
390 shared_library sl3(sl);
391 BOOST_TEST(sl.is_loaded());
392 BOOST_TEST(sl);
393 BOOST_TEST(sl3.is_loaded());
394 BOOST_TEST(sl3);
395 BOOST_TEST(sl3.location() == sl.location());
396 }
397
398 { // self_load
399 shared_library sl(program_location());
400 BOOST_TEST(sl.is_loaded());
401 BOOST_TEST(sl);
402 std::cout << "\nProgram location: " << program_location();
403 std::cout << "\nLibrary location: " << sl.location();
404 BOOST_TEST( boost::dll::fs::equivalent(sl.location(), program_location()) );
405
406 boost::dll::fs::error_code ec;
407 shared_library sl2(program_location());
408 BOOST_TEST(sl2.is_loaded());
409 BOOST_TEST( boost::dll::fs::equivalent(sl2.location(), program_location()) );
410 BOOST_TEST(sl2);
411 BOOST_TEST(!ec);
412
413 BOOST_TEST(sl == sl2);
414 BOOST_TEST(!(sl < sl2 || sl2 <sl));
415 BOOST_TEST(!(sl != sl2));
416
417 sl.load(shared_library_path);
418 BOOST_TEST(sl != sl2);
419 BOOST_TEST(sl < sl2 || sl2 <sl);
420 BOOST_TEST(!(sl == sl2));
421
422 sl.unload();
423 BOOST_TEST(!sl);
424 BOOST_TEST(sl != sl2);
425 BOOST_TEST(sl < sl2 || sl2 <sl);
426 BOOST_TEST(!(sl == sl2));
427
428 sl2.unload();
429 BOOST_TEST(!sl2);
430 BOOST_TEST(sl == sl2);
431 BOOST_TEST(!(sl < sl2 || sl2 <sl));
432 BOOST_TEST(!(sl != sl2));
433
434 // assigning self
435 sl.load(program_location());
436 sl2 = sl;
437 BOOST_TEST(sl == sl2);
438 BOOST_TEST(sl.location() == sl2.location());
439 }
440
441 {
442 shared_library sl;
443 boost::dll::fs::error_code ec;
444 sl.load(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
445 BOOST_TEST(sl.is_loaded());
446 BOOST_TEST(sl);
447 BOOST_TEST(!ec);
448 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
449
450 sl.load(program_location());
451 BOOST_TEST(sl.is_loaded());
452 BOOST_TEST(sl);
453
454 sl.load(program_location());
455 BOOST_TEST(sl.is_loaded());
456 BOOST_TEST(sl);
457 BOOST_TEST(!ec);
458 }
459
460 { // self_load
461 shared_library sl;
462 boost::dll::fs::error_code ec;
463 sl.load(program_location());
464 BOOST_TEST(sl.is_loaded());
465 BOOST_TEST(sl);
466 BOOST_TEST(!ec);
467 }
468
469 { // unload
470 shared_library sl(shared_library_path);
471 BOOST_TEST(sl.is_loaded());
472 BOOST_TEST(sl);
473 BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
474 sl.unload();
475 BOOST_TEST(!sl.is_loaded());
476 BOOST_TEST(!sl);
477 }
478
479
480 { // error_code load calls test
481 boost::dll::fs::error_code ec;
482 shared_library sl(shared_library_path / "dir_that_does_not_exist", ec);
483 BOOST_TEST(ec);
484 BOOST_TEST(!sl.is_loaded());
485 BOOST_TEST(!sl);
486
487 boost::dll::fs::path bad_path(shared_library_path);
488 bad_path += ".1.1.1.1.1.1";
489 sl.load(bad_path, ec);
490 BOOST_TEST(ec);
491 BOOST_TEST(!sl.is_loaded());
492 BOOST_TEST(!sl);
493
494 sl.load(shared_library_path, ec);
495 BOOST_TEST(!ec);
496 BOOST_TEST(sl.is_loaded());
497 BOOST_TEST(sl);
498
499 shared_library sl2(bad_path, ec);
500 BOOST_TEST(ec);
501 BOOST_TEST(!sl2.is_loaded());
502 BOOST_TEST(!sl2);
503
504 shared_library sl3(shared_library_path, ec);
505 BOOST_TEST(!ec);
506 BOOST_TEST(sl3.is_loaded());
507 BOOST_TEST(sl3);
508
509 sl.load("", ec);
510 BOOST_TEST(ec);
511 BOOST_TEST(!sl.is_loaded());
512 BOOST_TEST(!sl);
513 }
514
515
516 shared_library_path = do_find_correct_libs_path(argc, argv, "library1");
517 fs_copy_guard guard(shared_library_path);
518 shared_library starts_with_lib(
519 boost::dll::fs::path(guard.actual_path_).replace_extension(),
520 load_mode::append_decorations
521 );
522
523 starts_with_lib.load(
524 boost::dll::fs::path(guard.actual_path_).replace_extension(),
525 load_mode::append_decorations
526 );
527
528 return boost::report_errors();
529 }