blob: 95b77f2f3fc2e8c18294d8fafc2cd5cc4996e488 [file] [log] [blame]
The Android Open Source Projectf8057102009-03-15 16:47:16 -07001/*
2 * Copyright (C) 2008 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 */
Stuart Scott01c2b492014-10-08 18:07:28 -070016import com.android.cts.util.AbiUtils;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070017
Kenny Rootb5b47cb2013-02-27 17:03:16 -080018import org.junit.runner.RunWith;
Brian Muramatsu7f64e852011-02-17 16:52:16 -080019import org.w3c.dom.Document;
20import org.w3c.dom.Element;
21import org.w3c.dom.Node;
22import org.w3c.dom.NodeList;
23
Stuart Scott01c2b492014-10-08 18:07:28 -070024import vogar.Expectation;
Brian Muramatsu7f64e852011-02-17 16:52:16 -080025import vogar.ExpectationStore;
Brian Muramatsu7f64e852011-02-17 16:52:16 -080026
The Android Open Source Projectf8057102009-03-15 16:47:16 -070027import java.io.BufferedReader;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070028import java.io.File;
29import java.io.FileInputStream;
Urs Grobfc77f6e2009-04-17 02:07:14 -070030import java.io.FileReader;
31import java.io.IOException;
32import java.lang.annotation.Annotation;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070033import java.lang.reflect.Method;
Brian Carlstrom9f2dab82011-04-01 15:47:17 -070034import java.lang.reflect.Modifier;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070035import java.util.ArrayList;
Brian Carlstrom9f2dab82011-04-01 15:47:17 -070036import java.util.Enumeration;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070037import java.util.HashSet;
38import java.util.Iterator;
Urs Grobfc77f6e2009-04-17 02:07:14 -070039import java.util.LinkedHashMap;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070040import java.util.Map;
41import java.util.Set;
Brian Carlstrom9f2dab82011-04-01 15:47:17 -070042import java.util.jar.JarEntry;
43import java.util.jar.JarFile;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070044
45import javax.xml.parsers.DocumentBuilderFactory;
46import javax.xml.parsers.ParserConfigurationException;
47
The Android Open Source Projectf8057102009-03-15 16:47:16 -070048import junit.framework.TestCase;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070049
The Android Open Source Projectf8057102009-03-15 16:47:16 -070050public class CollectAllTests extends DescriptionGenerator {
51
Brian Carlstrom022aff42011-05-17 23:16:51 -070052 private static final String ATTRIBUTE_RUNNER = "runner";
53 private static final String ATTRIBUTE_PACKAGE = "appPackageName";
54 private static final String ATTRIBUTE_NS = "appNameSpace";
55 private static final String ATTRIBUTE_TARGET = "targetNameSpace";
56 private static final String ATTRIBUTE_TARGET_BINARY = "targetBinaryName";
57 private static final String ATTRIBUTE_HOST_SIDE_ONLY = "hostSideOnly";
58 private static final String ATTRIBUTE_VM_HOST_TEST = "vmHostTest";
59 private static final String ATTRIBUTE_JAR_PATH = "jarPath";
60 private static final String ATTRIBUTE_JAVA_PACKAGE_FILTER = "javaPackageFilter";
The Android Open Source Projectf8057102009-03-15 16:47:16 -070061
Brian Carlstrom022aff42011-05-17 23:16:51 -070062 private static final String JAR_PATH = "LOCAL_JAR_PATH :=";
63 private static final String TEST_TYPE = "LOCAL_TEST_TYPE :";
The Android Open Source Projectf8057102009-03-15 16:47:16 -070064
65 public static void main(String[] args) {
Stuart Scott01c2b492014-10-08 18:07:28 -070066 if (args.length < 5 || args.length > 7) {
Brian Carlstrom022aff42011-05-17 23:16:51 -070067 System.err.println("usage: CollectAllTests <output-file> <manifest-file> <jar-file> "
Stuart Scott01c2b492014-10-08 18:07:28 -070068 + "<java-package> <architecture> [expectation-dir [makefile-file]]");
Brian Carlstrom022aff42011-05-17 23:16:51 -070069 if (args.length != 0) {
70 System.err.println("received:");
71 for (String arg : args) {
72 System.err.println(" " + arg);
Brian Carlstrom9f2dab82011-04-01 15:47:17 -070073 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -070074 }
Urs Grobfc77f6e2009-04-17 02:07:14 -070075 System.exit(1);
The Android Open Source Projectf8057102009-03-15 16:47:16 -070076 }
77
Brian Carlstrom022aff42011-05-17 23:16:51 -070078 final String outputPathPrefix = args[0];
79 File manifestFile = new File(args[1]);
80 String jarFileName = args[2];
Narayan Kamathe160f382015-06-01 14:56:31 +010081 final String javaPackageFilterArg = args[3] != null ? args[3].replaceAll("\\s+", "") : "";
82 final String[] javaPackagePrefixes;
83 // Validate the javaPackageFilter value if non-empty.
84 if (!javaPackageFilterArg.isEmpty()) {
85 javaPackagePrefixes = javaPackageFilterArg.split(":");
86 for (int i = 0; i < javaPackagePrefixes.length; ++i) {
87 final String javaPackageFilter = javaPackagePrefixes[i];
88 if (!isValidJavaPackage(javaPackageFilter)) {
89 System.err.println("Invalid " + ATTRIBUTE_JAVA_PACKAGE_FILTER + ": " +
90 javaPackageFilter);
91 System.exit(1);
92 return;
93 } else {
94 javaPackagePrefixes[i] = javaPackageFilter.trim() + ".";
95 }
Tsu Chiang Chuangc87fd6b2011-07-13 17:04:40 -070096 }
Narayan Kamathe160f382015-06-01 14:56:31 +010097 } else {
98 javaPackagePrefixes = new String[0];
Tsu Chiang Chuangc87fd6b2011-07-13 17:04:40 -070099 }
Narayan Kamathe160f382015-06-01 14:56:31 +0100100
Stuart Scott01c2b492014-10-08 18:07:28 -0700101 String architecture = args[4];
102 if (architecture == null || architecture.equals("")) {
103 System.err.println("Invalid architecture");
104 System.exit(1);
105 return;
106 }
107 String libcoreExpectationDir = (args.length > 5) ? args[5] : null;
108 String androidMakeFile = (args.length > 6) ? args[6] : null;
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700109
Brian Carlstrom022aff42011-05-17 23:16:51 -0700110 final TestType testType = TestType.getTestType(androidMakeFile);
111
112 Document manifest;
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700113 try {
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700114 manifest = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
Brian Carlstrom022aff42011-05-17 23:16:51 -0700115 new FileInputStream(manifestFile));
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700116 } catch (Exception e) {
Brian Carlstrom022aff42011-05-17 23:16:51 -0700117 System.err.println("cannot open manifest " + manifestFile);
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700118 e.printStackTrace();
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700119 System.exit(1);
Brian Carlstrom022aff42011-05-17 23:16:51 -0700120 return;
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700121 }
122
123 Element documentElement = manifest.getDocumentElement();
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700124 documentElement.getAttribute("package");
Brian Carlstrom022aff42011-05-17 23:16:51 -0700125 final String runner = getElementAttribute(documentElement,
126 "instrumentation",
127 "android:name");
128 final String packageName = documentElement.getAttribute("package");
129 final String target = getElementAttribute(documentElement,
130 "instrumentation",
131 "android:targetPackage");
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700132
Brian Carlstrom022aff42011-05-17 23:16:51 -0700133 String outputXmlFile = outputPathPrefix + ".xml";
134 final String xmlName = new File(outputPathPrefix).getName();
135 XMLGenerator xmlGenerator;
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700136 try {
Brian Carlstrom022aff42011-05-17 23:16:51 -0700137 xmlGenerator = new XMLGenerator(outputXmlFile) {
138 {
139 Node testPackageElem = mDoc.getDocumentElement();
140
141 setAttribute(testPackageElem, ATTRIBUTE_NAME, xmlName);
142 setAttribute(testPackageElem, ATTRIBUTE_RUNNER, runner);
143 setAttribute(testPackageElem, ATTRIBUTE_PACKAGE, packageName);
144 setAttribute(testPackageElem, ATTRIBUTE_NS, packageName);
Narayan Kamathe160f382015-06-01 14:56:31 +0100145 setAttribute(testPackageElem, ATTRIBUTE_JAVA_PACKAGE_FILTER, javaPackageFilterArg);
Brian Carlstrom022aff42011-05-17 23:16:51 -0700146
147 if (testType.type == TestType.HOST_SIDE_ONLY) {
148 setAttribute(testPackageElem, ATTRIBUTE_HOST_SIDE_ONLY, "true");
149 setAttribute(testPackageElem, ATTRIBUTE_JAR_PATH, testType.jarPath);
150 }
151
152 if (testType.type == TestType.VM_HOST_TEST) {
153 setAttribute(testPackageElem, ATTRIBUTE_VM_HOST_TEST, "true");
154 setAttribute(testPackageElem, ATTRIBUTE_JAR_PATH, testType.jarPath);
155 }
156
157 if (!packageName.equals(target)) {
158 setAttribute(testPackageElem, ATTRIBUTE_TARGET, target);
159 setAttribute(testPackageElem, ATTRIBUTE_TARGET_BINARY, target);
160 }
161 }
162 };
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700163 } catch (ParserConfigurationException e) {
Brian Carlstrom022aff42011-05-17 23:16:51 -0700164 System.err.println("Can't initialize XML Generator " + outputXmlFile);
Urs Grobfc77f6e2009-04-17 02:07:14 -0700165 System.exit(1);
Brian Carlstrom022aff42011-05-17 23:16:51 -0700166 return;
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700167 }
168
Brian Carlstrom022aff42011-05-17 23:16:51 -0700169 ExpectationStore libcoreVogarExpectationStore;
170 ExpectationStore ctsVogarExpectationStore;
171
Brett Chabot5977e942010-12-13 16:42:42 -0800172 try {
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700173 libcoreVogarExpectationStore
Brian Carlstrom022aff42011-05-17 23:16:51 -0700174 = VogarUtils.provideExpectationStore(libcoreExpectationDir);
Brian Muramatsu7f64e852011-02-17 16:52:16 -0800175 ctsVogarExpectationStore = VogarUtils.provideExpectationStore(CTS_EXPECTATION_DIR);
Brett Chabot5977e942010-12-13 16:42:42 -0800176 } catch (IOException e) {
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700177 System.err.println("Can't initialize vogar expectation store from "
Brian Carlstrom022aff42011-05-17 23:16:51 -0700178 + libcoreExpectationDir);
Brett Chabot5977e942010-12-13 16:42:42 -0800179 e.printStackTrace(System.err);
180 System.exit(1);
Brian Carlstrom022aff42011-05-17 23:16:51 -0700181 return;
Brett Chabot5977e942010-12-13 16:42:42 -0800182 }
Brian Carlstrom022aff42011-05-17 23:16:51 -0700183 ExpectationStore[] expectations = new ExpectationStore[] {
184 libcoreVogarExpectationStore, ctsVogarExpectationStore
185 };
Brett Chabot5977e942010-12-13 16:42:42 -0800186
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700187 JarFile jarFile = null;
188 try {
Brian Carlstrom022aff42011-05-17 23:16:51 -0700189 jarFile = new JarFile(jarFileName);
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700190 } catch (Exception e) {
Brian Carlstrom022aff42011-05-17 23:16:51 -0700191 System.err.println("cannot open jarfile " + jarFileName);
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700192 e.printStackTrace();
Urs Grobfc77f6e2009-04-17 02:07:14 -0700193 System.exit(1);
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700194 }
195
Brian Carlstrom022aff42011-05-17 23:16:51 -0700196 Map<String,TestClass> testCases = new LinkedHashMap<String, TestClass>();
197
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700198 Enumeration<JarEntry> jarEntries = jarFile.entries();
199 while (jarEntries.hasMoreElements()) {
200 JarEntry jarEntry = jarEntries.nextElement();
201 String name = jarEntry.getName();
202 if (!name.endsWith(".class")) {
203 continue;
204 }
205 String className
206 = name.substring(0, name.length() - ".class".length()).replace('/', '.');
Narayan Kamathe160f382015-06-01 14:56:31 +0100207
208 boolean matchesPrefix = false;
209 if (javaPackagePrefixes.length > 0) {
210 for (String javaPackagePrefix : javaPackagePrefixes) {
211 if (className.startsWith(javaPackagePrefix)) {
212 matchesPrefix = true;
213 }
214 }
215 } else {
216 matchesPrefix = true;
217 }
218
219 if (!matchesPrefix) {
Brian Carlstrom022aff42011-05-17 23:16:51 -0700220 continue;
221 }
Narayan Kamathe160f382015-06-01 14:56:31 +0100222
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700223 try {
224 Class<?> klass = Class.forName(className,
225 false,
226 CollectAllTests.class.getClassLoader());
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800227 final int modifiers = klass.getModifiers();
228 if (Modifier.isAbstract(modifiers) || !Modifier.isPublic(modifiers)) {
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700229 continue;
230 }
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800231
232 final boolean isJunit4Class = isJunit4Class(klass);
233 if (!isJunit4Class && !isJunit3Test(klass)) {
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700234 continue;
235 }
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800236
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700237 try {
238 klass.getConstructor(new Class<?>[] { String.class } );
Stuart Scott01c2b492014-10-08 18:07:28 -0700239 addToTests(expectations, architecture, testCases, klass);
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700240 continue;
241 } catch (NoSuchMethodException e) {
Brian Carlstromd9f48462011-05-28 18:47:39 -0700242 } catch (SecurityException e) {
Tsu Chiang Chuangc87fd6b2011-07-13 17:04:40 -0700243 System.out.println("Known bug (Working as intended): problem with class "
244 + className);
Brian Carlstromd9f48462011-05-28 18:47:39 -0700245 e.printStackTrace();
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700246 }
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800247
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700248 try {
249 klass.getConstructor(new Class<?>[0]);
Stuart Scott01c2b492014-10-08 18:07:28 -0700250 addToTests(expectations, architecture, testCases, klass);
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700251 continue;
252 } catch (NoSuchMethodException e) {
Brian Carlstromd9f48462011-05-28 18:47:39 -0700253 } catch (SecurityException e) {
Tsu Chiang Chuangc87fd6b2011-07-13 17:04:40 -0700254 System.out.println("Known bug (Working as intended): problem with class "
255 + className);
Brian Carlstromd9f48462011-05-28 18:47:39 -0700256 e.printStackTrace();
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700257 }
258 } catch (ClassNotFoundException e) {
259 System.out.println("class not found " + className);
260 e.printStackTrace();
261 System.exit(1);
262 }
263 }
264
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700265 for (Iterator<TestClass> iterator = testCases.values().iterator(); iterator.hasNext();) {
266 TestClass type = iterator.next();
267 xmlGenerator.addTestClass(type);
268 }
269
270 try {
271 xmlGenerator.dump();
272 } catch (Exception e) {
Brian Carlstrom022aff42011-05-17 23:16:51 -0700273 System.err.println("cannot dump xml to " + outputXmlFile);
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700274 e.printStackTrace();
Urs Grobfc77f6e2009-04-17 02:07:14 -0700275 System.exit(1);
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700276 }
277 }
278
Brian Carlstrom022aff42011-05-17 23:16:51 -0700279 private static class TestType {
280 private static final int HOST_SIDE_ONLY = 1;
281 private static final int DEVICE_SIDE_ONLY = 2;
282 private static final int VM_HOST_TEST = 3;
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700283
Brian Carlstrom022aff42011-05-17 23:16:51 -0700284 private final int type;
285 private final String jarPath;
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700286
Brian Carlstrom022aff42011-05-17 23:16:51 -0700287 private TestType (int type, String jarPath) {
288 this.type = type;
289 this.jarPath = jarPath;
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700290 }
291
Brian Carlstrom022aff42011-05-17 23:16:51 -0700292 private static TestType getTestType(String makeFileName) {
293 if (makeFileName == null || makeFileName.isEmpty()) {
294 return new TestType(DEVICE_SIDE_ONLY, null);
295 }
296 int type = TestType.DEVICE_SIDE_ONLY;
297 String jarPath = null;
298 try {
299 BufferedReader reader = new BufferedReader(new FileReader(makeFileName));
300 String line;
301
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800302 while ((line = reader.readLine())!=null) {
Brian Carlstrom022aff42011-05-17 23:16:51 -0700303 if (line.startsWith(TEST_TYPE)) {
304 if (line.indexOf(ATTRIBUTE_VM_HOST_TEST) >= 0) {
305 type = VM_HOST_TEST;
306 } else {
307 type = HOST_SIDE_ONLY;
308 }
309 } else if (line.startsWith(JAR_PATH)) {
310 jarPath = line.substring(JAR_PATH.length(), line.length()).trim();
311 }
312 }
313 reader.close();
314 } catch (IOException e) {
315 }
316 return new TestType(type, jarPath);
317 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700318 }
319
320 private static Element getElement(Element element, String tagName) {
321 NodeList elements = element.getElementsByTagName(tagName);
322 if (elements.getLength() > 0) {
323 return (Element) elements.item(0);
324 } else {
325 return null;
326 }
327 }
328
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700329 private static String getElementAttribute(Element element,
330 String elementName,
331 String attributeName) {
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700332 Element e = getElement(element, elementName);
333 if (e != null) {
334 return e.getAttribute(attributeName);
335 } else {
336 return "";
337 }
338 }
339
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800340 private static String getKnownFailure(final Class<?> testClass,
Urs Grobfc77f6e2009-04-17 02:07:14 -0700341 final String testName) {
342 return getAnnotation(testClass, testName, KNOWN_FAILURE);
343 }
Brian Muramatsub8ed3162010-07-13 12:43:52 -0700344
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800345 private static boolean isKnownFailure(final Class<?> testClass,
Brian Muramatsub8ed3162010-07-13 12:43:52 -0700346 final String testName) {
347 return getAnnotation(testClass, testName, KNOWN_FAILURE) != null;
348 }
349
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800350 private static boolean isSuppressed(final Class<?> testClass,
Brian Muramatsu168beb02010-10-21 12:39:45 -0700351 final String testName) {
352 return getAnnotation(testClass, testName, SUPPRESSED_TEST) != null;
353 }
354
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800355 private static String getAnnotation(final Class<?> testClass,
Urs Grobfc77f6e2009-04-17 02:07:14 -0700356 final String testName, final String annotationName) {
The Android Open Source Project7671bec2009-03-19 23:08:36 -0700357 try {
Urs Grobfc77f6e2009-04-17 02:07:14 -0700358 Method testMethod = testClass.getMethod(testName, (Class[])null);
The Android Open Source Project7671bec2009-03-19 23:08:36 -0700359 Annotation[] annotations = testMethod.getAnnotations();
360 for (Annotation annot : annotations) {
361
Urs Grobfc77f6e2009-04-17 02:07:14 -0700362 if (annot.annotationType().getName().equals(annotationName)) {
The Android Open Source Project7671bec2009-03-19 23:08:36 -0700363 String annotStr = annot.toString();
364 String knownFailure = null;
365 if (annotStr.contains("(value=")) {
366 knownFailure =
Urs Grobfc77f6e2009-04-17 02:07:14 -0700367 annotStr.substring(annotStr.indexOf("=") + 1,
368 annotStr.length() - 1);
The Android Open Source Project7671bec2009-03-19 23:08:36 -0700369
370 }
371
372 if (knownFailure == null) {
373 knownFailure = "true";
374 }
375
376 return knownFailure;
377 }
378
379 }
380
Brian Carlstrom022aff42011-05-17 23:16:51 -0700381 } catch (NoSuchMethodException e) {
The Android Open Source Project7671bec2009-03-19 23:08:36 -0700382 }
383
384 return null;
385 }
386
Brian Carlstrom022aff42011-05-17 23:16:51 -0700387 private static void addToTests(ExpectationStore[] expectations,
Stuart Scott01c2b492014-10-08 18:07:28 -0700388 String architecture,
Brian Carlstrom022aff42011-05-17 23:16:51 -0700389 Map<String,TestClass> testCases,
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800390 Class<?> testClass) {
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700391 Set<String> testNames = new HashSet<String>();
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800392
393 boolean isJunit3Test = isJunit3Test(testClass);
394
395 Method[] testMethods = testClass.getMethods();
396 for (Method testMethod : testMethods) {
397 String testName = testMethod.getName();
398 if (testNames.contains(testName)) {
399 continue;
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700400 }
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800401
402 /* Make sure the method has the right signature. */
403 if (!Modifier.isPublic(testMethod.getModifiers())) {
404 continue;
405 }
406 if (!testMethod.getReturnType().equals(Void.TYPE)) {
407 continue;
408 }
409 if (testMethod.getParameterTypes().length != 0) {
410 continue;
411 }
412
413 if ((isJunit3Test && !testName.startsWith("test"))
414 || (!isJunit3Test && !isJunit4TestMethod(testMethod))) {
415 continue;
416 }
417
418 testNames.add(testName);
Stuart Scott01c2b492014-10-08 18:07:28 -0700419 addToTests(expectations, architecture, testCases, testClass, testName);
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700420 }
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700421 }
422
Brian Carlstrom022aff42011-05-17 23:16:51 -0700423 private static void addToTests(ExpectationStore[] expectations,
Stuart Scott01c2b492014-10-08 18:07:28 -0700424 String architecture,
Brian Carlstrom022aff42011-05-17 23:16:51 -0700425 Map<String,TestClass> testCases,
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800426 Class<?> test,
Brian Carlstrom022aff42011-05-17 23:16:51 -0700427 String testName) {
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700428
429 String testClassName = test.getName();
430 String knownFailure = getKnownFailure(test, testName);
431
432 if (isKnownFailure(test, testName)) {
433 System.out.println("ignoring known failure: " + test + "#" + testName);
434 return;
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700435 } else if (isSuppressed(test, testName)) {
436 System.out.println("ignoring suppressed test: " + test + "#" + testName);
437 return;
Brian Carlstrom022aff42011-05-17 23:16:51 -0700438 } else if (VogarUtils.isVogarKnownFailure(expectations,
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700439 testClassName,
440 testName)) {
Brian Carlstrom022aff42011-05-17 23:16:51 -0700441 System.out.println("ignoring expectation known failure: " + test
Brian Carlstrom9f2dab82011-04-01 15:47:17 -0700442 + "#" + testName);
443 return;
444 }
445
Stuart Scott01c2b492014-10-08 18:07:28 -0700446 Set<String> supportedAbis = VogarUtils.extractSupportedAbis(architecture,
447 expectations,
448 testClassName,
449 testName);
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800450 TestClass testClass;
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700451 if (testCases.containsKey(testClassName)) {
452 testClass = testCases.get(testClassName);
453 } else {
454 testClass = new TestClass(testClassName, new ArrayList<TestMethod>());
455 testCases.put(testClassName, testClass);
456 }
457
Stuart Scott01c2b492014-10-08 18:07:28 -0700458 testClass.mCases.add(new TestMethod(testName, "", "", supportedAbis,
459 knownFailure, false, false));
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700460 }
Tsu Chiang Chuangc87fd6b2011-07-13 17:04:40 -0700461
Kenny Rootb5b47cb2013-02-27 17:03:16 -0800462 private static boolean isJunit3Test(Class<?> klass) {
463 return TestCase.class.isAssignableFrom(klass);
464 }
465
466 private static boolean isJunit4Class(Class<?> klass) {
467 for (Annotation a : klass.getAnnotations()) {
468 if (RunWith.class.isAssignableFrom(a.annotationType())) {
469 // @RunWith is currently not supported for CTS tests because tradefed cannot handle
470 // a single test spawning other tests with different names.
471 System.out.println("Skipping test class " + klass.getName()
472 + ": JUnit4 @RunWith is not supported");
473 return false;
474 }
475 }
476
477 for (Method m : klass.getMethods()) {
478 if (isJunit4TestMethod(m)) {
479 return true;
480 }
481 }
482
483 return false;
484 }
485
486 private static boolean isJunit4TestMethod(Method method) {
487 for (Annotation a : method.getAnnotations()) {
488 if (org.junit.Test.class.isAssignableFrom(a.annotationType())) {
489 return true;
490 }
491 }
492
493 return false;
494 }
495
Tsu Chiang Chuangc87fd6b2011-07-13 17:04:40 -0700496 /**
497 * Determines if a given string is a valid java package name
498 * @param javaPackageName
499 * @return true if it is valid, false otherwise
500 */
501 private static boolean isValidJavaPackage(String javaPackageName) {
502 String[] strSections = javaPackageName.split(".");
503 for (String strSection : strSections) {
504 if (!isValidJavaIdentifier(strSection)) {
505 return false;
506 }
507 }
508 return true;
509 }
510
511 /**
512 * Determines if a given string is a valid java identifier.
513 * @param javaIdentifier
514 * @return true if it is a valid identifier, false otherwise
515 */
516 private static boolean isValidJavaIdentifier(String javaIdentifier) {
517 if (javaIdentifier.length() == 0 ||
518 !Character.isJavaIdentifierStart(javaIdentifier.charAt(0))) {
519 return false;
520 }
521 for (int i = 1; i < javaIdentifier.length(); i++) {
522 if (!Character.isJavaIdentifierPart(javaIdentifier.charAt(i))) {
523 return false;
524 }
525 }
526 return true;
527 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700528}