blob: 3c5f1ef95de031ba7c29e52f7633dccc5f33e2b0 [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"
Nicolas Geoffraye1672732018-11-30 01:09:49 +000026#include "class_root.h"
Calin Juravle821a2592017-08-11 14:33:38 -070027#include "common_runtime_test.h"
David Sehr9e734c72018-01-04 17:56:19 -080028#include "dex/dex_file.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070029#include "handle_scope-inl.h"
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +000030#include "jni/jni_internal.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070031#include "mirror/class.h"
32#include "mirror/class_loader.h"
33#include "mirror/object-inl.h"
Nicolas Geoffraye1672732018-11-30 01:09:49 +000034#include "mirror/object_array-alloc-inl.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070035#include "oat_file_assistant.h"
36#include "runtime.h"
37#include "scoped_thread_state_change-inl.h"
38#include "thread.h"
39#include "well_known_classes.h"
40
41namespace art {
42
43class ClassLoaderContextTest : public CommonRuntimeTest {
44 public:
45 void VerifyContextSize(ClassLoaderContext* context, size_t expected_size) {
46 ASSERT_TRUE(context != nullptr);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000047 ASSERT_EQ(expected_size, context->GetParentChainSize());
Calin Juravle87e2cb62017-06-13 21:48:45 -070048 }
49
50 void VerifyClassLoaderPCL(ClassLoaderContext* context,
51 size_t index,
Calin Juravle57d0acc2017-07-11 17:41:30 -070052 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -070053 VerifyClassLoaderInfo(
54 context, index, ClassLoaderContext::kPathClassLoader, classpath);
55 }
56
57 void VerifyClassLoaderDLC(ClassLoaderContext* context,
58 size_t index,
Calin Juravle57d0acc2017-07-11 17:41:30 -070059 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -070060 VerifyClassLoaderInfo(
61 context, index, ClassLoaderContext::kDelegateLastClassLoader, classpath);
62 }
63
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000064 void VerifyClassLoaderSharedLibraryPCL(ClassLoaderContext* context,
65 size_t loader_index,
66 size_t shared_library_index,
67 const std::string& classpath) {
68 VerifyClassLoaderInfoSL(
69 context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
70 classpath);
71 }
72
73 void VerifySharedLibrariesSize(ClassLoaderContext* context,
74 size_t loader_index,
75 size_t expected_size) {
76 ASSERT_TRUE(context != nullptr);
77 ASSERT_GT(context->GetParentChainSize(), loader_index);
78 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
79 ASSERT_EQ(info.shared_libraries.size(), expected_size);
80 }
81
82 void VerifyClassLoaderSharedLibraryDLC(ClassLoaderContext* context,
83 size_t loader_index,
84 size_t shared_library_index,
85 const std::string& classpath) {
86 VerifyClassLoaderInfoSL(
87 context, loader_index, shared_library_index, ClassLoaderContext::kDelegateLastClassLoader,
88 classpath);
89 }
90
Calin Juravle57d0acc2017-07-11 17:41:30 -070091 void VerifyClassLoaderPCLFromTestDex(ClassLoaderContext* context,
92 size_t index,
93 const std::string& test_name) {
94 VerifyClassLoaderFromTestDex(
95 context, index, ClassLoaderContext::kPathClassLoader, test_name);
96 }
97
98 void VerifyClassLoaderDLCFromTestDex(ClassLoaderContext* context,
99 size_t index,
100 const std::string& test_name) {
101 VerifyClassLoaderFromTestDex(
102 context, index, ClassLoaderContext::kDelegateLastClassLoader, test_name);
103 }
104
Andreas Gampe72527382017-09-02 16:53:03 -0700105 enum class LocationCheck {
106 kEquals,
107 kEndsWith
108 };
109 enum class BaseLocationCheck {
110 kEquals,
111 kEndsWith
112 };
113
Calin Juravle92003fe2017-09-06 02:22:57 +0000114 static bool IsAbsoluteLocation(const std::string& location) {
115 return !location.empty() && location[0] == '/';
116 }
117
Calin Juravle87e2cb62017-06-13 21:48:45 -0700118 void VerifyOpenDexFiles(
119 ClassLoaderContext* context,
120 size_t index,
Calin Juravlec5b215f2017-09-12 14:49:37 -0700121 std::vector<std::unique_ptr<const DexFile>>* all_dex_files) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700122 ASSERT_TRUE(context != nullptr);
123 ASSERT_TRUE(context->dex_files_open_attempted_);
124 ASSERT_TRUE(context->dex_files_open_result_);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000125 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700126 ASSERT_EQ(all_dex_files->size(), info.classpath.size());
127 ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700128 size_t cur_open_dex_index = 0;
Calin Juravlec5b215f2017-09-12 14:49:37 -0700129 for (size_t k = 0; k < all_dex_files->size(); k++) {
130 std::unique_ptr<const DexFile>& opened_dex_file =
Calin Juravle87e2cb62017-06-13 21:48:45 -0700131 info.opened_dex_files[cur_open_dex_index++];
Calin Juravlec5b215f2017-09-12 14:49:37 -0700132 std::unique_ptr<const DexFile>& expected_dex_file = (*all_dex_files)[k];
Calin Juravle87e2cb62017-06-13 21:48:45 -0700133
Calin Juravle92003fe2017-09-06 02:22:57 +0000134 std::string expected_location = expected_dex_file->GetLocation();
Calin Juravle821a2592017-08-11 14:33:38 -0700135
Calin Juravle92003fe2017-09-06 02:22:57 +0000136 const std::string& opened_location = opened_dex_file->GetLocation();
137 if (!IsAbsoluteLocation(opened_location)) {
138 // If the opened location is relative (it was open from a relative path without a
139 // classpath_dir) it might not match the expected location which is absolute in tests).
140 // So we compare the endings (the checksum will validate it's actually the same file).
141 ASSERT_EQ(0, expected_location.compare(
142 expected_location.length() - opened_location.length(),
143 opened_location.length(),
144 opened_location));
145 } else {
146 ASSERT_EQ(expected_location, opened_location);
147 }
Calin Juravlec5b215f2017-09-12 14:49:37 -0700148 ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_dex_file->GetLocationChecksum());
Calin Juravle92003fe2017-09-06 02:22:57 +0000149 ASSERT_EQ(info.classpath[k], opened_location);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700150 }
151 }
152
Calin Juravle57d0acc2017-07-11 17:41:30 -0700153 std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) {
154 return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr);
155 }
156
Calin Juravle3f918642017-07-11 19:04:20 -0700157 std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) {
158 std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext());
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700159 if (!context->Parse(context_spec, /*parse_checksums=*/ true)) {
Calin Juravle3f918642017-07-11 19:04:20 -0700160 return nullptr;
161 }
162 return context;
163 }
164
Calin Juravle57d0acc2017-07-11 17:41:30 -0700165 void VerifyContextForClassLoader(ClassLoaderContext* context) {
166 ASSERT_TRUE(context != nullptr);
167 ASSERT_TRUE(context->dex_files_open_attempted_);
168 ASSERT_TRUE(context->dex_files_open_result_);
169 ASSERT_FALSE(context->owns_the_dex_files_);
170 ASSERT_FALSE(context->special_shared_library_);
171 }
172
Calin Juravlec79470d2017-07-12 17:37:42 -0700173 void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa,
174 Handle<mirror::ClassLoader> class_loader,
175 jclass type,
176 std::vector<const DexFile*>& expected_dex_files)
177 REQUIRES_SHARED(Locks::mutator_lock_) {
178 ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type));
179
180 std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa, class_loader);
181 ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());
182
183 for (size_t i = 0; i < expected_dex_files.size(); i++) {
184 ASSERT_EQ(expected_dex_files[i]->GetLocation(),
185 class_loader_dex_files[i]->GetLocation());
186 ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(),
187 class_loader_dex_files[i]->GetLocationChecksum());
188 }
189 }
190
Calin Juravlec5b215f2017-09-12 14:49:37 -0700191 void PretendContextOpenedDexFiles(ClassLoaderContext* context) {
192 context->dex_files_open_attempted_ = true;
193 context->dex_files_open_result_ = true;
194 }
195
Calin Juravle87e2cb62017-06-13 21:48:45 -0700196 private:
197 void VerifyClassLoaderInfo(ClassLoaderContext* context,
198 size_t index,
199 ClassLoaderContext::ClassLoaderType type,
Calin Juravle57d0acc2017-07-11 17:41:30 -0700200 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700201 ASSERT_TRUE(context != nullptr);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000202 ASSERT_GT(context->GetParentChainSize(), index);
203 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700204 ASSERT_EQ(type, info.type);
205 std::vector<std::string> expected_classpath;
206 Split(classpath, ':', &expected_classpath);
207 ASSERT_EQ(expected_classpath, info.classpath);
208 }
Calin Juravle57d0acc2017-07-11 17:41:30 -0700209
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000210 void VerifyClassLoaderInfoSL(ClassLoaderContext* context,
211 size_t loader_index,
212 size_t shared_library_index,
213 ClassLoaderContext::ClassLoaderType type,
214 const std::string& classpath) {
215 ASSERT_TRUE(context != nullptr);
216 ASSERT_GT(context->GetParentChainSize(), loader_index);
217 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
218 ASSERT_GT(info.shared_libraries.size(), shared_library_index);
219 const ClassLoaderContext::ClassLoaderInfo& sl =
220 *info.shared_libraries[shared_library_index].get();
221 ASSERT_EQ(type, info.type);
222 std::vector<std::string> expected_classpath;
223 Split(classpath, ':', &expected_classpath);
224 ASSERT_EQ(expected_classpath, sl.classpath);
225 }
226
Calin Juravle57d0acc2017-07-11 17:41:30 -0700227 void VerifyClassLoaderFromTestDex(ClassLoaderContext* context,
228 size_t index,
229 ClassLoaderContext::ClassLoaderType type,
230 const std::string& test_name) {
231 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str());
Calin Juravle57d0acc2017-07-11 17:41:30 -0700232
233 VerifyClassLoaderInfo(context, index, type, GetTestDexFileName(test_name.c_str()));
Calin Juravlec5b215f2017-09-12 14:49:37 -0700234 VerifyOpenDexFiles(context, index, &dex_files);
Calin Juravle57d0acc2017-07-11 17:41:30 -0700235 }
Calin Juravle87e2cb62017-06-13 21:48:45 -0700236};
237
Calin Juravle1a509c82017-07-24 16:51:21 -0700238TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) {
239 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("");
240 // An empty context should create a single empty PathClassLoader.
241 VerifyContextSize(context.get(), 1);
242 VerifyClassLoaderPCL(context.get(), 0, "");
243}
244
245TEST_F(ClassLoaderContextTest, ParseValidSharedLibraryContext) {
246 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
247 // An shared library context should have no class loader in the chain.
248 VerifyContextSize(context.get(), 0);
249}
250
Calin Juravle87e2cb62017-06-13 21:48:45 -0700251TEST_F(ClassLoaderContextTest, ParseValidContextPCL) {
252 std::unique_ptr<ClassLoaderContext> context =
253 ClassLoaderContext::Create("PCL[a.dex]");
254 VerifyContextSize(context.get(), 1);
255 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
256}
257
258TEST_F(ClassLoaderContextTest, ParseValidContextDLC) {
259 std::unique_ptr<ClassLoaderContext> context =
260 ClassLoaderContext::Create("DLC[a.dex]");
261 VerifyContextSize(context.get(), 1);
262 VerifyClassLoaderDLC(context.get(), 0, "a.dex");
263}
264
265TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
266 std::unique_ptr<ClassLoaderContext> context =
267 ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
268 VerifyContextSize(context.get(), 3);
269 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
270 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
271 VerifyClassLoaderPCL(context.get(), 2, "e.dex");
272}
273
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000274TEST_F(ClassLoaderContextTest, ParseSharedLibraries) {
275 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
276 "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]};DLC[c.dex:d.dex]{DLC[s4.dex]}");
277 VerifyContextSize(context.get(), 2);
278 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
279 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex");
280 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
281 VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex");
282}
283
284TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) {
285 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
286 "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}");
287 VerifyContextSize(context.get(), 1);
288 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
289}
290
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000291TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) {
292 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
293 "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}");
294 VerifyContextSize(context.get(), 1);
295 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex");
296}
297
298TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) {
299 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
300 "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#"
301 "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}");
302 VerifyContextSize(context.get(), 1);
303 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
304 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex");
305 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex");
306 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex");
307 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex");
308}
309
Calin Juravle87e2cb62017-06-13 21:48:45 -0700310TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
311 std::unique_ptr<ClassLoaderContext> context =
312 ClassLoaderContext::Create("DLC[]");
313 VerifyContextSize(context.get(), 1);
314 VerifyClassLoaderDLC(context.get(), 0, "");
315}
316
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000317TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
318 std::unique_ptr<ClassLoaderContext> context =
319 ClassLoaderContext::Create("DLC[]{}");
320 VerifyContextSize(context.get(), 1);
321 VerifySharedLibrariesSize(context.get(), 0, 0);
322}
323
Calin Juravle87e2cb62017-06-13 21:48:45 -0700324TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) {
325 std::unique_ptr<ClassLoaderContext> context =
326 ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary);
327 VerifyContextSize(context.get(), 0);
328}
329
330TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
331 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
332 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
333 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
334 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
335 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
336 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000337 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
338 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
339 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
340 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
341 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000342 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}"));
343 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}"));
344 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}"));
345 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}"));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700346}
347
348TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
349 std::unique_ptr<ClassLoaderContext> context =
350 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
351 VerifyContextSize(context.get(), 1);
352 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
353}
354
355TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
356 std::string multidex_name = GetTestDexFileName("MultiDex");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700357 std::string myclass_dex_name = GetTestDexFileName("MyClass");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700358 std::string dex_name = GetTestDexFileName("Main");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700359
Calin Juravle92003fe2017-09-06 02:22:57 +0000360
Calin Juravle87e2cb62017-06-13 21:48:45 -0700361 std::unique_ptr<ClassLoaderContext> context =
362 ClassLoaderContext::Create(
363 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
364 "DLC[" + dex_name + "]");
365
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700366 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700367
368 VerifyContextSize(context.get(), 2);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700369
Calin Juravlec5b215f2017-09-12 14:49:37 -0700370 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
371 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
372 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
373 all_dex_files0.emplace_back(myclass_dex_files[i].release());
374 }
375 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
376
377 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
378 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700379}
380
Alex Light77ef93b2018-01-12 11:18:31 -0800381// Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
382// TODO We should somehow support this in all situations. b/72042237.
383static bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100384 int cwd_len = strlen(cwd);
385 if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
Alex Light77ef93b2018-01-12 11:18:31 -0800386 return false;
Andreas Gampe72527382017-09-02 16:53:03 -0700387 }
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100388 bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
389 int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
Alex Light77ef93b2018-01-12 11:18:31 -0800390 *out = in.substr(start_position);
391 return true;
Andreas Gampe72527382017-09-02 16:53:03 -0700392}
393
394TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
395 char cwd_buf[4096];
396 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
397 PLOG(FATAL) << "Could not get working directory";
398 }
Alex Light77ef93b2018-01-12 11:18:31 -0800399 std::string multidex_name;
400 std::string myclass_dex_name;
401 std::string dex_name;
402 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
403 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
404 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
405 LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
406 << "relative path.";
407 SUCCEED();
408 return;
409 }
Andreas Gampe72527382017-09-02 16:53:03 -0700410
411
412 std::unique_ptr<ClassLoaderContext> context =
413 ClassLoaderContext::Create(
414 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
415 "DLC[" + dex_name + "]");
416
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700417 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Andreas Gampe72527382017-09-02 16:53:03 -0700418
Calin Juravlec5b215f2017-09-12 14:49:37 -0700419 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
420 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
421 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
422 all_dex_files0.emplace_back(myclass_dex_files[i].release());
423 }
424 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700425
Calin Juravlec5b215f2017-09-12 14:49:37 -0700426 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
427 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700428}
429
430TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
431 char cwd_buf[4096];
432 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
433 PLOG(FATAL) << "Could not get working directory";
434 }
Alex Light77ef93b2018-01-12 11:18:31 -0800435 std::string multidex_name;
436 std::string myclass_dex_name;
437 std::string dex_name;
438 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
439 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
440 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
441 LOG(ERROR) << "Test OpenValidDexFilesClasspathDir cannot be run because target dex files have "
442 << "no relative path.";
443 SUCCEED();
444 return;
445 }
Andreas Gampe72527382017-09-02 16:53:03 -0700446 std::unique_ptr<ClassLoaderContext> context =
447 ClassLoaderContext::Create(
448 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
449 "DLC[" + dex_name + "]");
450
451 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, cwd_buf));
452
453 VerifyContextSize(context.get(), 2);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700454 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
455 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
456 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
457 all_dex_files0.emplace_back(myclass_dex_files[i].release());
458 }
459 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700460
Calin Juravlec5b215f2017-09-12 14:49:37 -0700461 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
462 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700463}
464
Calin Juravle87e2cb62017-06-13 21:48:45 -0700465TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
466 std::string dex_name = GetTestDexFileName("Main");
467 std::unique_ptr<ClassLoaderContext> context =
468 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
469 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ""));
470}
471
472TEST_F(ClassLoaderContextTest, CreateClassLoader) {
473 std::string dex_name = GetTestDexFileName("Main");
474 std::unique_ptr<ClassLoaderContext> context =
475 ClassLoaderContext::Create("PCL[" + dex_name + "]");
476 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
477
478 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
479 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
480
481 std::vector<const DexFile*> compilation_sources_raw =
482 MakeNonOwningPointerVector(compilation_sources);
483 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
484 ASSERT_TRUE(jclass_loader != nullptr);
485
486 ScopedObjectAccess soa(Thread::Current());
487
Calin Juravlec79470d2017-07-12 17:37:42 -0700488 StackHandleScope<1> hs(soa.Self());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700489 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
490 soa.Decode<mirror::ClassLoader>(jclass_loader));
491
492 ASSERT_TRUE(class_loader->GetClass() ==
493 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
494 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
495 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
496
Calin Juravlec79470d2017-07-12 17:37:42 -0700497 // For the first class loader the class path dex files must come first and then the
498 // compilation sources.
499 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
500 for (auto& dex : compilation_sources_raw) {
501 expected_classpath.push_back(dex);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700502 }
503
Calin Juravlec79470d2017-07-12 17:37:42 -0700504 VerifyClassLoaderDexFiles(soa,
505 class_loader,
506 WellKnownClasses::dalvik_system_PathClassLoader,
507 expected_classpath);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700508}
509
Calin Juravle7b0648a2017-07-07 18:40:50 -0700510TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
511 std::unique_ptr<ClassLoaderContext> context =
512 ClassLoaderContext::Create("");
513 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
514
515 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
516
517 std::vector<const DexFile*> compilation_sources_raw =
518 MakeNonOwningPointerVector(compilation_sources);
519 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
520 ASSERT_TRUE(jclass_loader != nullptr);
521
522 ScopedObjectAccess soa(Thread::Current());
523
Calin Juravlec79470d2017-07-12 17:37:42 -0700524 StackHandleScope<1> hs(soa.Self());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700525 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
526 soa.Decode<mirror::ClassLoader>(jclass_loader));
527
Calin Juravlec79470d2017-07-12 17:37:42 -0700528 // An empty context should create a single PathClassLoader with only the compilation sources.
529 VerifyClassLoaderDexFiles(soa,
530 class_loader,
531 WellKnownClasses::dalvik_system_PathClassLoader,
532 compilation_sources_raw);
Calin Juravle7b0648a2017-07-07 18:40:50 -0700533 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
534 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Calin Juravle7b0648a2017-07-07 18:40:50 -0700535}
536
Calin Juravle1a509c82017-07-24 16:51:21 -0700537TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraryContext) {
538 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
539
540 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
541
542 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
543
544 std::vector<const DexFile*> compilation_sources_raw =
545 MakeNonOwningPointerVector(compilation_sources);
546 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
547 ASSERT_TRUE(jclass_loader != nullptr);
548
549 ScopedObjectAccess soa(Thread::Current());
550
551 StackHandleScope<1> hs(soa.Self());
552 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
553 soa.Decode<mirror::ClassLoader>(jclass_loader));
554
555 // A shared library context should create a single PathClassLoader with only the compilation
556 // sources.
557 VerifyClassLoaderDexFiles(soa,
558 class_loader,
559 WellKnownClasses::dalvik_system_PathClassLoader,
560 compilation_sources_raw);
561 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
562 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
563}
564
Calin Juravlec79470d2017-07-12 17:37:42 -0700565TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
566 // Setup the context.
567 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
568 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
569 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
570 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
571
572 std::string context_spec =
573 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
574 "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
575 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
576
577 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
578 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
579
580 // Setup the compilation sources.
581 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
582 std::vector<const DexFile*> compilation_sources_raw =
583 MakeNonOwningPointerVector(compilation_sources);
584
585 // Create the class loader.
586 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
587 ASSERT_TRUE(jclass_loader != nullptr);
588
589 // Verify the class loader.
590 ScopedObjectAccess soa(Thread::Current());
591
592 StackHandleScope<3> hs(soa.Self());
593 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
594 soa.Decode<mirror::ClassLoader>(jclass_loader));
595
596 // Verify the first class loader
597
598 // For the first class loader the class path dex files must come first and then the
599 // compilation sources.
600 std::vector<const DexFile*> class_loader_1_dex_files =
601 MakeNonOwningPointerVector(classpath_dex_a);
602 for (auto& dex : classpath_dex_b) {
603 class_loader_1_dex_files.push_back(dex.get());
604 }
605 for (auto& dex : compilation_sources_raw) {
606 class_loader_1_dex_files.push_back(dex);
607 }
608 VerifyClassLoaderDexFiles(soa,
609 class_loader_1,
610 WellKnownClasses::dalvik_system_PathClassLoader,
611 class_loader_1_dex_files);
612
613 // Verify the second class loader
614 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
615 std::vector<const DexFile*> class_loader_2_dex_files =
616 MakeNonOwningPointerVector(classpath_dex_c);
617 VerifyClassLoaderDexFiles(soa,
618 class_loader_2,
619 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
620 class_loader_2_dex_files);
621
622 // Verify the third class loader
623 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
624 std::vector<const DexFile*> class_loader_3_dex_files =
625 MakeNonOwningPointerVector(classpath_dex_d);
626 VerifyClassLoaderDexFiles(soa,
627 class_loader_3,
628 WellKnownClasses::dalvik_system_PathClassLoader,
629 class_loader_3_dex_files);
630 // The last class loader should have the BootClassLoader as a parent.
631 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
632 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
633}
634
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +0000635TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
636 // Setup the context.
637 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
638 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
639 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
640 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
641
642 std::string context_spec =
643 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" +
644 "DLC[" + CreateClassPath(classpath_dex_c) + "]#" +
645 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
646
647 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
648 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
649
650 // Setup the compilation sources.
651 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
652 std::vector<const DexFile*> compilation_sources_raw =
653 MakeNonOwningPointerVector(compilation_sources);
654
655 // Create the class loader.
656 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
657 ASSERT_TRUE(jclass_loader != nullptr);
658
659 // Verify the class loader.
660 ScopedObjectAccess soa(Thread::Current());
661
662 StackHandleScope<4> hs(soa.Self());
663 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
664 soa.Decode<mirror::ClassLoader>(jclass_loader));
665
666 // For the first class loader the class path dex files must come first and then the
667 // compilation sources.
668 std::vector<const DexFile*> class_loader_1_dex_files =
669 MakeNonOwningPointerVector(classpath_dex_a);
670 for (auto& dex : classpath_dex_b) {
671 class_loader_1_dex_files.push_back(dex.get());
672 }
673 for (auto& dex : compilation_sources_raw) {
674 class_loader_1_dex_files.push_back(dex);
675 }
676 VerifyClassLoaderDexFiles(soa,
677 class_loader_1,
678 WellKnownClasses::dalvik_system_PathClassLoader,
679 class_loader_1_dex_files);
680
681 // Verify the shared libraries.
682 ArtField* field =
683 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
684 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
685 ASSERT_TRUE(raw_shared_libraries != nullptr);
686
687 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
688 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
689 ASSERT_EQ(shared_libraries->GetLength(), 2);
690
691 // Verify the first shared library.
692 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
693 std::vector<const DexFile*> class_loader_2_dex_files =
694 MakeNonOwningPointerVector(classpath_dex_c);
695 VerifyClassLoaderDexFiles(soa,
696 class_loader_2,
697 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
698 class_loader_2_dex_files);
699 raw_shared_libraries = field->GetObject(class_loader_2.Get());
700 ASSERT_TRUE(raw_shared_libraries == nullptr);
701
702 // Verify the second shared library.
703 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
704 std::vector<const DexFile*> class_loader_3_dex_files =
705 MakeNonOwningPointerVector(classpath_dex_d);
706 VerifyClassLoaderDexFiles(soa,
707 class_loader_3,
708 WellKnownClasses::dalvik_system_PathClassLoader,
709 class_loader_3_dex_files);
710 raw_shared_libraries = field->GetObject(class_loader_3.Get());
711 ASSERT_TRUE(raw_shared_libraries == nullptr);
712
713 // All class loaders should have the BootClassLoader as a parent.
714 ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
715 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
716 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
717 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
718 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
719 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
720}
721
722TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
723 // Setup the context.
724 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
725 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
726 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
727 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
728
729 std::string context_spec =
730 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
731 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
732 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
733 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
734
735 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
736 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
737
738 // Setup the compilation sources.
739 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
740 std::vector<const DexFile*> compilation_sources_raw =
741 MakeNonOwningPointerVector(compilation_sources);
742
743 // Create the class loader.
744 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
745 ASSERT_TRUE(jclass_loader != nullptr);
746
747 // Verify the class loader.
748 ScopedObjectAccess soa(Thread::Current());
749
750 StackHandleScope<6> hs(soa.Self());
751 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
752 soa.Decode<mirror::ClassLoader>(jclass_loader));
753
754 // For the first class loader the class path dex files must come first and then the
755 // compilation sources.
756 std::vector<const DexFile*> class_loader_1_dex_files =
757 MakeNonOwningPointerVector(classpath_dex_a);
758 for (auto& dex : compilation_sources_raw) {
759 class_loader_1_dex_files.push_back(dex);
760 }
761 VerifyClassLoaderDexFiles(soa,
762 class_loader_1,
763 WellKnownClasses::dalvik_system_PathClassLoader,
764 class_loader_1_dex_files);
765
766 // Verify its shared library.
767 ArtField* field =
768 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
769 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
770 ASSERT_TRUE(raw_shared_libraries != nullptr);
771
772 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
773 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
774 ASSERT_EQ(shared_libraries->GetLength(), 1);
775
776 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
777 std::vector<const DexFile*> class_loader_2_dex_files =
778 MakeNonOwningPointerVector(classpath_dex_b);
779 VerifyClassLoaderDexFiles(soa,
780 class_loader_2,
781 WellKnownClasses::dalvik_system_PathClassLoader,
782 class_loader_2_dex_files);
783 raw_shared_libraries = field->GetObject(class_loader_2.Get());
784 ASSERT_TRUE(raw_shared_libraries == nullptr);
785
786 // Verify the parent.
787 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
788 std::vector<const DexFile*> class_loader_3_dex_files =
789 MakeNonOwningPointerVector(classpath_dex_c);
790 VerifyClassLoaderDexFiles(soa,
791 class_loader_3,
792 WellKnownClasses::dalvik_system_PathClassLoader,
793 class_loader_3_dex_files);
794
795 // Verify its shared library.
796 raw_shared_libraries = field->GetObject(class_loader_3.Get());
797 ASSERT_TRUE(raw_shared_libraries != nullptr);
798
799 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
800 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
801 ASSERT_EQ(shared_libraries->GetLength(), 1);
802
803 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
804 std::vector<const DexFile*> class_loader_4_dex_files =
805 MakeNonOwningPointerVector(classpath_dex_d);
806 VerifyClassLoaderDexFiles(soa,
807 class_loader_4,
808 WellKnownClasses::dalvik_system_PathClassLoader,
809 class_loader_4_dex_files);
810 raw_shared_libraries = field->GetObject(class_loader_4.Get());
811 ASSERT_TRUE(raw_shared_libraries == nullptr);
812
813 // Class loaders should have the BootClassLoader as a parent.
814 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
815 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
816 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
817 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
818 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
819 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
820}
821
822TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
823 // Setup the context.
824 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
825 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
826 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
827 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
828
829 std::string context_spec =
830 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
831 "PCL[" + CreateClassPath(classpath_dex_b) + "]{" +
832 "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" +
833 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
834
835 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
836 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
837
838 // Setup the compilation sources.
839 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
840 std::vector<const DexFile*> compilation_sources_raw =
841 MakeNonOwningPointerVector(compilation_sources);
842
843 // Create the class loader.
844 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
845 ASSERT_TRUE(jclass_loader != nullptr);
846
847 // Verify the class loader.
848 ScopedObjectAccess soa(Thread::Current());
849
850 StackHandleScope<6> hs(soa.Self());
851 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
852 soa.Decode<mirror::ClassLoader>(jclass_loader));
853
854 // For the first class loader the class path dex files must come first and then the
855 // compilation sources.
856 std::vector<const DexFile*> class_loader_1_dex_files =
857 MakeNonOwningPointerVector(classpath_dex_a);
858 for (auto& dex : compilation_sources_raw) {
859 class_loader_1_dex_files.push_back(dex);
860 }
861 VerifyClassLoaderDexFiles(soa,
862 class_loader_1,
863 WellKnownClasses::dalvik_system_PathClassLoader,
864 class_loader_1_dex_files);
865
866 // Verify its shared library.
867 ArtField* field =
868 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
869 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
870 ASSERT_TRUE(raw_shared_libraries != nullptr);
871
872 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
873 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
874 ASSERT_EQ(shared_libraries->GetLength(), 1);
875
876 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
877 std::vector<const DexFile*> class_loader_2_dex_files =
878 MakeNonOwningPointerVector(classpath_dex_b);
879 VerifyClassLoaderDexFiles(soa,
880 class_loader_2,
881 WellKnownClasses::dalvik_system_PathClassLoader,
882 class_loader_2_dex_files);
883
884 // Verify the shared library dependency of the shared library.
885 raw_shared_libraries = field->GetObject(class_loader_2.Get());
886 ASSERT_TRUE(raw_shared_libraries != nullptr);
887
888 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
889 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
890 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
891
892 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
893 std::vector<const DexFile*> class_loader_3_dex_files =
894 MakeNonOwningPointerVector(classpath_dex_c);
895 VerifyClassLoaderDexFiles(soa,
896 class_loader_3,
897 WellKnownClasses::dalvik_system_PathClassLoader,
898 class_loader_3_dex_files);
899 raw_shared_libraries = field->GetObject(class_loader_3.Get());
900 ASSERT_TRUE(raw_shared_libraries == nullptr);
901
902 // Verify the parent.
903 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
904 std::vector<const DexFile*> class_loader_4_dex_files =
905 MakeNonOwningPointerVector(classpath_dex_d);
906 VerifyClassLoaderDexFiles(soa,
907 class_loader_4,
908 WellKnownClasses::dalvik_system_PathClassLoader,
909 class_loader_4_dex_files);
910 raw_shared_libraries = field->GetObject(class_loader_4.Get());
911 ASSERT_TRUE(raw_shared_libraries == nullptr);
912
913 // Class loaders should have the BootClassLoader as a parent.
914 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
915 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
916 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
917 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
918 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
919 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
920}
Calin Juravlec79470d2017-07-12 17:37:42 -0700921
Calin Juravle87e2cb62017-06-13 21:48:45 -0700922TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
923 std::unique_ptr<ClassLoaderContext> context =
924 ClassLoaderContext::Create("PCL[a.dex]");
925 dchecked_vector<std::string> classpath_dex;
926 classpath_dex.push_back("a.dex");
927 dchecked_vector<std::string> compilation_sources;
928 compilation_sources.push_back("src.dex");
929
930 // Nothing should be removed.
931 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
932 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
933 // Classes should be removed.
934 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
935 VerifyClassLoaderPCL(context.get(), 0, "");
936}
937
Nicolas Geoffraycb2e1dd2018-11-20 11:15:13 +0000938TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
939 // Setup the context.
940 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
941 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
942 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
943
944 std::string context_spec =
945 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
946 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
947 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
948 "PCL[" + CreateClassPath(classpath_dex_b) + "]}";
949
950 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
951 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
952
953 // Setup the compilation sources.
954 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
955 std::vector<const DexFile*> compilation_sources_raw =
956 MakeNonOwningPointerVector(compilation_sources);
957
958 // Create the class loader.
959 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
960 ASSERT_TRUE(jclass_loader != nullptr);
961
962 // Verify the class loader.
963 ScopedObjectAccess soa(Thread::Current());
964
965 StackHandleScope<6> hs(soa.Self());
966 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
967 soa.Decode<mirror::ClassLoader>(jclass_loader));
968
969 // For the first class loader the class path dex files must come first and then the
970 // compilation sources.
971 std::vector<const DexFile*> class_loader_1_dex_files =
972 MakeNonOwningPointerVector(classpath_dex_a);
973 for (auto& dex : compilation_sources_raw) {
974 class_loader_1_dex_files.push_back(dex);
975 }
976 VerifyClassLoaderDexFiles(soa,
977 class_loader_1,
978 WellKnownClasses::dalvik_system_PathClassLoader,
979 class_loader_1_dex_files);
980
981 // Verify its shared library.
982 ArtField* field =
983 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
984 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
985 ASSERT_TRUE(raw_shared_libraries != nullptr);
986
987 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
988 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
989 ASSERT_EQ(shared_libraries->GetLength(), 1);
990
991 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
992 std::vector<const DexFile*> class_loader_2_dex_files =
993 MakeNonOwningPointerVector(classpath_dex_b);
994 VerifyClassLoaderDexFiles(soa,
995 class_loader_2,
996 WellKnownClasses::dalvik_system_PathClassLoader,
997 class_loader_2_dex_files);
998
999 // Verify the parent.
1000 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
1001 std::vector<const DexFile*> class_loader_3_dex_files =
1002 MakeNonOwningPointerVector(classpath_dex_c);
1003 VerifyClassLoaderDexFiles(soa,
1004 class_loader_3,
1005 WellKnownClasses::dalvik_system_PathClassLoader,
1006 class_loader_3_dex_files);
1007
1008 // Verify its shared library is the same as the child.
1009 raw_shared_libraries = field->GetObject(class_loader_3.Get());
1010 ASSERT_TRUE(raw_shared_libraries != nullptr);
1011 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
1012 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1013 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
1014 ASSERT_EQ(shared_libraries_2->Get(0), class_loader_2.Get());
1015
1016 // Class loaders should have the BootClassLoader as a parent.
1017 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1018 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1019 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1020 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1021}
1022
Calin Juravle87e2cb62017-06-13 21:48:45 -07001023TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
1024 std::string dex1_name = GetTestDexFileName("Main");
1025 std::string dex2_name = GetTestDexFileName("MyClass");
1026 std::unique_ptr<ClassLoaderContext> context =
1027 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1028 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1029
1030 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1031 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1032 std::string encoding = context->EncodeContextForOatFile("");
Calin Juravlec79470d2017-07-12 17:37:42 -07001033 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
1034 CreateClassPathWithChecksums(dex2) + "]";
Calin Juravle87e2cb62017-06-13 21:48:45 -07001035 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1036}
1037
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001038TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
1039 std::string dex1_name = GetTestDexFileName("Main");
1040 std::string dex2_name = GetTestDexFileName("MultiDex");
1041 std::unique_ptr<ClassLoaderContext> context =
1042 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1043 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1044
1045 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1046 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MultiDex");
1047 std::string encoding = context->EncodeContextForDex2oat("");
1048 std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
1049 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1050}
1051
Calin Juravle57d0acc2017-07-11 17:41:30 -07001052// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
1053TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
1054 // The chain is
1055 // ClassLoaderA (PathClassLoader)
1056 // ^
1057 // |
1058 // ClassLoaderB (DelegateLastClassLoader)
1059 // ^
1060 // |
1061 // ClassLoaderC (PathClassLoader)
1062 // ^
1063 // |
1064 // ClassLoaderD (DelegateLastClassLoader)
1065
1066 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1067 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1068 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1069 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1070
1071 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1072
1073 VerifyContextForClassLoader(context.get());
1074 VerifyContextSize(context.get(), 4);
1075
1076 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1077 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
1078 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
1079 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1080}
1081
Mathieu Chartieradc90862018-05-11 13:03:06 -07001082
1083TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) {
1084 std::string context_spec = "PCL[]";
1085 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1086 ASSERT_TRUE(context != nullptr);
1087 PretendContextOpenedDexFiles(context.get());
1088 // Ensure that the special shared library marks as verified for the first thing in the class path.
1089 ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary),
1090 ClassLoaderContext::VerificationResult::kVerifies);
1091}
1092
Calin Juravle3f918642017-07-11 19:04:20 -07001093TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
1094 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
1095 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
Calin Juravlec5b215f2017-09-12 14:49:37 -07001096 // Pretend that we successfully open the dex files to pass the DCHECKS.
1097 // (as it's much easier to test all the corner cases without relying on actual dex files).
1098 PretendContextOpenedDexFiles(context.get());
Calin Juravle3f918642017-07-11 19:04:20 -07001099
1100 VerifyContextSize(context.get(), 2);
1101 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1102 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1103
Mathieu Chartieradc90862018-05-11 13:03:06 -07001104 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1105 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001106
1107 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001108 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1109 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001110
1111 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001112 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1113 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001114
1115 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001116 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1117 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001118
1119 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001120 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1121 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001122
1123 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 -07001124 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1125 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001126
1127 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 -07001128 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1129 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001130
1131 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001132 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
1133 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001134}
1135
Nicolas Geoffray9893c472018-11-13 15:39:53 +00001136TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) {
1137 std::string context_spec = "&";
1138 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1139 // Pretend that we successfully open the dex files to pass the DCHECKS.
1140 // (as it's much easier to test all the corner cases without relying on actual dex files).
1141 PretendContextOpenedDexFiles(context.get());
1142
1143 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1144 ClassLoaderContext::VerificationResult::kForcedToSkipChecks);
1145}
1146
Nicolas Geoffray06af3b42018-10-29 10:39:04 +00001147TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
1148 std::string context_spec =
1149 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1150 ";DLC[c.dex*890]";
1151 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1152 // Pretend that we successfully open the dex files to pass the DCHECKS.
1153 // (as it's much easier to test all the corner cases without relying on actual dex files).
1154 PretendContextOpenedDexFiles(context.get());
1155
1156 VerifyContextSize(context.get(), 2);
1157 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1158 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1159 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
1160 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
1161
1162 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1163 ClassLoaderContext::VerificationResult::kVerifies);
1164
1165 std::string wrong_class_loader_type =
1166 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1167 ";DLC[c.dex*890]";
1168 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1169 ClassLoaderContext::VerificationResult::kMismatch);
1170
1171 std::string wrong_class_loader_order =
1172 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
1173 ";DLC[c.dex*890]";
1174 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1175 ClassLoaderContext::VerificationResult::kMismatch);
1176
1177 std::string wrong_classpath_order =
1178 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1179 ";DLC[c.dex*890]";
1180 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1181 ClassLoaderContext::VerificationResult::kMismatch);
1182
1183 std::string wrong_checksum =
1184 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1185 ";DLC[c.dex*890]";
1186 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1187 ClassLoaderContext::VerificationResult::kMismatch);
1188
1189 std::string wrong_extra_class_loader =
1190 "PCL[a.dex*123:b.dex*456]"
1191 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
1192 ";DLC[c.dex*890]";
1193 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1194 ClassLoaderContext::VerificationResult::kMismatch);
1195
1196 std::string wrong_extra_classpath =
1197 "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]}"
1198 ";DLC[c.dex*890]";
1199 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1200 ClassLoaderContext::VerificationResult::kMismatch);
1201}
1202
Calin Juravle3f918642017-07-11 19:04:20 -07001203TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
1204 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1205 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1206 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1207 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1208
1209 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1210
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001211 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
Mathieu Chartieradc90862018-05-11 13:03:06 -07001212 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1213 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001214
1215 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1216 size_t pos = dex_location.rfind('/');
1217 ASSERT_NE(std::string::npos, pos);
1218 std::string parent = dex_location.substr(0, pos);
1219
1220 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1221 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
Mathieu Chartieradc90862018-05-11 13:03:06 -07001222 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1223 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001224}
1225
Calin Juravlea308a322017-07-18 16:51:51 -07001226TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
1227 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1228
1229 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1230
Mathieu Chartieradc90862018-05-11 13:03:06 -07001231 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1232 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravlea308a322017-07-18 16:51:51 -07001233}
1234
Nicolas Geoffraye1672732018-11-30 01:09:49 +00001235TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderWithSharedLibraries) {
1236 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1237
1238 ScopedObjectAccess soa(Thread::Current());
1239 StackHandleScope<1> hs(soa.Self());
1240 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1241 mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1242 soa.Self(),
1243 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1244 1));
1245 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1246
1247 jobject class_loader_b = LoadDexInPathClassLoader(
1248 "ForClassLoaderB", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1249
1250 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1251 ASSERT_TRUE(context != nullptr);
1252 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ForClassLoaderB");
1253 VerifyClassLoaderPCL(context.get(), 0, dex_files[0]->GetLocation());
1254 dex_files = OpenTestDexFiles("ForClassLoaderA");
1255 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, dex_files[0]->GetLocation());
1256
1257 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1258 ClassLoaderContext::VerificationResult::kVerifies);
1259}
1260
Calin Juravle87e2cb62017-06-13 21:48:45 -07001261} // namespace art