blob: 5655aecbe59dc0bba596291e08a8cdfe10254e28 [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
17#include <gtest/gtest.h>
18
Calin Juravle87e2cb62017-06-13 21:48:45 -070019#include "class_loader_context.h"
20#include "common_runtime_test.h"
21
22#include "base/dchecked_vector.h"
23#include "base/stl_util.h"
24#include "class_linker.h"
25#include "dex_file.h"
26#include "handle_scope-inl.h"
27#include "mirror/class.h"
28#include "mirror/class_loader.h"
29#include "mirror/object-inl.h"
30#include "oat_file_assistant.h"
31#include "runtime.h"
32#include "scoped_thread_state_change-inl.h"
33#include "thread.h"
34#include "well_known_classes.h"
35
36namespace art {
37
38class ClassLoaderContextTest : public CommonRuntimeTest {
39 public:
40 void VerifyContextSize(ClassLoaderContext* context, size_t expected_size) {
41 ASSERT_TRUE(context != nullptr);
42 ASSERT_EQ(expected_size, context->class_loader_chain_.size());
43 }
44
45 void VerifyClassLoaderPCL(ClassLoaderContext* context,
46 size_t index,
Calin Juravle57d0acc2017-07-11 17:41:30 -070047 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -070048 VerifyClassLoaderInfo(
49 context, index, ClassLoaderContext::kPathClassLoader, classpath);
50 }
51
52 void VerifyClassLoaderDLC(ClassLoaderContext* context,
53 size_t index,
Calin Juravle57d0acc2017-07-11 17:41:30 -070054 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -070055 VerifyClassLoaderInfo(
56 context, index, ClassLoaderContext::kDelegateLastClassLoader, classpath);
57 }
58
Calin Juravle57d0acc2017-07-11 17:41:30 -070059 void VerifyClassLoaderPCLFromTestDex(ClassLoaderContext* context,
60 size_t index,
61 const std::string& test_name) {
62 VerifyClassLoaderFromTestDex(
63 context, index, ClassLoaderContext::kPathClassLoader, test_name);
64 }
65
66 void VerifyClassLoaderDLCFromTestDex(ClassLoaderContext* context,
67 size_t index,
68 const std::string& test_name) {
69 VerifyClassLoaderFromTestDex(
70 context, index, ClassLoaderContext::kDelegateLastClassLoader, test_name);
71 }
72
Calin Juravle87e2cb62017-06-13 21:48:45 -070073 void VerifyOpenDexFiles(
74 ClassLoaderContext* context,
75 size_t index,
76 std::vector<std::vector<std::unique_ptr<const DexFile>>*>& all_dex_files) {
77 ASSERT_TRUE(context != nullptr);
78 ASSERT_TRUE(context->dex_files_open_attempted_);
79 ASSERT_TRUE(context->dex_files_open_result_);
80 ClassLoaderContext::ClassLoaderInfo& info = context->class_loader_chain_[index];
81 ASSERT_EQ(all_dex_files.size(), info.classpath.size());
82 size_t cur_open_dex_index = 0;
83 for (size_t k = 0; k < all_dex_files.size(); k++) {
84 std::vector<std::unique_ptr<const DexFile>>& dex_files_for_cp_elem = *(all_dex_files[k]);
85 for (size_t i = 0; i < dex_files_for_cp_elem.size(); i++) {
86 ASSERT_LT(cur_open_dex_index, info.opened_dex_files.size());
87
88 std::unique_ptr<const DexFile>& opened_dex_file =
89 info.opened_dex_files[cur_open_dex_index++];
90 std::unique_ptr<const DexFile>& expected_dex_file = dex_files_for_cp_elem[i];
91
92 ASSERT_EQ(expected_dex_file->GetLocation(), opened_dex_file->GetLocation());
93 ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_dex_file->GetLocationChecksum());
94 ASSERT_EQ(info.classpath[k], opened_dex_file->GetBaseLocation());
95 }
96 }
97 }
98
Calin Juravle57d0acc2017-07-11 17:41:30 -070099 std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) {
100 return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr);
101 }
102
Calin Juravle3f918642017-07-11 19:04:20 -0700103 std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) {
104 std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext());
105 if (!context->Parse(context_spec, /*parse_checksums*/ true)) {
106 return nullptr;
107 }
108 return context;
109 }
110
Calin Juravle57d0acc2017-07-11 17:41:30 -0700111 void VerifyContextForClassLoader(ClassLoaderContext* context) {
112 ASSERT_TRUE(context != nullptr);
113 ASSERT_TRUE(context->dex_files_open_attempted_);
114 ASSERT_TRUE(context->dex_files_open_result_);
115 ASSERT_FALSE(context->owns_the_dex_files_);
116 ASSERT_FALSE(context->special_shared_library_);
117 }
118
Calin Juravlec79470d2017-07-12 17:37:42 -0700119 void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa,
120 Handle<mirror::ClassLoader> class_loader,
121 jclass type,
122 std::vector<const DexFile*>& expected_dex_files)
123 REQUIRES_SHARED(Locks::mutator_lock_) {
124 ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type));
125
126 std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa, class_loader);
127 ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());
128
129 for (size_t i = 0; i < expected_dex_files.size(); i++) {
130 ASSERT_EQ(expected_dex_files[i]->GetLocation(),
131 class_loader_dex_files[i]->GetLocation());
132 ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(),
133 class_loader_dex_files[i]->GetLocationChecksum());
134 }
135 }
136
Calin Juravle87e2cb62017-06-13 21:48:45 -0700137 private:
138 void VerifyClassLoaderInfo(ClassLoaderContext* context,
139 size_t index,
140 ClassLoaderContext::ClassLoaderType type,
Calin Juravle57d0acc2017-07-11 17:41:30 -0700141 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700142 ASSERT_TRUE(context != nullptr);
143 ASSERT_GT(context->class_loader_chain_.size(), index);
144 ClassLoaderContext::ClassLoaderInfo& info = context->class_loader_chain_[index];
145 ASSERT_EQ(type, info.type);
146 std::vector<std::string> expected_classpath;
147 Split(classpath, ':', &expected_classpath);
148 ASSERT_EQ(expected_classpath, info.classpath);
149 }
Calin Juravle57d0acc2017-07-11 17:41:30 -0700150
151 void VerifyClassLoaderFromTestDex(ClassLoaderContext* context,
152 size_t index,
153 ClassLoaderContext::ClassLoaderType type,
154 const std::string& test_name) {
155 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str());
156 std::vector<std::vector<std::unique_ptr<const DexFile>>*> all_dex_files;
157 all_dex_files.push_back(&dex_files);
158
159 VerifyClassLoaderInfo(context, index, type, GetTestDexFileName(test_name.c_str()));
160 VerifyOpenDexFiles(context, index, all_dex_files);
161 }
Calin Juravle87e2cb62017-06-13 21:48:45 -0700162};
163
164TEST_F(ClassLoaderContextTest, ParseValidContextPCL) {
165 std::unique_ptr<ClassLoaderContext> context =
166 ClassLoaderContext::Create("PCL[a.dex]");
167 VerifyContextSize(context.get(), 1);
168 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
169}
170
171TEST_F(ClassLoaderContextTest, ParseValidContextDLC) {
172 std::unique_ptr<ClassLoaderContext> context =
173 ClassLoaderContext::Create("DLC[a.dex]");
174 VerifyContextSize(context.get(), 1);
175 VerifyClassLoaderDLC(context.get(), 0, "a.dex");
176}
177
178TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
179 std::unique_ptr<ClassLoaderContext> context =
180 ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
181 VerifyContextSize(context.get(), 3);
182 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
183 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
184 VerifyClassLoaderPCL(context.get(), 2, "e.dex");
185}
186
187TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
188 std::unique_ptr<ClassLoaderContext> context =
189 ClassLoaderContext::Create("DLC[]");
190 VerifyContextSize(context.get(), 1);
191 VerifyClassLoaderDLC(context.get(), 0, "");
192}
193
194TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) {
195 std::unique_ptr<ClassLoaderContext> context =
196 ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary);
197 VerifyContextSize(context.get(), 0);
198}
199
200TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
201 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
202 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
203 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
204 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
205 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
206 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
207}
208
209TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
210 std::unique_ptr<ClassLoaderContext> context =
211 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
212 VerifyContextSize(context.get(), 1);
213 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
214}
215
216TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
217 std::string multidex_name = GetTestDexFileName("MultiDex");
218 std::vector<std::unique_ptr<const DexFile>> multidex_files = OpenTestDexFiles("MultiDex");
219 std::string myclass_dex_name = GetTestDexFileName("MyClass");
220 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
221 std::string dex_name = GetTestDexFileName("Main");
222 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("Main");
223
224
225 std::unique_ptr<ClassLoaderContext> context =
226 ClassLoaderContext::Create(
227 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
228 "DLC[" + dex_name + "]");
229
230 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir*/ ""));
231
232 VerifyContextSize(context.get(), 2);
233 std::vector<std::vector<std::unique_ptr<const DexFile>>*> all_dex_files0;
234 all_dex_files0.push_back(&multidex_files);
235 all_dex_files0.push_back(&myclass_dex_files);
236 std::vector<std::vector<std::unique_ptr<const DexFile>>*> all_dex_files1;
237 all_dex_files1.push_back(&dex_files);
238
239 VerifyOpenDexFiles(context.get(), 0, all_dex_files0);
240 VerifyOpenDexFiles(context.get(), 1, all_dex_files1);
241}
242
243TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
244 std::string dex_name = GetTestDexFileName("Main");
245 std::unique_ptr<ClassLoaderContext> context =
246 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
247 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ""));
248}
249
250TEST_F(ClassLoaderContextTest, CreateClassLoader) {
251 std::string dex_name = GetTestDexFileName("Main");
252 std::unique_ptr<ClassLoaderContext> context =
253 ClassLoaderContext::Create("PCL[" + dex_name + "]");
254 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
255
256 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
257 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
258
259 std::vector<const DexFile*> compilation_sources_raw =
260 MakeNonOwningPointerVector(compilation_sources);
261 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
262 ASSERT_TRUE(jclass_loader != nullptr);
263
264 ScopedObjectAccess soa(Thread::Current());
265
Calin Juravlec79470d2017-07-12 17:37:42 -0700266 StackHandleScope<1> hs(soa.Self());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700267 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
268 soa.Decode<mirror::ClassLoader>(jclass_loader));
269
270 ASSERT_TRUE(class_loader->GetClass() ==
271 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
272 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
273 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
274
Calin Juravlec79470d2017-07-12 17:37:42 -0700275 // For the first class loader the class path dex files must come first and then the
276 // compilation sources.
277 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
278 for (auto& dex : compilation_sources_raw) {
279 expected_classpath.push_back(dex);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700280 }
281
Calin Juravlec79470d2017-07-12 17:37:42 -0700282 VerifyClassLoaderDexFiles(soa,
283 class_loader,
284 WellKnownClasses::dalvik_system_PathClassLoader,
285 expected_classpath);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700286}
287
Calin Juravle7b0648a2017-07-07 18:40:50 -0700288TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
289 std::unique_ptr<ClassLoaderContext> context =
290 ClassLoaderContext::Create("");
291 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
292
293 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
294
295 std::vector<const DexFile*> compilation_sources_raw =
296 MakeNonOwningPointerVector(compilation_sources);
297 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
298 ASSERT_TRUE(jclass_loader != nullptr);
299
300 ScopedObjectAccess soa(Thread::Current());
301
Calin Juravlec79470d2017-07-12 17:37:42 -0700302 StackHandleScope<1> hs(soa.Self());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700303 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
304 soa.Decode<mirror::ClassLoader>(jclass_loader));
305
Calin Juravlec79470d2017-07-12 17:37:42 -0700306 // An empty context should create a single PathClassLoader with only the compilation sources.
307 VerifyClassLoaderDexFiles(soa,
308 class_loader,
309 WellKnownClasses::dalvik_system_PathClassLoader,
310 compilation_sources_raw);
Calin Juravle7b0648a2017-07-07 18:40:50 -0700311 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
312 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Calin Juravle7b0648a2017-07-07 18:40:50 -0700313}
314
Calin Juravlec79470d2017-07-12 17:37:42 -0700315TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
316 // Setup the context.
317 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
318 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
319 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
320 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
321
322 std::string context_spec =
323 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
324 "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
325 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
326
327 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
328 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
329
330 // Setup the compilation sources.
331 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
332 std::vector<const DexFile*> compilation_sources_raw =
333 MakeNonOwningPointerVector(compilation_sources);
334
335 // Create the class loader.
336 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
337 ASSERT_TRUE(jclass_loader != nullptr);
338
339 // Verify the class loader.
340 ScopedObjectAccess soa(Thread::Current());
341
342 StackHandleScope<3> hs(soa.Self());
343 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
344 soa.Decode<mirror::ClassLoader>(jclass_loader));
345
346 // Verify the first class loader
347
348 // For the first class loader the class path dex files must come first and then the
349 // compilation sources.
350 std::vector<const DexFile*> class_loader_1_dex_files =
351 MakeNonOwningPointerVector(classpath_dex_a);
352 for (auto& dex : classpath_dex_b) {
353 class_loader_1_dex_files.push_back(dex.get());
354 }
355 for (auto& dex : compilation_sources_raw) {
356 class_loader_1_dex_files.push_back(dex);
357 }
358 VerifyClassLoaderDexFiles(soa,
359 class_loader_1,
360 WellKnownClasses::dalvik_system_PathClassLoader,
361 class_loader_1_dex_files);
362
363 // Verify the second class loader
364 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
365 std::vector<const DexFile*> class_loader_2_dex_files =
366 MakeNonOwningPointerVector(classpath_dex_c);
367 VerifyClassLoaderDexFiles(soa,
368 class_loader_2,
369 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
370 class_loader_2_dex_files);
371
372 // Verify the third class loader
373 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
374 std::vector<const DexFile*> class_loader_3_dex_files =
375 MakeNonOwningPointerVector(classpath_dex_d);
376 VerifyClassLoaderDexFiles(soa,
377 class_loader_3,
378 WellKnownClasses::dalvik_system_PathClassLoader,
379 class_loader_3_dex_files);
380 // The last class loader should have the BootClassLoader as a parent.
381 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
382 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
383}
384
385
Calin Juravle87e2cb62017-06-13 21:48:45 -0700386TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
387 std::unique_ptr<ClassLoaderContext> context =
388 ClassLoaderContext::Create("PCL[a.dex]");
389 dchecked_vector<std::string> classpath_dex;
390 classpath_dex.push_back("a.dex");
391 dchecked_vector<std::string> compilation_sources;
392 compilation_sources.push_back("src.dex");
393
394 // Nothing should be removed.
395 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
396 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
397 // Classes should be removed.
398 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
399 VerifyClassLoaderPCL(context.get(), 0, "");
400}
401
402TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
403 std::string dex1_name = GetTestDexFileName("Main");
404 std::string dex2_name = GetTestDexFileName("MyClass");
405 std::unique_ptr<ClassLoaderContext> context =
406 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
407 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
408
409 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
410 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
411 std::string encoding = context->EncodeContextForOatFile("");
Calin Juravlec79470d2017-07-12 17:37:42 -0700412 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
413 CreateClassPathWithChecksums(dex2) + "]";
Calin Juravle87e2cb62017-06-13 21:48:45 -0700414 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
415}
416
Calin Juravle57d0acc2017-07-11 17:41:30 -0700417// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
418TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
419 // The chain is
420 // ClassLoaderA (PathClassLoader)
421 // ^
422 // |
423 // ClassLoaderB (DelegateLastClassLoader)
424 // ^
425 // |
426 // ClassLoaderC (PathClassLoader)
427 // ^
428 // |
429 // ClassLoaderD (DelegateLastClassLoader)
430
431 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
432 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
433 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
434 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
435
436 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
437
438 VerifyContextForClassLoader(context.get());
439 VerifyContextSize(context.get(), 4);
440
441 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
442 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
443 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
444 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
445}
446
Calin Juravle3f918642017-07-11 19:04:20 -0700447TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
448 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
449 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
450
451 VerifyContextSize(context.get(), 2);
452 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
453 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
454
455 ASSERT_TRUE(context->VerifyClassLoaderContextMatch(context_spec));
456
457 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
458 ASSERT_FALSE(context->VerifyClassLoaderContextMatch(wrong_class_loader_type));
459
460 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
461 ASSERT_FALSE(context->VerifyClassLoaderContextMatch(wrong_class_loader_order));
462
463 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
464 ASSERT_FALSE(context->VerifyClassLoaderContextMatch(wrong_classpath_order));
465
466 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
467 ASSERT_FALSE(context->VerifyClassLoaderContextMatch(wrong_checksum));
468
469 std::string wrong_extra_class_loader = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];PCL[d.dex*321]";
470 ASSERT_FALSE(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader));
471
472 std::string wrong_extra_classpath = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890:d.dex*321]";
473 ASSERT_FALSE(context->VerifyClassLoaderContextMatch(wrong_extra_classpath));
474
475 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
476 ASSERT_FALSE(context->VerifyClassLoaderContextMatch(wrong_spec));
477}
478
479TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
480 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
481 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
482 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
483 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
484
485 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
486
487 ASSERT_TRUE(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")));
488}
489
Calin Juravlea308a322017-07-18 16:51:51 -0700490TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
491 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
492
493 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
494
495 ASSERT_TRUE(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")));
496}
497
Calin Juravle87e2cb62017-06-13 21:48:45 -0700498} // namespace art