blob: e498c172cee4782d3a8a392b5f2bc900d798b3e3 [file] [log] [blame]
/*
* Copyright (C) 2015 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 com.android.compatibility.common.util;
import junit.framework.Test;
import junit.framework.TestResult;
import junit.framework.TestSuite;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
public class TestSuiteFilter {
private TestSuiteFilter() {}
public static TestSuite createSuite(List<Class<?>> classes, Set<String> includes,
Set<String> excludes) {
return new FilterableTestSuite(classes, includes, excludes);
}
/**
* A {@link TestSuite} that can filter which tests run, given the include and exclude filters.
*
* This had to be private inner class because the test runner would find it and think it was a
* suite of tests, but it has no tests in it, causing a crash.
*/
private static class FilterableTestSuite extends TestSuite {
private Set<String> mIncludes;
private Set<String> mExcludes;
public FilterableTestSuite(List<Class<?>> classes, Set<String> includes,
Set<String> excludes) {
super(classes.toArray(new Class<?>[classes.size()]));
mIncludes = includes;
mExcludes = excludes;
}
/**
* {@inheritDoc}
*/
@Override
public int countTestCases() {
return countTests(this);
}
private int countTests(Test test) {
if (test instanceof TestSuite) {
// If the test is a suite it could contain multiple tests, these need to be split
// out into separate tests so they can be filtered
TestSuite suite = (TestSuite) test;
Enumeration<Test> enumerator = suite.tests();
int count = 0;
while (enumerator.hasMoreElements()) {
count += countTests(enumerator.nextElement());
}
return count;
} else if (shouldRun(test)) {
return 1;
}
return 0;
}
/**
* {@inheritDoc}
*/
@Override
public void runTest(Test test, TestResult result) {
runTests(test, result);
}
private void runTests(Test test, TestResult result) {
if (test instanceof TestSuite) {
// If the test is a suite it could contain multiple tests, these need to be split
// out into separate tests so they can be filtered
TestSuite suite = (TestSuite) test;
Enumeration<Test> enumerator = suite.tests();
while (enumerator.hasMoreElements()) {
runTests(enumerator.nextElement(), result);
}
} else if (shouldRun(test)) {
test.run(result);
}
}
private boolean shouldRun(Test test) {
String fullName = test.toString();
String[] parts = fullName.split("[\\(\\)]");
String className = parts[1];
String methodName = String.format("%s#%s", className, parts[0]);
int index = className.lastIndexOf('.');
String packageName = index < 0 ? "" : className.substring(0, index);
if (mExcludes.contains(packageName)) {
// Skip package because it was excluded
return false;
}
if (mExcludes.contains(className)) {
// Skip class because it was excluded
return false;
}
if (mExcludes.contains(methodName)) {
// Skip method because it was excluded
return false;
}
return mIncludes.isEmpty()
|| mIncludes.contains(methodName)
|| mIncludes.contains(className)
|| mIncludes.contains(packageName);
}
}
}