blob: d9faaa418c8871da44bcb6e6509caa383141d1c0 [file] [log] [blame]
Calin Juravle19da1cf2017-07-12 18:52:49 -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
17package com.android.server.pm.dex;
18
19import static org.junit.Assert.assertEquals;
Calin Juravlef1ff36f2017-07-22 12:33:41 -070020import static org.junit.Assert.assertNotNull;
21import static org.junit.Assert.assertNull;
22import static org.junit.Assert.assertTrue;
Shubham Ajmera557c0542017-09-05 10:20:41 -070023import static org.junit.Assert.fail;
Calin Juravle19da1cf2017-07-12 18:52:49 -070024
25import android.content.pm.ApplicationInfo;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +000026import android.content.pm.SharedLibraryInfo;
Calin Juravle19da1cf2017-07-12 18:52:49 -070027import android.util.SparseArray;
28
Brett Chabota26eda92018-07-23 13:08:30 -070029import androidx.test.filters.SmallTest;
30import androidx.test.runner.AndroidJUnit4;
31
Calin Juravle19da1cf2017-07-12 18:52:49 -070032import dalvik.system.DelegateLastClassLoader;
Calin Juravlef8c14e92017-07-24 17:56:51 -070033import dalvik.system.DexClassLoader;
Calin Juravle19da1cf2017-07-12 18:52:49 -070034import dalvik.system.PathClassLoader;
35
Nicolas Geoffray03dba3b2018-12-20 09:47:00 +000036import org.junit.Test;
37import org.junit.runner.RunWith;
38
Calin Juravlef1ff36f2017-07-22 12:33:41 -070039import java.io.File;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +000040import java.util.ArrayList;
Nicolas Geoffray03dba3b2018-12-20 09:47:00 +000041import java.util.Arrays;
Calin Juravlef1ff36f2017-07-22 12:33:41 -070042import java.util.Collections;
43import java.util.List;
44
Calin Juravle19da1cf2017-07-12 18:52:49 -070045@RunWith(AndroidJUnit4.class)
46@SmallTest
47public class DexoptUtilsTest {
Calin Juravlef8c14e92017-07-24 17:56:51 -070048 private static final String DEX_CLASS_LOADER_NAME = DexClassLoader.class.getName();
Calin Juravle19da1cf2017-07-12 18:52:49 -070049 private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName();
50 private static final String DELEGATE_LAST_CLASS_LOADER_NAME =
51 DelegateLastClassLoader.class.getName();
52
Calin Juravleda098152017-09-01 17:30:01 -070053 private static class TestData {
54 ApplicationInfo info;
55 boolean[] pathsWithCode;
56 }
57
58 private TestData createMockApplicationInfo(String baseClassLoader, boolean addSplits,
Calin Juravle19da1cf2017-07-12 18:52:49 -070059 boolean addSplitDependencies) {
60 ApplicationInfo ai = new ApplicationInfo();
61 String codeDir = "/data/app/mock.android.com";
62 ai.setBaseCodePath(codeDir + "/base.dex");
63 ai.classLoaderName = baseClassLoader;
Calin Juravle305aeea2017-07-14 16:40:07 -070064 ai.privateFlags = ai.privateFlags | ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING;
Calin Juravleda098152017-09-01 17:30:01 -070065 boolean[] pathsWithCode;
66 if (!addSplits) {
67 pathsWithCode = new boolean[] {true};
68 } else {
69 pathsWithCode = new boolean[9];
70 Arrays.fill(pathsWithCode, true);
71 pathsWithCode[7] = false; // config split
Calin Juravle19da1cf2017-07-12 18:52:49 -070072
Calin Juravle19da1cf2017-07-12 18:52:49 -070073 ai.setSplitCodePaths(new String[]{
74 codeDir + "/base-1.dex",
75 codeDir + "/base-2.dex",
76 codeDir + "/base-3.dex",
77 codeDir + "/base-4.dex",
78 codeDir + "/base-5.dex",
Calin Juravleda098152017-09-01 17:30:01 -070079 codeDir + "/base-6.dex",
80 codeDir + "/config-split-7.dex",
81 codeDir + "/feature-no-deps.dex"});
Calin Juravle19da1cf2017-07-12 18:52:49 -070082
83 ai.splitClassLoaderNames = new String[]{
84 DELEGATE_LAST_CLASS_LOADER_NAME,
85 DELEGATE_LAST_CLASS_LOADER_NAME,
86 PATH_CLASS_LOADER_NAME,
Calin Juravlef8c14e92017-07-24 17:56:51 -070087 DEX_CLASS_LOADER_NAME,
Calin Juravle19da1cf2017-07-12 18:52:49 -070088 PATH_CLASS_LOADER_NAME,
Calin Juravleda098152017-09-01 17:30:01 -070089 null, // A null class loader name should default to PathClassLoader.
90 null, // The config split gets a null class loader.
91 null}; // The feature split with no dependency and no specified class loader.
Calin Juravle19da1cf2017-07-12 18:52:49 -070092 if (addSplitDependencies) {
93 ai.splitDependencies = new SparseArray<>(ai.splitClassLoaderNames.length + 1);
94 ai.splitDependencies.put(0, new int[] {-1}); // base has no dependency
95 ai.splitDependencies.put(1, new int[] {2}); // split 1 depends on 2
96 ai.splitDependencies.put(2, new int[] {4}); // split 2 depends on 4
97 ai.splitDependencies.put(3, new int[] {4}); // split 3 depends on 4
98 ai.splitDependencies.put(4, new int[] {0}); // split 4 depends on base
99 ai.splitDependencies.put(5, new int[] {0}); // split 5 depends on base
100 ai.splitDependencies.put(6, new int[] {5}); // split 6 depends on 5
Calin Juravleda098152017-09-01 17:30:01 -0700101 // Do not add the config split to the dependency list.
102 // Do not add the feature split with no dependency to the dependency list.
Calin Juravle19da1cf2017-07-12 18:52:49 -0700103 }
104 }
Calin Juravleda098152017-09-01 17:30:01 -0700105 TestData data = new TestData();
106 data.info = ai;
107 data.pathsWithCode = pathsWithCode;
108 return data;
Calin Juravle19da1cf2017-07-12 18:52:49 -0700109 }
110
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000111 private List<SharedLibraryInfo> createMockSharedLibrary(String [] sharedLibrary) {
112 SharedLibraryInfo info = new SharedLibraryInfo(null, null, Arrays.asList(sharedLibrary),
113 null, 0L, SharedLibraryInfo.TYPE_STATIC, null, null, null);
114 ArrayList<SharedLibraryInfo> libraries = new ArrayList<>();
115 libraries.add(info);
116 return libraries;
117 }
118
Calin Juravle19da1cf2017-07-12 18:52:49 -0700119 @Test
120 public void testSplitChain() {
Calin Juravleda098152017-09-01 17:30:01 -0700121 TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000122 List<SharedLibraryInfo> sharedLibrary =
123 createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
Calin Juravleda098152017-09-01 17:30:01 -0700124 String[] contexts = DexoptUtils.getClassLoaderContexts(
125 data.info, sharedLibrary, data.pathsWithCode);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700126
Calin Juravleda098152017-09-01 17:30:01 -0700127 assertEquals(9, contexts.length);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000128 assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]);
129 assertEquals("DLC[];DLC[base-2.dex];PCL[base-4.dex];PCL[base.dex]{PCL[a.dex:b.dex]}",
Calin Juravle305aeea2017-07-14 16:40:07 -0700130 contexts[1]);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000131 assertEquals("DLC[];PCL[base-4.dex];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[2]);
132 assertEquals("PCL[];PCL[base-4.dex];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[3]);
133 assertEquals("PCL[];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[4]);
134 assertEquals("PCL[];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[5]);
135 assertEquals("PCL[];PCL[base-5.dex];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[6]);
Calin Juravleda098152017-09-01 17:30:01 -0700136 assertEquals(null, contexts[7]); // config split
137 assertEquals("PCL[]", contexts[8]); // feature split with no dependency
Calin Juravle19da1cf2017-07-12 18:52:49 -0700138 }
139
140 @Test
141 public void testSplitChainNoSplitDependencies() {
Calin Juravleda098152017-09-01 17:30:01 -0700142 TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, false);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000143 List<SharedLibraryInfo> sharedLibrary =
144 createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
Calin Juravleda098152017-09-01 17:30:01 -0700145 String[] contexts = DexoptUtils.getClassLoaderContexts(
146 data.info, sharedLibrary, data.pathsWithCode);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700147
Calin Juravleda098152017-09-01 17:30:01 -0700148 assertEquals(9, contexts.length);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000149 assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]);
150 assertEquals("PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[1]);
151 assertEquals("PCL[base.dex:base-1.dex]{PCL[a.dex:b.dex]}", contexts[2]);
152 assertEquals("PCL[base.dex:base-1.dex:base-2.dex]{PCL[a.dex:b.dex]}", contexts[3]);
Calin Juravle305aeea2017-07-14 16:40:07 -0700153 assertEquals(
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000154 "PCL[base.dex:base-1.dex:base-2.dex:base-3.dex]{PCL[a.dex:b.dex]}",
155 contexts[4]);
156 assertEquals(
157 "PCL[base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex]{PCL[a.dex:b.dex]}",
Calin Juravle305aeea2017-07-14 16:40:07 -0700158 contexts[5]);
159 assertEquals(
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000160 "PCL[base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex:base-5.dex]{PCL[a.dex:b.dex]}",
Calin Juravle305aeea2017-07-14 16:40:07 -0700161 contexts[6]);
Calin Juravleda098152017-09-01 17:30:01 -0700162 assertEquals(null, contexts[7]); // config split
163 assertEquals(
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000164 "PCL[base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex:base-5.dex:base-6.dex:config-split-7.dex]{PCL[a.dex:b.dex]}",
Calin Juravleda098152017-09-01 17:30:01 -0700165 contexts[8]); // feature split with no dependency
Calin Juravle19da1cf2017-07-12 18:52:49 -0700166 }
167
168 @Test
Calin Juravle305aeea2017-07-14 16:40:07 -0700169 public void testSplitChainNoIsolationNoSharedLibrary() {
Calin Juravleda098152017-09-01 17:30:01 -0700170 TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true);
171 data.info.privateFlags = data.info.privateFlags
172 & (~ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING);
173 String[] contexts = DexoptUtils.getClassLoaderContexts(
174 data.info, null, data.pathsWithCode);
Calin Juravle305aeea2017-07-14 16:40:07 -0700175
Calin Juravleda098152017-09-01 17:30:01 -0700176 assertEquals(9, contexts.length);
Calin Juravle305aeea2017-07-14 16:40:07 -0700177 assertEquals("PCL[]", contexts[0]);
178 assertEquals("PCL[base.dex]", contexts[1]);
179 assertEquals("PCL[base.dex:base-1.dex]", contexts[2]);
180 assertEquals("PCL[base.dex:base-1.dex:base-2.dex]", contexts[3]);
181 assertEquals("PCL[base.dex:base-1.dex:base-2.dex:base-3.dex]", contexts[4]);
182 assertEquals("PCL[base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex]", contexts[5]);
183 assertEquals(
184 "PCL[base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex:base-5.dex]",
185 contexts[6]);
Calin Juravleda098152017-09-01 17:30:01 -0700186 assertEquals(null, contexts[7]); // config split
187 assertEquals(
188 "PCL[base.dex:base-1.dex:base-2.dex:base-3.dex:base-4.dex:base-5.dex:base-6.dex:config-split-7.dex]",
189 contexts[8]); // feature split with no dependency
Calin Juravle305aeea2017-07-14 16:40:07 -0700190 }
Calin Juravleda098152017-09-01 17:30:01 -0700191
Calin Juravle305aeea2017-07-14 16:40:07 -0700192 @Test
Calin Juravle19da1cf2017-07-12 18:52:49 -0700193 public void testSplitChainNoSharedLibraries() {
Calin Juravleda098152017-09-01 17:30:01 -0700194 TestData data = createMockApplicationInfo(
Calin Juravle19da1cf2017-07-12 18:52:49 -0700195 DELEGATE_LAST_CLASS_LOADER_NAME, true, true);
Calin Juravleda098152017-09-01 17:30:01 -0700196 String[] contexts = DexoptUtils.getClassLoaderContexts(
197 data.info, null, data.pathsWithCode);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700198
Calin Juravleda098152017-09-01 17:30:01 -0700199 assertEquals(9, contexts.length);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700200 assertEquals("DLC[]", contexts[0]);
201 assertEquals("DLC[];DLC[base-2.dex];PCL[base-4.dex];DLC[base.dex]", contexts[1]);
202 assertEquals("DLC[];PCL[base-4.dex];DLC[base.dex]", contexts[2]);
203 assertEquals("PCL[];PCL[base-4.dex];DLC[base.dex]", contexts[3]);
204 assertEquals("PCL[];DLC[base.dex]", contexts[4]);
205 assertEquals("PCL[];DLC[base.dex]", contexts[5]);
206 assertEquals("PCL[];PCL[base-5.dex];DLC[base.dex]", contexts[6]);
Calin Juravleda098152017-09-01 17:30:01 -0700207 assertEquals(null, contexts[7]); // config split
208 assertEquals("PCL[]", contexts[8]); // feature split with no dependency
Calin Juravle19da1cf2017-07-12 18:52:49 -0700209 }
210
211 @Test
212 public void testSplitChainWithNullPrimaryClassLoader() {
213 // A null classLoaderName should mean PathClassLoader.
Calin Juravleda098152017-09-01 17:30:01 -0700214 TestData data = createMockApplicationInfo(null, true, true);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000215 List<SharedLibraryInfo> sharedLibrary =
216 createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
Calin Juravleda098152017-09-01 17:30:01 -0700217 String[] contexts = DexoptUtils.getClassLoaderContexts(
218 data.info, sharedLibrary, data.pathsWithCode);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700219
Calin Juravleda098152017-09-01 17:30:01 -0700220 assertEquals(9, contexts.length);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000221 assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]);
222 assertEquals(
223 "DLC[];DLC[base-2.dex];PCL[base-4.dex];PCL[base.dex]{PCL[a.dex:b.dex]}",
224 contexts[1]);
225 assertEquals("DLC[];PCL[base-4.dex];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[2]);
226 assertEquals("PCL[];PCL[base-4.dex];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[3]);
227 assertEquals("PCL[];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[4]);
228 assertEquals("PCL[];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[5]);
229 assertEquals("PCL[];PCL[base-5.dex];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[6]);
Calin Juravleda098152017-09-01 17:30:01 -0700230 assertEquals(null, contexts[7]); // config split
231 assertEquals("PCL[]", contexts[8]); // feature split with no dependency
Calin Juravle19da1cf2017-07-12 18:52:49 -0700232 }
233
234 @Test
235 public void tesNoSplits() {
Calin Juravleda098152017-09-01 17:30:01 -0700236 TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000237 List<SharedLibraryInfo> sharedLibrary =
238 createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
Calin Juravleda098152017-09-01 17:30:01 -0700239 String[] contexts = DexoptUtils.getClassLoaderContexts(
240 data.info, sharedLibrary, data.pathsWithCode);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700241
242 assertEquals(1, contexts.length);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000243 assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700244 }
245
246 @Test
247 public void tesNoSplitsNullClassLoaderName() {
Calin Juravleda098152017-09-01 17:30:01 -0700248 TestData data = createMockApplicationInfo(null, false, false);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000249 List<SharedLibraryInfo> sharedLibrary =
250 createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
Calin Juravleda098152017-09-01 17:30:01 -0700251 String[] contexts = DexoptUtils.getClassLoaderContexts(
252 data.info, sharedLibrary, data.pathsWithCode);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700253
254 assertEquals(1, contexts.length);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000255 assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700256 }
257
258 @Test
259 public void tesNoSplitDelegateLast() {
Calin Juravleda098152017-09-01 17:30:01 -0700260 TestData data = createMockApplicationInfo(
Calin Juravle19da1cf2017-07-12 18:52:49 -0700261 DELEGATE_LAST_CLASS_LOADER_NAME, false, false);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000262 List<SharedLibraryInfo> sharedLibrary =
263 createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
Calin Juravleda098152017-09-01 17:30:01 -0700264 String[] contexts = DexoptUtils.getClassLoaderContexts(
265 data.info, sharedLibrary, data.pathsWithCode);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700266
267 assertEquals(1, contexts.length);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000268 assertEquals("DLC[]{PCL[a.dex:b.dex]}", contexts[0]);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700269 }
270
271 @Test
272 public void tesNoSplitsNoSharedLibraries() {
Calin Juravleda098152017-09-01 17:30:01 -0700273 TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false);
274 String[] contexts = DexoptUtils.getClassLoaderContexts(
275 data.info, null, data.pathsWithCode);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700276
277 assertEquals(1, contexts.length);
278 assertEquals("PCL[]", contexts[0]);
279 }
280
281 @Test
282 public void tesNoSplitDelegateLastNoSharedLibraries() {
Calin Juravleda098152017-09-01 17:30:01 -0700283 TestData data = createMockApplicationInfo(
Calin Juravle19da1cf2017-07-12 18:52:49 -0700284 DELEGATE_LAST_CLASS_LOADER_NAME, false, false);
Calin Juravleda098152017-09-01 17:30:01 -0700285 String[] contexts = DexoptUtils.getClassLoaderContexts(
286 data.info, null, data.pathsWithCode);
Calin Juravle19da1cf2017-07-12 18:52:49 -0700287
288 assertEquals(1, contexts.length);
289 assertEquals("DLC[]", contexts[0]);
290 }
Calin Juravlef1ff36f2017-07-22 12:33:41 -0700291
292 @Test
Calin Juravleda098152017-09-01 17:30:01 -0700293 public void testContextWithNoCode() {
294 TestData data = createMockApplicationInfo(null, true, false);
295 Arrays.fill(data.pathsWithCode, false);
296
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000297 List<SharedLibraryInfo> sharedLibrary =
298 createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
Calin Juravleda098152017-09-01 17:30:01 -0700299 String[] contexts = DexoptUtils.getClassLoaderContexts(
300 data.info, sharedLibrary, data.pathsWithCode);
301
302 assertEquals(9, contexts.length);
303 assertEquals(null, contexts[0]);
304 assertEquals(null, contexts[1]);
305 assertEquals(null, contexts[2]);
306 assertEquals(null, contexts[3]);
307 assertEquals(null, contexts[4]);
308 assertEquals(null, contexts[5]);
309 assertEquals(null, contexts[6]);
310 assertEquals(null, contexts[7]);
311 }
312
313 @Test
314 public void testContextBaseNoCode() {
315 TestData data = createMockApplicationInfo(null, true, true);
316 data.pathsWithCode[0] = false;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000317 List<SharedLibraryInfo> sharedLibrary =
318 createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
Calin Juravleda098152017-09-01 17:30:01 -0700319 String[] contexts = DexoptUtils.getClassLoaderContexts(
320 data.info, sharedLibrary, data.pathsWithCode);
321
322 assertEquals(9, contexts.length);
323 assertEquals(null, contexts[0]);
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000324 assertEquals(
325 "DLC[];DLC[base-2.dex];PCL[base-4.dex];PCL[base.dex]{PCL[a.dex:b.dex]}",
326 contexts[1]);
327 assertEquals("DLC[];PCL[base-4.dex];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[2]);
328 assertEquals("PCL[];PCL[base-4.dex];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[3]);
329 assertEquals("PCL[];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[4]);
330 assertEquals("PCL[];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[5]);
331 assertEquals("PCL[];PCL[base-5.dex];PCL[base.dex]{PCL[a.dex:b.dex]}", contexts[6]);
Calin Juravleda098152017-09-01 17:30:01 -0700332 assertEquals(null, contexts[7]);
333 }
334
335 @Test
Calin Juravlef1ff36f2017-07-22 12:33:41 -0700336 public void testProcessContextForDexLoad() {
337 List<String> classLoaders = Arrays.asList(
338 DELEGATE_LAST_CLASS_LOADER_NAME,
339 PATH_CLASS_LOADER_NAME,
340 PATH_CLASS_LOADER_NAME);
341 List<String> classPaths = Arrays.asList(
342 String.join(File.pathSeparator, "foo.dex", "bar.dex"),
343 String.join(File.pathSeparator, "parent1.dex"),
344 String.join(File.pathSeparator, "parent2.dex", "parent3.dex"));
345 String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
346 assertNotNull(context);
347 assertEquals(2, context.length);
348 assertEquals("DLC[];PCL[parent1.dex];PCL[parent2.dex:parent3.dex]", context[0]);
349 assertEquals("DLC[foo.dex];PCL[parent1.dex];PCL[parent2.dex:parent3.dex]", context[1]);
350 }
351
352 @Test
353 public void testProcessContextForDexLoadSingleElement() {
354 List<String> classLoaders = Arrays.asList(PATH_CLASS_LOADER_NAME);
355 List<String> classPaths = Arrays.asList(
356 String.join(File.pathSeparator, "foo.dex", "bar.dex", "zoo.dex"));
357 String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
358 assertNotNull(context);
359 assertEquals(3, context.length);
360 assertEquals("PCL[]", context[0]);
361 assertEquals("PCL[foo.dex]", context[1]);
362 assertEquals("PCL[foo.dex:bar.dex]", context[2]);
363 }
364
365 @Test
366 public void testProcessContextForDexLoadUnsupported() {
367 List<String> classLoaders = Arrays.asList(
368 DELEGATE_LAST_CLASS_LOADER_NAME,
369 "unsupported.class.loader");
370 List<String> classPaths = Arrays.asList(
371 String.join(File.pathSeparator, "foo.dex", "bar.dex"),
372 String.join(File.pathSeparator, "parent1.dex"));
373 String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
374 assertNull(context);
375 }
376
377 @Test
Alan Stokesb6c3a602018-11-02 12:10:42 +0000378 public void testProcessContextForDexLoadNoClassPath() {
379 List<String> classLoaders = Arrays.asList(
380 DELEGATE_LAST_CLASS_LOADER_NAME,
381 PATH_CLASS_LOADER_NAME);
382 List<String> classPaths = Arrays.asList(
383 String.join(File.pathSeparator, "foo.dex", "bar.dex"),
384 null);
385 String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
386 assertNull(context);
387 }
388
389 @Test
Calin Juravlef1ff36f2017-07-22 12:33:41 -0700390 public void testProcessContextForDexLoadIllegalCallEmptyList() {
391 boolean gotException = false;
392 try {
393 DexoptUtils.processContextForDexLoad(Collections.emptyList(), Collections.emptyList());
394 } catch (IllegalArgumentException ignore) {
395 gotException = true;
396 }
397 assertTrue(gotException);
398 }
399
400 @Test
401 public void testProcessContextForDexLoadIllegalCallDifferentSize() {
402 boolean gotException = false;
403 try {
404 DexoptUtils.processContextForDexLoad(Collections.emptyList(), Arrays.asList("a"));
405 } catch (IllegalArgumentException ignore) {
406 gotException = true;
407 }
408 assertTrue(gotException);
409 }
Shubham Ajmera557c0542017-09-05 10:20:41 -0700410
411 @Test
412 public void testEncodeClassLoader() {
Shubham Ajmera557c0542017-09-05 10:20:41 -0700413 assertEquals("PCL[xyz]", DexoptUtils.encodeClassLoader("xyz",
414 "dalvik.system.PathClassLoader"));
415 assertEquals("PCL[xyz]", DexoptUtils.encodeClassLoader("xyz",
416 "dalvik.system.DexClassLoader"));
417 assertEquals("DLC[xyz]", DexoptUtils.encodeClassLoader("xyz",
418 "dalvik.system.DelegateLastClassLoader"));
419 assertEquals("PCL[xyz]", DexoptUtils.encodeClassLoader("xyz", null));
420 assertEquals("abc[xyz]", DexoptUtils.encodeClassLoader("xyz", "abc"));
421
422 try {
423 DexoptUtils.encodeClassLoader(null, "abc");
424 fail(); // Exception should be caught.
425 } catch (NullPointerException expected) {}
426 }
427
428 @Test
429 public void testEncodeClassLoaderChain() {
Shubham Ajmera557c0542017-09-05 10:20:41 -0700430 assertEquals("PCL[a];DLC[b]", DexoptUtils.encodeClassLoaderChain("PCL[a]",
431 "DLC[b]"));
Shubham Ajmera557c0542017-09-05 10:20:41 -0700432 try {
433 DexoptUtils.encodeClassLoaderChain("a", null);
434 fail(); // exception is expected
435 } catch (NullPointerException expected) {}
436
437 try {
438 DexoptUtils.encodeClassLoaderChain(null, "b");
439 fail(); // exception is expected
440 } catch (NullPointerException expected) {}
441 }
Calin Juravle19da1cf2017-07-12 18:52:49 -0700442}