1 /*
2  * Copyright (C) 2019 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.preload.check;
18 
19 import static org.junit.Assert.assertTrue;
20 
21 import com.android.tradefed.device.ITestDevice;
22 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
23 import com.android.tradefed.testtype.IDeviceTest;
24 
25 import org.junit.Test;
26 import org.junit.runner.RunWith;
27 
28 import java.io.BufferedReader;
29 import java.io.InputStreamReader;
30 
31 @RunWith(DeviceJUnit4ClassRunner.class)
32 public class PreloadCheck implements IDeviceTest {
33     private ITestDevice mTestDevice;
34 
35     private static final String TEST_CLASSPATH = "/data/local/tmp/preload-check-device.jar";
36 
37     @Override
setDevice(ITestDevice testDevice)38     public void setDevice(ITestDevice testDevice) {
39         mTestDevice = testDevice;
40     }
41 
42     @Override
getDevice()43     public ITestDevice getDevice() {
44         return mTestDevice;
45     }
46 
47     /**
48      * Test that checks work as expected.
49      */
50     @Test
testStatus()51     public void testStatus() throws Exception {
52         run("com.android.preload.check.IntegrityCheck");
53     }
54 
55     /**
56      * b/130206915.
57      */
58     @Test
testAsyncTask()59     public void testAsyncTask() throws Exception {
60         run("com.android.preload.check.NotInitialized", "android.os.AsyncTask");
61     }
62 
63     /**
64      * Just a check for something we expect to see initialized.
65      */
66     @Test
testAnimator()67     public void testAnimator() throws Exception {
68         run("com.android.preload.check.Initialized", "android.animation.Animator");
69     }
70 
71     /**
72      * Test the classes mentioned in the embedded preloaded-classes blacklist.
73      */
74     @Test
testBlackList()75     public void testBlackList() throws Exception {
76         StringBuilder sb = new StringBuilder();
77         try (BufferedReader br = new BufferedReader(new InputStreamReader(getClass()
78                 .getResourceAsStream("/preloaded-classes-blacklist")))) {
79             String s;
80             while ((s = br.readLine()) != null) {
81                 s = s.trim();
82                 if (s.startsWith("#") || s.isEmpty()) {
83                     continue;
84                 }
85                 try {
86                     run("com.android.preload.check.NotInitialized", s);
87                 } catch (Throwable t) {
88                     if (sb.length() > 0) {
89                         sb.append('\n');
90                     }
91                     sb.append(t.getMessage());
92                 }
93             }
94         }
95         if (sb.length() > 0) {
96             throw new RuntimeException(sb.toString());
97         }
98     }
99 
100     /**
101      * Test the classes ending in NoPreloadHolder are not initialized.
102      */
103     @Test
testNoPreloadHolder()104     public void testNoPreloadHolder() throws Exception {
105         run("com.android.preload.check.NotInitializedRegex", ".*NoPreloadHolder$", "true");
106     }
107 
run(String cmd, String... args)108     private void run(String cmd, String... args) throws Exception {
109         StringBuilder sb = new StringBuilder();
110         sb.append("app_process ")
111                 .append("-cp ").append(TEST_CLASSPATH)
112                 .append(" /system/bin ")
113                 .append(cmd);
114         for (String arg : args) {
115             sb.append(' ').append(escape(arg));
116         }
117         String res = mTestDevice.executeShellCommand(sb.toString());
118         assertTrue(sb.toString() + "\n===\n" + res, res.trim().endsWith("OK"));
119     }
120 
escape(String input)121     private static String escape(String input) {
122         if (input.indexOf('$') == -1) {
123             return input;
124         }
125         return input.replace("$", "\\$");
126     }
127 }
128