blob: dad07bd98d0c4229c4d107a6284ed24225c5a7d2 [file] [log] [blame]
Calin Juravle87e2cb62017-06-13 21:48:45 -07001/*
2 * Copyright (C) 2017 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
Andreas Gampe72527382017-09-02 16:53:03 -070017#include "class_loader_context.h"
18
Calin Juravle87e2cb62017-06-13 21:48:45 -070019#include <gtest/gtest.h>
20
Andreas Gampe72527382017-09-02 16:53:03 -070021#include "android-base/strings.h"
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +000022#include "art_field-inl.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070023#include "base/dchecked_vector.h"
24#include "base/stl_util.h"
25#include "class_linker.h"
Calin Juravle821a2592017-08-11 14:33:38 -070026#include "common_runtime_test.h"
David Sehr9e734c72018-01-04 17:56:19 -080027#include "dex/dex_file.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070028#include "handle_scope-inl.h"
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +000029#include "jni/jni_internal.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070030#include "mirror/class.h"
31#include "mirror/class_loader.h"
32#include "mirror/object-inl.h"
33#include "oat_file_assistant.h"
34#include "runtime.h"
35#include "scoped_thread_state_change-inl.h"
36#include "thread.h"
37#include "well_known_classes.h"
38
39namespace art {
40
41class ClassLoaderContextTest : public CommonRuntimeTest {
42 public:
43 void VerifyContextSize(ClassLoaderContext* context, size_t expected_size) {
44 ASSERT_TRUE(context != nullptr);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000045 ASSERT_EQ(expected_size, context->GetParentChainSize());
Calin Juravle87e2cb62017-06-13 21:48:45 -070046 }
47
48 void VerifyClassLoaderPCL(ClassLoaderContext* context,
49 size_t index,
Calin Juravle57d0acc2017-07-11 17:41:30 -070050 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -070051 VerifyClassLoaderInfo(
52 context, index, ClassLoaderContext::kPathClassLoader, classpath);
53 }
54
55 void VerifyClassLoaderDLC(ClassLoaderContext* context,
56 size_t index,
Calin Juravle57d0acc2017-07-11 17:41:30 -070057 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -070058 VerifyClassLoaderInfo(
59 context, index, ClassLoaderContext::kDelegateLastClassLoader, classpath);
60 }
61
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000062 void VerifyClassLoaderSharedLibraryPCL(ClassLoaderContext* context,
63 size_t loader_index,
64 size_t shared_library_index,
65 const std::string& classpath) {
66 VerifyClassLoaderInfoSL(
67 context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
68 classpath);
69 }
70
71 void VerifySharedLibrariesSize(ClassLoaderContext* context,
72 size_t loader_index,
73 size_t expected_size) {
74 ASSERT_TRUE(context != nullptr);
75 ASSERT_GT(context->GetParentChainSize(), loader_index);
76 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
77 ASSERT_EQ(info.shared_libraries.size(), expected_size);
78 }
79
80 void VerifyClassLoaderSharedLibraryDLC(ClassLoaderContext* context,
81 size_t loader_index,
82 size_t shared_library_index,
83 const std::string& classpath) {
84 VerifyClassLoaderInfoSL(
85 context, loader_index, shared_library_index, ClassLoaderContext::kDelegateLastClassLoader,
86 classpath);
87 }
88
Calin Juravle57d0acc2017-07-11 17:41:30 -070089 void VerifyClassLoaderPCLFromTestDex(ClassLoaderContext* context,
90 size_t index,
91 const std::string& test_name) {
92 VerifyClassLoaderFromTestDex(
93 context, index, ClassLoaderContext::kPathClassLoader, test_name);
94 }
95
96 void VerifyClassLoaderDLCFromTestDex(ClassLoaderContext* context,
97 size_t index,
98 const std::string& test_name) {
99 VerifyClassLoaderFromTestDex(
100 context, index, ClassLoaderContext::kDelegateLastClassLoader, test_name);
101 }
102
Andreas Gampe72527382017-09-02 16:53:03 -0700103 enum class LocationCheck {
104 kEquals,
105 kEndsWith
106 };
107 enum class BaseLocationCheck {
108 kEquals,
109 kEndsWith
110 };
111
Calin Juravle92003fe2017-09-06 02:22:57 +0000112 static bool IsAbsoluteLocation(const std::string& location) {
113 return !location.empty() && location[0] == '/';
114 }
115
Calin Juravle87e2cb62017-06-13 21:48:45 -0700116 void VerifyOpenDexFiles(
117 ClassLoaderContext* context,
118 size_t index,
Calin Juravlec5b215f2017-09-12 14:49:37 -0700119 std::vector<std::unique_ptr<const DexFile>>* all_dex_files) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700120 ASSERT_TRUE(context != nullptr);
121 ASSERT_TRUE(context->dex_files_open_attempted_);
122 ASSERT_TRUE(context->dex_files_open_result_);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000123 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700124 ASSERT_EQ(all_dex_files->size(), info.classpath.size());
125 ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700126 size_t cur_open_dex_index = 0;
Calin Juravlec5b215f2017-09-12 14:49:37 -0700127 for (size_t k = 0; k < all_dex_files->size(); k++) {
128 std::unique_ptr<const DexFile>& opened_dex_file =
Calin Juravle87e2cb62017-06-13 21:48:45 -0700129 info.opened_dex_files[cur_open_dex_index++];
Calin Juravlec5b215f2017-09-12 14:49:37 -0700130 std::unique_ptr<const DexFile>& expected_dex_file = (*all_dex_files)[k];
Calin Juravle87e2cb62017-06-13 21:48:45 -0700131
Calin Juravle92003fe2017-09-06 02:22:57 +0000132 std::string expected_location = expected_dex_file->GetLocation();
Calin Juravle821a2592017-08-11 14:33:38 -0700133
Calin Juravle92003fe2017-09-06 02:22:57 +0000134 const std::string& opened_location = opened_dex_file->GetLocation();
135 if (!IsAbsoluteLocation(opened_location)) {
136 // If the opened location is relative (it was open from a relative path without a
137 // classpath_dir) it might not match the expected location which is absolute in tests).
138 // So we compare the endings (the checksum will validate it's actually the same file).
139 ASSERT_EQ(0, expected_location.compare(
140 expected_location.length() - opened_location.length(),
141 opened_location.length(),
142 opened_location));
143 } else {
144 ASSERT_EQ(expected_location, opened_location);
145 }
Calin Juravlec5b215f2017-09-12 14:49:37 -0700146 ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_dex_file->GetLocationChecksum());
Calin Juravle92003fe2017-09-06 02:22:57 +0000147 ASSERT_EQ(info.classpath[k], opened_location);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700148 }
149 }
150
Calin Juravle57d0acc2017-07-11 17:41:30 -0700151 std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) {
152 return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr);
153 }
154
Calin Juravle3f918642017-07-11 19:04:20 -0700155 std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) {
156 std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext());
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700157 if (!context->Parse(context_spec, /*parse_checksums=*/ true)) {
Calin Juravle3f918642017-07-11 19:04:20 -0700158 return nullptr;
159 }
160 return context;
161 }
162
Calin Juravle57d0acc2017-07-11 17:41:30 -0700163 void VerifyContextForClassLoader(ClassLoaderContext* context) {
164 ASSERT_TRUE(context != nullptr);
165 ASSERT_TRUE(context->dex_files_open_attempted_);
166 ASSERT_TRUE(context->dex_files_open_result_);
167 ASSERT_FALSE(context->owns_the_dex_files_);
168 ASSERT_FALSE(context->special_shared_library_);
169 }
170
Calin Juravlec79470d2017-07-12 17:37:42 -0700171 void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa,
172 Handle<mirror::ClassLoader> class_loader,
173 jclass type,
174 std::vector<const DexFile*>& expected_dex_files)
175 REQUIRES_SHARED(Locks::mutator_lock_) {
176 ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type));
177
178 std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa, class_loader);
179 ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());
180
181 for (size_t i = 0; i < expected_dex_files.size(); i++) {
182 ASSERT_EQ(expected_dex_files[i]->GetLocation(),
183 class_loader_dex_files[i]->GetLocation());
184 ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(),
185 class_loader_dex_files[i]->GetLocationChecksum());
186 }
187 }
188
Calin Juravlec5b215f2017-09-12 14:49:37 -0700189 void PretendContextOpenedDexFiles(ClassLoaderContext* context) {
190 context->dex_files_open_attempted_ = true;
191 context->dex_files_open_result_ = true;
192 }
193
Calin Juravle87e2cb62017-06-13 21:48:45 -0700194 private:
195 void VerifyClassLoaderInfo(ClassLoaderContext* context,
196 size_t index,
197 ClassLoaderContext::ClassLoaderType type,
Calin Juravle57d0acc2017-07-11 17:41:30 -0700198 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700199 ASSERT_TRUE(context != nullptr);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000200 ASSERT_GT(context->GetParentChainSize(), index);
201 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700202 ASSERT_EQ(type, info.type);
203 std::vector<std::string> expected_classpath;
204 Split(classpath, ':', &expected_classpath);
205 ASSERT_EQ(expected_classpath, info.classpath);
206 }
Calin Juravle57d0acc2017-07-11 17:41:30 -0700207
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000208 void VerifyClassLoaderInfoSL(ClassLoaderContext* context,
209 size_t loader_index,
210 size_t shared_library_index,
211 ClassLoaderContext::ClassLoaderType type,
212 const std::string& classpath) {
213 ASSERT_TRUE(context != nullptr);
214 ASSERT_GT(context->GetParentChainSize(), loader_index);
215 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
216 ASSERT_GT(info.shared_libraries.size(), shared_library_index);
217 const ClassLoaderContext::ClassLoaderInfo& sl =
218 *info.shared_libraries[shared_library_index].get();
219 ASSERT_EQ(type, info.type);
220 std::vector<std::string> expected_classpath;
221 Split(classpath, ':', &expected_classpath);
222 ASSERT_EQ(expected_classpath, sl.classpath);
223 }
224
Calin Juravle57d0acc2017-07-11 17:41:30 -0700225 void VerifyClassLoaderFromTestDex(ClassLoaderContext* context,
226 size_t index,
227 ClassLoaderContext::ClassLoaderType type,
228 const std::string& test_name) {
229 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str());
Calin Juravle57d0acc2017-07-11 17:41:30 -0700230
231 VerifyClassLoaderInfo(context, index, type, GetTestDexFileName(test_name.c_str()));
Calin Juravlec5b215f2017-09-12 14:49:37 -0700232 VerifyOpenDexFiles(context, index, &dex_files);
Calin Juravle57d0acc2017-07-11 17:41:30 -0700233 }
Calin Juravle87e2cb62017-06-13 21:48:45 -0700234};
235
Calin Juravle1a509c82017-07-24 16:51:21 -0700236TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) {
237 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("");
238 // An empty context should create a single empty PathClassLoader.
239 VerifyContextSize(context.get(), 1);
240 VerifyClassLoaderPCL(context.get(), 0, "");
241}
242
243TEST_F(ClassLoaderContextTest, ParseValidSharedLibraryContext) {
244 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
245 // An shared library context should have no class loader in the chain.
246 VerifyContextSize(context.get(), 0);
247}
248
Calin Juravle87e2cb62017-06-13 21:48:45 -0700249TEST_F(ClassLoaderContextTest, ParseValidContextPCL) {
250 std::unique_ptr<ClassLoaderContext> context =
251 ClassLoaderContext::Create("PCL[a.dex]");
252 VerifyContextSize(context.get(), 1);
253 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
254}
255
256TEST_F(ClassLoaderContextTest, ParseValidContextDLC) {
257 std::unique_ptr<ClassLoaderContext> context =
258 ClassLoaderContext::Create("DLC[a.dex]");
259 VerifyContextSize(context.get(), 1);
260 VerifyClassLoaderDLC(context.get(), 0, "a.dex");
261}
262
263TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
264 std::unique_ptr<ClassLoaderContext> context =
265 ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
266 VerifyContextSize(context.get(), 3);
267 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
268 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
269 VerifyClassLoaderPCL(context.get(), 2, "e.dex");
270}
271
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000272TEST_F(ClassLoaderContextTest, ParseSharedLibraries) {
273 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
274 "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]};DLC[c.dex:d.dex]{DLC[s4.dex]}");
275 VerifyContextSize(context.get(), 2);
276 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
277 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex");
278 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
279 VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex");
280}
281
282TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) {
283 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
284 "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}");
285 VerifyContextSize(context.get(), 1);
286 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
287}
288
Calin Juravle87e2cb62017-06-13 21:48:45 -0700289TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
290 std::unique_ptr<ClassLoaderContext> context =
291 ClassLoaderContext::Create("DLC[]");
292 VerifyContextSize(context.get(), 1);
293 VerifyClassLoaderDLC(context.get(), 0, "");
294}
295
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000296TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
297 std::unique_ptr<ClassLoaderContext> context =
298 ClassLoaderContext::Create("DLC[]{}");
299 VerifyContextSize(context.get(), 1);
300 VerifySharedLibrariesSize(context.get(), 0, 0);
301}
302
Calin Juravle87e2cb62017-06-13 21:48:45 -0700303TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) {
304 std::unique_ptr<ClassLoaderContext> context =
305 ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary);
306 VerifyContextSize(context.get(), 0);
307}
308
309TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
310 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
311 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
312 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
313 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
314 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
315 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000316 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
317 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
318 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
319 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
320 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700321}
322
323TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
324 std::unique_ptr<ClassLoaderContext> context =
325 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
326 VerifyContextSize(context.get(), 1);
327 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
328}
329
330TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
331 std::string multidex_name = GetTestDexFileName("MultiDex");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700332 std::string myclass_dex_name = GetTestDexFileName("MyClass");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700333 std::string dex_name = GetTestDexFileName("Main");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700334
Calin Juravle92003fe2017-09-06 02:22:57 +0000335
Calin Juravle87e2cb62017-06-13 21:48:45 -0700336 std::unique_ptr<ClassLoaderContext> context =
337 ClassLoaderContext::Create(
338 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
339 "DLC[" + dex_name + "]");
340
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700341 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700342
343 VerifyContextSize(context.get(), 2);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700344
Calin Juravlec5b215f2017-09-12 14:49:37 -0700345 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
346 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
347 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
348 all_dex_files0.emplace_back(myclass_dex_files[i].release());
349 }
350 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
351
352 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
353 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700354}
355
Alex Light77ef93b2018-01-12 11:18:31 -0800356// Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
357// TODO We should somehow support this in all situations. b/72042237.
358static bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100359 int cwd_len = strlen(cwd);
360 if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
Alex Light77ef93b2018-01-12 11:18:31 -0800361 return false;
Andreas Gampe72527382017-09-02 16:53:03 -0700362 }
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100363 bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
364 int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
Alex Light77ef93b2018-01-12 11:18:31 -0800365 *out = in.substr(start_position);
366 return true;
Andreas Gampe72527382017-09-02 16:53:03 -0700367}
368
369TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
370 char cwd_buf[4096];
371 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
372 PLOG(FATAL) << "Could not get working directory";
373 }
Alex Light77ef93b2018-01-12 11:18:31 -0800374 std::string multidex_name;
375 std::string myclass_dex_name;
376 std::string dex_name;
377 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
378 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
379 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
380 LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
381 << "relative path.";
382 SUCCEED();
383 return;
384 }
Andreas Gampe72527382017-09-02 16:53:03 -0700385
386
387 std::unique_ptr<ClassLoaderContext> context =
388 ClassLoaderContext::Create(
389 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
390 "DLC[" + dex_name + "]");
391
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700392 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Andreas Gampe72527382017-09-02 16:53:03 -0700393
Calin Juravlec5b215f2017-09-12 14:49:37 -0700394 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
395 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
396 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
397 all_dex_files0.emplace_back(myclass_dex_files[i].release());
398 }
399 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700400
Calin Juravlec5b215f2017-09-12 14:49:37 -0700401 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
402 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700403}
404
405TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
406 char cwd_buf[4096];
407 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
408 PLOG(FATAL) << "Could not get working directory";
409 }
Alex Light77ef93b2018-01-12 11:18:31 -0800410 std::string multidex_name;
411 std::string myclass_dex_name;
412 std::string dex_name;
413 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
414 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
415 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
416 LOG(ERROR) << "Test OpenValidDexFilesClasspathDir cannot be run because target dex files have "
417 << "no relative path.";
418 SUCCEED();
419 return;
420 }
Andreas Gampe72527382017-09-02 16:53:03 -0700421 std::unique_ptr<ClassLoaderContext> context =
422 ClassLoaderContext::Create(
423 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
424 "DLC[" + dex_name + "]");
425
426 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, cwd_buf));
427
428 VerifyContextSize(context.get(), 2);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700429 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
430 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
431 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
432 all_dex_files0.emplace_back(myclass_dex_files[i].release());
433 }
434 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700435
Calin Juravlec5b215f2017-09-12 14:49:37 -0700436 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
437 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700438}
439
Calin Juravle87e2cb62017-06-13 21:48:45 -0700440TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
441 std::string dex_name = GetTestDexFileName("Main");
442 std::unique_ptr<ClassLoaderContext> context =
443 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
444 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ""));
445}
446
447TEST_F(ClassLoaderContextTest, CreateClassLoader) {
448 std::string dex_name = GetTestDexFileName("Main");
449 std::unique_ptr<ClassLoaderContext> context =
450 ClassLoaderContext::Create("PCL[" + dex_name + "]");
451 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
452
453 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
454 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
455
456 std::vector<const DexFile*> compilation_sources_raw =
457 MakeNonOwningPointerVector(compilation_sources);
458 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
459 ASSERT_TRUE(jclass_loader != nullptr);
460
461 ScopedObjectAccess soa(Thread::Current());
462
Calin Juravlec79470d2017-07-12 17:37:42 -0700463 StackHandleScope<1> hs(soa.Self());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700464 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
465 soa.Decode<mirror::ClassLoader>(jclass_loader));
466
467 ASSERT_TRUE(class_loader->GetClass() ==
468 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
469 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
470 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
471
Calin Juravlec79470d2017-07-12 17:37:42 -0700472 // For the first class loader the class path dex files must come first and then the
473 // compilation sources.
474 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
475 for (auto& dex : compilation_sources_raw) {
476 expected_classpath.push_back(dex);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700477 }
478
Calin Juravlec79470d2017-07-12 17:37:42 -0700479 VerifyClassLoaderDexFiles(soa,
480 class_loader,
481 WellKnownClasses::dalvik_system_PathClassLoader,
482 expected_classpath);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700483}
484
Calin Juravle7b0648a2017-07-07 18:40:50 -0700485TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
486 std::unique_ptr<ClassLoaderContext> context =
487 ClassLoaderContext::Create("");
488 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
489
490 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
491
492 std::vector<const DexFile*> compilation_sources_raw =
493 MakeNonOwningPointerVector(compilation_sources);
494 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
495 ASSERT_TRUE(jclass_loader != nullptr);
496
497 ScopedObjectAccess soa(Thread::Current());
498
Calin Juravlec79470d2017-07-12 17:37:42 -0700499 StackHandleScope<1> hs(soa.Self());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700500 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
501 soa.Decode<mirror::ClassLoader>(jclass_loader));
502
Calin Juravlec79470d2017-07-12 17:37:42 -0700503 // An empty context should create a single PathClassLoader with only the compilation sources.
504 VerifyClassLoaderDexFiles(soa,
505 class_loader,
506 WellKnownClasses::dalvik_system_PathClassLoader,
507 compilation_sources_raw);
Calin Juravle7b0648a2017-07-07 18:40:50 -0700508 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
509 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Calin Juravle7b0648a2017-07-07 18:40:50 -0700510}
511
Calin Juravle1a509c82017-07-24 16:51:21 -0700512TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraryContext) {
513 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
514
515 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
516
517 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
518
519 std::vector<const DexFile*> compilation_sources_raw =
520 MakeNonOwningPointerVector(compilation_sources);
521 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
522 ASSERT_TRUE(jclass_loader != nullptr);
523
524 ScopedObjectAccess soa(Thread::Current());
525
526 StackHandleScope<1> hs(soa.Self());
527 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
528 soa.Decode<mirror::ClassLoader>(jclass_loader));
529
530 // A shared library context should create a single PathClassLoader with only the compilation
531 // sources.
532 VerifyClassLoaderDexFiles(soa,
533 class_loader,
534 WellKnownClasses::dalvik_system_PathClassLoader,
535 compilation_sources_raw);
536 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
537 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
538}
539
Calin Juravlec79470d2017-07-12 17:37:42 -0700540TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
541 // Setup the context.
542 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
543 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
544 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
545 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
546
547 std::string context_spec =
548 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
549 "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
550 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
551
552 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
553 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
554
555 // Setup the compilation sources.
556 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
557 std::vector<const DexFile*> compilation_sources_raw =
558 MakeNonOwningPointerVector(compilation_sources);
559
560 // Create the class loader.
561 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
562 ASSERT_TRUE(jclass_loader != nullptr);
563
564 // Verify the class loader.
565 ScopedObjectAccess soa(Thread::Current());
566
567 StackHandleScope<3> hs(soa.Self());
568 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
569 soa.Decode<mirror::ClassLoader>(jclass_loader));
570
571 // Verify the first class loader
572
573 // For the first class loader the class path dex files must come first and then the
574 // compilation sources.
575 std::vector<const DexFile*> class_loader_1_dex_files =
576 MakeNonOwningPointerVector(classpath_dex_a);
577 for (auto& dex : classpath_dex_b) {
578 class_loader_1_dex_files.push_back(dex.get());
579 }
580 for (auto& dex : compilation_sources_raw) {
581 class_loader_1_dex_files.push_back(dex);
582 }
583 VerifyClassLoaderDexFiles(soa,
584 class_loader_1,
585 WellKnownClasses::dalvik_system_PathClassLoader,
586 class_loader_1_dex_files);
587
588 // Verify the second class loader
589 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
590 std::vector<const DexFile*> class_loader_2_dex_files =
591 MakeNonOwningPointerVector(classpath_dex_c);
592 VerifyClassLoaderDexFiles(soa,
593 class_loader_2,
594 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
595 class_loader_2_dex_files);
596
597 // Verify the third class loader
598 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
599 std::vector<const DexFile*> class_loader_3_dex_files =
600 MakeNonOwningPointerVector(classpath_dex_d);
601 VerifyClassLoaderDexFiles(soa,
602 class_loader_3,
603 WellKnownClasses::dalvik_system_PathClassLoader,
604 class_loader_3_dex_files);
605 // The last class loader should have the BootClassLoader as a parent.
606 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
607 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
608}
609
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +0000610TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
611 // Setup the context.
612 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
613 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
614 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
615 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
616
617 std::string context_spec =
618 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" +
619 "DLC[" + CreateClassPath(classpath_dex_c) + "]#" +
620 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
621
622 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
623 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
624
625 // Setup the compilation sources.
626 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
627 std::vector<const DexFile*> compilation_sources_raw =
628 MakeNonOwningPointerVector(compilation_sources);
629
630 // Create the class loader.
631 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
632 ASSERT_TRUE(jclass_loader != nullptr);
633
634 // Verify the class loader.
635 ScopedObjectAccess soa(Thread::Current());
636
637 StackHandleScope<4> hs(soa.Self());
638 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
639 soa.Decode<mirror::ClassLoader>(jclass_loader));
640
641 // For the first class loader the class path dex files must come first and then the
642 // compilation sources.
643 std::vector<const DexFile*> class_loader_1_dex_files =
644 MakeNonOwningPointerVector(classpath_dex_a);
645 for (auto& dex : classpath_dex_b) {
646 class_loader_1_dex_files.push_back(dex.get());
647 }
648 for (auto& dex : compilation_sources_raw) {
649 class_loader_1_dex_files.push_back(dex);
650 }
651 VerifyClassLoaderDexFiles(soa,
652 class_loader_1,
653 WellKnownClasses::dalvik_system_PathClassLoader,
654 class_loader_1_dex_files);
655
656 // Verify the shared libraries.
657 ArtField* field =
658 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
659 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
660 ASSERT_TRUE(raw_shared_libraries != nullptr);
661
662 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
663 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
664 ASSERT_EQ(shared_libraries->GetLength(), 2);
665
666 // Verify the first shared library.
667 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
668 std::vector<const DexFile*> class_loader_2_dex_files =
669 MakeNonOwningPointerVector(classpath_dex_c);
670 VerifyClassLoaderDexFiles(soa,
671 class_loader_2,
672 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
673 class_loader_2_dex_files);
674 raw_shared_libraries = field->GetObject(class_loader_2.Get());
675 ASSERT_TRUE(raw_shared_libraries == nullptr);
676
677 // Verify the second shared library.
678 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
679 std::vector<const DexFile*> class_loader_3_dex_files =
680 MakeNonOwningPointerVector(classpath_dex_d);
681 VerifyClassLoaderDexFiles(soa,
682 class_loader_3,
683 WellKnownClasses::dalvik_system_PathClassLoader,
684 class_loader_3_dex_files);
685 raw_shared_libraries = field->GetObject(class_loader_3.Get());
686 ASSERT_TRUE(raw_shared_libraries == nullptr);
687
688 // All class loaders should have the BootClassLoader as a parent.
689 ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
690 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
691 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
692 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
693 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
694 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
695}
696
697TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
698 // Setup the context.
699 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
700 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
701 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
702 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
703
704 std::string context_spec =
705 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
706 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
707 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
708 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
709
710 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
711 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
712
713 // Setup the compilation sources.
714 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
715 std::vector<const DexFile*> compilation_sources_raw =
716 MakeNonOwningPointerVector(compilation_sources);
717
718 // Create the class loader.
719 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
720 ASSERT_TRUE(jclass_loader != nullptr);
721
722 // Verify the class loader.
723 ScopedObjectAccess soa(Thread::Current());
724
725 StackHandleScope<6> hs(soa.Self());
726 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
727 soa.Decode<mirror::ClassLoader>(jclass_loader));
728
729 // For the first class loader the class path dex files must come first and then the
730 // compilation sources.
731 std::vector<const DexFile*> class_loader_1_dex_files =
732 MakeNonOwningPointerVector(classpath_dex_a);
733 for (auto& dex : compilation_sources_raw) {
734 class_loader_1_dex_files.push_back(dex);
735 }
736 VerifyClassLoaderDexFiles(soa,
737 class_loader_1,
738 WellKnownClasses::dalvik_system_PathClassLoader,
739 class_loader_1_dex_files);
740
741 // Verify its shared library.
742 ArtField* field =
743 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
744 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
745 ASSERT_TRUE(raw_shared_libraries != nullptr);
746
747 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
748 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
749 ASSERT_EQ(shared_libraries->GetLength(), 1);
750
751 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
752 std::vector<const DexFile*> class_loader_2_dex_files =
753 MakeNonOwningPointerVector(classpath_dex_b);
754 VerifyClassLoaderDexFiles(soa,
755 class_loader_2,
756 WellKnownClasses::dalvik_system_PathClassLoader,
757 class_loader_2_dex_files);
758 raw_shared_libraries = field->GetObject(class_loader_2.Get());
759 ASSERT_TRUE(raw_shared_libraries == nullptr);
760
761 // Verify the parent.
762 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
763 std::vector<const DexFile*> class_loader_3_dex_files =
764 MakeNonOwningPointerVector(classpath_dex_c);
765 VerifyClassLoaderDexFiles(soa,
766 class_loader_3,
767 WellKnownClasses::dalvik_system_PathClassLoader,
768 class_loader_3_dex_files);
769
770 // Verify its shared library.
771 raw_shared_libraries = field->GetObject(class_loader_3.Get());
772 ASSERT_TRUE(raw_shared_libraries != nullptr);
773
774 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
775 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
776 ASSERT_EQ(shared_libraries->GetLength(), 1);
777
778 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
779 std::vector<const DexFile*> class_loader_4_dex_files =
780 MakeNonOwningPointerVector(classpath_dex_d);
781 VerifyClassLoaderDexFiles(soa,
782 class_loader_4,
783 WellKnownClasses::dalvik_system_PathClassLoader,
784 class_loader_4_dex_files);
785 raw_shared_libraries = field->GetObject(class_loader_4.Get());
786 ASSERT_TRUE(raw_shared_libraries == nullptr);
787
788 // Class loaders should have the BootClassLoader as a parent.
789 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
790 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
791 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
792 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
793 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
794 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
795}
796
797TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
798 // Setup the context.
799 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
800 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
801 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
802 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
803
804 std::string context_spec =
805 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
806 "PCL[" + CreateClassPath(classpath_dex_b) + "]{" +
807 "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" +
808 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
809
810 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
811 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
812
813 // Setup the compilation sources.
814 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
815 std::vector<const DexFile*> compilation_sources_raw =
816 MakeNonOwningPointerVector(compilation_sources);
817
818 // Create the class loader.
819 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
820 ASSERT_TRUE(jclass_loader != nullptr);
821
822 // Verify the class loader.
823 ScopedObjectAccess soa(Thread::Current());
824
825 StackHandleScope<6> hs(soa.Self());
826 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
827 soa.Decode<mirror::ClassLoader>(jclass_loader));
828
829 // For the first class loader the class path dex files must come first and then the
830 // compilation sources.
831 std::vector<const DexFile*> class_loader_1_dex_files =
832 MakeNonOwningPointerVector(classpath_dex_a);
833 for (auto& dex : compilation_sources_raw) {
834 class_loader_1_dex_files.push_back(dex);
835 }
836 VerifyClassLoaderDexFiles(soa,
837 class_loader_1,
838 WellKnownClasses::dalvik_system_PathClassLoader,
839 class_loader_1_dex_files);
840
841 // Verify its shared library.
842 ArtField* field =
843 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
844 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
845 ASSERT_TRUE(raw_shared_libraries != nullptr);
846
847 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
848 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
849 ASSERT_EQ(shared_libraries->GetLength(), 1);
850
851 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
852 std::vector<const DexFile*> class_loader_2_dex_files =
853 MakeNonOwningPointerVector(classpath_dex_b);
854 VerifyClassLoaderDexFiles(soa,
855 class_loader_2,
856 WellKnownClasses::dalvik_system_PathClassLoader,
857 class_loader_2_dex_files);
858
859 // Verify the shared library dependency of the shared library.
860 raw_shared_libraries = field->GetObject(class_loader_2.Get());
861 ASSERT_TRUE(raw_shared_libraries != nullptr);
862
863 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
864 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
865 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
866
867 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
868 std::vector<const DexFile*> class_loader_3_dex_files =
869 MakeNonOwningPointerVector(classpath_dex_c);
870 VerifyClassLoaderDexFiles(soa,
871 class_loader_3,
872 WellKnownClasses::dalvik_system_PathClassLoader,
873 class_loader_3_dex_files);
874 raw_shared_libraries = field->GetObject(class_loader_3.Get());
875 ASSERT_TRUE(raw_shared_libraries == nullptr);
876
877 // Verify the parent.
878 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
879 std::vector<const DexFile*> class_loader_4_dex_files =
880 MakeNonOwningPointerVector(classpath_dex_d);
881 VerifyClassLoaderDexFiles(soa,
882 class_loader_4,
883 WellKnownClasses::dalvik_system_PathClassLoader,
884 class_loader_4_dex_files);
885 raw_shared_libraries = field->GetObject(class_loader_4.Get());
886 ASSERT_TRUE(raw_shared_libraries == nullptr);
887
888 // Class loaders should have the BootClassLoader as a parent.
889 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
890 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
891 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
892 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
893 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
894 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
895}
Calin Juravlec79470d2017-07-12 17:37:42 -0700896
Calin Juravle87e2cb62017-06-13 21:48:45 -0700897TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
898 std::unique_ptr<ClassLoaderContext> context =
899 ClassLoaderContext::Create("PCL[a.dex]");
900 dchecked_vector<std::string> classpath_dex;
901 classpath_dex.push_back("a.dex");
902 dchecked_vector<std::string> compilation_sources;
903 compilation_sources.push_back("src.dex");
904
905 // Nothing should be removed.
906 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
907 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
908 // Classes should be removed.
909 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
910 VerifyClassLoaderPCL(context.get(), 0, "");
911}
912
913TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
914 std::string dex1_name = GetTestDexFileName("Main");
915 std::string dex2_name = GetTestDexFileName("MyClass");
916 std::unique_ptr<ClassLoaderContext> context =
917 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
918 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
919
920 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
921 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
922 std::string encoding = context->EncodeContextForOatFile("");
Calin Juravlec79470d2017-07-12 17:37:42 -0700923 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
924 CreateClassPathWithChecksums(dex2) + "]";
Calin Juravle87e2cb62017-06-13 21:48:45 -0700925 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
926}
927
Calin Juravle27e0d1f2017-07-26 00:16:07 -0700928TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
929 std::string dex1_name = GetTestDexFileName("Main");
930 std::string dex2_name = GetTestDexFileName("MultiDex");
931 std::unique_ptr<ClassLoaderContext> context =
932 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
933 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
934
935 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
936 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MultiDex");
937 std::string encoding = context->EncodeContextForDex2oat("");
938 std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
939 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
940}
941
Calin Juravle57d0acc2017-07-11 17:41:30 -0700942// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
943TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
944 // The chain is
945 // ClassLoaderA (PathClassLoader)
946 // ^
947 // |
948 // ClassLoaderB (DelegateLastClassLoader)
949 // ^
950 // |
951 // ClassLoaderC (PathClassLoader)
952 // ^
953 // |
954 // ClassLoaderD (DelegateLastClassLoader)
955
956 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
957 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
958 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
959 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
960
961 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
962
963 VerifyContextForClassLoader(context.get());
964 VerifyContextSize(context.get(), 4);
965
966 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
967 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
968 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
969 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
970}
971
Mathieu Chartieradc90862018-05-11 13:03:06 -0700972
973TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) {
974 std::string context_spec = "PCL[]";
975 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
976 ASSERT_TRUE(context != nullptr);
977 PretendContextOpenedDexFiles(context.get());
978 // Ensure that the special shared library marks as verified for the first thing in the class path.
979 ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary),
980 ClassLoaderContext::VerificationResult::kVerifies);
981}
982
Calin Juravle3f918642017-07-11 19:04:20 -0700983TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
984 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
985 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700986 // Pretend that we successfully open the dex files to pass the DCHECKS.
987 // (as it's much easier to test all the corner cases without relying on actual dex files).
988 PretendContextOpenedDexFiles(context.get());
Calin Juravle3f918642017-07-11 19:04:20 -0700989
990 VerifyContextSize(context.get(), 2);
991 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
992 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
993
Mathieu Chartieradc90862018-05-11 13:03:06 -0700994 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
995 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -0700996
997 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700998 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
999 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001000
1001 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001002 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1003 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001004
1005 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001006 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1007 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001008
1009 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001010 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1011 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001012
1013 std::string wrong_extra_class_loader = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];PCL[d.dex*321]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001014 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1015 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001016
1017 std::string wrong_extra_classpath = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890:d.dex*321]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001018 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1019 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001020
1021 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001022 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
1023 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001024}
1025
Nicolas Geoffray9893c472018-11-13 15:39:53 +00001026TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) {
1027 std::string context_spec = "&";
1028 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1029 // Pretend that we successfully open the dex files to pass the DCHECKS.
1030 // (as it's much easier to test all the corner cases without relying on actual dex files).
1031 PretendContextOpenedDexFiles(context.get());
1032
1033 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1034 ClassLoaderContext::VerificationResult::kForcedToSkipChecks);
1035}
1036
Nicolas Geoffray06af3b42018-10-29 10:39:04 +00001037TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
1038 std::string context_spec =
1039 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1040 ";DLC[c.dex*890]";
1041 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1042 // Pretend that we successfully open the dex files to pass the DCHECKS.
1043 // (as it's much easier to test all the corner cases without relying on actual dex files).
1044 PretendContextOpenedDexFiles(context.get());
1045
1046 VerifyContextSize(context.get(), 2);
1047 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1048 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1049 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
1050 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
1051
1052 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1053 ClassLoaderContext::VerificationResult::kVerifies);
1054
1055 std::string wrong_class_loader_type =
1056 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1057 ";DLC[c.dex*890]";
1058 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1059 ClassLoaderContext::VerificationResult::kMismatch);
1060
1061 std::string wrong_class_loader_order =
1062 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
1063 ";DLC[c.dex*890]";
1064 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1065 ClassLoaderContext::VerificationResult::kMismatch);
1066
1067 std::string wrong_classpath_order =
1068 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1069 ";DLC[c.dex*890]";
1070 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1071 ClassLoaderContext::VerificationResult::kMismatch);
1072
1073 std::string wrong_checksum =
1074 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1075 ";DLC[c.dex*890]";
1076 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1077 ClassLoaderContext::VerificationResult::kMismatch);
1078
1079 std::string wrong_extra_class_loader =
1080 "PCL[a.dex*123:b.dex*456]"
1081 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
1082 ";DLC[c.dex*890]";
1083 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1084 ClassLoaderContext::VerificationResult::kMismatch);
1085
1086 std::string wrong_extra_classpath =
1087 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321:i.dex#444];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1088 ";DLC[c.dex*890]";
1089 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1090 ClassLoaderContext::VerificationResult::kMismatch);
1091}
1092
Calin Juravle3f918642017-07-11 19:04:20 -07001093TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
1094 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1095 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1096 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1097 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1098
1099 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1100
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001101 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
Mathieu Chartieradc90862018-05-11 13:03:06 -07001102 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1103 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001104
1105 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1106 size_t pos = dex_location.rfind('/');
1107 ASSERT_NE(std::string::npos, pos);
1108 std::string parent = dex_location.substr(0, pos);
1109
1110 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1111 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
Mathieu Chartieradc90862018-05-11 13:03:06 -07001112 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1113 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001114}
1115
Calin Juravlea308a322017-07-18 16:51:51 -07001116TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
1117 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1118
1119 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1120
Mathieu Chartieradc90862018-05-11 13:03:06 -07001121 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1122 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravlea308a322017-07-18 16:51:51 -07001123}
1124
Calin Juravle87e2cb62017-06-13 21:48:45 -07001125} // namespace art