blob: 0756982b6560e073337d49bf9ac024ab9411b89b [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
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000289TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) {
290 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
291 "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}");
292 VerifyContextSize(context.get(), 1);
293 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex");
294}
295
296TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) {
297 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
298 "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#"
299 "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}");
300 VerifyContextSize(context.get(), 1);
301 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
302 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex");
303 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex");
304 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex");
305 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex");
306}
307
Calin Juravle87e2cb62017-06-13 21:48:45 -0700308TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
309 std::unique_ptr<ClassLoaderContext> context =
310 ClassLoaderContext::Create("DLC[]");
311 VerifyContextSize(context.get(), 1);
312 VerifyClassLoaderDLC(context.get(), 0, "");
313}
314
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000315TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
316 std::unique_ptr<ClassLoaderContext> context =
317 ClassLoaderContext::Create("DLC[]{}");
318 VerifyContextSize(context.get(), 1);
319 VerifySharedLibrariesSize(context.get(), 0, 0);
320}
321
Calin Juravle87e2cb62017-06-13 21:48:45 -0700322TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) {
323 std::unique_ptr<ClassLoaderContext> context =
324 ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary);
325 VerifyContextSize(context.get(), 0);
326}
327
328TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
329 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
330 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
331 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
332 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
333 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
334 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000335 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
336 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
337 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
338 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
339 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000340 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}"));
341 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}"));
342 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}"));
343 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}"));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700344}
345
346TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
347 std::unique_ptr<ClassLoaderContext> context =
348 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
349 VerifyContextSize(context.get(), 1);
350 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
351}
352
353TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
354 std::string multidex_name = GetTestDexFileName("MultiDex");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700355 std::string myclass_dex_name = GetTestDexFileName("MyClass");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700356 std::string dex_name = GetTestDexFileName("Main");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700357
Calin Juravle92003fe2017-09-06 02:22:57 +0000358
Calin Juravle87e2cb62017-06-13 21:48:45 -0700359 std::unique_ptr<ClassLoaderContext> context =
360 ClassLoaderContext::Create(
361 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
362 "DLC[" + dex_name + "]");
363
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700364 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700365
366 VerifyContextSize(context.get(), 2);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700367
Calin Juravlec5b215f2017-09-12 14:49:37 -0700368 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
369 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
370 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
371 all_dex_files0.emplace_back(myclass_dex_files[i].release());
372 }
373 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
374
375 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
376 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700377}
378
Alex Light77ef93b2018-01-12 11:18:31 -0800379// Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
380// TODO We should somehow support this in all situations. b/72042237.
381static bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100382 int cwd_len = strlen(cwd);
383 if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
Alex Light77ef93b2018-01-12 11:18:31 -0800384 return false;
Andreas Gampe72527382017-09-02 16:53:03 -0700385 }
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100386 bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
387 int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
Alex Light77ef93b2018-01-12 11:18:31 -0800388 *out = in.substr(start_position);
389 return true;
Andreas Gampe72527382017-09-02 16:53:03 -0700390}
391
392TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
393 char cwd_buf[4096];
394 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
395 PLOG(FATAL) << "Could not get working directory";
396 }
Alex Light77ef93b2018-01-12 11:18:31 -0800397 std::string multidex_name;
398 std::string myclass_dex_name;
399 std::string dex_name;
400 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
401 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
402 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
403 LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
404 << "relative path.";
405 SUCCEED();
406 return;
407 }
Andreas Gampe72527382017-09-02 16:53:03 -0700408
409
410 std::unique_ptr<ClassLoaderContext> context =
411 ClassLoaderContext::Create(
412 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
413 "DLC[" + dex_name + "]");
414
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700415 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Andreas Gampe72527382017-09-02 16:53:03 -0700416
Calin Juravlec5b215f2017-09-12 14:49:37 -0700417 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
418 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
419 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
420 all_dex_files0.emplace_back(myclass_dex_files[i].release());
421 }
422 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700423
Calin Juravlec5b215f2017-09-12 14:49:37 -0700424 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
425 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700426}
427
428TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
429 char cwd_buf[4096];
430 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
431 PLOG(FATAL) << "Could not get working directory";
432 }
Alex Light77ef93b2018-01-12 11:18:31 -0800433 std::string multidex_name;
434 std::string myclass_dex_name;
435 std::string dex_name;
436 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
437 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
438 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
439 LOG(ERROR) << "Test OpenValidDexFilesClasspathDir cannot be run because target dex files have "
440 << "no relative path.";
441 SUCCEED();
442 return;
443 }
Andreas Gampe72527382017-09-02 16:53:03 -0700444 std::unique_ptr<ClassLoaderContext> context =
445 ClassLoaderContext::Create(
446 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
447 "DLC[" + dex_name + "]");
448
449 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, cwd_buf));
450
451 VerifyContextSize(context.get(), 2);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700452 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
453 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
454 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
455 all_dex_files0.emplace_back(myclass_dex_files[i].release());
456 }
457 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700458
Calin Juravlec5b215f2017-09-12 14:49:37 -0700459 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
460 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700461}
462
Calin Juravle87e2cb62017-06-13 21:48:45 -0700463TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
464 std::string dex_name = GetTestDexFileName("Main");
465 std::unique_ptr<ClassLoaderContext> context =
466 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
467 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ""));
468}
469
470TEST_F(ClassLoaderContextTest, CreateClassLoader) {
471 std::string dex_name = GetTestDexFileName("Main");
472 std::unique_ptr<ClassLoaderContext> context =
473 ClassLoaderContext::Create("PCL[" + dex_name + "]");
474 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
475
476 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
477 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
478
479 std::vector<const DexFile*> compilation_sources_raw =
480 MakeNonOwningPointerVector(compilation_sources);
481 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
482 ASSERT_TRUE(jclass_loader != nullptr);
483
484 ScopedObjectAccess soa(Thread::Current());
485
Calin Juravlec79470d2017-07-12 17:37:42 -0700486 StackHandleScope<1> hs(soa.Self());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700487 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
488 soa.Decode<mirror::ClassLoader>(jclass_loader));
489
490 ASSERT_TRUE(class_loader->GetClass() ==
491 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
492 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
493 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
494
Calin Juravlec79470d2017-07-12 17:37:42 -0700495 // For the first class loader the class path dex files must come first and then the
496 // compilation sources.
497 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
498 for (auto& dex : compilation_sources_raw) {
499 expected_classpath.push_back(dex);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700500 }
501
Calin Juravlec79470d2017-07-12 17:37:42 -0700502 VerifyClassLoaderDexFiles(soa,
503 class_loader,
504 WellKnownClasses::dalvik_system_PathClassLoader,
505 expected_classpath);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700506}
507
Calin Juravle7b0648a2017-07-07 18:40:50 -0700508TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
509 std::unique_ptr<ClassLoaderContext> context =
510 ClassLoaderContext::Create("");
511 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
512
513 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
514
515 std::vector<const DexFile*> compilation_sources_raw =
516 MakeNonOwningPointerVector(compilation_sources);
517 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
518 ASSERT_TRUE(jclass_loader != nullptr);
519
520 ScopedObjectAccess soa(Thread::Current());
521
Calin Juravlec79470d2017-07-12 17:37:42 -0700522 StackHandleScope<1> hs(soa.Self());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700523 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
524 soa.Decode<mirror::ClassLoader>(jclass_loader));
525
Calin Juravlec79470d2017-07-12 17:37:42 -0700526 // An empty context should create a single PathClassLoader with only the compilation sources.
527 VerifyClassLoaderDexFiles(soa,
528 class_loader,
529 WellKnownClasses::dalvik_system_PathClassLoader,
530 compilation_sources_raw);
Calin Juravle7b0648a2017-07-07 18:40:50 -0700531 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
532 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Calin Juravle7b0648a2017-07-07 18:40:50 -0700533}
534
Calin Juravle1a509c82017-07-24 16:51:21 -0700535TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraryContext) {
536 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
537
538 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
539
540 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
541
542 std::vector<const DexFile*> compilation_sources_raw =
543 MakeNonOwningPointerVector(compilation_sources);
544 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
545 ASSERT_TRUE(jclass_loader != nullptr);
546
547 ScopedObjectAccess soa(Thread::Current());
548
549 StackHandleScope<1> hs(soa.Self());
550 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
551 soa.Decode<mirror::ClassLoader>(jclass_loader));
552
553 // A shared library context should create a single PathClassLoader with only the compilation
554 // sources.
555 VerifyClassLoaderDexFiles(soa,
556 class_loader,
557 WellKnownClasses::dalvik_system_PathClassLoader,
558 compilation_sources_raw);
559 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
560 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
561}
562
Calin Juravlec79470d2017-07-12 17:37:42 -0700563TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
564 // Setup the context.
565 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
566 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
567 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
568 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
569
570 std::string context_spec =
571 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
572 "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
573 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
574
575 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
576 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
577
578 // Setup the compilation sources.
579 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
580 std::vector<const DexFile*> compilation_sources_raw =
581 MakeNonOwningPointerVector(compilation_sources);
582
583 // Create the class loader.
584 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
585 ASSERT_TRUE(jclass_loader != nullptr);
586
587 // Verify the class loader.
588 ScopedObjectAccess soa(Thread::Current());
589
590 StackHandleScope<3> hs(soa.Self());
591 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
592 soa.Decode<mirror::ClassLoader>(jclass_loader));
593
594 // Verify the first class loader
595
596 // For the first class loader the class path dex files must come first and then the
597 // compilation sources.
598 std::vector<const DexFile*> class_loader_1_dex_files =
599 MakeNonOwningPointerVector(classpath_dex_a);
600 for (auto& dex : classpath_dex_b) {
601 class_loader_1_dex_files.push_back(dex.get());
602 }
603 for (auto& dex : compilation_sources_raw) {
604 class_loader_1_dex_files.push_back(dex);
605 }
606 VerifyClassLoaderDexFiles(soa,
607 class_loader_1,
608 WellKnownClasses::dalvik_system_PathClassLoader,
609 class_loader_1_dex_files);
610
611 // Verify the second class loader
612 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
613 std::vector<const DexFile*> class_loader_2_dex_files =
614 MakeNonOwningPointerVector(classpath_dex_c);
615 VerifyClassLoaderDexFiles(soa,
616 class_loader_2,
617 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
618 class_loader_2_dex_files);
619
620 // Verify the third class loader
621 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
622 std::vector<const DexFile*> class_loader_3_dex_files =
623 MakeNonOwningPointerVector(classpath_dex_d);
624 VerifyClassLoaderDexFiles(soa,
625 class_loader_3,
626 WellKnownClasses::dalvik_system_PathClassLoader,
627 class_loader_3_dex_files);
628 // The last class loader should have the BootClassLoader as a parent.
629 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
630 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
631}
632
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +0000633TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
634 // Setup the context.
635 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
636 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
637 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
638 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
639
640 std::string context_spec =
641 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" +
642 "DLC[" + CreateClassPath(classpath_dex_c) + "]#" +
643 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
644
645 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
646 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
647
648 // Setup the compilation sources.
649 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
650 std::vector<const DexFile*> compilation_sources_raw =
651 MakeNonOwningPointerVector(compilation_sources);
652
653 // Create the class loader.
654 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
655 ASSERT_TRUE(jclass_loader != nullptr);
656
657 // Verify the class loader.
658 ScopedObjectAccess soa(Thread::Current());
659
660 StackHandleScope<4> hs(soa.Self());
661 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
662 soa.Decode<mirror::ClassLoader>(jclass_loader));
663
664 // For the first class loader the class path dex files must come first and then the
665 // compilation sources.
666 std::vector<const DexFile*> class_loader_1_dex_files =
667 MakeNonOwningPointerVector(classpath_dex_a);
668 for (auto& dex : classpath_dex_b) {
669 class_loader_1_dex_files.push_back(dex.get());
670 }
671 for (auto& dex : compilation_sources_raw) {
672 class_loader_1_dex_files.push_back(dex);
673 }
674 VerifyClassLoaderDexFiles(soa,
675 class_loader_1,
676 WellKnownClasses::dalvik_system_PathClassLoader,
677 class_loader_1_dex_files);
678
679 // Verify the shared libraries.
680 ArtField* field =
681 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
682 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
683 ASSERT_TRUE(raw_shared_libraries != nullptr);
684
685 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
686 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
687 ASSERT_EQ(shared_libraries->GetLength(), 2);
688
689 // Verify the first shared library.
690 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
691 std::vector<const DexFile*> class_loader_2_dex_files =
692 MakeNonOwningPointerVector(classpath_dex_c);
693 VerifyClassLoaderDexFiles(soa,
694 class_loader_2,
695 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
696 class_loader_2_dex_files);
697 raw_shared_libraries = field->GetObject(class_loader_2.Get());
698 ASSERT_TRUE(raw_shared_libraries == nullptr);
699
700 // Verify the second shared library.
701 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
702 std::vector<const DexFile*> class_loader_3_dex_files =
703 MakeNonOwningPointerVector(classpath_dex_d);
704 VerifyClassLoaderDexFiles(soa,
705 class_loader_3,
706 WellKnownClasses::dalvik_system_PathClassLoader,
707 class_loader_3_dex_files);
708 raw_shared_libraries = field->GetObject(class_loader_3.Get());
709 ASSERT_TRUE(raw_shared_libraries == nullptr);
710
711 // All class loaders should have the BootClassLoader as a parent.
712 ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
713 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
714 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
715 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
716 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
717 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
718}
719
720TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
721 // Setup the context.
722 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
723 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
724 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
725 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
726
727 std::string context_spec =
728 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
729 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
730 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
731 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
732
733 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
734 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
735
736 // Setup the compilation sources.
737 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
738 std::vector<const DexFile*> compilation_sources_raw =
739 MakeNonOwningPointerVector(compilation_sources);
740
741 // Create the class loader.
742 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
743 ASSERT_TRUE(jclass_loader != nullptr);
744
745 // Verify the class loader.
746 ScopedObjectAccess soa(Thread::Current());
747
748 StackHandleScope<6> hs(soa.Self());
749 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
750 soa.Decode<mirror::ClassLoader>(jclass_loader));
751
752 // For the first class loader the class path dex files must come first and then the
753 // compilation sources.
754 std::vector<const DexFile*> class_loader_1_dex_files =
755 MakeNonOwningPointerVector(classpath_dex_a);
756 for (auto& dex : compilation_sources_raw) {
757 class_loader_1_dex_files.push_back(dex);
758 }
759 VerifyClassLoaderDexFiles(soa,
760 class_loader_1,
761 WellKnownClasses::dalvik_system_PathClassLoader,
762 class_loader_1_dex_files);
763
764 // Verify its shared library.
765 ArtField* field =
766 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
767 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
768 ASSERT_TRUE(raw_shared_libraries != nullptr);
769
770 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
771 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
772 ASSERT_EQ(shared_libraries->GetLength(), 1);
773
774 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
775 std::vector<const DexFile*> class_loader_2_dex_files =
776 MakeNonOwningPointerVector(classpath_dex_b);
777 VerifyClassLoaderDexFiles(soa,
778 class_loader_2,
779 WellKnownClasses::dalvik_system_PathClassLoader,
780 class_loader_2_dex_files);
781 raw_shared_libraries = field->GetObject(class_loader_2.Get());
782 ASSERT_TRUE(raw_shared_libraries == nullptr);
783
784 // Verify the parent.
785 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
786 std::vector<const DexFile*> class_loader_3_dex_files =
787 MakeNonOwningPointerVector(classpath_dex_c);
788 VerifyClassLoaderDexFiles(soa,
789 class_loader_3,
790 WellKnownClasses::dalvik_system_PathClassLoader,
791 class_loader_3_dex_files);
792
793 // Verify its shared library.
794 raw_shared_libraries = field->GetObject(class_loader_3.Get());
795 ASSERT_TRUE(raw_shared_libraries != nullptr);
796
797 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
798 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
799 ASSERT_EQ(shared_libraries->GetLength(), 1);
800
801 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
802 std::vector<const DexFile*> class_loader_4_dex_files =
803 MakeNonOwningPointerVector(classpath_dex_d);
804 VerifyClassLoaderDexFiles(soa,
805 class_loader_4,
806 WellKnownClasses::dalvik_system_PathClassLoader,
807 class_loader_4_dex_files);
808 raw_shared_libraries = field->GetObject(class_loader_4.Get());
809 ASSERT_TRUE(raw_shared_libraries == nullptr);
810
811 // Class loaders should have the BootClassLoader as a parent.
812 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
813 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
814 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
815 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
816 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
817 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
818}
819
820TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
821 // Setup the context.
822 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
823 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
824 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
825 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
826
827 std::string context_spec =
828 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
829 "PCL[" + CreateClassPath(classpath_dex_b) + "]{" +
830 "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" +
831 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
832
833 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
834 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
835
836 // Setup the compilation sources.
837 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
838 std::vector<const DexFile*> compilation_sources_raw =
839 MakeNonOwningPointerVector(compilation_sources);
840
841 // Create the class loader.
842 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
843 ASSERT_TRUE(jclass_loader != nullptr);
844
845 // Verify the class loader.
846 ScopedObjectAccess soa(Thread::Current());
847
848 StackHandleScope<6> hs(soa.Self());
849 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
850 soa.Decode<mirror::ClassLoader>(jclass_loader));
851
852 // For the first class loader the class path dex files must come first and then the
853 // compilation sources.
854 std::vector<const DexFile*> class_loader_1_dex_files =
855 MakeNonOwningPointerVector(classpath_dex_a);
856 for (auto& dex : compilation_sources_raw) {
857 class_loader_1_dex_files.push_back(dex);
858 }
859 VerifyClassLoaderDexFiles(soa,
860 class_loader_1,
861 WellKnownClasses::dalvik_system_PathClassLoader,
862 class_loader_1_dex_files);
863
864 // Verify its shared library.
865 ArtField* field =
866 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
867 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
868 ASSERT_TRUE(raw_shared_libraries != nullptr);
869
870 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
871 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
872 ASSERT_EQ(shared_libraries->GetLength(), 1);
873
874 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
875 std::vector<const DexFile*> class_loader_2_dex_files =
876 MakeNonOwningPointerVector(classpath_dex_b);
877 VerifyClassLoaderDexFiles(soa,
878 class_loader_2,
879 WellKnownClasses::dalvik_system_PathClassLoader,
880 class_loader_2_dex_files);
881
882 // Verify the shared library dependency of the shared library.
883 raw_shared_libraries = field->GetObject(class_loader_2.Get());
884 ASSERT_TRUE(raw_shared_libraries != nullptr);
885
886 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
887 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
888 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
889
890 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
891 std::vector<const DexFile*> class_loader_3_dex_files =
892 MakeNonOwningPointerVector(classpath_dex_c);
893 VerifyClassLoaderDexFiles(soa,
894 class_loader_3,
895 WellKnownClasses::dalvik_system_PathClassLoader,
896 class_loader_3_dex_files);
897 raw_shared_libraries = field->GetObject(class_loader_3.Get());
898 ASSERT_TRUE(raw_shared_libraries == nullptr);
899
900 // Verify the parent.
901 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
902 std::vector<const DexFile*> class_loader_4_dex_files =
903 MakeNonOwningPointerVector(classpath_dex_d);
904 VerifyClassLoaderDexFiles(soa,
905 class_loader_4,
906 WellKnownClasses::dalvik_system_PathClassLoader,
907 class_loader_4_dex_files);
908 raw_shared_libraries = field->GetObject(class_loader_4.Get());
909 ASSERT_TRUE(raw_shared_libraries == nullptr);
910
911 // Class loaders should have the BootClassLoader as a parent.
912 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
913 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
914 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
915 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
916 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
917 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
918}
Calin Juravlec79470d2017-07-12 17:37:42 -0700919
Calin Juravle87e2cb62017-06-13 21:48:45 -0700920TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
921 std::unique_ptr<ClassLoaderContext> context =
922 ClassLoaderContext::Create("PCL[a.dex]");
923 dchecked_vector<std::string> classpath_dex;
924 classpath_dex.push_back("a.dex");
925 dchecked_vector<std::string> compilation_sources;
926 compilation_sources.push_back("src.dex");
927
928 // Nothing should be removed.
929 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
930 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
931 // Classes should be removed.
932 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
933 VerifyClassLoaderPCL(context.get(), 0, "");
934}
935
Nicolas Geoffraycb2e1dd2018-11-20 11:15:13 +0000936TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
937 // Setup the context.
938 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
939 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
940 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
941
942 std::string context_spec =
943 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
944 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
945 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
946 "PCL[" + CreateClassPath(classpath_dex_b) + "]}";
947
948 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
949 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
950
951 // Setup the compilation sources.
952 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
953 std::vector<const DexFile*> compilation_sources_raw =
954 MakeNonOwningPointerVector(compilation_sources);
955
956 // Create the class loader.
957 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
958 ASSERT_TRUE(jclass_loader != nullptr);
959
960 // Verify the class loader.
961 ScopedObjectAccess soa(Thread::Current());
962
963 StackHandleScope<6> hs(soa.Self());
964 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
965 soa.Decode<mirror::ClassLoader>(jclass_loader));
966
967 // For the first class loader the class path dex files must come first and then the
968 // compilation sources.
969 std::vector<const DexFile*> class_loader_1_dex_files =
970 MakeNonOwningPointerVector(classpath_dex_a);
971 for (auto& dex : compilation_sources_raw) {
972 class_loader_1_dex_files.push_back(dex);
973 }
974 VerifyClassLoaderDexFiles(soa,
975 class_loader_1,
976 WellKnownClasses::dalvik_system_PathClassLoader,
977 class_loader_1_dex_files);
978
979 // Verify its shared library.
980 ArtField* field =
981 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
982 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
983 ASSERT_TRUE(raw_shared_libraries != nullptr);
984
985 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
986 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
987 ASSERT_EQ(shared_libraries->GetLength(), 1);
988
989 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
990 std::vector<const DexFile*> class_loader_2_dex_files =
991 MakeNonOwningPointerVector(classpath_dex_b);
992 VerifyClassLoaderDexFiles(soa,
993 class_loader_2,
994 WellKnownClasses::dalvik_system_PathClassLoader,
995 class_loader_2_dex_files);
996
997 // Verify the parent.
998 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
999 std::vector<const DexFile*> class_loader_3_dex_files =
1000 MakeNonOwningPointerVector(classpath_dex_c);
1001 VerifyClassLoaderDexFiles(soa,
1002 class_loader_3,
1003 WellKnownClasses::dalvik_system_PathClassLoader,
1004 class_loader_3_dex_files);
1005
1006 // Verify its shared library is the same as the child.
1007 raw_shared_libraries = field->GetObject(class_loader_3.Get());
1008 ASSERT_TRUE(raw_shared_libraries != nullptr);
1009 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
1010 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1011 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
1012 ASSERT_EQ(shared_libraries_2->Get(0), class_loader_2.Get());
1013
1014 // Class loaders should have the BootClassLoader as a parent.
1015 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1016 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1017 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1018 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1019}
1020
Calin Juravle87e2cb62017-06-13 21:48:45 -07001021TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
1022 std::string dex1_name = GetTestDexFileName("Main");
1023 std::string dex2_name = GetTestDexFileName("MyClass");
1024 std::unique_ptr<ClassLoaderContext> context =
1025 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1026 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1027
1028 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1029 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1030 std::string encoding = context->EncodeContextForOatFile("");
Calin Juravlec79470d2017-07-12 17:37:42 -07001031 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
1032 CreateClassPathWithChecksums(dex2) + "]";
Calin Juravle87e2cb62017-06-13 21:48:45 -07001033 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1034}
1035
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001036TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
1037 std::string dex1_name = GetTestDexFileName("Main");
1038 std::string dex2_name = GetTestDexFileName("MultiDex");
1039 std::unique_ptr<ClassLoaderContext> context =
1040 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1041 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1042
1043 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1044 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MultiDex");
1045 std::string encoding = context->EncodeContextForDex2oat("");
1046 std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
1047 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1048}
1049
Calin Juravle57d0acc2017-07-11 17:41:30 -07001050// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
1051TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
1052 // The chain is
1053 // ClassLoaderA (PathClassLoader)
1054 // ^
1055 // |
1056 // ClassLoaderB (DelegateLastClassLoader)
1057 // ^
1058 // |
1059 // ClassLoaderC (PathClassLoader)
1060 // ^
1061 // |
1062 // ClassLoaderD (DelegateLastClassLoader)
1063
1064 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1065 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1066 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1067 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1068
1069 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1070
1071 VerifyContextForClassLoader(context.get());
1072 VerifyContextSize(context.get(), 4);
1073
1074 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1075 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
1076 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
1077 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1078}
1079
Mathieu Chartieradc90862018-05-11 13:03:06 -07001080
1081TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) {
1082 std::string context_spec = "PCL[]";
1083 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1084 ASSERT_TRUE(context != nullptr);
1085 PretendContextOpenedDexFiles(context.get());
1086 // Ensure that the special shared library marks as verified for the first thing in the class path.
1087 ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary),
1088 ClassLoaderContext::VerificationResult::kVerifies);
1089}
1090
Calin Juravle3f918642017-07-11 19:04:20 -07001091TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
1092 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
1093 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
Calin Juravlec5b215f2017-09-12 14:49:37 -07001094 // Pretend that we successfully open the dex files to pass the DCHECKS.
1095 // (as it's much easier to test all the corner cases without relying on actual dex files).
1096 PretendContextOpenedDexFiles(context.get());
Calin Juravle3f918642017-07-11 19:04:20 -07001097
1098 VerifyContextSize(context.get(), 2);
1099 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1100 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1101
Mathieu Chartieradc90862018-05-11 13:03:06 -07001102 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1103 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001104
1105 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001106 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1107 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001108
1109 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001110 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1111 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001112
1113 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001114 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1115 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001116
1117 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001118 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1119 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001120
1121 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 -07001122 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1123 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001124
1125 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 -07001126 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1127 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001128
1129 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001130 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
1131 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001132}
1133
Nicolas Geoffray9893c472018-11-13 15:39:53 +00001134TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) {
1135 std::string context_spec = "&";
1136 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1137 // Pretend that we successfully open the dex files to pass the DCHECKS.
1138 // (as it's much easier to test all the corner cases without relying on actual dex files).
1139 PretendContextOpenedDexFiles(context.get());
1140
1141 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1142 ClassLoaderContext::VerificationResult::kForcedToSkipChecks);
1143}
1144
Nicolas Geoffray06af3b42018-10-29 10:39:04 +00001145TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
1146 std::string context_spec =
1147 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1148 ";DLC[c.dex*890]";
1149 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1150 // Pretend that we successfully open the dex files to pass the DCHECKS.
1151 // (as it's much easier to test all the corner cases without relying on actual dex files).
1152 PretendContextOpenedDexFiles(context.get());
1153
1154 VerifyContextSize(context.get(), 2);
1155 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1156 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1157 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
1158 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
1159
1160 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1161 ClassLoaderContext::VerificationResult::kVerifies);
1162
1163 std::string wrong_class_loader_type =
1164 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1165 ";DLC[c.dex*890]";
1166 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1167 ClassLoaderContext::VerificationResult::kMismatch);
1168
1169 std::string wrong_class_loader_order =
1170 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
1171 ";DLC[c.dex*890]";
1172 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1173 ClassLoaderContext::VerificationResult::kMismatch);
1174
1175 std::string wrong_classpath_order =
1176 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1177 ";DLC[c.dex*890]";
1178 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1179 ClassLoaderContext::VerificationResult::kMismatch);
1180
1181 std::string wrong_checksum =
1182 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1183 ";DLC[c.dex*890]";
1184 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1185 ClassLoaderContext::VerificationResult::kMismatch);
1186
1187 std::string wrong_extra_class_loader =
1188 "PCL[a.dex*123:b.dex*456]"
1189 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
1190 ";DLC[c.dex*890]";
1191 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1192 ClassLoaderContext::VerificationResult::kMismatch);
1193
1194 std::string wrong_extra_classpath =
1195 "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]}"
1196 ";DLC[c.dex*890]";
1197 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1198 ClassLoaderContext::VerificationResult::kMismatch);
1199}
1200
Calin Juravle3f918642017-07-11 19:04:20 -07001201TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
1202 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1203 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1204 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1205 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1206
1207 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1208
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001209 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
Mathieu Chartieradc90862018-05-11 13:03:06 -07001210 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1211 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001212
1213 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1214 size_t pos = dex_location.rfind('/');
1215 ASSERT_NE(std::string::npos, pos);
1216 std::string parent = dex_location.substr(0, pos);
1217
1218 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1219 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
Mathieu Chartieradc90862018-05-11 13:03:06 -07001220 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1221 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001222}
1223
Calin Juravlea308a322017-07-18 16:51:51 -07001224TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
1225 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1226
1227 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1228
Mathieu Chartieradc90862018-05-11 13:03:06 -07001229 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1230 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravlea308a322017-07-18 16:51:51 -07001231}
1232
Calin Juravle87e2cb62017-06-13 21:48:45 -07001233} // namespace art