blob: 0fa4619e07fc6035b2499018e9870101bb5d6c23 [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
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000287TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) {
288 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
289 "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}");
290 VerifyContextSize(context.get(), 1);
291 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex");
292}
293
294TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) {
295 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
296 "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#"
297 "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}");
298 VerifyContextSize(context.get(), 1);
299 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
300 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex");
301 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex");
302 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex");
303 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex");
304}
305
Calin Juravle87e2cb62017-06-13 21:48:45 -0700306TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
307 std::unique_ptr<ClassLoaderContext> context =
308 ClassLoaderContext::Create("DLC[]");
309 VerifyContextSize(context.get(), 1);
310 VerifyClassLoaderDLC(context.get(), 0, "");
311}
312
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000313TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
314 std::unique_ptr<ClassLoaderContext> context =
315 ClassLoaderContext::Create("DLC[]{}");
316 VerifyContextSize(context.get(), 1);
317 VerifySharedLibrariesSize(context.get(), 0, 0);
318}
319
Calin Juravle87e2cb62017-06-13 21:48:45 -0700320TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) {
321 std::unique_ptr<ClassLoaderContext> context =
322 ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary);
323 VerifyContextSize(context.get(), 0);
324}
325
326TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
327 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
328 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
329 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
330 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
331 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
332 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000333 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
334 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
335 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
336 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
337 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000338 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}"));
339 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}"));
340 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}"));
341 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}"));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700342}
343
344TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
345 std::unique_ptr<ClassLoaderContext> context =
346 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
347 VerifyContextSize(context.get(), 1);
348 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
349}
350
351TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
352 std::string multidex_name = GetTestDexFileName("MultiDex");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700353 std::string myclass_dex_name = GetTestDexFileName("MyClass");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700354 std::string dex_name = GetTestDexFileName("Main");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700355
Calin Juravle92003fe2017-09-06 02:22:57 +0000356
Calin Juravle87e2cb62017-06-13 21:48:45 -0700357 std::unique_ptr<ClassLoaderContext> context =
358 ClassLoaderContext::Create(
359 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
360 "DLC[" + dex_name + "]");
361
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700362 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700363
364 VerifyContextSize(context.get(), 2);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700365
Calin Juravlec5b215f2017-09-12 14:49:37 -0700366 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
367 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
368 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
369 all_dex_files0.emplace_back(myclass_dex_files[i].release());
370 }
371 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
372
373 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
374 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700375}
376
Alex Light77ef93b2018-01-12 11:18:31 -0800377// Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
378// TODO We should somehow support this in all situations. b/72042237.
379static bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100380 int cwd_len = strlen(cwd);
381 if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
Alex Light77ef93b2018-01-12 11:18:31 -0800382 return false;
Andreas Gampe72527382017-09-02 16:53:03 -0700383 }
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100384 bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
385 int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
Alex Light77ef93b2018-01-12 11:18:31 -0800386 *out = in.substr(start_position);
387 return true;
Andreas Gampe72527382017-09-02 16:53:03 -0700388}
389
390TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
391 char cwd_buf[4096];
392 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
393 PLOG(FATAL) << "Could not get working directory";
394 }
Alex Light77ef93b2018-01-12 11:18:31 -0800395 std::string multidex_name;
396 std::string myclass_dex_name;
397 std::string dex_name;
398 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
399 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
400 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
401 LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
402 << "relative path.";
403 SUCCEED();
404 return;
405 }
Andreas Gampe72527382017-09-02 16:53:03 -0700406
407
408 std::unique_ptr<ClassLoaderContext> context =
409 ClassLoaderContext::Create(
410 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
411 "DLC[" + dex_name + "]");
412
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700413 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Andreas Gampe72527382017-09-02 16:53:03 -0700414
Calin Juravlec5b215f2017-09-12 14:49:37 -0700415 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
416 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
417 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
418 all_dex_files0.emplace_back(myclass_dex_files[i].release());
419 }
420 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700421
Calin Juravlec5b215f2017-09-12 14:49:37 -0700422 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
423 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700424}
425
426TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
427 char cwd_buf[4096];
428 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
429 PLOG(FATAL) << "Could not get working directory";
430 }
Alex Light77ef93b2018-01-12 11:18:31 -0800431 std::string multidex_name;
432 std::string myclass_dex_name;
433 std::string dex_name;
434 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
435 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
436 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
437 LOG(ERROR) << "Test OpenValidDexFilesClasspathDir cannot be run because target dex files have "
438 << "no relative path.";
439 SUCCEED();
440 return;
441 }
Andreas Gampe72527382017-09-02 16:53:03 -0700442 std::unique_ptr<ClassLoaderContext> context =
443 ClassLoaderContext::Create(
444 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
445 "DLC[" + dex_name + "]");
446
447 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, cwd_buf));
448
449 VerifyContextSize(context.get(), 2);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700450 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
451 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
452 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
453 all_dex_files0.emplace_back(myclass_dex_files[i].release());
454 }
455 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700456
Calin Juravlec5b215f2017-09-12 14:49:37 -0700457 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
458 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700459}
460
Calin Juravle87e2cb62017-06-13 21:48:45 -0700461TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
462 std::string dex_name = GetTestDexFileName("Main");
463 std::unique_ptr<ClassLoaderContext> context =
464 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
465 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ""));
466}
467
468TEST_F(ClassLoaderContextTest, CreateClassLoader) {
469 std::string dex_name = GetTestDexFileName("Main");
470 std::unique_ptr<ClassLoaderContext> context =
471 ClassLoaderContext::Create("PCL[" + dex_name + "]");
472 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
473
474 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
475 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
476
477 std::vector<const DexFile*> compilation_sources_raw =
478 MakeNonOwningPointerVector(compilation_sources);
479 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
480 ASSERT_TRUE(jclass_loader != nullptr);
481
482 ScopedObjectAccess soa(Thread::Current());
483
Calin Juravlec79470d2017-07-12 17:37:42 -0700484 StackHandleScope<1> hs(soa.Self());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700485 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
486 soa.Decode<mirror::ClassLoader>(jclass_loader));
487
488 ASSERT_TRUE(class_loader->GetClass() ==
489 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
490 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
491 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
492
Calin Juravlec79470d2017-07-12 17:37:42 -0700493 // For the first class loader the class path dex files must come first and then the
494 // compilation sources.
495 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
496 for (auto& dex : compilation_sources_raw) {
497 expected_classpath.push_back(dex);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700498 }
499
Calin Juravlec79470d2017-07-12 17:37:42 -0700500 VerifyClassLoaderDexFiles(soa,
501 class_loader,
502 WellKnownClasses::dalvik_system_PathClassLoader,
503 expected_classpath);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700504}
505
Calin Juravle7b0648a2017-07-07 18:40:50 -0700506TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
507 std::unique_ptr<ClassLoaderContext> context =
508 ClassLoaderContext::Create("");
509 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
510
511 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
512
513 std::vector<const DexFile*> compilation_sources_raw =
514 MakeNonOwningPointerVector(compilation_sources);
515 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
516 ASSERT_TRUE(jclass_loader != nullptr);
517
518 ScopedObjectAccess soa(Thread::Current());
519
Calin Juravlec79470d2017-07-12 17:37:42 -0700520 StackHandleScope<1> hs(soa.Self());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700521 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
522 soa.Decode<mirror::ClassLoader>(jclass_loader));
523
Calin Juravlec79470d2017-07-12 17:37:42 -0700524 // An empty context should create a single PathClassLoader with only the compilation sources.
525 VerifyClassLoaderDexFiles(soa,
526 class_loader,
527 WellKnownClasses::dalvik_system_PathClassLoader,
528 compilation_sources_raw);
Calin Juravle7b0648a2017-07-07 18:40:50 -0700529 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
530 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Calin Juravle7b0648a2017-07-07 18:40:50 -0700531}
532
Calin Juravle1a509c82017-07-24 16:51:21 -0700533TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraryContext) {
534 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
535
536 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
537
538 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
539
540 std::vector<const DexFile*> compilation_sources_raw =
541 MakeNonOwningPointerVector(compilation_sources);
542 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
543 ASSERT_TRUE(jclass_loader != nullptr);
544
545 ScopedObjectAccess soa(Thread::Current());
546
547 StackHandleScope<1> hs(soa.Self());
548 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
549 soa.Decode<mirror::ClassLoader>(jclass_loader));
550
551 // A shared library context should create a single PathClassLoader with only the compilation
552 // sources.
553 VerifyClassLoaderDexFiles(soa,
554 class_loader,
555 WellKnownClasses::dalvik_system_PathClassLoader,
556 compilation_sources_raw);
557 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
558 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
559}
560
Calin Juravlec79470d2017-07-12 17:37:42 -0700561TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
562 // Setup the context.
563 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
564 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
565 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
566 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
567
568 std::string context_spec =
569 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
570 "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
571 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
572
573 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
574 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
575
576 // Setup the compilation sources.
577 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
578 std::vector<const DexFile*> compilation_sources_raw =
579 MakeNonOwningPointerVector(compilation_sources);
580
581 // Create the class loader.
582 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
583 ASSERT_TRUE(jclass_loader != nullptr);
584
585 // Verify the class loader.
586 ScopedObjectAccess soa(Thread::Current());
587
588 StackHandleScope<3> hs(soa.Self());
589 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
590 soa.Decode<mirror::ClassLoader>(jclass_loader));
591
592 // Verify the first class loader
593
594 // For the first class loader the class path dex files must come first and then the
595 // compilation sources.
596 std::vector<const DexFile*> class_loader_1_dex_files =
597 MakeNonOwningPointerVector(classpath_dex_a);
598 for (auto& dex : classpath_dex_b) {
599 class_loader_1_dex_files.push_back(dex.get());
600 }
601 for (auto& dex : compilation_sources_raw) {
602 class_loader_1_dex_files.push_back(dex);
603 }
604 VerifyClassLoaderDexFiles(soa,
605 class_loader_1,
606 WellKnownClasses::dalvik_system_PathClassLoader,
607 class_loader_1_dex_files);
608
609 // Verify the second class loader
610 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
611 std::vector<const DexFile*> class_loader_2_dex_files =
612 MakeNonOwningPointerVector(classpath_dex_c);
613 VerifyClassLoaderDexFiles(soa,
614 class_loader_2,
615 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
616 class_loader_2_dex_files);
617
618 // Verify the third class loader
619 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
620 std::vector<const DexFile*> class_loader_3_dex_files =
621 MakeNonOwningPointerVector(classpath_dex_d);
622 VerifyClassLoaderDexFiles(soa,
623 class_loader_3,
624 WellKnownClasses::dalvik_system_PathClassLoader,
625 class_loader_3_dex_files);
626 // The last class loader should have the BootClassLoader as a parent.
627 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
628 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
629}
630
631
Calin Juravle87e2cb62017-06-13 21:48:45 -0700632TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
633 std::unique_ptr<ClassLoaderContext> context =
634 ClassLoaderContext::Create("PCL[a.dex]");
635 dchecked_vector<std::string> classpath_dex;
636 classpath_dex.push_back("a.dex");
637 dchecked_vector<std::string> compilation_sources;
638 compilation_sources.push_back("src.dex");
639
640 // Nothing should be removed.
641 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
642 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
643 // Classes should be removed.
644 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
645 VerifyClassLoaderPCL(context.get(), 0, "");
646}
647
648TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
649 std::string dex1_name = GetTestDexFileName("Main");
650 std::string dex2_name = GetTestDexFileName("MyClass");
651 std::unique_ptr<ClassLoaderContext> context =
652 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
653 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
654
655 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
656 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
657 std::string encoding = context->EncodeContextForOatFile("");
Calin Juravlec79470d2017-07-12 17:37:42 -0700658 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
659 CreateClassPathWithChecksums(dex2) + "]";
Calin Juravle87e2cb62017-06-13 21:48:45 -0700660 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
661}
662
Calin Juravle27e0d1f2017-07-26 00:16:07 -0700663TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
664 std::string dex1_name = GetTestDexFileName("Main");
665 std::string dex2_name = GetTestDexFileName("MultiDex");
666 std::unique_ptr<ClassLoaderContext> context =
667 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
668 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
669
670 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
671 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MultiDex");
672 std::string encoding = context->EncodeContextForDex2oat("");
673 std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
674 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
675}
676
Calin Juravle57d0acc2017-07-11 17:41:30 -0700677// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
678TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
679 // The chain is
680 // ClassLoaderA (PathClassLoader)
681 // ^
682 // |
683 // ClassLoaderB (DelegateLastClassLoader)
684 // ^
685 // |
686 // ClassLoaderC (PathClassLoader)
687 // ^
688 // |
689 // ClassLoaderD (DelegateLastClassLoader)
690
691 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
692 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
693 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
694 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
695
696 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
697
698 VerifyContextForClassLoader(context.get());
699 VerifyContextSize(context.get(), 4);
700
701 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
702 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
703 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
704 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
705}
706
Mathieu Chartieradc90862018-05-11 13:03:06 -0700707
708TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) {
709 std::string context_spec = "PCL[]";
710 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
711 ASSERT_TRUE(context != nullptr);
712 PretendContextOpenedDexFiles(context.get());
713 // Ensure that the special shared library marks as verified for the first thing in the class path.
714 ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary),
715 ClassLoaderContext::VerificationResult::kVerifies);
716}
717
Calin Juravle3f918642017-07-11 19:04:20 -0700718TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
719 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
720 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700721 // Pretend that we successfully open the dex files to pass the DCHECKS.
722 // (as it's much easier to test all the corner cases without relying on actual dex files).
723 PretendContextOpenedDexFiles(context.get());
Calin Juravle3f918642017-07-11 19:04:20 -0700724
725 VerifyContextSize(context.get(), 2);
726 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
727 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
728
Mathieu Chartieradc90862018-05-11 13:03:06 -0700729 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
730 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -0700731
732 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700733 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
734 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700735
736 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700737 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
738 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700739
740 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700741 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
742 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700743
744 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700745 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
746 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700747
748 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 -0700749 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
750 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700751
752 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 -0700753 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
754 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700755
756 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
Mathieu Chartieradc90862018-05-11 13:03:06 -0700757 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
758 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -0700759}
760
Nicolas Geoffray9893c472018-11-13 15:39:53 +0000761TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) {
762 std::string context_spec = "&";
763 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
764 // Pretend that we successfully open the dex files to pass the DCHECKS.
765 // (as it's much easier to test all the corner cases without relying on actual dex files).
766 PretendContextOpenedDexFiles(context.get());
767
768 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
769 ClassLoaderContext::VerificationResult::kForcedToSkipChecks);
770}
771
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000772TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
773 std::string context_spec =
774 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
775 ";DLC[c.dex*890]";
776 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
777 // Pretend that we successfully open the dex files to pass the DCHECKS.
778 // (as it's much easier to test all the corner cases without relying on actual dex files).
779 PretendContextOpenedDexFiles(context.get());
780
781 VerifyContextSize(context.get(), 2);
782 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
783 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
784 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
785 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
786
787 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
788 ClassLoaderContext::VerificationResult::kVerifies);
789
790 std::string wrong_class_loader_type =
791 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
792 ";DLC[c.dex*890]";
793 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
794 ClassLoaderContext::VerificationResult::kMismatch);
795
796 std::string wrong_class_loader_order =
797 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
798 ";DLC[c.dex*890]";
799 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
800 ClassLoaderContext::VerificationResult::kMismatch);
801
802 std::string wrong_classpath_order =
803 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
804 ";DLC[c.dex*890]";
805 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
806 ClassLoaderContext::VerificationResult::kMismatch);
807
808 std::string wrong_checksum =
809 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
810 ";DLC[c.dex*890]";
811 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
812 ClassLoaderContext::VerificationResult::kMismatch);
813
814 std::string wrong_extra_class_loader =
815 "PCL[a.dex*123:b.dex*456]"
816 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
817 ";DLC[c.dex*890]";
818 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
819 ClassLoaderContext::VerificationResult::kMismatch);
820
821 std::string wrong_extra_classpath =
822 "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]}"
823 ";DLC[c.dex*890]";
824 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
825 ClassLoaderContext::VerificationResult::kMismatch);
826}
827
Calin Juravle3f918642017-07-11 19:04:20 -0700828TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
829 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
830 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
831 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
832 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
833
834 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
835
Calin Juravle1e96a5d2017-09-05 17:10:48 -0700836 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
Mathieu Chartieradc90862018-05-11 13:03:06 -0700837 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
838 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle1e96a5d2017-09-05 17:10:48 -0700839
840 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
841 size_t pos = dex_location.rfind('/');
842 ASSERT_NE(std::string::npos, pos);
843 std::string parent = dex_location.substr(0, pos);
844
845 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
846 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
Mathieu Chartieradc90862018-05-11 13:03:06 -0700847 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
848 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -0700849}
850
Calin Juravlea308a322017-07-18 16:51:51 -0700851TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
852 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
853
854 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
855
Mathieu Chartieradc90862018-05-11 13:03:06 -0700856 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
857 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravlea308a322017-07-18 16:51:51 -0700858}
859
Calin Juravle87e2cb62017-06-13 21:48:45 -0700860} // namespace art