Deqptestrunner efficient filtering
authorAaron Holden <aaronholden@google.com>
Mon, 6 Jun 2016 23:51:56 +0000 (16:51 -0700)
committerAaron Holden <aaronholden@google.com>
Tue, 7 Jun 2016 03:27:58 +0000 (20:27 -0700)
bug:28245788

Change-Id: I2c28fb7aed7a13c4f011b76b699cf0845c821f7c

android/cts/runner/src/com/drawelements/deqp/runner/DeqpTestRunner.java
android/cts/runner/tests/src/com/drawelements/deqp/runner/DeqpTestRunnerTest.java

index bb8ff68..ef6034a 100644 (file)
@@ -1882,14 +1882,26 @@ public class DeqpTestRunner implements IBuildReceiver, IDeviceTest,
         }
     }
 
-    private static List<Pattern> buildPatternList(List<String> filters) {
-        List<Pattern> patterns = new ArrayList(filters.size());
+    private static List<Pattern> getPatternFilters(List<String> filters) {
+        List<Pattern> patterns = new ArrayList<Pattern>();
         for (String filter : filters) {
-            patterns.add(Pattern.compile(filter.replace(".","\\.").replace("*",".*")));
+            if (filter.contains("*")) {
+                patterns.add(Pattern.compile(filter.replace(".","\\.").replace("*",".*")));
+            }
         }
         return patterns;
     }
 
+    private static Set<String> getNonPatternFilters(List<String> filters) {
+        Set<String> nonPatternFilters = new HashSet<String>();
+        for (String filter : filters) {
+            if (!filter.contains("*")) {
+                nonPatternFilters.add(filter);
+            }
+        }
+        return nonPatternFilters;
+    }
+
     private static boolean matchesAny(TestIdentifier test, List<Pattern> patterns) {
         for (Pattern pattern : patterns) {
             if (pattern.matcher(test.toString()).matches()) {
@@ -1900,32 +1912,35 @@ public class DeqpTestRunner implements IBuildReceiver, IDeviceTest,
     }
 
     /**
-     * Filter tests.
-     *
-     * '*' is 0 or more characters. '.' is interpreted verbatim.
-     *
-     * Optimized for small number of filters against many tests.
+     * Filter tests with the option of filtering by pattern.
      *
+     * '*' is 0 or more characters.
+     * '.' is interpreted verbatim.
      */
     private static void filterTests(Map<TestIdentifier, Set<BatchRunConfiguration>> tests,
                                     List<String> includeFilters,
                                     List<String> excludeFilters) {
         // We could filter faster by building the test case tree.
         // Let's see if this is fast enough.
-        List<Pattern> includes = buildPatternList(includeFilters);
-        List<Pattern> excludes = buildPatternList(excludeFilters);
+        Set<String> includeStrings = getNonPatternFilters(includeFilters);
+        Set<String> excludeStrings = getNonPatternFilters(excludeFilters);
+        List<Pattern> includePatterns = getPatternFilters(includeFilters);
+        List<Pattern> excludePatterns = getPatternFilters(excludeFilters);
 
         List<TestIdentifier> testList = new ArrayList(tests.keySet());
         for (TestIdentifier test : testList) {
-            // Remove test if it does not match includes or matches
-            // excludes.
-            // Empty include filter includes everything.
-            if (includes.isEmpty() || matchesAny(test, includes)) {
-                if (!matchesAny(test, excludes)) {
-                    continue;
-                }
+            if (excludeStrings.contains(test.toString())) {
+                tests.remove(test); // remove test if explicitly excluded
+                continue;
+            }
+            boolean includesExist = !includeStrings.isEmpty() || !includePatterns.isEmpty();
+            boolean testIsIncluded = includeStrings.contains(test.toString())
+                    || matchesAny(test, includePatterns);
+            if ((includesExist && !testIsIncluded) || matchesAny(test, excludePatterns)) {
+                // if this test isn't included and other tests are,
+                // or if test matches exclude pattern, exclude test
+                tests.remove(test);
             }
-            tests.remove(test);
         }
     }
 
index 5e994bb..b11377c 100644 (file)
@@ -640,7 +640,7 @@ public class DeqpTestRunnerTest extends TestCase {
                                String expectedTrie,
                                List<TestIdentifier> expectedTests) throws Exception {
 
-
+        boolean thereAreTests = !expectedTests.isEmpty();
         ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
         ITestInvocationListener mockListener
                 = EasyMock.createStrictMock(ITestInvocationListener.class);
@@ -658,16 +658,21 @@ public class DeqpTestRunnerTest extends TestCase {
         EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
                 .andReturn(Integer.toString(version)).atLeastOnce();
 
-        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
+        if (thereAreTests)
+        {
+            // only expect to install/uninstall packages if there are any tests
+            EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
                 .once();
-        EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+            EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
                 EasyMock.eq(true), EasyMock.eq(AbiUtils.createAbiFlag(ABI.getName()))))
                 .andReturn(null).once();
+        }
+
 
         mockListener.testRunStarted(getTestId(deqpTest), expectedTests.size());
         EasyMock.expectLastCall().once();
 
-        if (expectedTests.size() > 0)
+        if (thereAreTests)
         {
             expectRenderConfigQuery(mockDevice, 3, 0);
 
@@ -688,8 +693,12 @@ public class DeqpTestRunnerTest extends TestCase {
         mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
         EasyMock.expectLastCall().once();
 
-        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
+        if (thereAreTests)
+        {
+            // package will only be installed if there are tests to run
+            EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
                 .once();
+        }
 
         EasyMock.replay(mockDevice, mockIDevice);
         EasyMock.replay(mockListener);