diff options
Diffstat (limited to 'libnativeloader/native_loader_api_test.cpp')
-rw-r--r-- | libnativeloader/native_loader_api_test.cpp | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/libnativeloader/native_loader_api_test.cpp b/libnativeloader/native_loader_api_test.cpp new file mode 100644 index 0000000000..78fb29f91d --- /dev/null +++ b/libnativeloader/native_loader_api_test.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(ART_TARGET_ANDROID) + +#include "gtest/gtest.h" +#include "native_loader_test.h" +#include "nativehelper/scoped_utf_chars.h" +#include "nativeloader/native_loader.h" + +namespace android { +namespace nativeloader { + +using ::testing::Return; +using ::testing::StrEq; + +// Test the exported API in libnativeloader and libnativeloader_lazy. The +// testing we can do here outside a full VM is limited, but this is only to +// complement other tests and ensure coverage of the APIs that aren't in the +// common call paths. + +class NativeLoaderLazyTest : public ::testing::Test { + protected: + void SetUp() override { + mock = std::make_unique<testing::NiceMock<MockPlatform>>(false); + env = std::make_unique<JNIEnv>(); + env->functions = CreateJNINativeInterface(); + } + + void TearDown() override { + // ResetNativeLoader isn't accessible through the lazy library, so we cannot + // reset libnativeloader internal state. Hence be sure to not reuse the same + // class loader/namespace names. + delete env->functions; + mock.reset(); + } + + void CallCreateClassLoaderNamespace(const char* class_loader) { + ON_CALL(*mock, JniObject_getParent(StrEq(class_loader))).WillByDefault(Return(nullptr)); + + jstring err = CreateClassLoaderNamespace(env.get(), + 17, + env.get()->NewStringUTF(class_loader), + false, + env.get()->NewStringUTF("/data/app/foo/classes.dex"), + env.get()->NewStringUTF("/data/app/foo"), + /*permitted_path=*/nullptr, + /*uses_library_list=*/nullptr); + EXPECT_EQ(err, nullptr) << "Error is: " << std::string(ScopedUtfChars(env.get(), err).c_str()); + } + + std::unique_ptr<JNIEnv> env; +}; + +TEST_F(NativeLoaderLazyTest, CreateClassLoaderNamespace) { + CallCreateClassLoaderNamespace("my_classloader_1"); + EXPECT_NE(FindNamespaceByClassLoader(env.get(), env.get()->NewStringUTF("my_classloader_1")), + nullptr); +} + +TEST_F(NativeLoaderLazyTest, OpenNativeLibrary) { + bool needs_native_bridge; + char* errmsg = nullptr; + EXPECT_EQ(nullptr, + OpenNativeLibrary(env.get(), + 17, + "libnotfound.so", + env.get()->NewStringUTF("my_classloader"), + /*caller_location=*/nullptr, + /*library_path=*/nullptr, + &needs_native_bridge, + &errmsg)); + EXPECT_NE(nullptr, errmsg); + NativeLoaderFreeErrorMessage(errmsg); +} + +TEST_F(NativeLoaderLazyTest, CloseNativeLibrary) { + char* errmsg = nullptr; + EXPECT_FALSE(CloseNativeLibrary(nullptr, false, &errmsg)); + EXPECT_NE(nullptr, errmsg); + NativeLoaderFreeErrorMessage(errmsg); +} + +TEST_F(NativeLoaderLazyTest, OpenNativeLibraryInNamespace) { + CallCreateClassLoaderNamespace("my_classloader_2"); + struct NativeLoaderNamespace* ns = FindNativeLoaderNamespaceByClassLoader( + env.get(), env.get()->NewStringUTF("my_classloader_2")); + ASSERT_NE(nullptr, ns); + + bool needs_native_bridge; + char* errmsg = nullptr; + EXPECT_FALSE(OpenNativeLibraryInNamespace(ns, "libnotfound.so", &needs_native_bridge, &errmsg)); + EXPECT_NE(nullptr, errmsg); + NativeLoaderFreeErrorMessage(errmsg); +} + +TEST_F(NativeLoaderLazyTest, FindNamespaceByClassLoader) { + EXPECT_EQ(nullptr, FindNamespaceByClassLoader(env.get(), env.get()->NewStringUTF("namespace"))); +} + +TEST_F(NativeLoaderLazyTest, FindNativeLoaderNamespaceByClassLoader) { + EXPECT_EQ( + nullptr, + FindNativeLoaderNamespaceByClassLoader(env.get(), env.get()->NewStringUTF("namespace"))); +} + +TEST_F(NativeLoaderLazyTest, NativeLoaderFreeErrorMessage) { + NativeLoaderFreeErrorMessage(nullptr); +} + +} // namespace nativeloader +} // namespace android + +#endif // defined(ART_TARGET_ANDROID) |