xref: /aosp_15_r20/external/cronet/base/native_library_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/native_library.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/path_service.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/test/native_library_test_utils.h"
11*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
12*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker namespace base {
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker const FilePath::CharType kDummyLibraryPath[] =
17*6777b538SAndroid Build Coastguard Worker     FILE_PATH_LITERAL("dummy_library");
18*6777b538SAndroid Build Coastguard Worker 
TEST(NativeLibraryTest,LoadFailure)19*6777b538SAndroid Build Coastguard Worker TEST(NativeLibraryTest, LoadFailure) {
20*6777b538SAndroid Build Coastguard Worker   NativeLibraryLoadError error;
21*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(LoadNativeLibrary(FilePath(kDummyLibraryPath), &error));
22*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(error.ToString().empty());
23*6777b538SAndroid Build Coastguard Worker }
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker // |error| is optional and can be null.
TEST(NativeLibraryTest,LoadFailureWithNullError)26*6777b538SAndroid Build Coastguard Worker TEST(NativeLibraryTest, LoadFailureWithNullError) {
27*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(LoadNativeLibrary(FilePath(kDummyLibraryPath), nullptr));
28*6777b538SAndroid Build Coastguard Worker }
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
TEST(NativeLibraryTest,LoadAbsolutePath)31*6777b538SAndroid Build Coastguard Worker TEST(NativeLibraryTest, LoadAbsolutePath) {
32*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LoadNativeLibrary(FilePath("/pkg/lib/libtest_shared_library.so"),
33*6777b538SAndroid Build Coastguard Worker                                 nullptr));
34*6777b538SAndroid Build Coastguard Worker }
35*6777b538SAndroid Build Coastguard Worker 
TEST(NativeLibraryTest,LoadAbsolutePath_OutsideLibraryRoot)36*6777b538SAndroid Build Coastguard Worker TEST(NativeLibraryTest, LoadAbsolutePath_OutsideLibraryRoot) {
37*6777b538SAndroid Build Coastguard Worker   NativeLibraryLoadError error;
38*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(LoadNativeLibrary(FilePath("/pkg/tmp/libtest_shared_library.so"),
39*6777b538SAndroid Build Coastguard Worker                                  &error));
40*6777b538SAndroid Build Coastguard Worker   std::string expected_error =
41*6777b538SAndroid Build Coastguard Worker       "Absolute library paths must begin with /pkg/lib";
42*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(error.ToString(), expected_error);
43*6777b538SAndroid Build Coastguard Worker }
44*6777b538SAndroid Build Coastguard Worker #endif
45*6777b538SAndroid Build Coastguard Worker 
TEST(NativeLibraryTest,GetNativeLibraryName)46*6777b538SAndroid Build Coastguard Worker TEST(NativeLibraryTest, GetNativeLibraryName) {
47*6777b538SAndroid Build Coastguard Worker   const char kExpectedName[] =
48*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
49*6777b538SAndroid Build Coastguard Worker       "mylib.dll";
50*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_IOS)
51*6777b538SAndroid Build Coastguard Worker       "mylib";
52*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_MAC)
53*6777b538SAndroid Build Coastguard Worker       "libmylib.dylib";
54*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
55*6777b538SAndroid Build Coastguard Worker       "libmylib.so";
56*6777b538SAndroid Build Coastguard Worker #endif
57*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedName, GetNativeLibraryName("mylib"));
58*6777b538SAndroid Build Coastguard Worker }
59*6777b538SAndroid Build Coastguard Worker 
TEST(NativeLibraryTest,GetLoadableModuleName)60*6777b538SAndroid Build Coastguard Worker TEST(NativeLibraryTest, GetLoadableModuleName) {
61*6777b538SAndroid Build Coastguard Worker   const char kExpectedName[] =
62*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
63*6777b538SAndroid Build Coastguard Worker       "mylib.dll";
64*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_IOS)
65*6777b538SAndroid Build Coastguard Worker       "mylib";
66*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_MAC)
67*6777b538SAndroid Build Coastguard Worker       "mylib.so";
68*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
69*6777b538SAndroid Build Coastguard Worker       "libmylib.so";
70*6777b538SAndroid Build Coastguard Worker #endif
71*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedName, GetLoadableModuleName("mylib"));
72*6777b538SAndroid Build Coastguard Worker }
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker // We don't support dynamic loading on iOS, and ASAN will complain about our
75*6777b538SAndroid Build Coastguard Worker // intentional ODR violation because of |g_native_library_exported_value| being
76*6777b538SAndroid Build Coastguard Worker // defined globally both here and in the shared library.
77*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_IOS) && !defined(ADDRESS_SANITIZER)
78*6777b538SAndroid Build Coastguard Worker 
79*6777b538SAndroid Build Coastguard Worker const char kTestLibraryName[] =
80*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
81*6777b538SAndroid Build Coastguard Worker     "test_shared_library.dll";
82*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_MAC)
83*6777b538SAndroid Build Coastguard Worker     "libtest_shared_library.dylib";
84*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
85*6777b538SAndroid Build Coastguard Worker     "libtest_shared_library.so";
86*6777b538SAndroid Build Coastguard Worker #endif
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker class TestLibrary {
89*6777b538SAndroid Build Coastguard Worker  public:
TestLibrary()90*6777b538SAndroid Build Coastguard Worker   TestLibrary() : TestLibrary(NativeLibraryOptions()) {}
91*6777b538SAndroid Build Coastguard Worker 
TestLibrary(const NativeLibraryOptions & options)92*6777b538SAndroid Build Coastguard Worker   explicit TestLibrary(const NativeLibraryOptions& options)
93*6777b538SAndroid Build Coastguard Worker       : library_(nullptr) {
94*6777b538SAndroid Build Coastguard Worker     base::FilePath exe_path;
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_FUCHSIA)
97*6777b538SAndroid Build Coastguard Worker     // Libraries do not sit alongside the executable in Fuchsia. NativeLibrary
98*6777b538SAndroid Build Coastguard Worker     // is aware of this and is able to resolve library paths correctly.
99*6777b538SAndroid Build Coastguard Worker     CHECK(base::PathService::Get(base::DIR_EXE, &exe_path));
100*6777b538SAndroid Build Coastguard Worker #endif
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker     library_ = LoadNativeLibraryWithOptions(
103*6777b538SAndroid Build Coastguard Worker         exe_path.AppendASCII(kTestLibraryName), options, nullptr);
104*6777b538SAndroid Build Coastguard Worker     CHECK(library_);
105*6777b538SAndroid Build Coastguard Worker   }
106*6777b538SAndroid Build Coastguard Worker   TestLibrary(const TestLibrary&) = delete;
107*6777b538SAndroid Build Coastguard Worker   TestLibrary& operator=(const TestLibrary&) = delete;
~TestLibrary()108*6777b538SAndroid Build Coastguard Worker   ~TestLibrary() { UnloadNativeLibrary(library_); }
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker   template <typename ReturnType, typename... Args>
Call(const char * function_name,Args...args)111*6777b538SAndroid Build Coastguard Worker   ReturnType Call(const char* function_name, Args... args) {
112*6777b538SAndroid Build Coastguard Worker     return reinterpret_cast<ReturnType (*)(Args...)>(
113*6777b538SAndroid Build Coastguard Worker         GetFunctionPointerFromNativeLibrary(library_, function_name))(args...);
114*6777b538SAndroid Build Coastguard Worker   }
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker  private:
117*6777b538SAndroid Build Coastguard Worker   NativeLibrary library_;
118*6777b538SAndroid Build Coastguard Worker };
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker // NativeLibraaryTest.LoadLibrary is failing on M tablets only.
121*6777b538SAndroid Build Coastguard Worker // crbug/641309
122*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_ANDROID)
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker // Verifies that we can load a native library and resolve its exported symbols.
TEST(NativeLibraryTest,LoadLibrary)125*6777b538SAndroid Build Coastguard Worker TEST(NativeLibraryTest, LoadLibrary) {
126*6777b538SAndroid Build Coastguard Worker   TestLibrary library;
127*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5, library.Call<int>("GetSimpleTestValue"));
128*6777b538SAndroid Build Coastguard Worker }
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker #endif  // !BUILDFLAG(IS_ANDROID)
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker // Android dlopen() requires further investigation, as it might vary across
133*6777b538SAndroid Build Coastguard Worker // versions with respect to symbol resolution scope.
134*6777b538SAndroid Build Coastguard Worker // TSan and MSan error out on RTLD_DEEPBIND, https://crbug.com/705255
135*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_ANDROID) && !defined(THREAD_SANITIZER) && \
136*6777b538SAndroid Build Coastguard Worker     !defined(MEMORY_SANITIZER)
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker // Verifies that the |prefer_own_symbols| option satisfies its guarantee that
139*6777b538SAndroid Build Coastguard Worker // a loaded library will always prefer local symbol resolution before
140*6777b538SAndroid Build Coastguard Worker // considering global symbols.
TEST(NativeLibraryTest,LoadLibraryPreferOwnSymbols)141*6777b538SAndroid Build Coastguard Worker TEST(NativeLibraryTest, LoadLibraryPreferOwnSymbols) {
142*6777b538SAndroid Build Coastguard Worker   NativeLibraryOptions options;
143*6777b538SAndroid Build Coastguard Worker   options.prefer_own_symbols = true;
144*6777b538SAndroid Build Coastguard Worker   TestLibrary library(options);
145*6777b538SAndroid Build Coastguard Worker 
146*6777b538SAndroid Build Coastguard Worker   // Verify that this binary and the DSO use different storage for
147*6777b538SAndroid Build Coastguard Worker   // |g_native_library_exported_value|.
148*6777b538SAndroid Build Coastguard Worker   g_native_library_exported_value = 1;
149*6777b538SAndroid Build Coastguard Worker   library.Call<void>("SetExportedValue", 2);
150*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, g_native_library_exported_value);
151*6777b538SAndroid Build Coastguard Worker   g_native_library_exported_value = 3;
152*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, library.Call<int>("GetExportedValue"));
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker   // Both this binary and the library link against the
155*6777b538SAndroid Build Coastguard Worker   // native_library_test_utils source library, which in turn exports the
156*6777b538SAndroid Build Coastguard Worker   // NativeLibraryTestIncrement() function whose return value depends on some
157*6777b538SAndroid Build Coastguard Worker   // static internal state.
158*6777b538SAndroid Build Coastguard Worker   //
159*6777b538SAndroid Build Coastguard Worker   // The DSO's GetIncrementValue() forwards to that function inside the DSO.
160*6777b538SAndroid Build Coastguard Worker   //
161*6777b538SAndroid Build Coastguard Worker   // Here we verify that direct calls to NativeLibraryTestIncrement() in this
162*6777b538SAndroid Build Coastguard Worker   // binary return a sequence of values independent from the sequence returned
163*6777b538SAndroid Build Coastguard Worker   // by GetIncrementValue(), ensuring that the DSO is calling its own local
164*6777b538SAndroid Build Coastguard Worker   // definition of NativeLibraryTestIncrement().
165*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, library.Call<int>("GetIncrementValue"));
166*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, NativeLibraryTestIncrement());
167*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, library.Call<int>("GetIncrementValue"));
168*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, library.Call<int>("GetIncrementValue"));
169*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, library.Call<int>("NativeLibraryTestIncrement"));
170*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, NativeLibraryTestIncrement());
171*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, NativeLibraryTestIncrement());
172*6777b538SAndroid Build Coastguard Worker }
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker #endif  // !BUILDFLAG(IS_ANDROID) && !defined(THREAD_SANITIZER) && \
175*6777b538SAndroid Build Coastguard Worker         // !defined(MEMORY_SANITIZER)
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker #endif  // !BUILDFLAG(IS_IOS) && !defined(ADDRESS_SANITIZER)
178*6777b538SAndroid Build Coastguard Worker 
179*6777b538SAndroid Build Coastguard Worker }  // namespace base
180