blob: f3e2ac00bac54419873212f2de3b8b4f92de6e3c [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"
Calin Juravle87e2cb62017-06-13 21:48:45 -070022#include "base/dchecked_vector.h"
23#include "base/stl_util.h"
24#include "class_linker.h"
Calin Juravle821a2592017-08-11 14:33:38 -070025#include "common_runtime_test.h"
David Sehr9e734c72018-01-04 17:56:19 -080026#include "dex/dex_file.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070027#include "handle_scope-inl.h"
28#include "mirror/class.h"
29#include "mirror/class_loader.h"
30#include "mirror/object-inl.h"
31#include "oat_file_assistant.h"
32#include "runtime.h"
33#include "scoped_thread_state_change-inl.h"
34#include "thread.h"
35#include "well_known_classes.h"
36
37namespace art {
38
39class ClassLoaderContextTest : public CommonRuntimeTest {
40 public:
41 void VerifyContextSize(ClassLoaderContext* context, size_t expected_size) {
42 ASSERT_TRUE(context != nullptr);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000043 ASSERT_EQ(expected_size, context->GetParentChainSize());
Calin Juravle87e2cb62017-06-13 21:48:45 -070044 }
45
46 void VerifyClassLoaderPCL(ClassLoaderContext* context,
47 size_t index,
Calin Juravle57d0acc2017-07-11 17:41:30 -070048 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -070049 VerifyClassLoaderInfo(
50 context, index, ClassLoaderContext::kPathClassLoader, classpath);
51 }
52
53 void VerifyClassLoaderDLC(ClassLoaderContext* context,
54 size_t index,
Calin Juravle57d0acc2017-07-11 17:41:30 -070055 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -070056 VerifyClassLoaderInfo(
57 context, index, ClassLoaderContext::kDelegateLastClassLoader, classpath);
58 }
59
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000060 void VerifyClassLoaderSharedLibraryPCL(ClassLoaderContext* context,
61 size_t loader_index,
62 size_t shared_library_index,
63 const std::string& classpath) {
64 VerifyClassLoaderInfoSL(
65 context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
66 classpath);
67 }
68
69 void VerifySharedLibrariesSize(ClassLoaderContext* context,
70 size_t loader_index,
71 size_t expected_size) {
72 ASSERT_TRUE(context != nullptr);
73 ASSERT_GT(context->GetParentChainSize(), loader_index);
74 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
75 ASSERT_EQ(info.shared_libraries.size(), expected_size);
76 }
77
78 void VerifyClassLoaderSharedLibraryDLC(ClassLoaderContext* context,
79 size_t loader_index,
80 size_t shared_library_index,
81 const std::string& classpath) {
82 VerifyClassLoaderInfoSL(
83 context, loader_index, shared_library_index, ClassLoaderContext::kDelegateLastClassLoader,
84 classpath);
85 }
86
Calin Juravle57d0acc2017-07-11 17:41:30 -070087 void VerifyClassLoaderPCLFromTestDex(ClassLoaderContext* context,
88 size_t index,
89 const std::string& test_name) {
90 VerifyClassLoaderFromTestDex(
91 context, index, ClassLoaderContext::kPathClassLoader, test_name);
92 }
93
94 void VerifyClassLoaderDLCFromTestDex(ClassLoaderContext* context,
95 size_t index,
96 const std::string& test_name) {
97 VerifyClassLoaderFromTestDex(
98 context, index, ClassLoaderContext::kDelegateLastClassLoader, test_name);
99 }
100
Andreas Gampe72527382017-09-02 16:53:03 -0700101 enum class LocationCheck {
102 kEquals,
103 kEndsWith
104 };
105 enum class BaseLocationCheck {
106 kEquals,
107 kEndsWith
108 };
109
Calin Juravle92003fe2017-09-06 02:22:57 +0000110 static bool IsAbsoluteLocation(const std::string& location) {
111 return !location.empty() && location[0] == '/';
112 }
113
Calin Juravle87e2cb62017-06-13 21:48:45 -0700114 void VerifyOpenDexFiles(
115 ClassLoaderContext* context,
116 size_t index,
Calin Juravlec5b215f2017-09-12 14:49:37 -0700117 std::vector<std::unique_ptr<const DexFile>>* all_dex_files) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700118 ASSERT_TRUE(context != nullptr);
119 ASSERT_TRUE(context->dex_files_open_attempted_);
120 ASSERT_TRUE(context->dex_files_open_result_);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000121 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700122 ASSERT_EQ(all_dex_files->size(), info.classpath.size());
123 ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700124 size_t cur_open_dex_index = 0;
Calin Juravlec5b215f2017-09-12 14:49:37 -0700125 for (size_t k = 0; k < all_dex_files->size(); k++) {
126 std::unique_ptr<const DexFile>& opened_dex_file =
Calin Juravle87e2cb62017-06-13 21:48:45 -0700127 info.opened_dex_files[cur_open_dex_index++];
Calin Juravlec5b215f2017-09-12 14:49:37 -0700128 std::unique_ptr<const DexFile>& expected_dex_file = (*all_dex_files)[k];
Calin Juravle87e2cb62017-06-13 21:48:45 -0700129
Calin Juravle92003fe2017-09-06 02:22:57 +0000130 std::string expected_location = expected_dex_file->GetLocation();
Calin Juravle821a2592017-08-11 14:33:38 -0700131
Calin Juravle92003fe2017-09-06 02:22:57 +0000132 const std::string& opened_location = opened_dex_file->GetLocation();
133 if (!IsAbsoluteLocation(opened_location)) {
134 // If the opened location is relative (it was open from a relative path without a
135 // classpath_dir) it might not match the expected location which is absolute in tests).
136 // So we compare the endings (the checksum will validate it's actually the same file).
137 ASSERT_EQ(0, expected_location.compare(
138 expected_location.length() - opened_location.length(),
139 opened_location.length(),
140 opened_location));
141 } else {
142 ASSERT_EQ(expected_location, opened_location);
143 }
Calin Juravlec5b215f2017-09-12 14:49:37 -0700144 ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_dex_file->GetLocationChecksum());
Calin Juravle92003fe2017-09-06 02:22:57 +0000145 ASSERT_EQ(info.classpath[k], opened_location);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700146 }
147 }
148
Calin Juravle57d0acc2017-07-11 17:41:30 -0700149 std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) {
150 return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr);
151 }
152
Calin Juravle3f918642017-07-11 19:04:20 -0700153 std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) {
154 std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext());
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700155 if (!context->Parse(context_spec, /*parse_checksums=*/ true)) {
Calin Juravle3f918642017-07-11 19:04:20 -0700156 return nullptr;
157 }
158 return context;
159 }
160
Calin Juravle57d0acc2017-07-11 17:41:30 -0700161 void VerifyContextForClassLoader(ClassLoaderContext* context) {
162 ASSERT_TRUE(context != nullptr);
163 ASSERT_TRUE(context->dex_files_open_attempted_);
164 ASSERT_TRUE(context->dex_files_open_result_);
165 ASSERT_FALSE(context->owns_the_dex_files_);
166 ASSERT_FALSE(context->special_shared_library_);
167 }
168
Calin Juravlec79470d2017-07-12 17:37:42 -0700169 void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa,
170 Handle<mirror::ClassLoader> class_loader,
171 jclass type,
172 std::vector<const DexFile*>& expected_dex_files)
173 REQUIRES_SHARED(Locks::mutator_lock_) {
174 ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type));
175
176 std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa, class_loader);
177 ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());
178
179 for (size_t i = 0; i < expected_dex_files.size(); i++) {
180 ASSERT_EQ(expected_dex_files[i]->GetLocation(),
181 class_loader_dex_files[i]->GetLocation());
182 ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(),
183 class_loader_dex_files[i]->GetLocationChecksum());
184 }
185 }
186
Calin Juravlec5b215f2017-09-12 14:49:37 -0700187 void PretendContextOpenedDexFiles(ClassLoaderContext* context) {
188 context->dex_files_open_attempted_ = true;
189 context->dex_files_open_result_ = true;
190 }
191
Calin Juravle87e2cb62017-06-13 21:48:45 -0700192 private:
193 void VerifyClassLoaderInfo(ClassLoaderContext* context,
194 size_t index,
195 ClassLoaderContext::ClassLoaderType type,
Calin Juravle57d0acc2017-07-11 17:41:30 -0700196 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700197 ASSERT_TRUE(context != nullptr);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000198 ASSERT_GT(context->GetParentChainSize(), index);
199 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700200 ASSERT_EQ(type, info.type);
201 std::vector<std::string> expected_classpath;
202 Split(classpath, ':', &expected_classpath);
203 ASSERT_EQ(expected_classpath, info.classpath);
204 }
Calin Juravle57d0acc2017-07-11 17:41:30 -0700205
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000206 void VerifyClassLoaderInfoSL(ClassLoaderContext* context,
207 size_t loader_index,
208 size_t shared_library_index,
209 ClassLoaderContext::ClassLoaderType type,
210 const std::string& classpath) {
211 ASSERT_TRUE(context != nullptr);
212 ASSERT_GT(context->GetParentChainSize(), loader_index);
213 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
214 ASSERT_GT(info.shared_libraries.size(), shared_library_index);
215 const ClassLoaderContext::ClassLoaderInfo& sl =
216 *info.shared_libraries[shared_library_index].get();
217 ASSERT_EQ(type, info.type);
218 std::vector<std::string> expected_classpath;
219 Split(classpath, ':', &expected_classpath);
220 ASSERT_EQ(expected_classpath, sl.classpath);
221 }
222
Calin Juravle57d0acc2017-07-11 17:41:30 -0700223 void VerifyClassLoaderFromTestDex(ClassLoaderContext* context,
224 size_t index,
225 ClassLoaderContext::ClassLoaderType type,
226 const std::string& test_name) {
227 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str());
Calin Juravle57d0acc2017-07-11 17:41:30 -0700228
229 VerifyClassLoaderInfo(context, index, type, GetTestDexFileName(test_name.c_str()));
Calin Juravlec5b215f2017-09-12 14:49:37 -0700230 VerifyOpenDexFiles(context, index, &dex_files);
Calin Juravle57d0acc2017-07-11 17:41:30 -0700231 }
Calin Juravle87e2cb62017-06-13 21:48:45 -0700232};
233
Calin Juravle1a509c82017-07-24 16:51:21 -0700234TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) {
235 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("");
236 // An empty context should create a single empty PathClassLoader.
237 VerifyContextSize(context.get(), 1);
238 VerifyClassLoaderPCL(context.get(), 0, "");
239}
240
241TEST_F(ClassLoaderContextTest, ParseValidSharedLibraryContext) {
242 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
243 // An shared library context should have no class loader in the chain.
244 VerifyContextSize(context.get(), 0);
245}
246
Calin Juravle87e2cb62017-06-13 21:48:45 -0700247TEST_F(ClassLoaderContextTest, ParseValidContextPCL) {
248 std::unique_ptr<ClassLoaderContext> context =
249 ClassLoaderContext::Create("PCL[a.dex]");
250 VerifyContextSize(context.get(), 1);
251 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
252}
253
254TEST_F(ClassLoaderContextTest, ParseValidContextDLC) {
255 std::unique_ptr<ClassLoaderContext> context =
256 ClassLoaderContext::Create("DLC[a.dex]");
257 VerifyContextSize(context.get(), 1);
258 VerifyClassLoaderDLC(context.get(), 0, "a.dex");
259}
260
261TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
262 std::unique_ptr<ClassLoaderContext> context =
263 ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
264 VerifyContextSize(context.get(), 3);
265 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
266 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
267 VerifyClassLoaderPCL(context.get(), 2, "e.dex");
268}
269
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000270TEST_F(ClassLoaderContextTest, ParseSharedLibraries) {
271 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
272 "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]};DLC[c.dex:d.dex]{DLC[s4.dex]}");
273 VerifyContextSize(context.get(), 2);
274 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
275 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex");
276 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
277 VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex");
278}
279
280TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) {
281 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
282 "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}");
283 VerifyContextSize(context.get(), 1);
284 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
285}
286
Calin Juravle87e2cb62017-06-13 21:48:45 -0700287TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
288 std::unique_ptr<ClassLoaderContext> context =
289 ClassLoaderContext::Create("DLC[]");
290 VerifyContextSize(context.get(), 1);
291 VerifyClassLoaderDLC(context.get(), 0, "");
292}
293
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000294TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
295 std::unique_ptr<ClassLoaderContext> context =
296 ClassLoaderContext::Create("DLC[]{}");
297 VerifyContextSize(context.get(), 1);
298 VerifySharedLibrariesSize(context.get(), 0, 0);
299}
300
Calin Juravle87e2cb62017-06-13 21:48:45 -0700301TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) {
302 std::unique_ptr<ClassLoaderContext> context =
303 ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary);
304 VerifyContextSize(context.get(), 0);
305}
306
307TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
308 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
309 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
310 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
311 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
312 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
313 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000314 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
315 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
316 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
317 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
318 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700319}
320
321TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
322 std::unique_ptr<ClassLoaderContext> context =
323 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
324 VerifyContextSize(context.get(), 1);
325 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
326}
327
328TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
329 std::string multidex_name = GetTestDexFileName("MultiDex");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700330 std::string myclass_dex_name = GetTestDexFileName("MyClass");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700331 std::string dex_name = GetTestDexFileName("Main");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700332
Calin Juravle92003fe2017-09-06 02:22:57 +0000333
Calin Juravle87e2cb62017-06-13 21:48:45 -0700334 std::unique_ptr<ClassLoaderContext> context =
335 ClassLoaderContext::Create(
336 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
337 "DLC[" + dex_name + "]");
338
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700339 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700340
341 VerifyContextSize(context.get(), 2);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700342
Calin Juravlec5b215f2017-09-12 14:49:37 -0700343 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
344 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
345 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
346 all_dex_files0.emplace_back(myclass_dex_files[i].release());
347 }
348 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
349
350 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
351 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700352}
353
Alex Light77ef93b2018-01-12 11:18:31 -0800354// Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
355// TODO We should somehow support this in all situations. b/72042237.
356static bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100357 int cwd_len = strlen(cwd);
358 if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
Alex Light77ef93b2018-01-12 11:18:31 -0800359 return false;
Andreas Gampe72527382017-09-02 16:53:03 -0700360 }
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100361 bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
362 int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
Alex Light77ef93b2018-01-12 11:18:31 -0800363 *out = in.substr(start_position);
364 return true;
Andreas Gampe72527382017-09-02 16:53:03 -0700365}
366
367TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
368 char cwd_buf[4096];
369 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
370 PLOG(FATAL) << "Could not get working directory";
371 }
Alex Light77ef93b2018-01-12 11:18:31 -0800372 std::string multidex_name;
373 std::string myclass_dex_name;
374 std::string dex_name;
375 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
376 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
377 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
378 LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
379 << "relative path.";
380 SUCCEED();
381 return;
382 }
Andreas Gampe72527382017-09-02 16:53:03 -0700383
384
385 std::unique_ptr<ClassLoaderContext> context =
386 ClassLoaderContext::Create(
387 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
388 "DLC[" + dex_name + "]");
389
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700390 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Andreas Gampe72527382017-09-02 16:53:03 -0700391
Calin Juravlec5b215f2017-09-12 14:49:37 -0700392 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
393 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
394 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
395 all_dex_files0.emplace_back(myclass_dex_files[i].release());
396 }
397 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700398
Calin Juravlec5b215f2017-09-12 14:49:37 -0700399 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
400 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700401}
402
403TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
404 char cwd_buf[4096];
405 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
406 PLOG(FATAL) << "Could not get working directory";
407 }
Alex Light77ef93b2018-01-12 11:18:31 -0800408 std::string multidex_name;
409 std::string myclass_dex_name;
410 std::string dex_name;
411 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
412 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
413 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
414 LOG(ERROR) << "Test OpenValidDexFilesClasspathDir cannot be run because target dex files have "
415 << "no relative path.";
416 SUCCEED();
417 return;
418 }
Andreas Gampe72527382017-09-02 16:53:03 -0700419 std::unique_ptr<ClassLoaderContext> context =
420 ClassLoaderContext::Create(
421 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
422 "DLC[" + dex_name + "]");
423
424 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, cwd_buf));
425
426 VerifyContextSize(context.get(), 2);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700427 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
428 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
429 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
430 all_dex_files0.emplace_back(myclass_dex_files[i].release());
431 }
432 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700433
Calin Juravlec5b215f2017-09-12 14:49:37 -0700434 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
435 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700436}
437
Calin Juravle87e2cb62017-06-13 21:48:45 -0700438TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
439 std::string dex_name = GetTestDexFileName("Main");
440 std::unique_ptr<ClassLoaderContext> context =
441 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
442 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ""));
443}
444
445TEST_F(ClassLoaderContextTest, CreateClassLoader) {
446 std::string dex_name = GetTestDexFileName("Main");
447 std::unique_ptr<ClassLoaderContext> context =
448 ClassLoaderContext::Create("PCL[" + dex_name + "]");
449 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
450
451 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
452 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
453
454 std::vector<const DexFile*> compilation_sources_raw =
455 MakeNonOwningPointerVector(compilation_sources);
456 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
457 ASSERT_TRUE(jclass_loader != nullptr);
458
459 ScopedObjectAccess soa(Thread::Current());
460
Calin Juravlec79470d2017-07-12 17:37:42 -0700461 StackHandleScope<1> hs(soa.Self());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700462 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
463 soa.Decode<mirror::ClassLoader>(jclass_loader));
464
465 ASSERT_TRUE(class_loader->GetClass() ==
466 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
467 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
468 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
469
Calin Juravlec79470d2017-07-12 17:37:42 -0700470 // For the first class loader the class path dex files must come first and then the
471 // compilation sources.
472 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
473 for (auto& dex : compilation_sources_raw) {
474 expected_classpath.push_back(dex);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700475 }
476
Calin Juravlec79470d2017-07-12 17:37:42 -0700477 VerifyClassLoaderDexFiles(soa,
478 class_loader,
479 WellKnownClasses::dalvik_system_PathClassLoader,
480 expected_classpath);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700481}
482
Calin Juravle7b0648a2017-07-07 18:40:50 -0700483TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
484 std::unique_ptr<ClassLoaderContext> context =
485 ClassLoaderContext::Create("");
486 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
487
488 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
489
490 std::vector<const DexFile*> compilation_sources_raw =
491 MakeNonOwningPointerVector(compilation_sources);
492 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
493 ASSERT_TRUE(jclass_loader != nullptr);
494
495 ScopedObjectAccess soa(Thread::Current());
496
Calin Juravlec79470d2017-07-12 17:37:42 -0700497 StackHandleScope<1> hs(soa.Self());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700498 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
499 soa.Decode<mirror::ClassLoader>(jclass_loader));
500
Calin Juravlec79470d2017-07-12 17:37:42 -0700501 // An empty context should create a single PathClassLoader with only the compilation sources.
502 VerifyClassLoaderDexFiles(soa,
503 class_loader,
504 WellKnownClasses::dalvik_system_PathClassLoader,
505 compilation_sources_raw);
Calin Juravle7b0648a2017-07-07 18:40:50 -0700506 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
507 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Calin Juravle7b0648a2017-07-07 18:40:50 -0700508}
509
Calin Juravle1a509c82017-07-24 16:51:21 -0700510TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraryContext) {
511 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
512
513 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
514
515 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
516
517 std::vector<const DexFile*> compilation_sources_raw =
518 MakeNonOwningPointerVector(compilation_sources);
519 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
520 ASSERT_TRUE(jclass_loader != nullptr);
521
522 ScopedObjectAccess soa(Thread::Current());
523
524 StackHandleScope<1> hs(soa.Self());
525 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
526 soa.Decode<mirror::ClassLoader>(jclass_loader));
527
528 // A shared library context should create a single PathClassLoader with only the compilation
529 // sources.
530 VerifyClassLoaderDexFiles(soa,
531 class_loader,
532 WellKnownClasses::dalvik_system_PathClassLoader,
533 compilation_sources_raw);
534 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
535 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
536}
537
Calin Juravlec79470d2017-07-12 17:37:42 -0700538TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
539 // Setup the context.
540 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
541 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
542 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
543 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
544
545 std::string context_spec =
546 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
547 "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
548 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
549
550 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
551 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
552
553 // Setup the compilation sources.
554 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
555 std::vector<const DexFile*> compilation_sources_raw =
556 MakeNonOwningPointerVector(compilation_sources);
557
558 // Create the class loader.
559 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
560 ASSERT_TRUE(jclass_loader != nullptr);
561
562 // Verify the class loader.
563 ScopedObjectAccess soa(Thread::Current());
564
565 StackHandleScope<3> hs(soa.Self());
566 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
567 soa.Decode<mirror::ClassLoader>(jclass_loader));
568
569 // Verify the first class loader
570
571 // For the first class loader the class path dex files must come first and then the
572 // compilation sources.
573 std::vector<const DexFile*> class_loader_1_dex_files =
574 MakeNonOwningPointerVector(classpath_dex_a);
575 for (auto& dex : classpath_dex_b) {
576 class_loader_1_dex_files.push_back(dex.get());
577 }
578 for (auto& dex : compilation_sources_raw) {
579 class_loader_1_dex_files.push_back(dex);
580 }
581 VerifyClassLoaderDexFiles(soa,
582 class_loader_1,
583 WellKnownClasses::dalvik_system_PathClassLoader,
584 class_loader_1_dex_files);
585
586 // Verify the second class loader
587 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
588 std::vector<const DexFile*> class_loader_2_dex_files =
589 MakeNonOwningPointerVector(classpath_dex_c);
590 VerifyClassLoaderDexFiles(soa,
591 class_loader_2,
592 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
593 class_loader_2_dex_files);
594
595 // Verify the third class loader
596 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
597 std::vector<const DexFile*> class_loader_3_dex_files =
598 MakeNonOwningPointerVector(classpath_dex_d);
599 VerifyClassLoaderDexFiles(soa,
600 class_loader_3,
601 WellKnownClasses::dalvik_system_PathClassLoader,
602 class_loader_3_dex_files);
603 // The last class loader should have the BootClassLoader as a parent.
604 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
605 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
606}
607
608
Calin Juravle87e2cb62017-06-13 21:48:45 -0700609TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
610 std::unique_ptr<ClassLoaderContext> context =
611 ClassLoaderContext::Create("PCL[a.dex]");
612 dchecked_vector<std::string> classpath_dex;
613 classpath_dex.push_back("a.dex");
614 dchecked_vector<std::string> compilation_sources;
615 compilation_sources.push_back("src.dex");
616
617 // Nothing should be removed.
618 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
619 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
620 // Classes should be removed.
621 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
622 VerifyClassLoaderPCL(context.get(), 0, "");
623}
624
625TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
626 std::string dex1_name = GetTestDexFileName("Main");
627 std::string dex2_name = GetTestDexFileName("MyClass");
628 std::unique_ptr<ClassLoaderContext> context =
629 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
630 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
631
632 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
633 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
634 std::string encoding = context->EncodeContextForOatFile("");
Calin Juravlec79470d2017-07-12 17:37:42 -0700635 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
636 CreateClassPathWithChecksums(dex2) + "]";
Calin Juravle87e2cb62017-06-13 21:48:45 -0700637 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
638}
639
Calin Juravle27e0d1f2017-07-26 00:16:07 -0700640TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
641 std::string dex1_name = GetTestDexFileName("Main");
642 std::string dex2_name = GetTestDexFileName("MultiDex");
643 std::unique_ptr<ClassLoaderContext> context =
644 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
645 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
646
647 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
648 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MultiDex");
649 std::string encoding = context->EncodeContextForDex2oat("");
650 std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
651 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
652}
653
Calin Juravle57d0acc2017-07-11 17:41:30 -0700654// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
655TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
656 // The chain is
657 // ClassLoaderA (PathClassLoader)
658 // ^
659 // |
660 // ClassLoaderB (DelegateLastClassLoader)
661 // ^
662 // |
663 // ClassLoaderC (PathClassLoader)
664 // ^
665 // |
666 // ClassLoaderD (DelegateLastClassLoader)
667
668 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
669 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
670 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
671 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
672
673 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
674
675 VerifyContextForClassLoader(context.get());
676 VerifyContextSize(context.get(), 4);
677
678 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
679 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
680 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
681 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
682}
683
Mathieu Chartieradc90862018-05-11 13:03:06 -0700684
685TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) {
686 std::string context_spec = "PCL[]";
687 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
688 ASSERT_TRUE(context != nullptr);
689 PretendContextOpenedDexFiles(context.get());
690 // Ensure that the special shared library marks as verified for the first thing in the class path.
691 ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary),
692 ClassLoaderContext::VerificationResult::kVerifies);
693}
694
Calin Juravle3f918642017-07-11 19:04:20 -0700695TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
696 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
697 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700698 // Pretend that we successfully open the dex files to pass the DCHECKS.
699 // (as it's much easier to test all the corner cases without relying on actual dex files).
700 PretendContextOpenedDexFiles(context.get());
Calin Juravle3f918642017-07-11 19:04:20 -0700701
702 VerifyContextSize(context.get(), 2);
703 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
704 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
705
Mathieu Chartieradc90862018-05-11 13:03:06 -0700706 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
707 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -0700708
709 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700710 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
711 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700712
713 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700714 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
715 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700716
717 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700718 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
719 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700720
721 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700722 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
723 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700724
725 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 -0700726 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
727 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700728
729 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 -0700730 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
731 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700732
733 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700734 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
735 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700736}
737
Nicolas Geoffray9893c472018-11-13 15:39:53 +0000738TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) {
739 std::string context_spec = "&";
740 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
741 // Pretend that we successfully open the dex files to pass the DCHECKS.
742 // (as it's much easier to test all the corner cases without relying on actual dex files).
743 PretendContextOpenedDexFiles(context.get());
744
745 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
746 ClassLoaderContext::VerificationResult::kForcedToSkipChecks);
747}
748
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000749TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
750 std::string context_spec =
751 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
752 ";DLC[c.dex*890]";
753 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
754 // Pretend that we successfully open the dex files to pass the DCHECKS.
755 // (as it's much easier to test all the corner cases without relying on actual dex files).
756 PretendContextOpenedDexFiles(context.get());
757
758 VerifyContextSize(context.get(), 2);
759 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
760 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
761 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
762 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
763
764 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
765 ClassLoaderContext::VerificationResult::kVerifies);
766
767 std::string wrong_class_loader_type =
768 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
769 ";DLC[c.dex*890]";
770 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
771 ClassLoaderContext::VerificationResult::kMismatch);
772
773 std::string wrong_class_loader_order =
774 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
775 ";DLC[c.dex*890]";
776 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
777 ClassLoaderContext::VerificationResult::kMismatch);
778
779 std::string wrong_classpath_order =
780 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
781 ";DLC[c.dex*890]";
782 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
783 ClassLoaderContext::VerificationResult::kMismatch);
784
785 std::string wrong_checksum =
786 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
787 ";DLC[c.dex*890]";
788 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
789 ClassLoaderContext::VerificationResult::kMismatch);
790
791 std::string wrong_extra_class_loader =
792 "PCL[a.dex*123:b.dex*456]"
793 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
794 ";DLC[c.dex*890]";
795 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
796 ClassLoaderContext::VerificationResult::kMismatch);
797
798 std::string wrong_extra_classpath =
799 "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]}"
800 ";DLC[c.dex*890]";
801 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
802 ClassLoaderContext::VerificationResult::kMismatch);
803}
804
Calin Juravle3f918642017-07-11 19:04:20 -0700805TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
806 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
807 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
808 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
809 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
810
811 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
812
Calin Juravle1e96a5d2017-09-05 17:10:48 -0700813 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
Mathieu Chartieradc90862018-05-11 13:03:06 -0700814 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
815 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle1e96a5d2017-09-05 17:10:48 -0700816
817 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
818 size_t pos = dex_location.rfind('/');
819 ASSERT_NE(std::string::npos, pos);
820 std::string parent = dex_location.substr(0, pos);
821
822 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
823 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
Mathieu Chartieradc90862018-05-11 13:03:06 -0700824 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
825 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -0700826}
827
Calin Juravlea308a322017-07-18 16:51:51 -0700828TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
829 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
830
831 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
832
Mathieu Chartieradc90862018-05-11 13:03:06 -0700833 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
834 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravlea308a322017-07-18 16:51:51 -0700835}
836
Calin Juravle87e2cb62017-06-13 21:48:45 -0700837} // namespace art