summaryrefslogtreecommitdiff
path: root/test-runner
diff options
context:
space:
mode:
authorPaul Duffin <paulduffin@google.com>2017-06-20 16:18:07 +0100
committerPaul Duffin <paulduffin@google.com>2017-06-26 17:00:21 +0100
commitaaaba76810c0b5b61c609a929536b64ac7e368fc (patch)
tree9dabcf4edf22526ff3a057fcd5a0bb2d0be0ae53 /test-runner
parent3c5ab7d3243e646137d9e60c2a54ffc907a85a27 (diff)
Clean up ClassPathPackageInfoSource
Part of the work of removing JUnit and dependent android.test classes from the Android API involves providing a static library that developers can include in their test applications to ease migration. That library will be built directly from the source (as opposed to android.jar which is built from stubs) and so developers will be able to see classes and methods that are not present in the stubs. This change is one of a number of similar changes that cleanup the existing non-API code in order to minimize the additional methods and classes exposed externally. The basic approach is to remove unused classes and methods, use least visible access modifier possible and generally minimize the amount of publicly visible code. PackageInfoSources only provided a static field and accessor method so they were moved into ClassPathPackageInfoSource and PackageInfoSources was removed. ClassPathPackageInfo was only used in ClassPathPackageInfoSource and in TestGrouping. In the latter it was simply used as an intermediate value between ClassPathPackageInfoSource.getPackage(String packageName) and ClassPathPackageInfo.getTopLevelClassesRecursive(String packageName). Moving that method into ClassPathPackageInfoSource allowed the ClassPathPackageInfo to become an inner class of ClassPathPackageInfoSource. As it is an inner class it no longer needed an explicit reference to the containing ClassPathPackageInfoSource. Bug: 30188076 Test: make checkbuild and ran FrameworkTestRunnerTests Change-Id: Idb0b6a585030805b9cff8562abb93b7e5920c53a
Diffstat (limited to 'test-runner')
-rw-r--r--test-runner/src/android/test/ClassPathPackageInfo.java79
-rw-r--r--test-runner/src/android/test/ClassPathPackageInfoSource.java193
-rw-r--r--test-runner/src/android/test/PackageInfoSources.java38
-rw-r--r--test-runner/src/android/test/suitebuilder/TestGrouping.java7
-rw-r--r--test-runner/tests/Android.mk2
5 files changed, 74 insertions, 245 deletions
diff --git a/test-runner/src/android/test/ClassPathPackageInfo.java b/test-runner/src/android/test/ClassPathPackageInfo.java
deleted file mode 100644
index 2cf76afa1d94..000000000000
--- a/test-runner/src/android/test/ClassPathPackageInfo.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * The Package object doesn't allow you to iterate over the contained
- * classes and subpackages of that package. This is a version that does.
- *
- * {@hide} Not needed for 1.0 SDK.
- */
-@Deprecated
-public class ClassPathPackageInfo {
-
- private final ClassPathPackageInfoSource source;
- private final String packageName;
- private final Set<String> subpackageNames;
- private final Set<Class<?>> topLevelClasses;
-
- ClassPathPackageInfo(ClassPathPackageInfoSource source, String packageName,
- Set<String> subpackageNames, Set<Class<?>> topLevelClasses) {
- this.source = source;
- this.packageName = packageName;
- this.subpackageNames = Collections.unmodifiableSet(subpackageNames);
- this.topLevelClasses = Collections.unmodifiableSet(topLevelClasses);
- }
-
- public Set<ClassPathPackageInfo> getSubpackages() {
- Set<ClassPathPackageInfo> info = new HashSet<>();
- for (String name : subpackageNames) {
- info.add(source.getPackageInfo(name));
- }
- return info;
- }
-
- public Set<Class<?>> getTopLevelClassesRecursive() {
- Set<Class<?>> set = new HashSet<>();
- addTopLevelClassesTo(set);
- return set;
- }
-
- private void addTopLevelClassesTo(Set<Class<?>> set) {
- set.addAll(topLevelClasses);
- for (ClassPathPackageInfo info : getSubpackages()) {
- info.addTopLevelClassesTo(set);
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof ClassPathPackageInfo) {
- ClassPathPackageInfo that = (ClassPathPackageInfo) obj;
- return (this.packageName).equals(that.packageName);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return packageName.hashCode();
- }
-}
diff --git a/test-runner/src/android/test/ClassPathPackageInfoSource.java b/test-runner/src/android/test/ClassPathPackageInfoSource.java
index 9bcc25adf8d3..755b540cbbb8 100644
--- a/test-runner/src/android/test/ClassPathPackageInfoSource.java
+++ b/test-runner/src/android/test/ClassPathPackageInfoSource.java
@@ -21,15 +21,12 @@ import dalvik.system.DexFile;
import java.io.File;
import java.io.IOException;
+import java.util.Collections;
import java.util.Enumeration;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
/**
* Generate {@link ClassPathPackageInfo}s by scanning apk paths.
@@ -39,11 +36,13 @@ import java.util.zip.ZipFile;
@Deprecated
public class ClassPathPackageInfoSource {
- private static final String CLASS_EXTENSION = ".class";
-
private static final ClassLoader CLASS_LOADER
= ClassPathPackageInfoSource.class.getClassLoader();
+ private static String[] apkPaths;
+
+ private static ClassPathPackageInfoSource classPathSource;
+
private final SimpleCache<String, ClassPathPackageInfo> cache =
new SimpleCache<String, ClassPathPackageInfo>() {
@Override
@@ -54,23 +53,28 @@ public class ClassPathPackageInfoSource {
// The class path of the running application
private final String[] classPath;
- private static String[] apkPaths;
- // A cache of jar file contents
- private final Map<File, Set<String>> jarFiles = new HashMap<>();
- private ClassLoader classLoader;
+ private final ClassLoader classLoader;
- ClassPathPackageInfoSource() {
+ private ClassPathPackageInfoSource(ClassLoader classLoader) {
+ this.classLoader = classLoader;
classPath = getClassPath();
}
-
- public static void setApkPaths(String[] apkPaths) {
+ static void setApkPaths(String[] apkPaths) {
ClassPathPackageInfoSource.apkPaths = apkPaths;
}
- public ClassPathPackageInfo getPackageInfo(String pkgName) {
- return cache.get(pkgName);
+ public static ClassPathPackageInfoSource forClassPath(ClassLoader classLoader) {
+ if (classPathSource == null) {
+ classPathSource = new ClassPathPackageInfoSource(classLoader);
+ }
+ return classPathSource;
+ }
+
+ public Set<Class<?>> getTopLevelClassesRecursive(String packageName) {
+ ClassPathPackageInfo packageInfo = cache.get(packageName);
+ return packageInfo.getTopLevelClassesRecursive();
}
private ClassPathPackageInfo createPackageInfo(String packageName) {
@@ -96,7 +100,7 @@ public class ClassPathPackageInfoSource {
+ "'. Message: " + e.getMessage(), e);
}
}
- return new ClassPathPackageInfo(this, packageName, subpackageNames,
+ return new ClassPathPackageInfo(packageName, subpackageNames,
topLevelClasses);
}
@@ -107,9 +111,6 @@ public class ClassPathPackageInfoSource {
*/
private void findClasses(String packageName, Set<String> classNames,
Set<String> subpackageNames) {
- String packagePrefix = packageName + '.';
- String pathPrefix = packagePrefix.replace('.', '/');
-
for (String entryName : classPath) {
File classPathEntry = new File(entryName);
@@ -150,58 +151,6 @@ public class ClassPathPackageInfoSource {
/**
* Finds all classes and sub packages that are below the packageName and
- * add them to the respective sets. Searches the package in a class directory.
- */
- private void findClassesInDirectory(File classDir,
- String packagePrefix, String pathPrefix, Set<String> classNames,
- Set<String> subpackageNames)
- throws IOException {
- File directory = new File(classDir, pathPrefix);
-
- if (directory.exists()) {
- for (File f : directory.listFiles()) {
- String name = f.getName();
- if (name.endsWith(CLASS_EXTENSION) && isToplevelClass(name)) {
- classNames.add(packagePrefix + getClassName(name));
- } else if (f.isDirectory()) {
- subpackageNames.add(packagePrefix + name);
- }
- }
- }
- }
-
- /**
- * Finds all classes and sub packages that are below the packageName and
- * add them to the respective sets. Searches the package in a single jar file.
- */
- private void findClassesInJar(File jarFile, String pathPrefix,
- Set<String> classNames, Set<String> subpackageNames)
- throws IOException {
- Set<String> entryNames = getJarEntries(jarFile);
- // check if the Jar contains the package.
- if (!entryNames.contains(pathPrefix)) {
- return;
- }
- int prefixLength = pathPrefix.length();
- for (String entryName : entryNames) {
- if (entryName.startsWith(pathPrefix)) {
- if (entryName.endsWith(CLASS_EXTENSION)) {
- // check if the class is in the package itself or in one of its
- // subpackages.
- int index = entryName.indexOf('/', prefixLength);
- if (index >= 0) {
- String p = entryName.substring(0, index).replace('/', '.');
- subpackageNames.add(p);
- } else if (isToplevelClass(entryName)) {
- classNames.add(getClassName(entryName).replace('/', '.'));
- }
- }
- }
- }
- }
-
- /**
- * Finds all classes and sub packages that are below the packageName and
* add them to the respective sets. Searches the package in a single apk file.
*/
private void findClassesInApk(String apkPath, String packageName,
@@ -242,47 +191,6 @@ public class ClassPathPackageInfoSource {
}
/**
- * Gets the class and package entries from a Jar.
- */
- private Set<String> getJarEntries(File jarFile)
- throws IOException {
- Set<String> entryNames = jarFiles.get(jarFile);
- if (entryNames == null) {
- entryNames = new HashSet<>();
- ZipFile zipFile = new ZipFile(jarFile);
- Enumeration<? extends ZipEntry> entries = zipFile.entries();
- while (entries.hasMoreElements()) {
- String entryName = entries.nextElement().getName();
- if (entryName.endsWith(CLASS_EXTENSION)) {
- // add the entry name of the class
- entryNames.add(entryName);
-
- // add the entry name of the classes package, i.e. the entry name of
- // the directory that the class is in. Used to quickly skip jar files
- // if they do not contain a certain package.
- //
- // Also add parent packages so that a JAR that contains
- // pkg1/pkg2/Foo.class will be marked as containing pkg1/ in addition
- // to pkg1/pkg2/ and pkg1/pkg2/Foo.class. We're still interested in
- // JAR files that contains subpackages of a given package, even if
- // an intermediate package contains no direct classes.
- //
- // Classes in the default package will cause a single package named
- // "" to be added instead.
- int lastIndex = entryName.lastIndexOf('/');
- do {
- String packageName = entryName.substring(0, lastIndex + 1);
- entryNames.add(packageName);
- lastIndex = entryName.lastIndexOf('/', lastIndex - 1);
- } while (lastIndex > 0);
- }
- }
- jarFiles.put(jarFile, entryNames);
- }
- return entryNames;
- }
-
- /**
* Checks if a given file name represents a toplevel class.
*/
private static boolean isToplevelClass(String fileName) {
@@ -290,14 +198,6 @@ public class ClassPathPackageInfoSource {
}
/**
- * Given the absolute path of a class file, return the class name.
- */
- private static String getClassName(String className) {
- int classNameEnd = className.length() - CLASS_EXTENSION.length();
- return className.substring(0, classNameEnd);
- }
-
- /**
* Gets the class path from the System Property "java.class.path" and splits
* it up into the individual elements.
*/
@@ -307,7 +207,56 @@ public class ClassPathPackageInfoSource {
return classPath.split(Pattern.quote(separator));
}
- public void setClassLoader(ClassLoader classLoader) {
- this.classLoader = classLoader;
+ /**
+ * The Package object doesn't allow you to iterate over the contained
+ * classes and subpackages of that package. This is a version that does.
+ */
+ private class ClassPathPackageInfo {
+
+ private final String packageName;
+ private final Set<String> subpackageNames;
+ private final Set<Class<?>> topLevelClasses;
+
+ private ClassPathPackageInfo(String packageName,
+ Set<String> subpackageNames, Set<Class<?>> topLevelClasses) {
+ this.packageName = packageName;
+ this.subpackageNames = Collections.unmodifiableSet(subpackageNames);
+ this.topLevelClasses = Collections.unmodifiableSet(topLevelClasses);
+ }
+
+ private Set<ClassPathPackageInfo> getSubpackages() {
+ Set<ClassPathPackageInfo> info = new HashSet<>();
+ for (String name : subpackageNames) {
+ info.add(cache.get(name));
+ }
+ return info;
+ }
+
+ private Set<Class<?>> getTopLevelClassesRecursive() {
+ Set<Class<?>> set = new HashSet<>();
+ addTopLevelClassesTo(set);
+ return set;
+ }
+
+ private void addTopLevelClassesTo(Set<Class<?>> set) {
+ set.addAll(topLevelClasses);
+ for (ClassPathPackageInfo info : getSubpackages()) {
+ info.addTopLevelClassesTo(set);
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ClassPathPackageInfo) {
+ ClassPathPackageInfo that = (ClassPathPackageInfo) obj;
+ return (this.packageName).equals(that.packageName);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return packageName.hashCode();
+ }
}
}
diff --git a/test-runner/src/android/test/PackageInfoSources.java b/test-runner/src/android/test/PackageInfoSources.java
deleted file mode 100644
index 205f86b04d5f..000000000000
--- a/test-runner/src/android/test/PackageInfoSources.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test;
-
-/**
- * {@hide} Not needed for SDK.
- */
-@Deprecated
-public class PackageInfoSources {
-
- private static ClassPathPackageInfoSource classPathSource;
-
- private PackageInfoSources() {
- }
-
- public static ClassPathPackageInfoSource forClassPath(ClassLoader classLoader) {
- if (classPathSource == null) {
- classPathSource = new ClassPathPackageInfoSource();
- classPathSource.setClassLoader(classLoader);
- }
- return classPathSource;
- }
-
-}
diff --git a/test-runner/src/android/test/suitebuilder/TestGrouping.java b/test-runner/src/android/test/suitebuilder/TestGrouping.java
index 307afb55e47a..030bc426ac19 100644
--- a/test-runner/src/android/test/suitebuilder/TestGrouping.java
+++ b/test-runner/src/android/test/suitebuilder/TestGrouping.java
@@ -16,9 +16,7 @@
package android.test.suitebuilder;
-import android.test.ClassPathPackageInfo;
import android.test.ClassPathPackageInfoSource;
-import android.test.PackageInfoSources;
import android.util.Log;
import com.android.internal.util.Predicate;
import junit.framework.TestCase;
@@ -131,10 +129,9 @@ class TestGrouping {
}
private List<Class<? extends TestCase>> testCaseClassesInPackage(String packageName) {
- ClassPathPackageInfoSource source = PackageInfoSources.forClassPath(classLoader);
- ClassPathPackageInfo packageInfo = source.getPackageInfo(packageName);
+ ClassPathPackageInfoSource source = ClassPathPackageInfoSource.forClassPath(classLoader);
- return selectTestClasses(packageInfo.getTopLevelClassesRecursive());
+ return selectTestClasses(source.getTopLevelClassesRecursive(packageName));
}
@SuppressWarnings("unchecked")
diff --git a/test-runner/tests/Android.mk b/test-runner/tests/Android.mk
index cc9b01d18fa6..7ee047e47058 100644
--- a/test-runner/tests/Android.mk
+++ b/test-runner/tests/Android.mk
@@ -18,7 +18,7 @@ include $(CLEAR_VARS)
# We only want this apk build for tests.
#
# Run the tests using the following commands:
-# adb -r install ${ANDROID_PRODUCT_OUT}/data/app/FrameworkTestRunnerTests/FrameworkTestRunnerTests.apk
+# adb install -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworkTestRunnerTests/FrameworkTestRunnerTests.apk
# adb shell am instrument \
-e notAnnotation android.test.suitebuilder.examples.error.RunAsPartOfSeparateTest \
-w com.android.frameworks.testrunner.tests/android.test.InstrumentationTestRunner