summaryrefslogtreecommitdiff
path: root/libnativeloader/native_loader_test.cpp
diff options
context:
space:
mode:
authorCalin Juravle <calin@google.com>2021-05-07 22:44:29 +0000
committerTreehugger Robot <treehugger-gerrit@google.com>2021-05-09 00:37:05 +0000
commit91d2c5c1d1157f27e723d8ebee458913c6f0ed43 (patch)
tree61089b69928171706cf93d939bb068d115e92c5d /libnativeloader/native_loader_test.cpp
parent6958df93f8cb3d82bddadbabb5ed94b3b63a7f14 (diff)
Revert "Avoid loading external libraries from ARTs internal linker namespace."
This reverts commit 582448f29f2f2529202bf868d00ba5d3d3776bb6. Reason for revert: breaks tests Change-Id: I2e0b2a28d4644b314887673d4aef4f1094aea289
Diffstat (limited to 'libnativeloader/native_loader_test.cpp')
-rw-r--r--libnativeloader/native_loader_test.cpp110
1 files changed, 27 insertions, 83 deletions
diff --git a/libnativeloader/native_loader_test.cpp b/libnativeloader/native_loader_test.cpp
index e754414f46..43c3c151c9 100644
--- a/libnativeloader/native_loader_test.cpp
+++ b/libnativeloader/native_loader_test.cpp
@@ -36,13 +36,12 @@ namespace android {
namespace nativeloader {
using ::testing::Eq;
-using ::testing::NotNull;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::_;
using internal::ConfigEntry;
-using internal::ParseApexLibrariesConfig;
using internal::ParseConfig;
+using internal::ParseApexLibrariesConfig;
#if defined(__LP64__)
#define LIB_DIR "lib64"
@@ -50,15 +49,19 @@ using internal::ParseConfig;
#define LIB_DIR "lib"
#endif
-// gmock interface that represents interested platform APIs on libdl_android and libnativebridge
+// gmock interface that represents interested platform APIs on libdl and libnativebridge
class Platform {
public:
virtual ~Platform() {}
- // These mock_* are the APIs semantically the same across libdl_android and libnativebridge.
+ // libdl APIs
+ virtual void* dlopen(const char* filename, int flags) = 0;
+ virtual int dlclose(void* handle) = 0;
+ virtual char* dlerror(void) = 0;
+
+ // These mock_* are the APIs semantically the same across libdl and libnativebridge.
// Instead of having two set of mock APIs for the two, define only one set with an additional
- // argument 'bool bridged' to identify the context (i.e., called for libdl_android or
- // libnativebridge).
+ // argument 'bool bridged' to identify the context (i.e., called for libdl or libnativebridge).
typedef char* mock_namespace_handle;
virtual bool mock_init_anonymous_namespace(bool bridged, const char* sonames,
const char* search_paths) = 0;
@@ -71,7 +74,7 @@ class Platform {
virtual void* mock_dlopen_ext(bool bridged, const char* filename, int flags,
mock_namespace_handle ns) = 0;
- // libnativebridge APIs for which libdl_android has no corresponding APIs
+ // libnativebridge APIs for which libdl has no corresponding APIs
virtual bool NativeBridgeInitialized() = 0;
virtual const char* NativeBridgeGetError() = 0;
virtual bool NativeBridgeIsPathSupported(const char*) = 0;
@@ -122,6 +125,11 @@ class MockPlatform : public Platform {
}));
}
+ // Mocking libdl APIs
+ MOCK_METHOD2(dlopen, void*(const char*, int));
+ MOCK_METHOD1(dlclose, int(void*));
+ MOCK_METHOD0(dlerror, char*());
+
// Mocking the common APIs
MOCK_METHOD3(mock_init_anonymous_namespace, bool(bool, const char*, const char*));
MOCK_METHOD7(mock_create_namespace,
@@ -147,11 +155,19 @@ class MockPlatform : public Platform {
static std::unique_ptr<MockPlatform> mock;
-// Provide C wrappers for the mock object. These symbols must be exported by ld
-// to be able to override the real symbols in the shared libs.
+// Provide C wrappers for the mock object.
extern "C" {
+void* dlopen(const char* file, int flag) {
+ return mock->dlopen(file, flag);
+}
-// libdl_android APIs
+int dlclose(void* handle) {
+ return mock->dlclose(handle);
+}
+
+char* dlerror(void) {
+ return mock->dlerror();
+}
bool android_init_anonymous_namespace(const char* sonames, const char* search_path) {
return mock->mock_init_anonymous_namespace(false, sonames, search_path);
@@ -181,7 +197,6 @@ void* android_dlopen_ext(const char* filename, int flags, const android_dlextinf
}
// libnativebridge APIs
-
bool NativeBridgeIsSupported(const char* libpath) {
return mock->NativeBridgeIsSupported(libpath);
}
@@ -298,8 +313,7 @@ class NativeLoaderTest : public ::testing::TestWithParam<bool> {
std::vector<std::string> default_public_libs =
android::base::Split(preloadable_public_libraries(), ":");
for (auto l : default_public_libs) {
- EXPECT_CALL(*mock,
- mock_dlopen_ext(false, StrEq(l.c_str()), RTLD_NOW | RTLD_NODELETE, NotNull()))
+ EXPECT_CALL(*mock, dlopen(StrEq(l.c_str()), RTLD_NOW | RTLD_NODELETE))
.WillOnce(Return(any_nonnull));
}
}
@@ -322,76 +336,6 @@ TEST_P(NativeLoaderTest, InitializeLoadsDefaultPublicLibraries) {
RunTest();
}
-TEST_P(NativeLoaderTest, OpenNativeLibraryWithoutClassloaderInApex) {
- const char* test_lib_path = "libfoo.so";
- void* fake_handle = &fake_handle; // Arbitrary non-null value
- EXPECT_CALL(*mock,
- mock_dlopen_ext(false, StrEq(test_lib_path), RTLD_NOW, NsEq("com_android_art")))
- .WillOnce(Return(fake_handle));
-
- bool needs_native_bridge = false;
- char* errmsg = nullptr;
- EXPECT_EQ(fake_handle,
- OpenNativeLibrary(env.get(),
- /*target_sdk_version=*/17,
- test_lib_path,
- /*class_loader=*/nullptr,
- /*caller_location=*/"/apex/com.android.art/javalib/myloadinglib.jar",
- /*library_path=*/nullptr,
- &needs_native_bridge,
- &errmsg));
- // OpenNativeLibrary never uses nativebridge when there's no classloader. That
- // should maybe change.
- EXPECT_EQ(needs_native_bridge, false);
- EXPECT_EQ(errmsg, nullptr);
-}
-
-TEST_P(NativeLoaderTest, OpenNativeLibraryWithoutClassloaderInFramework) {
- const char* test_lib_path = "libfoo.so";
- void* fake_handle = &fake_handle; // Arbitrary non-null value
- EXPECT_CALL(*mock, mock_dlopen_ext(false, StrEq(test_lib_path), RTLD_NOW, NsEq("system")))
- .WillOnce(Return(fake_handle));
-
- bool needs_native_bridge = false;
- char* errmsg = nullptr;
- EXPECT_EQ(fake_handle,
- OpenNativeLibrary(env.get(),
- /*target_sdk_version=*/17,
- test_lib_path,
- /*class_loader=*/nullptr,
- /*caller_location=*/"/system/framework/framework.jar!classes1.dex",
- /*library_path=*/nullptr,
- &needs_native_bridge,
- &errmsg));
- // OpenNativeLibrary never uses nativebridge when there's no classloader. That
- // should maybe change.
- EXPECT_EQ(needs_native_bridge, false);
- EXPECT_EQ(errmsg, nullptr);
-}
-
-TEST_P(NativeLoaderTest, OpenNativeLibraryWithoutClassloaderAndCallerLocation) {
- const char* test_lib_path = "libfoo.so";
- void* fake_handle = &fake_handle; // Arbitrary non-null value
- EXPECT_CALL(*mock, mock_dlopen_ext(false, StrEq(test_lib_path), RTLD_NOW, NsEq("system")))
- .WillOnce(Return(fake_handle));
-
- bool needs_native_bridge = false;
- char* errmsg = nullptr;
- EXPECT_EQ(fake_handle,
- OpenNativeLibrary(env.get(),
- /*target_sdk_version=*/17,
- test_lib_path,
- /*class_loader=*/nullptr,
- /*caller_location=*/nullptr,
- /*library_path=*/nullptr,
- &needs_native_bridge,
- &errmsg));
- // OpenNativeLibrary never uses nativebridge when there's no classloader. That
- // should maybe change.
- EXPECT_EQ(needs_native_bridge, false);
- EXPECT_EQ(errmsg, nullptr);
-}
-
INSTANTIATE_TEST_SUITE_P(NativeLoaderTests, NativeLoaderTest, testing::Bool());
/////////////////////////////////////////////////////////////////