| Index: base/native_library_unittest.cc
|
| diff --git a/base/native_library_unittest.cc b/base/native_library_unittest.cc
|
| index c189f56e995c04598df5bf2d85c1a882dcafd629..1d0683d4c7e6e083da99efcd96acb517e338e128 100644
|
| --- a/base/native_library_unittest.cc
|
| +++ b/base/native_library_unittest.cc
|
| @@ -3,7 +3,11 @@
|
| // found in the LICENSE file.
|
|
|
| #include "base/files/file_path.h"
|
| +#include "base/macros.h"
|
| #include "base/native_library.h"
|
| +#include "base/path_service.h"
|
| +#include "base/test/native_library_test_utils.h"
|
| +#include "build/build_config.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace base {
|
| @@ -36,4 +40,100 @@ TEST(NativeLibraryTest, GetNativeLibraryName) {
|
| EXPECT_EQ(kExpectedName, GetNativeLibraryName("mylib"));
|
| }
|
|
|
| +// We don't support dynamic loading on iOS, and ASAN will complain about our
|
| +// intentional ODR violation because of |g_native_library_exported_value| being
|
| +// defined globally both here and in the shared library.
|
| +#if !defined(OS_IOS) && !defined(ADDRESS_SANITIZER)
|
| +
|
| +const char kTestLibraryName[] =
|
| +#if defined(OS_MACOSX)
|
| + "libtest_shared_library.dylib";
|
| +#elif defined(OS_ANDROID) && defined(COMPONENT_BUILD)
|
| + "libtest_shared_library.cr.so";
|
| +#elif defined(OS_POSIX)
|
| + "libtest_shared_library.so";
|
| +#elif defined(OS_WIN)
|
| + "test_shared_library.dll";
|
| +#endif
|
| +
|
| +class TestLibrary {
|
| + public:
|
| + TestLibrary() : TestLibrary(NativeLibraryOptions()) {}
|
| +
|
| + explicit TestLibrary(const NativeLibraryOptions& options)
|
| + : library_(nullptr) {
|
| + base::FilePath exe_path;
|
| + CHECK(base::PathService::Get(base::DIR_EXE, &exe_path));
|
| +
|
| + library_ = LoadNativeLibraryWithOptions(
|
| + exe_path.AppendASCII(kTestLibraryName), options, nullptr);
|
| + CHECK(library_);
|
| + }
|
| +
|
| + ~TestLibrary() {
|
| + UnloadNativeLibrary(library_);
|
| + }
|
| +
|
| + template <typename ReturnType, typename... Args>
|
| + ReturnType Call(const char* function_name, Args... args) {
|
| + return reinterpret_cast<ReturnType(*)(Args...)>(
|
| + GetFunctionPointerFromNativeLibrary(library_, function_name))(args...);
|
| + }
|
| +
|
| + private:
|
| + NativeLibrary library_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TestLibrary);
|
| +};
|
| +
|
| +// Verifies that we can load a native library and resolve its exported symbols.
|
| +TEST(NativeLibraryTest, LoadLibrary) {
|
| + TestLibrary library;
|
| + EXPECT_EQ(5, library.Call<int>("GetSimpleTestValue"));
|
| +}
|
| +
|
| +// Android dlopen() requires further investigation, as it might vary across
|
| +// versions with respect to symbol resolution scope.
|
| +#if !defined(OS_ANDROID)
|
| +
|
| +// Verifies that the |prefer_own_symbols| option satisfies its guarantee that
|
| +// a loaded library will always prefer local symbol resolution before
|
| +// considering global symbols.
|
| +TEST(NativeLibraryTest, LoadLibraryPreferOwnSymbols) {
|
| + NativeLibraryOptions options;
|
| + options.prefer_own_symbols = true;
|
| + TestLibrary library(options);
|
| +
|
| + // Verify that this binary and the DSO use different storage for
|
| + // |g_native_library_exported_value|.
|
| + g_native_library_exported_value = 1;
|
| + library.Call<void>("SetExportedValue", 2);
|
| + EXPECT_EQ(1, g_native_library_exported_value);
|
| + g_native_library_exported_value = 3;
|
| + EXPECT_EQ(2, library.Call<int>("GetExportedValue"));
|
| +
|
| + // Both this binary and the library link against the
|
| + // native_library_test_utils source library, which in turn exports the
|
| + // NativeLibraryTestIncrement() function whose return value depends on some
|
| + // static internal state.
|
| + //
|
| + // The DSO's GetIncrementValue() forwards to that function inside the DSO.
|
| + //
|
| + // Here we verify that direct calls to NativeLibraryTestIncrement() in this
|
| + // binary return a sequence of values independent from the sequence returned
|
| + // by GetIncrementValue(), ensuring that the DSO is calling its own local
|
| + // definition of NativeLibraryTestIncrement().
|
| + EXPECT_EQ(1, library.Call<int>("GetIncrementValue"));
|
| + EXPECT_EQ(1, NativeLibraryTestIncrement());
|
| + EXPECT_EQ(2, library.Call<int>("GetIncrementValue"));
|
| + EXPECT_EQ(3, library.Call<int>("GetIncrementValue"));
|
| + EXPECT_EQ(4, library.Call<int>("NativeLibraryTestIncrement"));
|
| + EXPECT_EQ(2, NativeLibraryTestIncrement());
|
| + EXPECT_EQ(3, NativeLibraryTestIncrement());
|
| +}
|
| +
|
| +#endif // !defined(OS_ANDROID)
|
| +
|
| +#endif // !defined(OS_IOS) && !defined(ADDRESS_SANITIZER)
|
| +
|
| } // namespace base
|
|
|