• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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 
17 package com.android.dx;
18 
19 import android.os.Build;
20 import org.junit.Test;
21 
22 import java.io.File;
23 import java.util.Arrays;
24 import java.util.HashSet;
25 import java.util.Set;
26 
27 import static org.junit.Assert.assertEquals;
28 import static org.junit.Assert.assertNotNull;
29 import static org.junit.Assert.assertTrue;
30 
31 public final class AppDataDirGuesserTest {
32     @Test
testGuessCacheDir_SimpleExample()33     public void testGuessCacheDir_SimpleExample() {
34         guessCacheDirFor("/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache");
35         guessCacheDirFor("/data/app/a.b.c.tests.apk").shouldGive("/data/data/a.b.c.tests/cache");
36     }
37 
38     @Test
testGuessCacheDir_MultipleResultsSeparatedByColon()39     public void testGuessCacheDir_MultipleResultsSeparatedByColon() {
40         guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
41                 .shouldGive("/data/data/a.b.c/cache", "/data/data/d.e.f/cache");
42     }
43 
44     @Test
testGuessCacheDir_NotWriteableSkipped()45     public void testGuessCacheDir_NotWriteableSkipped() {
46         guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
47                 .withNonWriteable("/data/data/a.b.c/cache")
48                 .shouldGive("/data/data/d.e.f/cache");
49     }
50 
51     @Test
testGuessCacheDir_StripHyphenatedSuffixes()52     public void testGuessCacheDir_StripHyphenatedSuffixes() {
53         guessCacheDirFor("/data/app/a.b.c-2.apk").shouldGive("/data/data/a.b.c/cache");
54     }
55 
56     @Test
testGuessCacheDir_LeadingAndTrailingColonsIgnored()57     public void testGuessCacheDir_LeadingAndTrailingColonsIgnored() {
58         guessCacheDirFor("/data/app/a.b.c.apk:asdf:").shouldGive("/data/data/a.b.c/cache");
59         guessCacheDirFor(":asdf:/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache");
60     }
61 
62     @Test
testGuessCacheDir_InvalidInputsGiveEmptyArray()63     public void testGuessCacheDir_InvalidInputsGiveEmptyArray() {
64         guessCacheDirFor("").shouldGive();
65     }
66 
67     @Test
testGuessCacheDir_JarsIgnored()68     public void testGuessCacheDir_JarsIgnored() {
69         guessCacheDirFor("/data/app/a.b.c.jar").shouldGive();
70         guessCacheDirFor("/system/framework/android.test.runner.jar").shouldGive();
71     }
72 
73     @Test
testGuessCacheDir_RealWorldExample()74     public void testGuessCacheDir_RealWorldExample() {
75         String realPath = "/system/framework/android.test.runner.jar:" +
76                 "/data/app/com.google.android.voicesearch.tests-2.apk:" +
77                 "/data/app/com.google.android.voicesearch-1.apk";
78         guessCacheDirFor(realPath)
79                 .withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache")
80                 .shouldGive("/data/data/com.google.android.voicesearch/cache");
81     }
82 
83     @Test
testSplitPathList()84     public void testSplitPathList() {
85         final String[] expected = { "foo", "bar" };
86         assertTrue(Arrays.equals(expected, AppDataDirGuesser.splitPathList("foo:bar")));
87         assertTrue(Arrays.equals(expected,
88                 AppDataDirGuesser.splitPathList("dexPath=foo:bar")));
89         assertTrue(Arrays.equals(expected,
90                 AppDataDirGuesser.splitPathList("dexPath=foo:bar,bazPath=bar:bar2")));
91     }
92 
93     @Test
testPre43PathProcessing()94     public void testPre43PathProcessing() {
95         String input = "dalvik.system.PathClassLoader[dexPath=/data/app/abc-1.apk," +
96                        "libraryPath=/data/app-lib/abc-1]";
97         String processed = AppDataDirGuesser.processClassLoaderString(input);
98         assertTrue("dexPath=/data/app/abc-1.apk,libraryPath=/data/app-lib/abc-1".equals(processed));
99     }
100 
101     @Test
test43PathProcessing()102     public void test43PathProcessing() {
103         String input = "dalvik.system.PathClassLoader[DexPathList[[zip file " +
104                        "\"/data/app/abc-1/base.apk\", zip file \"/data/app/def-1/base.apk\"], " +
105                        "nativeLibraryDirectories=[/data/app-lib/abc-1]]]";
106         String processed = AppDataDirGuesser.processClassLoaderString(input);
107         assertTrue("/data/app/abc-1/base.apk:/data/app/def-1/base.apk".equals(processed));
108     }
109 
110     @Test
testApiLevel17PlusPathProcessing()111     public void testApiLevel17PlusPathProcessing() {
112         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
113             // Our processing should work for anything >= Android 4.2.
114             String input = getClass().getClassLoader().toString();
115             String processed = AppDataDirGuesser.processClassLoaderString(input);
116             // TODO: this comment is no longer true now that we run tests on Android instead of vogar
117             // A tighter check would be interesting. But vogar doesn't run the tests in a directory
118             // recognized by the guesser (usually under /data/local/tmp), so we cannot use the
119             // processed result as input to guessPath.
120             assertTrue(!input.equals(processed));
121         }
122     }
123 
124     private interface TestCondition {
withNonWriteable(String... files)125         TestCondition withNonWriteable(String... files);
shouldGive(String... files)126         void shouldGive(String... files);
127     }
128 
guessCacheDirFor(final String path)129     private TestCondition guessCacheDirFor(final String path) {
130         final Set<String> notWriteable = new HashSet<>();
131         return new TestCondition() {
132             public void shouldGive(String... files) {
133                 AppDataDirGuesser guesser = new AppDataDirGuesser() {
134                     @Override
135                     public boolean isWriteableDirectory(File file) {
136                         return !notWriteable.contains(file.getAbsolutePath());
137                     }
138                     @Override
139                     boolean fileOrDirExists(File file) {
140                         return true;
141                     }
142                 };
143                 File[] results = guesser.guessPath(path);
144                 assertNotNull("Null results for " + path, results);
145                 assertEquals("Bad lengths for " + path, files.length, results.length);
146                 for (int i = 0; i < files.length; ++i) {
147                     assertEquals("Element " + i, new File(files[i]), results[i]);
148                 }
149             }
150 
151             public TestCondition withNonWriteable(String... files) {
152                 notWriteable.addAll(Arrays.asList(files));
153                 return this;
154             }
155         };
156     }
157 }
158