1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package android.startop.test;
16 
17 import android.content.Context;
18 import androidx.test.InstrumentationRegistry;
19 import dalvik.system.PathClassLoader;
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import org.junit.Assert;
23 import org.junit.Test;
24 
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 
28 // Adding tests here requires changes in several other places. See README.md in
29 // the view_compiler directory for more information.
30 public final class DexBuilderTest {
loadDexFile(String filename)31   static ClassLoader loadDexFile(String filename) throws Exception {
32     return new PathClassLoader("/data/local/tmp/dex-builder-test/" + filename,
33         DexBuilderTest.class.getClassLoader());
34   }
35 
hello()36   public void hello() {}
37 
38   @Test
loadTrivialDex()39   public void loadTrivialDex() throws Exception {
40     ClassLoader loader = loadDexFile("trivial.dex");
41     loader.loadClass("android.startop.test.testcases.Trivial");
42   }
43 
44   @Test
return5()45   public void return5() throws Exception {
46     ClassLoader loader = loadDexFile("simple.dex");
47     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
48     Method method = clazz.getMethod("return5");
49     Assert.assertEquals(5, method.invoke(null));
50   }
51 
52   @Test
returnInteger5()53   public void returnInteger5() throws Exception {
54     ClassLoader loader = loadDexFile("simple.dex");
55     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
56     Method method = clazz.getMethod("returnInteger5");
57     Assert.assertEquals(5, method.invoke(null));
58   }
59 
60   @Test
returnParam()61   public void returnParam() throws Exception {
62     ClassLoader loader = loadDexFile("simple.dex");
63     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
64     Method method = clazz.getMethod("returnParam", int.class);
65     Assert.assertEquals(5, method.invoke(null, 5));
66     Assert.assertEquals(42, method.invoke(null, 42));
67   }
68 
69   @Test
returnStringLength()70   public void returnStringLength() throws Exception {
71     ClassLoader loader = loadDexFile("simple.dex");
72     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
73     Method method = clazz.getMethod("returnStringLength", String.class);
74     Assert.assertEquals(13, method.invoke(null, "Hello, World!"));
75   }
76 
77   @Test
returnIfZero()78   public void returnIfZero() throws Exception {
79     ClassLoader loader = loadDexFile("simple.dex");
80     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
81     Method method = clazz.getMethod("returnIfZero", int.class);
82     Assert.assertEquals(5, method.invoke(null, 0));
83     Assert.assertEquals(3, method.invoke(null, 17));
84   }
85 
86   @Test
returnIfNotZero()87   public void returnIfNotZero() throws Exception {
88     ClassLoader loader = loadDexFile("simple.dex");
89     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
90     Method method = clazz.getMethod("returnIfNotZero", int.class);
91     Assert.assertEquals(3, method.invoke(null, 0));
92     Assert.assertEquals(5, method.invoke(null, 17));
93   }
94 
95   @Test
backwardsBranch()96   public void backwardsBranch() throws Exception {
97     ClassLoader loader = loadDexFile("simple.dex");
98     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
99     Method method = clazz.getMethod("backwardsBranch");
100     Assert.assertEquals(2, method.invoke(null));
101   }
102 
103   @Test
returnNull()104   public void returnNull() throws Exception {
105     ClassLoader loader = loadDexFile("simple.dex");
106     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
107     Method method = clazz.getMethod("returnNull");
108     Assert.assertEquals(null, method.invoke(null));
109   }
110 
111   @Test
makeString()112   public void makeString() throws Exception {
113     ClassLoader loader = loadDexFile("simple.dex");
114     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
115     Method method = clazz.getMethod("makeString");
116     Assert.assertEquals("Hello, World!", method.invoke(null));
117   }
118 
119   @Test
returnStringIfZeroAB()120   public void returnStringIfZeroAB() throws Exception {
121     ClassLoader loader = loadDexFile("simple.dex");
122     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
123     Method method = clazz.getMethod("returnStringIfZeroAB", int.class);
124     Assert.assertEquals("a", method.invoke(null, 0));
125     Assert.assertEquals("b", method.invoke(null, 1));
126   }
127 
128   @Test
returnStringIfZeroBA()129   public void returnStringIfZeroBA() throws Exception {
130     ClassLoader loader = loadDexFile("simple.dex");
131     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
132     Method method = clazz.getMethod("returnStringIfZeroBA", int.class);
133     Assert.assertEquals("b", method.invoke(null, 0));
134     Assert.assertEquals("a", method.invoke(null, 1));
135   }
136 
137   @Test
invokeStaticReturnObject()138   public void invokeStaticReturnObject() throws Exception {
139     ClassLoader loader = loadDexFile("simple.dex");
140     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
141     Method method = clazz.getMethod("invokeStaticReturnObject", int.class, int.class);
142     Assert.assertEquals("10", method.invoke(null, 10, 10));
143     Assert.assertEquals("a", method.invoke(null, 10, 16));
144     Assert.assertEquals("5", method.invoke(null, 5, 16));
145   }
146 
147   @Test
invokeVirtualReturnObject()148   public void invokeVirtualReturnObject() throws Exception {
149     ClassLoader loader = loadDexFile("simple.dex");
150     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
151     Method method = clazz.getMethod("invokeVirtualReturnObject", String.class, int.class);
152     Assert.assertEquals("bc", method.invoke(null, "abc", 1));
153   }
154 
155   @Test
castObjectToString()156   public void castObjectToString() throws Exception {
157     ClassLoader loader = loadDexFile("simple.dex");
158     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
159     Method method = clazz.getMethod("castObjectToString", Object.class);
160     Assert.assertEquals("abc", method.invoke(null, "abc"));
161     boolean castFailed = false;
162     try {
163       method.invoke(null, 5);
164     } catch (InvocationTargetException e) {
165       if (e.getCause() instanceof ClassCastException) {
166         castFailed = true;
167       } else {
168         throw e;
169       }
170     }
171     Assert.assertTrue(castFailed);
172   }
173 
174   @Test
readStaticField()175   public void readStaticField() throws Exception {
176     ClassLoader loader = loadDexFile("simple.dex");
177     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
178     Method method = clazz.getMethod("readStaticField");
179     TestClass.staticInteger = 5;
180     Assert.assertEquals(5, method.invoke(null));
181   }
182 
183   @Test
setStaticField()184   public void setStaticField() throws Exception {
185     ClassLoader loader = loadDexFile("simple.dex");
186     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
187     Method method = clazz.getMethod("setStaticField");
188     TestClass.staticInteger = 5;
189     method.invoke(null);
190     Assert.assertEquals(7, TestClass.staticInteger);
191   }
192 
193   @Test
readInstanceField()194   public void readInstanceField() throws Exception {
195     ClassLoader loader = loadDexFile("simple.dex");
196     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
197     Method method = clazz.getMethod("readInstanceField", TestClass.class);
198     TestClass obj = new TestClass();
199     obj.instanceField = 5;
200     Assert.assertEquals(5, method.invoke(null, obj));
201   }
202 
203   @Test
setInstanceField()204   public void setInstanceField() throws Exception {
205     ClassLoader loader = loadDexFile("simple.dex");
206     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
207     Method method = clazz.getMethod("setInstanceField", TestClass.class);
208     TestClass obj = new TestClass();
209     obj.instanceField = 5;
210     method.invoke(null, obj);
211     Assert.assertEquals(7, obj.instanceField);
212   }
213 }
214