blob: 073b4b61e2a344d26416ec5efed309030fa57190 [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"
Vladimir Marko5868ada2020-05-12 11:50:34 +010026#include "class_root-inl.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"
Vladimir Markobdc93b42019-03-29 16:12:04 +000032#include "mirror/class_loader-inl.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070033#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
David Brazdil1a9ac532019-03-05 11:57:13 +000064 void VerifyClassLoaderIMC(ClassLoaderContext* context,
65 size_t index,
66 const std::string& classpath) {
67 VerifyClassLoaderInfo(
68 context, index, ClassLoaderContext::kInMemoryDexClassLoader, classpath);
69 }
70
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000071 void VerifyClassLoaderSharedLibraryPCL(ClassLoaderContext* context,
72 size_t loader_index,
73 size_t shared_library_index,
74 const std::string& classpath) {
75 VerifyClassLoaderInfoSL(
76 context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
77 classpath);
78 }
79
Brad Stenning9c924e82021-10-11 19:09:00 -070080 void VerifyClassLoaderSharedLibraryPCLAfter(ClassLoaderContext* context,
81 size_t loader_index,
82 size_t shared_library_index,
83 const std::string& classpath) {
84 VerifyClassLoaderInfoSLAfter(
85 context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
86 classpath);
87 }
88
David Brazdil1a9ac532019-03-05 11:57:13 +000089 void VerifyClassLoaderSharedLibraryIMC(ClassLoaderContext* context,
90 size_t loader_index,
91 size_t shared_library_index,
92 const std::string& classpath) {
93 VerifyClassLoaderInfoSL(
94 context, loader_index, shared_library_index, ClassLoaderContext::kInMemoryDexClassLoader,
95 classpath);
96 }
97
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000098 void VerifySharedLibrariesSize(ClassLoaderContext* context,
99 size_t loader_index,
100 size_t expected_size) {
101 ASSERT_TRUE(context != nullptr);
102 ASSERT_GT(context->GetParentChainSize(), loader_index);
103 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
104 ASSERT_EQ(info.shared_libraries.size(), expected_size);
105 }
106
107 void VerifyClassLoaderSharedLibraryDLC(ClassLoaderContext* context,
108 size_t loader_index,
109 size_t shared_library_index,
110 const std::string& classpath) {
111 VerifyClassLoaderInfoSL(
112 context, loader_index, shared_library_index, ClassLoaderContext::kDelegateLastClassLoader,
113 classpath);
114 }
115
Calin Juravle57d0acc2017-07-11 17:41:30 -0700116 void VerifyClassLoaderPCLFromTestDex(ClassLoaderContext* context,
117 size_t index,
118 const std::string& test_name) {
119 VerifyClassLoaderFromTestDex(
120 context, index, ClassLoaderContext::kPathClassLoader, test_name);
121 }
122
123 void VerifyClassLoaderDLCFromTestDex(ClassLoaderContext* context,
124 size_t index,
125 const std::string& test_name) {
126 VerifyClassLoaderFromTestDex(
127 context, index, ClassLoaderContext::kDelegateLastClassLoader, test_name);
128 }
129
David Brazdil1a9ac532019-03-05 11:57:13 +0000130 void VerifyClassLoaderIMCFromTestDex(ClassLoaderContext* context,
131 size_t index,
132 const std::string& test_name) {
133 VerifyClassLoaderFromTestDex(
David Brazdil93d339d2019-03-27 09:56:45 +0000134 context, index, ClassLoaderContext::kInMemoryDexClassLoader, test_name, "<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +0000135 }
136
Andreas Gampe72527382017-09-02 16:53:03 -0700137 enum class LocationCheck {
138 kEquals,
139 kEndsWith
140 };
141 enum class BaseLocationCheck {
142 kEquals,
143 kEndsWith
144 };
145
Calin Juravle92003fe2017-09-06 02:22:57 +0000146 static bool IsAbsoluteLocation(const std::string& location) {
147 return !location.empty() && location[0] == '/';
148 }
149
Calin Juravle87e2cb62017-06-13 21:48:45 -0700150 void VerifyOpenDexFiles(
151 ClassLoaderContext* context,
152 size_t index,
David Brazdil93d339d2019-03-27 09:56:45 +0000153 std::vector<std::unique_ptr<const DexFile>>* all_dex_files,
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800154 bool classpath_matches_dex_location = true,
155 bool only_read_checksums = false) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700156 ASSERT_TRUE(context != nullptr);
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800157 if (only_read_checksums) {
158 ASSERT_EQ(context->dex_files_state_,
159 ClassLoaderContext::ContextDexFilesState::kDexFilesChecksumsRead);
160 } else {
161 ASSERT_EQ(context->dex_files_state_,
162 ClassLoaderContext::ContextDexFilesState::kDexFilesOpened);
163 }
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000164 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700165 ASSERT_EQ(all_dex_files->size(), info.classpath.size());
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800166 ASSERT_EQ(all_dex_files->size(), info.checksums.size());
167 if (only_read_checksums) {
168 ASSERT_EQ(0u, info.opened_dex_files.size());
169 } else {
170 ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size());
171 }
Calin Juravle87e2cb62017-06-13 21:48:45 -0700172
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800173 for (size_t k = 0, cur_open_dex_index = 0;
174 k < all_dex_files->size();
175 k++, cur_open_dex_index++) {
176 const std::string& opened_location = only_read_checksums
177 ? info.classpath[cur_open_dex_index]
178 : info.opened_dex_files[cur_open_dex_index]->GetLocation();
179 uint32_t opened_checksum = only_read_checksums
180 ? info.checksums[cur_open_dex_index]
181 : info.opened_dex_files[cur_open_dex_index]->GetLocationChecksum();
182
183 std::unique_ptr<const DexFile>& expected_dex_file = (*all_dex_files)[k];
Calin Juravle92003fe2017-09-06 02:22:57 +0000184 std::string expected_location = expected_dex_file->GetLocation();
Calin Juravle821a2592017-08-11 14:33:38 -0700185
Calin Juravle92003fe2017-09-06 02:22:57 +0000186 if (!IsAbsoluteLocation(opened_location)) {
187 // If the opened location is relative (it was open from a relative path without a
188 // classpath_dir) it might not match the expected location which is absolute in tests).
189 // So we compare the endings (the checksum will validate it's actually the same file).
190 ASSERT_EQ(0, expected_location.compare(
191 expected_location.length() - opened_location.length(),
192 opened_location.length(),
193 opened_location));
194 } else {
195 ASSERT_EQ(expected_location, opened_location);
196 }
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800197 ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_checksum);
David Brazdil93d339d2019-03-27 09:56:45 +0000198 if (classpath_matches_dex_location) {
199 ASSERT_EQ(info.classpath[k], opened_location);
200 }
Calin Juravle87e2cb62017-06-13 21:48:45 -0700201 }
202 }
203
Calin Juravle57d0acc2017-07-11 17:41:30 -0700204 std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) {
205 return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr);
206 }
207
Calin Juravle3f918642017-07-11 19:04:20 -0700208 std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) {
209 std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext());
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700210 if (!context->Parse(context_spec, /*parse_checksums=*/ true)) {
Calin Juravle3f918642017-07-11 19:04:20 -0700211 return nullptr;
212 }
213 return context;
214 }
215
Calin Juravle57d0acc2017-07-11 17:41:30 -0700216 void VerifyContextForClassLoader(ClassLoaderContext* context) {
217 ASSERT_TRUE(context != nullptr);
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800218 ASSERT_EQ(context->dex_files_state_, ClassLoaderContext::ContextDexFilesState::kDexFilesOpened);
Calin Juravle57d0acc2017-07-11 17:41:30 -0700219 ASSERT_FALSE(context->owns_the_dex_files_);
Calin Juravle57d0acc2017-07-11 17:41:30 -0700220 }
221
Calin Juravlec79470d2017-07-12 17:37:42 -0700222 void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa,
223 Handle<mirror::ClassLoader> class_loader,
224 jclass type,
225 std::vector<const DexFile*>& expected_dex_files)
226 REQUIRES_SHARED(Locks::mutator_lock_) {
227 ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type));
228
229 std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa, class_loader);
230 ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());
231
232 for (size_t i = 0; i < expected_dex_files.size(); i++) {
233 ASSERT_EQ(expected_dex_files[i]->GetLocation(),
234 class_loader_dex_files[i]->GetLocation());
235 ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(),
236 class_loader_dex_files[i]->GetLocationChecksum());
237 }
238 }
239
Calin Juravlec5b215f2017-09-12 14:49:37 -0700240 void PretendContextOpenedDexFiles(ClassLoaderContext* context) {
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800241 context->dex_files_state_ = ClassLoaderContext::ContextDexFilesState::kDexFilesOpened;
242 }
243
244 void PretendContextOpenedDexFilesForChecksums(ClassLoaderContext* context) {
245 context->dex_files_state_ = ClassLoaderContext::ContextDexFilesState::kDexFilesChecksumsRead;
246 }
247
248 void TestOpenDexFiles(bool only_read_checksums) {
249 std::string multidex_name = GetTestDexFileName("MultiDex");
250 std::string myclass_dex_name = GetTestDexFileName("MyClass");
251 std::string dex_name = GetTestDexFileName("Main");
252
253 std::unique_ptr<ClassLoaderContext> context =
254 ClassLoaderContext::Create(
255 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
256 "DLC[" + dex_name + "]");
257
258 ASSERT_TRUE(context->OpenDexFiles(
259 /*classpath_dir=*/ "",
260 /*context_fds=*/ std::vector<int>(),
261 only_read_checksums));
262
263 VerifyContextSize(context.get(), 2);
264
265 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
266 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
267 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
268 all_dex_files0.emplace_back(myclass_dex_files[i].release());
269 }
270 VerifyOpenDexFiles(context.get(),
271 /*index=*/ 0,
272 &all_dex_files0,
273 /*classpath_matches_dex_location=*/ false,
274 only_read_checksums);
275 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
276 VerifyOpenDexFiles(context.get(),
277 /*index=*/ 1,
278 &all_dex_files1,
279 /*classpath_matches_dex_location=*/ false,
280 only_read_checksums);
281 }
282
283 void TestOpenValidDexFilesRelative(bool use_classpath_dir, bool only_read_checksums) {
284 char cwd_buf[4096];
285 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
286 PLOG(FATAL) << "Could not get working directory";
287 }
288 std::string multidex_name;
289 std::string myclass_dex_name;
290 std::string dex_name;
291 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
292 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
293 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
294 LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
295 << "relative path.";
296 SUCCEED();
297 return;
298 }
299
300 std::unique_ptr<ClassLoaderContext> context =
301 ClassLoaderContext::Create(
302 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
303 "DLC[" + dex_name + "]");
304
305 ASSERT_TRUE(context->OpenDexFiles(
306 /*classpath_dir=*/ use_classpath_dir ? cwd_buf : "",
307 /*context_fds=*/ std::vector<int>(),
308 only_read_checksums));
309 VerifyContextSize(context.get(), 2);
310
311 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
312 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
313 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
314 all_dex_files0.emplace_back(myclass_dex_files[i].release());
315 }
316 VerifyOpenDexFiles(context.get(),
317 /*index=*/ 0,
318 &all_dex_files0,
319 /*classpath_matches_dex_location=*/ false,
320 only_read_checksums);
321
322 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
323 VerifyOpenDexFiles(context.get(),
324 /*index=*/ 1,
325 &all_dex_files1,
326 /*classpath_matches_dex_location=*/ false,
327 only_read_checksums);
328 }
329
330 // Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
331 // TODO We should somehow support this in all situations. b/72042237.
332 bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
333 int cwd_len = strlen(cwd);
334 if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
335 return false;
336 }
337 bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
338 int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
339 *out = in.substr(start_position);
340 return true;
Calin Juravlec5b215f2017-09-12 14:49:37 -0700341 }
342
Calin Juravle87e2cb62017-06-13 21:48:45 -0700343 private:
344 void VerifyClassLoaderInfo(ClassLoaderContext* context,
345 size_t index,
346 ClassLoaderContext::ClassLoaderType type,
Calin Juravle57d0acc2017-07-11 17:41:30 -0700347 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700348 ASSERT_TRUE(context != nullptr);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000349 ASSERT_GT(context->GetParentChainSize(), index);
350 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700351 ASSERT_EQ(type, info.type);
352 std::vector<std::string> expected_classpath;
353 Split(classpath, ':', &expected_classpath);
354 ASSERT_EQ(expected_classpath, info.classpath);
355 }
Calin Juravle57d0acc2017-07-11 17:41:30 -0700356
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000357 void VerifyClassLoaderInfoSL(ClassLoaderContext* context,
358 size_t loader_index,
359 size_t shared_library_index,
360 ClassLoaderContext::ClassLoaderType type,
361 const std::string& classpath) {
362 ASSERT_TRUE(context != nullptr);
363 ASSERT_GT(context->GetParentChainSize(), loader_index);
364 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
365 ASSERT_GT(info.shared_libraries.size(), shared_library_index);
366 const ClassLoaderContext::ClassLoaderInfo& sl =
367 *info.shared_libraries[shared_library_index].get();
Brad Stenning9c924e82021-10-11 19:09:00 -0700368 ASSERT_EQ(type, sl.type);
369 std::vector<std::string> expected_classpath;
370 Split(classpath, ':', &expected_classpath);
371 ASSERT_EQ(expected_classpath, sl.classpath);
372 }
373
374 void VerifyClassLoaderInfoSLAfter(ClassLoaderContext* context,
375 size_t loader_index,
376 size_t shared_library_index,
377 ClassLoaderContext::ClassLoaderType type,
378 const std::string& classpath) {
379 ASSERT_TRUE(context != nullptr);
380 ASSERT_GT(context->GetParentChainSize(), loader_index);
381 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
382 ASSERT_GT(info.shared_libraries_after.size(), shared_library_index);
383
384 const ClassLoaderContext::ClassLoaderInfo& sl =
385 *info.shared_libraries_after[shared_library_index].get();
386 ASSERT_EQ(type, sl.type);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000387 std::vector<std::string> expected_classpath;
388 Split(classpath, ':', &expected_classpath);
389 ASSERT_EQ(expected_classpath, sl.classpath);
390 }
391
Calin Juravle57d0acc2017-07-11 17:41:30 -0700392 void VerifyClassLoaderFromTestDex(ClassLoaderContext* context,
393 size_t index,
394 ClassLoaderContext::ClassLoaderType type,
David Brazdil93d339d2019-03-27 09:56:45 +0000395 const std::string& test_name,
396 const std::string& classpath = "") {
Calin Juravle57d0acc2017-07-11 17:41:30 -0700397 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str());
Calin Juravle57d0acc2017-07-11 17:41:30 -0700398
David Brazdil93d339d2019-03-27 09:56:45 +0000399 // If `classpath` is set, override the expected value of ClassLoaderInfo::classpath.
400 // Otherwise assume it is equal to dex location (here test dex file name).
401 VerifyClassLoaderInfo(context,
402 index,
403 type,
404 classpath.empty() ? GetTestDexFileName(test_name.c_str()) : classpath);
405 VerifyOpenDexFiles(context,
406 index,
407 &dex_files,
408 /* classpath_matches_dex_location= */ classpath.empty());
Calin Juravle57d0acc2017-07-11 17:41:30 -0700409 }
Calin Juravle87e2cb62017-06-13 21:48:45 -0700410};
411
Calin Juravle1a509c82017-07-24 16:51:21 -0700412TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) {
413 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("");
414 // An empty context should create a single empty PathClassLoader.
415 VerifyContextSize(context.get(), 1);
416 VerifyClassLoaderPCL(context.get(), 0, "");
417}
418
Nicolas Geoffray982eced2021-03-29 08:49:38 +0100419TEST_F(ClassLoaderContextTest, ParseInvalidSharedLibraryContext) {
420 // '&' used to be a special context.
Calin Juravle1a509c82017-07-24 16:51:21 -0700421 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
Nicolas Geoffray982eced2021-03-29 08:49:38 +0100422 ASSERT_TRUE(context == nullptr);
Calin Juravle1a509c82017-07-24 16:51:21 -0700423}
424
Calin Juravle87e2cb62017-06-13 21:48:45 -0700425TEST_F(ClassLoaderContextTest, ParseValidContextPCL) {
David Brazdil1a9ac532019-03-05 11:57:13 +0000426 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("PCL[a.dex]");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700427 VerifyContextSize(context.get(), 1);
428 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
429}
430
431TEST_F(ClassLoaderContextTest, ParseValidContextDLC) {
David Brazdil1a9ac532019-03-05 11:57:13 +0000432 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("DLC[a.dex]");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700433 VerifyContextSize(context.get(), 1);
434 VerifyClassLoaderDLC(context.get(), 0, "a.dex");
435}
436
David Brazdil93d339d2019-03-27 09:56:45 +0000437TEST_F(ClassLoaderContextTest, ParseValidContextIMC) {
438 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums("IMC[<unknown>*111]");
439 ASSERT_FALSE(context == nullptr);
440}
441
442TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCNoChecksum) {
David Brazdil1a9ac532019-03-05 11:57:13 +0000443 // IMC is treated as an unknown class loader unless a checksum is provided.
444 // This is because the dex location is always bogus.
David Brazdil93d339d2019-03-27 09:56:45 +0000445 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[<unknown>]");
446 ASSERT_TRUE(context == nullptr);
447}
448
449TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCWrongClasspathMagic) {
450 // IMC does not support arbitrary dex location. A magic marker must be used
451 // otherwise the spec should be rejected.
452 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[a.dex*111]");
David Brazdil1a9ac532019-03-05 11:57:13 +0000453 ASSERT_TRUE(context == nullptr);
454}
455
Calin Juravle87e2cb62017-06-13 21:48:45 -0700456TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
457 std::unique_ptr<ClassLoaderContext> context =
458 ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
459 VerifyContextSize(context.get(), 3);
460 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
461 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
462 VerifyClassLoaderPCL(context.get(), 2, "e.dex");
463}
464
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000465TEST_F(ClassLoaderContextTest, ParseSharedLibraries) {
466 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
Brad Stenning9c924e82021-10-11 19:09:00 -0700467 "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]#~PCL[s5.dex]#~PCL[s6.dex:s7.dex]};"
468 "DLC[c.dex:d.dex]{DLC[s4.dex]}");
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000469 VerifyContextSize(context.get(), 2);
470 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
471 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex");
Brad Stenning9c924e82021-10-11 19:09:00 -0700472 VerifyClassLoaderSharedLibraryPCLAfter(context.get(), 0, 0, "s5.dex");
473 VerifyClassLoaderSharedLibraryPCLAfter(context.get(), 0, 1, "s6.dex:s7.dex");
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000474 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
475 VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex");
476}
477
478TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) {
479 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
480 "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}");
481 VerifyContextSize(context.get(), 1);
482 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
483}
484
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000485TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) {
486 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
487 "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}");
488 VerifyContextSize(context.get(), 1);
489 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex");
490}
491
492TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) {
493 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
494 "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#"
495 "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}");
496 VerifyContextSize(context.get(), 1);
497 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
498 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex");
499 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex");
500 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex");
501 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex");
502}
503
Calin Juravle87e2cb62017-06-13 21:48:45 -0700504TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
505 std::unique_ptr<ClassLoaderContext> context =
506 ClassLoaderContext::Create("DLC[]");
507 VerifyContextSize(context.get(), 1);
508 VerifyClassLoaderDLC(context.get(), 0, "");
509}
510
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000511TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
512 std::unique_ptr<ClassLoaderContext> context =
513 ClassLoaderContext::Create("DLC[]{}");
514 VerifyContextSize(context.get(), 1);
515 VerifySharedLibrariesSize(context.get(), 0, 0);
516}
517
Calin Juravle87e2cb62017-06-13 21:48:45 -0700518TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
519 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
520 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
521 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
522 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
523 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
524 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000525 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
526 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
527 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
528 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
529 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000530 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}"));
531 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}"));
532 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}"));
533 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}"));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700534}
535
536TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
537 std::unique_ptr<ClassLoaderContext> context =
538 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
539 VerifyContextSize(context.get(), 1);
Calin Juravle5ff23932020-12-11 18:26:14 -0800540 ASSERT_FALSE(context->OpenDexFiles("."));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700541}
542
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800543TEST_F(ClassLoaderContextTest, ReadChecksumsInvalidDexFiles) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700544 std::unique_ptr<ClassLoaderContext> context =
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800545 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
546 VerifyContextSize(context.get(), 1);
547 ASSERT_FALSE(context->OpenDexFiles(
548 /*classpath_dir=*/ ".",
549 /*context_fds=*/ std::vector<int>(),
550 /*only_read_checksums=*/ true));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700551}
552
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800553TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
554 TestOpenDexFiles(/*only_read_checksums=*/ false);
555}
556
557TEST_F(ClassLoaderContextTest, ReadDexFileChecksums) {
558 TestOpenDexFiles(/*only_read_checksums=*/ true);
Andreas Gampe72527382017-09-02 16:53:03 -0700559}
560
561TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800562 TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ false, /*only_read_checksums=*/ false);
563}
Andreas Gampe72527382017-09-02 16:53:03 -0700564
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800565TEST_F(ClassLoaderContextTest, ReadChecksumsValidDexFilesRelative) {
566 TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ false, /*only_read_checksums=*/ true);
Andreas Gampe72527382017-09-02 16:53:03 -0700567}
568
569TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800570 TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ true, /*only_read_checksums=*/ false);
571}
Andreas Gampe72527382017-09-02 16:53:03 -0700572
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800573TEST_F(ClassLoaderContextTest, ReadChecksumsValidDexFilesClasspathDir) {
574 TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ true, /*only_read_checksums=*/ true);
Andreas Gampe72527382017-09-02 16:53:03 -0700575}
576
Calin Juravle87e2cb62017-06-13 21:48:45 -0700577TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
578 std::string dex_name = GetTestDexFileName("Main");
579 std::unique_ptr<ClassLoaderContext> context =
580 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
Calin Juravle5ff23932020-12-11 18:26:14 -0800581 ASSERT_FALSE(context->OpenDexFiles());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700582}
583
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800584TEST_F(ClassLoaderContextTest, ReadChecksumsInvalidDexFilesMix) {
585 std::string dex_name = GetTestDexFileName("Main");
586 std::unique_ptr<ClassLoaderContext> context =
587 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
588 ASSERT_FALSE(context->OpenDexFiles(
589 /*classpath_dir=*/ "",
590 /*context_fds=*/ std::vector<int>(),
591 /*only_read_checksums=*/ true));
592}
593
David Brazdil1a9ac532019-03-05 11:57:13 +0000594TEST_F(ClassLoaderContextTest, OpenDexFilesForIMCFails) {
595 std::unique_ptr<ClassLoaderContext> context;
596 std::string dex_name = GetTestDexFileName("Main");
597
David Brazdil93d339d2019-03-27 09:56:45 +0000598 context = ParseContextWithChecksums("IMC[<unknown>*111]");
David Brazdil1a9ac532019-03-05 11:57:13 +0000599 VerifyContextSize(context.get(), 1);
Calin Juravle5ff23932020-12-11 18:26:14 -0800600 ASSERT_FALSE(context->OpenDexFiles("."));
David Brazdil1a9ac532019-03-05 11:57:13 +0000601}
602
Calin Juravle6e6f1b22020-12-15 19:13:19 -0800603// Verify that we can fully open the dex files after only reading their checksums.
604TEST_F(ClassLoaderContextTest, SubsequentOpenDexFilesOperations) {
605 std::string dex_name = GetTestDexFileName("Main");
606 std::unique_ptr<ClassLoaderContext> context =
607 ClassLoaderContext::Create("PCL[" + dex_name + "]");
608
609 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("Main");
610
611 ASSERT_TRUE(context->OpenDexFiles(
612 /*classpath_dir=*/ "",
613 /*context_fds=*/ std::vector<int>(),
614 /*only_read_checksums=*/ true));
615
616 VerifyOpenDexFiles(
617 context.get(),
618 /*index=*/ 0,
619 &all_dex_files0,
620 /*classpath_matches_dex_location=*/ false,
621 /*only_read_checksums=*/ true);
622
623 ASSERT_TRUE(context->OpenDexFiles(
624 /*classpath_dir=*/ "",
625 /*context_fds=*/ std::vector<int>(),
626 /*only_read_checksums=*/ false));
627
628 VerifyOpenDexFiles(
629 context.get(),
630 /*index=*/ 0,
631 &all_dex_files0,
632 /*classpath_matches_dex_location=*/ false,
633 /*only_read_checksums=*/ false);
634}
635
Calin Juravle87e2cb62017-06-13 21:48:45 -0700636TEST_F(ClassLoaderContextTest, CreateClassLoader) {
637 std::string dex_name = GetTestDexFileName("Main");
638 std::unique_ptr<ClassLoaderContext> context =
639 ClassLoaderContext::Create("PCL[" + dex_name + "]");
Calin Juravle5ff23932020-12-11 18:26:14 -0800640 ASSERT_TRUE(context->OpenDexFiles());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700641
642 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
643 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
644
645 std::vector<const DexFile*> compilation_sources_raw =
646 MakeNonOwningPointerVector(compilation_sources);
647 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
648 ASSERT_TRUE(jclass_loader != nullptr);
649
650 ScopedObjectAccess soa(Thread::Current());
651
Calin Juravlec79470d2017-07-12 17:37:42 -0700652 StackHandleScope<1> hs(soa.Self());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700653 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
654 soa.Decode<mirror::ClassLoader>(jclass_loader));
655
656 ASSERT_TRUE(class_loader->GetClass() ==
657 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
658 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
659 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
660
Calin Juravlec79470d2017-07-12 17:37:42 -0700661 // For the first class loader the class path dex files must come first and then the
662 // compilation sources.
663 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
664 for (auto& dex : compilation_sources_raw) {
665 expected_classpath.push_back(dex);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700666 }
667
Calin Juravlec79470d2017-07-12 17:37:42 -0700668 VerifyClassLoaderDexFiles(soa,
669 class_loader,
670 WellKnownClasses::dalvik_system_PathClassLoader,
671 expected_classpath);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700672}
673
Calin Juravle7b0648a2017-07-07 18:40:50 -0700674TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
675 std::unique_ptr<ClassLoaderContext> context =
676 ClassLoaderContext::Create("");
Calin Juravle5ff23932020-12-11 18:26:14 -0800677 ASSERT_TRUE(context->OpenDexFiles());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700678
679 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
680
681 std::vector<const DexFile*> compilation_sources_raw =
682 MakeNonOwningPointerVector(compilation_sources);
683 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
684 ASSERT_TRUE(jclass_loader != nullptr);
685
686 ScopedObjectAccess soa(Thread::Current());
687
Calin Juravlec79470d2017-07-12 17:37:42 -0700688 StackHandleScope<1> hs(soa.Self());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700689 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
690 soa.Decode<mirror::ClassLoader>(jclass_loader));
691
Calin Juravlec79470d2017-07-12 17:37:42 -0700692 // An empty context should create a single PathClassLoader with only the compilation sources.
693 VerifyClassLoaderDexFiles(soa,
694 class_loader,
695 WellKnownClasses::dalvik_system_PathClassLoader,
696 compilation_sources_raw);
Calin Juravle7b0648a2017-07-07 18:40:50 -0700697 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
698 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Calin Juravle7b0648a2017-07-07 18:40:50 -0700699}
700
Calin Juravlec79470d2017-07-12 17:37:42 -0700701TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
702 // Setup the context.
703 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
704 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
705 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
706 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
707
708 std::string context_spec =
709 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
710 "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
711 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
712
713 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
Calin Juravle5ff23932020-12-11 18:26:14 -0800714 ASSERT_TRUE(context->OpenDexFiles());
Calin Juravlec79470d2017-07-12 17:37:42 -0700715
716 // Setup the compilation sources.
717 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
718 std::vector<const DexFile*> compilation_sources_raw =
719 MakeNonOwningPointerVector(compilation_sources);
720
721 // Create the class loader.
722 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
723 ASSERT_TRUE(jclass_loader != nullptr);
724
725 // Verify the class loader.
726 ScopedObjectAccess soa(Thread::Current());
727
728 StackHandleScope<3> hs(soa.Self());
729 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
730 soa.Decode<mirror::ClassLoader>(jclass_loader));
731
732 // Verify the first class loader
733
734 // For the first class loader the class path dex files must come first and then the
735 // compilation sources.
736 std::vector<const DexFile*> class_loader_1_dex_files =
737 MakeNonOwningPointerVector(classpath_dex_a);
738 for (auto& dex : classpath_dex_b) {
739 class_loader_1_dex_files.push_back(dex.get());
740 }
741 for (auto& dex : compilation_sources_raw) {
742 class_loader_1_dex_files.push_back(dex);
743 }
744 VerifyClassLoaderDexFiles(soa,
745 class_loader_1,
746 WellKnownClasses::dalvik_system_PathClassLoader,
747 class_loader_1_dex_files);
748
749 // Verify the second class loader
750 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
751 std::vector<const DexFile*> class_loader_2_dex_files =
752 MakeNonOwningPointerVector(classpath_dex_c);
753 VerifyClassLoaderDexFiles(soa,
754 class_loader_2,
755 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
756 class_loader_2_dex_files);
757
758 // Verify the third class loader
759 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
760 std::vector<const DexFile*> class_loader_3_dex_files =
761 MakeNonOwningPointerVector(classpath_dex_d);
762 VerifyClassLoaderDexFiles(soa,
763 class_loader_3,
764 WellKnownClasses::dalvik_system_PathClassLoader,
765 class_loader_3_dex_files);
766 // The last class loader should have the BootClassLoader as a parent.
767 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
768 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
769}
770
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +0000771TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
772 // Setup the context.
773 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
774 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
775 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
776 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
777
778 std::string context_spec =
779 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" +
780 "DLC[" + CreateClassPath(classpath_dex_c) + "]#" +
781 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
782
783 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
Calin Juravle5ff23932020-12-11 18:26:14 -0800784 ASSERT_TRUE(context->OpenDexFiles());
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +0000785
786 // Setup the compilation sources.
787 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
788 std::vector<const DexFile*> compilation_sources_raw =
789 MakeNonOwningPointerVector(compilation_sources);
790
791 // Create the class loader.
792 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
793 ASSERT_TRUE(jclass_loader != nullptr);
794
795 // Verify the class loader.
796 ScopedObjectAccess soa(Thread::Current());
797
798 StackHandleScope<4> hs(soa.Self());
799 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
800 soa.Decode<mirror::ClassLoader>(jclass_loader));
801
802 // For the first class loader the class path dex files must come first and then the
803 // compilation sources.
804 std::vector<const DexFile*> class_loader_1_dex_files =
805 MakeNonOwningPointerVector(classpath_dex_a);
806 for (auto& dex : classpath_dex_b) {
807 class_loader_1_dex_files.push_back(dex.get());
808 }
809 for (auto& dex : compilation_sources_raw) {
810 class_loader_1_dex_files.push_back(dex);
811 }
812 VerifyClassLoaderDexFiles(soa,
813 class_loader_1,
814 WellKnownClasses::dalvik_system_PathClassLoader,
815 class_loader_1_dex_files);
816
817 // Verify the shared libraries.
818 ArtField* field =
819 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
820 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
821 ASSERT_TRUE(raw_shared_libraries != nullptr);
822
823 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
824 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
825 ASSERT_EQ(shared_libraries->GetLength(), 2);
826
827 // Verify the first shared library.
828 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
829 std::vector<const DexFile*> class_loader_2_dex_files =
830 MakeNonOwningPointerVector(classpath_dex_c);
831 VerifyClassLoaderDexFiles(soa,
832 class_loader_2,
833 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
834 class_loader_2_dex_files);
835 raw_shared_libraries = field->GetObject(class_loader_2.Get());
836 ASSERT_TRUE(raw_shared_libraries == nullptr);
837
838 // Verify the second shared library.
839 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
840 std::vector<const DexFile*> class_loader_3_dex_files =
841 MakeNonOwningPointerVector(classpath_dex_d);
842 VerifyClassLoaderDexFiles(soa,
843 class_loader_3,
844 WellKnownClasses::dalvik_system_PathClassLoader,
845 class_loader_3_dex_files);
846 raw_shared_libraries = field->GetObject(class_loader_3.Get());
847 ASSERT_TRUE(raw_shared_libraries == nullptr);
848
849 // All class loaders should have the BootClassLoader as a parent.
850 ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
851 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
852 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
853 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
854 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
855 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
856}
857
858TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
859 // Setup the context.
860 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
861 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
862 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
863 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
864
865 std::string context_spec =
866 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
867 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
868 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
869 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
870
871 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
Calin Juravle5ff23932020-12-11 18:26:14 -0800872 ASSERT_TRUE(context->OpenDexFiles());
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +0000873
874 // Setup the compilation sources.
875 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
876 std::vector<const DexFile*> compilation_sources_raw =
877 MakeNonOwningPointerVector(compilation_sources);
878
879 // Create the class loader.
880 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
881 ASSERT_TRUE(jclass_loader != nullptr);
882
883 // Verify the class loader.
884 ScopedObjectAccess soa(Thread::Current());
885
886 StackHandleScope<6> hs(soa.Self());
887 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
888 soa.Decode<mirror::ClassLoader>(jclass_loader));
889
890 // For the first class loader the class path dex files must come first and then the
891 // compilation sources.
892 std::vector<const DexFile*> class_loader_1_dex_files =
893 MakeNonOwningPointerVector(classpath_dex_a);
894 for (auto& dex : compilation_sources_raw) {
895 class_loader_1_dex_files.push_back(dex);
896 }
897 VerifyClassLoaderDexFiles(soa,
898 class_loader_1,
899 WellKnownClasses::dalvik_system_PathClassLoader,
900 class_loader_1_dex_files);
901
902 // Verify its shared library.
903 ArtField* field =
904 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
905 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
906 ASSERT_TRUE(raw_shared_libraries != nullptr);
907
908 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
909 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
910 ASSERT_EQ(shared_libraries->GetLength(), 1);
911
912 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
913 std::vector<const DexFile*> class_loader_2_dex_files =
914 MakeNonOwningPointerVector(classpath_dex_b);
915 VerifyClassLoaderDexFiles(soa,
916 class_loader_2,
917 WellKnownClasses::dalvik_system_PathClassLoader,
918 class_loader_2_dex_files);
919 raw_shared_libraries = field->GetObject(class_loader_2.Get());
920 ASSERT_TRUE(raw_shared_libraries == nullptr);
921
922 // Verify the parent.
923 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
924 std::vector<const DexFile*> class_loader_3_dex_files =
925 MakeNonOwningPointerVector(classpath_dex_c);
926 VerifyClassLoaderDexFiles(soa,
927 class_loader_3,
928 WellKnownClasses::dalvik_system_PathClassLoader,
929 class_loader_3_dex_files);
930
931 // Verify its shared library.
932 raw_shared_libraries = field->GetObject(class_loader_3.Get());
933 ASSERT_TRUE(raw_shared_libraries != nullptr);
934
935 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
936 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
937 ASSERT_EQ(shared_libraries->GetLength(), 1);
938
939 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
940 std::vector<const DexFile*> class_loader_4_dex_files =
941 MakeNonOwningPointerVector(classpath_dex_d);
942 VerifyClassLoaderDexFiles(soa,
943 class_loader_4,
944 WellKnownClasses::dalvik_system_PathClassLoader,
945 class_loader_4_dex_files);
946 raw_shared_libraries = field->GetObject(class_loader_4.Get());
947 ASSERT_TRUE(raw_shared_libraries == nullptr);
948
949 // Class loaders should have the BootClassLoader as a parent.
950 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
951 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
952 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
953 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
954 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
955 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
956}
957
958TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
959 // Setup the context.
960 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
961 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
962 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
963 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
964
965 std::string context_spec =
966 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
967 "PCL[" + CreateClassPath(classpath_dex_b) + "]{" +
968 "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" +
969 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
970
971 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
Calin Juravle5ff23932020-12-11 18:26:14 -0800972 ASSERT_TRUE(context->OpenDexFiles());
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +0000973
974 // Setup the compilation sources.
975 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
976 std::vector<const DexFile*> compilation_sources_raw =
977 MakeNonOwningPointerVector(compilation_sources);
978
979 // Create the class loader.
980 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
981 ASSERT_TRUE(jclass_loader != nullptr);
982
983 // Verify the class loader.
984 ScopedObjectAccess soa(Thread::Current());
985
986 StackHandleScope<6> hs(soa.Self());
987 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
988 soa.Decode<mirror::ClassLoader>(jclass_loader));
989
990 // For the first class loader the class path dex files must come first and then the
991 // compilation sources.
992 std::vector<const DexFile*> class_loader_1_dex_files =
993 MakeNonOwningPointerVector(classpath_dex_a);
994 for (auto& dex : compilation_sources_raw) {
995 class_loader_1_dex_files.push_back(dex);
996 }
997 VerifyClassLoaderDexFiles(soa,
998 class_loader_1,
999 WellKnownClasses::dalvik_system_PathClassLoader,
1000 class_loader_1_dex_files);
1001
1002 // Verify its shared library.
1003 ArtField* field =
1004 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
1005 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
1006 ASSERT_TRUE(raw_shared_libraries != nullptr);
1007
1008 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
1009 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1010 ASSERT_EQ(shared_libraries->GetLength(), 1);
1011
1012 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
1013 std::vector<const DexFile*> class_loader_2_dex_files =
1014 MakeNonOwningPointerVector(classpath_dex_b);
1015 VerifyClassLoaderDexFiles(soa,
1016 class_loader_2,
1017 WellKnownClasses::dalvik_system_PathClassLoader,
1018 class_loader_2_dex_files);
1019
1020 // Verify the shared library dependency of the shared library.
1021 raw_shared_libraries = field->GetObject(class_loader_2.Get());
1022 ASSERT_TRUE(raw_shared_libraries != nullptr);
1023
1024 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
1025 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1026 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
1027
1028 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
1029 std::vector<const DexFile*> class_loader_3_dex_files =
1030 MakeNonOwningPointerVector(classpath_dex_c);
1031 VerifyClassLoaderDexFiles(soa,
1032 class_loader_3,
1033 WellKnownClasses::dalvik_system_PathClassLoader,
1034 class_loader_3_dex_files);
1035 raw_shared_libraries = field->GetObject(class_loader_3.Get());
1036 ASSERT_TRUE(raw_shared_libraries == nullptr);
1037
1038 // Verify the parent.
1039 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
1040 std::vector<const DexFile*> class_loader_4_dex_files =
1041 MakeNonOwningPointerVector(classpath_dex_d);
1042 VerifyClassLoaderDexFiles(soa,
1043 class_loader_4,
1044 WellKnownClasses::dalvik_system_PathClassLoader,
1045 class_loader_4_dex_files);
1046 raw_shared_libraries = field->GetObject(class_loader_4.Get());
1047 ASSERT_TRUE(raw_shared_libraries == nullptr);
1048
1049 // Class loaders should have the BootClassLoader as a parent.
1050 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1051 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1052 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1053 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1054 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
1055 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1056}
Calin Juravlec79470d2017-07-12 17:37:42 -07001057
Calin Juravle87e2cb62017-06-13 21:48:45 -07001058TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
1059 std::unique_ptr<ClassLoaderContext> context =
1060 ClassLoaderContext::Create("PCL[a.dex]");
1061 dchecked_vector<std::string> classpath_dex;
1062 classpath_dex.push_back("a.dex");
1063 dchecked_vector<std::string> compilation_sources;
1064 compilation_sources.push_back("src.dex");
1065
1066 // Nothing should be removed.
1067 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
1068 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
1069 // Classes should be removed.
1070 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
1071 VerifyClassLoaderPCL(context.get(), 0, "");
1072}
1073
Nicolas Geoffraycb2e1dd2018-11-20 11:15:13 +00001074TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
1075 // Setup the context.
1076 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
1077 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
1078 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
1079
1080 std::string context_spec =
1081 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
1082 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
1083 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
1084 "PCL[" + CreateClassPath(classpath_dex_b) + "]}";
1085
1086 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
Calin Juravle5ff23932020-12-11 18:26:14 -08001087 ASSERT_TRUE(context->OpenDexFiles());
Nicolas Geoffraycb2e1dd2018-11-20 11:15:13 +00001088
1089 // Setup the compilation sources.
1090 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
1091 std::vector<const DexFile*> compilation_sources_raw =
1092 MakeNonOwningPointerVector(compilation_sources);
1093
1094 // Create the class loader.
1095 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
1096 ASSERT_TRUE(jclass_loader != nullptr);
1097
1098 // Verify the class loader.
1099 ScopedObjectAccess soa(Thread::Current());
1100
1101 StackHandleScope<6> hs(soa.Self());
1102 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
1103 soa.Decode<mirror::ClassLoader>(jclass_loader));
1104
1105 // For the first class loader the class path dex files must come first and then the
1106 // compilation sources.
1107 std::vector<const DexFile*> class_loader_1_dex_files =
1108 MakeNonOwningPointerVector(classpath_dex_a);
1109 for (auto& dex : compilation_sources_raw) {
1110 class_loader_1_dex_files.push_back(dex);
1111 }
1112 VerifyClassLoaderDexFiles(soa,
1113 class_loader_1,
1114 WellKnownClasses::dalvik_system_PathClassLoader,
1115 class_loader_1_dex_files);
1116
1117 // Verify its shared library.
1118 ArtField* field =
1119 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
1120 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
1121 ASSERT_TRUE(raw_shared_libraries != nullptr);
1122
1123 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
1124 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1125 ASSERT_EQ(shared_libraries->GetLength(), 1);
1126
1127 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
1128 std::vector<const DexFile*> class_loader_2_dex_files =
1129 MakeNonOwningPointerVector(classpath_dex_b);
1130 VerifyClassLoaderDexFiles(soa,
1131 class_loader_2,
1132 WellKnownClasses::dalvik_system_PathClassLoader,
1133 class_loader_2_dex_files);
1134
1135 // Verify the parent.
1136 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
1137 std::vector<const DexFile*> class_loader_3_dex_files =
1138 MakeNonOwningPointerVector(classpath_dex_c);
1139 VerifyClassLoaderDexFiles(soa,
1140 class_loader_3,
1141 WellKnownClasses::dalvik_system_PathClassLoader,
1142 class_loader_3_dex_files);
1143
1144 // Verify its shared library is the same as the child.
1145 raw_shared_libraries = field->GetObject(class_loader_3.Get());
1146 ASSERT_TRUE(raw_shared_libraries != nullptr);
1147 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
1148 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1149 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
Vladimir Marko423bebb2019-03-26 15:17:21 +00001150 ASSERT_OBJ_PTR_EQ(shared_libraries_2->Get(0), class_loader_2.Get());
Nicolas Geoffraycb2e1dd2018-11-20 11:15:13 +00001151
1152 // Class loaders should have the BootClassLoader as a parent.
1153 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1154 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1155 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1156 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1157}
1158
Calin Juravle87e2cb62017-06-13 21:48:45 -07001159TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
1160 std::string dex1_name = GetTestDexFileName("Main");
1161 std::string dex2_name = GetTestDexFileName("MyClass");
1162 std::unique_ptr<ClassLoaderContext> context =
1163 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
Calin Juravle5ff23932020-12-11 18:26:14 -08001164 ASSERT_TRUE(context->OpenDexFiles());
Calin Juravle87e2cb62017-06-13 21:48:45 -07001165
1166 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1167 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1168 std::string encoding = context->EncodeContextForOatFile("");
Calin Juravlec79470d2017-07-12 17:37:42 -07001169 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
1170 CreateClassPathWithChecksums(dex2) + "]";
Calin Juravle87e2cb62017-06-13 21:48:45 -07001171 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1172}
1173
David Brazdil93d339d2019-03-27 09:56:45 +00001174TEST_F(ClassLoaderContextTest, EncodeInOatFileIMC) {
1175 jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1176 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1177
1178 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
Calin Juravle5ff23932020-12-11 18:26:14 -08001179 ASSERT_TRUE(context->OpenDexFiles());
David Brazdil93d339d2019-03-27 09:56:45 +00001180
1181 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1182 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1183 ASSERT_EQ(dex2.size(), 1u);
1184
1185 std::string encoding = context->EncodeContextForOatFile("");
1186 std::string expected_encoding = "IMC[<unknown>*" + std::to_string(dex2[0]->GetLocationChecksum())
1187 + "];PCL[" + CreateClassPathWithChecksums(dex1) + "]";
1188 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1189}
1190
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001191TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
1192 std::string dex1_name = GetTestDexFileName("Main");
1193 std::string dex2_name = GetTestDexFileName("MultiDex");
1194 std::unique_ptr<ClassLoaderContext> context =
1195 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
Calin Juravle5ff23932020-12-11 18:26:14 -08001196 ASSERT_TRUE(context->OpenDexFiles());
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001197
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001198 std::string encoding = context->EncodeContextForDex2oat("");
1199 std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
1200 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1201}
1202
David Brazdil93d339d2019-03-27 09:56:45 +00001203TEST_F(ClassLoaderContextTest, EncodeForDex2oatIMC) {
1204 jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1205 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1206
1207 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
Calin Juravle5ff23932020-12-11 18:26:14 -08001208 ASSERT_TRUE(context->OpenDexFiles());
David Brazdil93d339d2019-03-27 09:56:45 +00001209
1210 std::string encoding = context->EncodeContextForDex2oat("");
1211 std::string expected_encoding = "IMC[<unknown>];PCL[" + GetTestDexFileName("Main") + "]";
1212 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1213}
1214
Dan Zimmermanb682ea42019-12-23 06:59:06 -08001215TEST_F(ClassLoaderContextTest, EncodeContextsSinglePath) {
1216 jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
1217 std::unique_ptr<ClassLoaderContext> context =
1218 CreateContextForClassLoader(class_loader);
1219
1220 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1221 ASSERT_EQ(1u, encodings.size());
1222 ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1223}
1224
1225TEST_F(ClassLoaderContextTest, EncodeContextsMultiDex) {
1226 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1227 std::unique_ptr<ClassLoaderContext> context =
1228 CreateContextForClassLoader(class_loader);
1229
1230 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1231 ASSERT_EQ(1u, encodings.size());
1232 ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("MultiDex")));
1233}
1234
1235TEST_F(ClassLoaderContextTest, EncodeContextsRepeatedMultiDex) {
1236 jobject top_class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1237 jobject middle_class_loader =
1238 LoadDexInPathClassLoader("Main", top_class_loader);
1239 jobject bottom_class_loader =
1240 LoadDexInPathClassLoader("MultiDex", middle_class_loader);
1241 std::unique_ptr<ClassLoaderContext> context =
1242 CreateContextForClassLoader(bottom_class_loader);
1243
1244 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1245 ASSERT_EQ(1u, encodings.size());
1246
1247 std::string main_dex_name = GetTestDexFileName("Main");
1248 std::string multidex_dex_name = GetTestDexFileName("MultiDex");
1249 ASSERT_EQ(
1250 "PCL[];PCL[" + main_dex_name + "];PCL[" + multidex_dex_name + "]",
1251 encodings.at(multidex_dex_name));
1252}
1253
1254TEST_F(ClassLoaderContextTest, EncodeContextsSinglePathWithShared) {
1255 jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);
1256
1257 ScopedObjectAccess soa(Thread::Current());
1258 StackHandleScope<1> hs(soa.Self());
1259 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1260 mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1261 soa.Self(),
1262 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1263 1));
1264 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1265
1266 jobject class_loader_b = LoadDexInPathClassLoader(
1267 "Main", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1268
1269 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1270
1271 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1272 ASSERT_EQ(1u, encodings.size());
1273 ASSERT_EQ(
1274 "PCL[]{PCL[" + GetTestDexFileName("MyClass") + "]}",
1275 encodings.at(GetTestDexFileName("Main")));
1276}
1277
1278TEST_F(ClassLoaderContextTest, EncodeContextsMultiplePaths) {
1279 jobject class_loader = LoadDexInPathClassLoader(
1280 std::vector<std::string>{ "Main", "MultiDex"}, nullptr);
1281
1282 std::unique_ptr<ClassLoaderContext> context =
1283 CreateContextForClassLoader(class_loader);
1284
1285 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1286 ASSERT_EQ(2u, encodings.size());
1287 ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1288 ASSERT_EQ(
1289 "PCL[" + GetTestDexFileName("Main") + "]", encodings.at(GetTestDexFileName("MultiDex")));
1290}
1291
1292TEST_F(ClassLoaderContextTest, EncodeContextsMultiplePathsWithShared) {
1293 jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);
1294
1295 ScopedObjectAccess soa(Thread::Current());
1296 StackHandleScope<1> hs(soa.Self());
1297 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1298 mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1299 soa.Self(),
1300 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1301 1));
1302 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1303
1304 jobject class_loader_b = LoadDexInPathClassLoader(
1305 std::vector<std::string> { "Main", "MultiDex" },
1306 nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1307
1308 std::unique_ptr<ClassLoaderContext> context =
1309 CreateContextForClassLoader(class_loader_b);
1310
1311 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1312 ASSERT_EQ(2u, encodings.size());
1313 const std::string context_suffix =
1314 "{PCL[" + GetTestDexFileName("MyClass") + "]}";
1315 ASSERT_EQ("PCL[]" + context_suffix, encodings.at(GetTestDexFileName("Main")));
1316 ASSERT_EQ(
1317 "PCL[" + GetTestDexFileName("Main") + "]" + context_suffix,
1318 encodings.at(GetTestDexFileName("MultiDex")));
1319}
1320
1321TEST_F(ClassLoaderContextTest, EncodeContextsIMC) {
1322 jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1323 jobject class_loader_b =
1324 LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1325
1326 std::unique_ptr<ClassLoaderContext> context =
1327 CreateContextForClassLoader(class_loader_b);
1328
1329 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1330 ASSERT_EQ(1u, encodings.size());
1331 ASSERT_EQ(
1332 "IMC[];PCL[" + GetTestDexFileName("Main") + "]",
1333 encodings.at("<unknown>"));
1334}
1335
1336TEST_F(ClassLoaderContextTest, EncodeContextsForSingleDex) {
1337 jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
1338 std::map<std::string, std::string> encodings =
1339 ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1340 ASSERT_EQ(1u, encodings.size());
1341 ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1342}
1343
1344static jobject CreateForeignClassLoader() {
1345 ScopedObjectAccess soa(Thread::Current());
1346 JNIEnv* env = soa.Env();
1347
1348 // We cannot instantiate a ClassLoader directly, so instead we allocate an Object to represent
1349 // our foreign ClassLoader (this works because the runtime does proper instanceof checks before
1350 // operating on this object.
1351 jmethodID ctor = env->GetMethodID(WellKnownClasses::java_lang_Object, "<init>", "()V");
1352 return env->NewObject(WellKnownClasses::java_lang_Object, ctor);
1353}
1354
1355TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedBase) {
1356 std::map<std::string, std::string> empty;
1357 ASSERT_EQ(
1358 empty, ClassLoaderContext::EncodeClassPathContextsForClassLoader(CreateForeignClassLoader()));
1359}
1360
1361TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChain) {
1362 jobject class_loader = LoadDexInPathClassLoader("Main", CreateForeignClassLoader());
1363 std::map<std::string, std::string> encodings =
1364 ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1365 ASSERT_EQ(1u, encodings.size());
1366 ASSERT_EQ(
1367 ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1368 encodings.at(GetTestDexFileName("Main")));
1369}
1370
1371TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChainMultiPath) {
1372 jobject class_loader = LoadDexInPathClassLoader(std::vector<std::string> { "Main", "MyClass" },
1373 CreateForeignClassLoader());
1374 std::map<std::string, std::string> encodings =
1375 ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1376 ASSERT_EQ(2u, encodings.size());
1377 ASSERT_EQ(
1378 ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1379 encodings.at(GetTestDexFileName("Main")));
1380 ASSERT_EQ(
1381 ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1382 encodings.at(GetTestDexFileName("MyClass")));
1383}
1384
1385TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChainMultiDex) {
1386 jobject class_loader = LoadDexInPathClassLoader("MultiDex", CreateForeignClassLoader());
1387 std::map<std::string, std::string> encodings =
1388 ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1389 ASSERT_EQ(1u, encodings.size());
1390 ASSERT_EQ(
1391 ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1392 encodings.at(GetTestDexFileName("MultiDex")));
1393}
1394
Dan Zimmermanc9fa7702020-01-31 13:35:12 -08001395TEST_F(ClassLoaderContextTest, IsValidEncoding) {
1396 ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[]"));
1397 ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[foo.dex]"));
1398 ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[foo.dex];PCL[bar.dex]"));
1399 ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("DLC[];PCL[bar.dex]"));
1400 ASSERT_TRUE(
1401 ClassLoaderContext::IsValidEncoding(
1402 ClassLoaderContext::kUnsupportedClassLoaderContextEncoding));
1403 ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("not_valid"));
1404 ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("[]"));
1405 ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("FCL[]"));
1406 ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("foo.dex:bar.dex"));
1407}
1408
Calin Juravle57d0acc2017-07-11 17:41:30 -07001409// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
1410TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
1411 // The chain is
1412 // ClassLoaderA (PathClassLoader)
1413 // ^
1414 // |
1415 // ClassLoaderB (DelegateLastClassLoader)
1416 // ^
1417 // |
1418 // ClassLoaderC (PathClassLoader)
1419 // ^
1420 // |
1421 // ClassLoaderD (DelegateLastClassLoader)
1422
1423 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1424 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1425 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1426 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1427
1428 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1429
1430 VerifyContextForClassLoader(context.get());
1431 VerifyContextSize(context.get(), 4);
1432
1433 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1434 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
1435 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
1436 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1437}
1438
David Brazdil1a9ac532019-03-05 11:57:13 +00001439TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderIMC) {
1440 // The chain is
1441 // ClassLoaderA (PathClassLoader)
1442 // ^
1443 // |
1444 // ClassLoaderB (InMemoryDexClassLoader)
1445 // ^
1446 // |
1447 // ClassLoaderC (InMemoryDexClassLoader)
1448 // ^
1449 // |
1450 // ClassLoaderD (DelegateLastClassLoader)
1451
1452 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1453 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1454 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1455 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1456
1457 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1458
1459 VerifyContextForClassLoader(context.get());
1460 VerifyContextSize(context.get(), 4);
1461
1462 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1463 VerifyClassLoaderIMCFromTestDex(context.get(), 1, "ForClassLoaderC");
1464 VerifyClassLoaderIMCFromTestDex(context.get(), 2, "ForClassLoaderB");
1465 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1466}
Mathieu Chartieradc90862018-05-11 13:03:06 -07001467
Calin Juravle3f918642017-07-11 19:04:20 -07001468TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
1469 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
1470 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
Calin Juravlec5b215f2017-09-12 14:49:37 -07001471 // Pretend that we successfully open the dex files to pass the DCHECKS.
1472 // (as it's much easier to test all the corner cases without relying on actual dex files).
Calin Juravle6e6f1b22020-12-15 19:13:19 -08001473 PretendContextOpenedDexFilesForChecksums(context.get());
Calin Juravle3f918642017-07-11 19:04:20 -07001474
1475 VerifyContextSize(context.get(), 2);
1476 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1477 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1478
Mathieu Chartieradc90862018-05-11 13:03:06 -07001479 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1480 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001481
1482 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001483 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1484 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001485
1486 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001487 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1488 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001489
1490 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001491 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1492 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001493
1494 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001495 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1496 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001497
1498 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 -07001499 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1500 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001501
1502 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 -07001503 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1504 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001505
1506 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001507 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
1508 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001509}
1510
David Brazdil1a9ac532019-03-05 11:57:13 +00001511TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) {
David Brazdil93d339d2019-03-27 09:56:45 +00001512 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];IMC[<unknown>*111]";
David Brazdil1a9ac532019-03-05 11:57:13 +00001513 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1514 // Pretend that we successfully open the dex files to pass the DCHECKS.
1515 // (as it's much easier to test all the corner cases without relying on actual dex files).
1516 PretendContextOpenedDexFiles(context.get());
1517
1518 VerifyContextSize(context.get(), 3);
1519 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1520 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
David Brazdil93d339d2019-03-27 09:56:45 +00001521 VerifyClassLoaderIMC(context.get(), 2, "<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001522
1523 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1524 ClassLoaderContext::VerificationResult::kVerifies);
1525}
1526
Nicolas Geoffray06af3b42018-10-29 10:39:04 +00001527TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
1528 std::string context_spec =
1529 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1530 ";DLC[c.dex*890]";
1531 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1532 // Pretend that we successfully open the dex files to pass the DCHECKS.
1533 // (as it's much easier to test all the corner cases without relying on actual dex files).
1534 PretendContextOpenedDexFiles(context.get());
1535
1536 VerifyContextSize(context.get(), 2);
1537 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1538 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1539 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
1540 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
1541
1542 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1543 ClassLoaderContext::VerificationResult::kVerifies);
1544
1545 std::string wrong_class_loader_type =
1546 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1547 ";DLC[c.dex*890]";
1548 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1549 ClassLoaderContext::VerificationResult::kMismatch);
1550
1551 std::string wrong_class_loader_order =
1552 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
1553 ";DLC[c.dex*890]";
1554 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1555 ClassLoaderContext::VerificationResult::kMismatch);
1556
1557 std::string wrong_classpath_order =
1558 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1559 ";DLC[c.dex*890]";
1560 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1561 ClassLoaderContext::VerificationResult::kMismatch);
1562
1563 std::string wrong_checksum =
1564 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1565 ";DLC[c.dex*890]";
1566 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1567 ClassLoaderContext::VerificationResult::kMismatch);
1568
1569 std::string wrong_extra_class_loader =
1570 "PCL[a.dex*123:b.dex*456]"
1571 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
1572 ";DLC[c.dex*890]";
1573 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1574 ClassLoaderContext::VerificationResult::kMismatch);
1575
1576 std::string wrong_extra_classpath =
1577 "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]}"
1578 ";DLC[c.dex*890]";
1579 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1580 ClassLoaderContext::VerificationResult::kMismatch);
1581}
1582
David Brazdil1a9ac532019-03-05 11:57:13 +00001583TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithIMCSL) {
1584 std::string context_spec =
David Brazdil93d339d2019-03-27 09:56:45 +00001585 "IMC[<unknown>*123:<unknown>*456]"
1586 "{IMC[<unknown>*321];IMC[<unknown>*654]#IMC[<unknown>*098:<unknown>*999]};"
1587 "DLC[c.dex*890]";
David Brazdil1a9ac532019-03-05 11:57:13 +00001588 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1589 // Pretend that we successfully open the dex files to pass the DCHECKS.
1590 // (as it's much easier to test all the corner cases without relying on actual dex files).
1591 PretendContextOpenedDexFiles(context.get());
1592
1593 VerifyContextSize(context.get(), 2);
David Brazdil93d339d2019-03-27 09:56:45 +00001594 VerifyClassLoaderIMC(context.get(), 0, "<unknown>:<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001595 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
David Brazdil93d339d2019-03-27 09:56:45 +00001596 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, "<unknown>");
1597 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, "<unknown>:<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001598
1599 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1600 ClassLoaderContext::VerificationResult::kVerifies);
1601}
1602
Calin Juravle3f918642017-07-11 19:04:20 -07001603TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
1604 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1605 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1606 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1607 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1608
1609 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1610
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001611 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
Mathieu Chartieradc90862018-05-11 13:03:06 -07001612 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1613 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001614
1615 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1616 size_t pos = dex_location.rfind('/');
1617 ASSERT_NE(std::string::npos, pos);
1618 std::string parent = dex_location.substr(0, pos);
1619
1620 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1621 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
Mathieu Chartieradc90862018-05-11 13:03:06 -07001622 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1623 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001624}
1625
David Brazdil1a9ac532019-03-05 11:57:13 +00001626TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingIMC) {
1627 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1628 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1629 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1630 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1631
1632 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1633
1634 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1635 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1636 ClassLoaderContext::VerificationResult::kVerifies);
1637
1638 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1639 size_t pos = dex_location.rfind('/');
1640 ASSERT_NE(std::string::npos, pos);
1641 std::string parent = dex_location.substr(0, pos);
1642
1643 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1644 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1645 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1646 ClassLoaderContext::VerificationResult::kVerifies);
1647}
1648
Calin Juravlea308a322017-07-18 16:51:51 -07001649TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
1650 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1651
1652 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1653
Vladimir Marko36ec5982019-11-28 10:55:16 +00001654 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1655 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1656 ClassLoaderContext::VerificationResult::kVerifies);
1657
1658 std::string dex_location = GetTestDexFileName("MultiDex");
1659 size_t pos = dex_location.rfind('/');
1660 ASSERT_NE(std::string::npos, pos);
1661 std::string parent = dex_location.substr(0, pos);
1662
1663 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1664 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1665 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
Mathieu Chartieradc90862018-05-11 13:03:06 -07001666 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravlea308a322017-07-18 16:51:51 -07001667}
1668
Nicolas Geoffraye1672732018-11-30 01:09:49 +00001669TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderWithSharedLibraries) {
1670 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1671
1672 ScopedObjectAccess soa(Thread::Current());
1673 StackHandleScope<1> hs(soa.Self());
1674 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1675 mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1676 soa.Self(),
1677 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1678 1));
1679 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1680
1681 jobject class_loader_b = LoadDexInPathClassLoader(
1682 "ForClassLoaderB", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1683
1684 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1685 ASSERT_TRUE(context != nullptr);
1686 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ForClassLoaderB");
1687 VerifyClassLoaderPCL(context.get(), 0, dex_files[0]->GetLocation());
1688 dex_files = OpenTestDexFiles("ForClassLoaderA");
1689 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, dex_files[0]->GetLocation());
1690
1691 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1692 ClassLoaderContext::VerificationResult::kVerifies);
1693}
1694
Calin Juravlea63a2e92020-04-15 20:02:00 -07001695TEST_F(ClassLoaderContextTest, CheckForDuplicateDexFilesNotFoundSingleCL) {
1696 jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
Calin Juravleb495e7f2020-04-06 19:29:45 -07001697
Calin Juravlea63a2e92020-04-15 20:02:00 -07001698 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
Calin Juravleb495e7f2020-04-06 19:29:45 -07001699
Calin Juravlea63a2e92020-04-15 20:02:00 -07001700 std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(
Calin Juravleb495e7f2020-04-06 19:29:45 -07001701 std::vector<const DexFile*>());
1702 ASSERT_EQ(0u, result.size());
1703
Calin Juravlea63a2e92020-04-15 20:02:00 -07001704 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("ForClassLoaderA");
Calin Juravleb495e7f2020-04-06 19:29:45 -07001705 std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
1706 result = context->CheckForDuplicateDexFiles(dex1_raw);
Calin Juravlea63a2e92020-04-15 20:02:00 -07001707 ASSERT_EQ(0u, result.size());
1708}
1709
1710TEST_F(ClassLoaderContextTest, CheckForDuplicateDexFilesFound) {
1711 jobject class_loader = LoadDexInPathClassLoader(std::vector<std::string> { "Main", "Main" }, nullptr);
1712
1713 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1714
1715 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1716 std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
1717 std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(dex1_raw);
1718 ASSERT_EQ(1u, result.size()) << context->EncodeContextForOatFile("");
1719 ASSERT_EQ(dex1_raw[0], *(result.begin()));
1720}
1721
1722
1723TEST_F(ClassLoaderContextTest, CheckForDuplicateCrossCLNotFound) {
1724 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1725 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1726
1727 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1728
1729 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("ForClassLoaderA");
1730 std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
1731 std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(dex1_raw);
1732 ASSERT_EQ(0u, result.size());
Calin Juravleb495e7f2020-04-06 19:29:45 -07001733}
1734
Calin Juravle87e2cb62017-06-13 21:48:45 -07001735} // namespace art