• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <memory>
18 #include <string>
19 
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 #include "jni.h"
23 #include "native_loader_test.h"
24 #include "nativehelper/scoped_utf_chars.h"
25 #include "nativeloader/native_loader.h"
26 
27 namespace android {
28 namespace nativeloader {
29 
30 using ::testing::Return;
31 using ::testing::StrEq;
32 
33 // Test the exported API in libnativeloader and libnativeloader_lazy. The
34 // testing we can do here outside a full VM is limited, but this is only to
35 // complement other tests and ensure coverage of the APIs that aren't in the
36 // common call paths.
37 
38 class NativeLoaderLazyTest : public ::testing::Test {
39  protected:
SetUp()40   void SetUp() override {
41     jni_mock = std::make_unique<testing::NiceMock<MockJni>>();
42     env = std::make_unique<JNIEnv>();
43     env->functions = CreateJNINativeInterface();
44   }
45 
TearDown()46   void TearDown() override {
47     // ResetNativeLoader isn't accessible through the lazy library, so we cannot
48     // reset libnativeloader internal state. Hence be sure to not reuse the same
49     // class loader/namespace names.
50     delete env->functions;
51     jni_mock.reset();
52   }
53 
CallCreateClassLoaderNamespace(const char * class_loader)54   void CallCreateClassLoaderNamespace(const char* class_loader) {
55     ON_CALL(*jni_mock, JniObject_getParent(StrEq(class_loader))).WillByDefault(Return(nullptr));
56 
57     jstring err = CreateClassLoaderNamespace(env.get(),
58                                              17,
59                                              env.get()->NewStringUTF(class_loader),
60                                              false,
61                                              env.get()->NewStringUTF("/data/app/foo/classes.dex"),
62                                              env.get()->NewStringUTF("/data/app/foo"),
63                                              /*permitted_path=*/nullptr,
64                                              /*uses_library_list=*/nullptr);
65     EXPECT_EQ(err, nullptr) << "Error is: " << std::string(ScopedUtfChars(env.get(), err).c_str());
66   }
67 
68   std::unique_ptr<JNIEnv> env;
69 };
70 
TEST_F(NativeLoaderLazyTest,CreateClassLoaderNamespace)71 TEST_F(NativeLoaderLazyTest, CreateClassLoaderNamespace) {
72   CallCreateClassLoaderNamespace("my_classloader_1");
73   EXPECT_NE(FindNamespaceByClassLoader(env.get(), env.get()->NewStringUTF("my_classloader_1")),
74             nullptr);
75 }
76 
TEST_F(NativeLoaderLazyTest,OpenNativeLibrary)77 TEST_F(NativeLoaderLazyTest, OpenNativeLibrary) {
78   bool needs_native_bridge;
79   char* errmsg = nullptr;
80   EXPECT_EQ(nullptr,
81             OpenNativeLibrary(env.get(),
82                               17,
83                               "libnotfound.so",
84                               env.get()->NewStringUTF("my_classloader"),
85                               /*caller_location=*/nullptr,
86                               /*library_path=*/nullptr,
87                               &needs_native_bridge,
88                               &errmsg));
89   EXPECT_NE(nullptr, errmsg);
90   NativeLoaderFreeErrorMessage(errmsg);
91 }
92 
TEST_F(NativeLoaderLazyTest,CloseNativeLibrary)93 TEST_F(NativeLoaderLazyTest, CloseNativeLibrary) {
94   char* errmsg = nullptr;
95   EXPECT_FALSE(CloseNativeLibrary(nullptr, false, &errmsg));
96   EXPECT_NE(nullptr, errmsg);
97   NativeLoaderFreeErrorMessage(errmsg);
98 }
99 
TEST_F(NativeLoaderLazyTest,OpenNativeLibraryInNamespace)100 TEST_F(NativeLoaderLazyTest, OpenNativeLibraryInNamespace) {
101   CallCreateClassLoaderNamespace("my_classloader_2");
102   struct NativeLoaderNamespace* ns = FindNativeLoaderNamespaceByClassLoader(
103       env.get(), env.get()->NewStringUTF("my_classloader_2"));
104   ASSERT_NE(nullptr, ns);
105 
106   bool needs_native_bridge;
107   char* errmsg = nullptr;
108   EXPECT_FALSE(OpenNativeLibraryInNamespace(ns, "libnotfound.so", &needs_native_bridge, &errmsg));
109   EXPECT_NE(nullptr, errmsg);
110   NativeLoaderFreeErrorMessage(errmsg);
111 }
112 
TEST_F(NativeLoaderLazyTest,FindNamespaceByClassLoader)113 TEST_F(NativeLoaderLazyTest, FindNamespaceByClassLoader) {
114   EXPECT_EQ(nullptr, FindNamespaceByClassLoader(env.get(), env.get()->NewStringUTF("namespace")));
115 }
116 
TEST_F(NativeLoaderLazyTest,FindNativeLoaderNamespaceByClassLoader)117 TEST_F(NativeLoaderLazyTest, FindNativeLoaderNamespaceByClassLoader) {
118   EXPECT_EQ(
119       nullptr,
120       FindNativeLoaderNamespaceByClassLoader(env.get(), env.get()->NewStringUTF("namespace")));
121 }
122 
TEST_F(NativeLoaderLazyTest,NativeLoaderFreeErrorMessage)123 TEST_F(NativeLoaderLazyTest, NativeLoaderFreeErrorMessage) {
124   NativeLoaderFreeErrorMessage(nullptr);
125 }
126 
127 }  // namespace nativeloader
128 }  // namespace android
129