Fix TestMappingSuiteRunner when handling test with exclude-filter

When a test config has exclude-filter option, an include-filter is still
needed for the BaseTestSuite.

Bug: 127637793
Test: unittest
Change-Id: I528e7b27b4e35243c9f1ce90f28459f6376e25dd
diff --git a/src/com/android/tradefed/testtype/suite/BaseTestSuite.java b/src/com/android/tradefed/testtype/suite/BaseTestSuite.java
index cee54cf..71de26e 100644
--- a/src/com/android/tradefed/testtype/suite/BaseTestSuite.java
+++ b/src/com/android/tradefed/testtype/suite/BaseTestSuite.java
@@ -280,6 +280,11 @@
         mExcludeFilters.addAll(excludeFilters);
     }
 
+    /** Gets a copy of exclude-filters for the compatibility test */
+    protected Set<String> getExcludeFilter() {
+        return new HashSet<String>(mExcludeFilters);
+    }
+
     /** Returns the current {@link SuiteModuleLoader}. */
     public SuiteModuleLoader getModuleLoader() {
         return mModuleRepo;
diff --git a/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunner.java b/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunner.java
index d3be357..c0dc16a 100644
--- a/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunner.java
+++ b/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunner.java
@@ -115,18 +115,17 @@
             // module-arg options compiled from test options for each test.
             Set<String> moduleArgs = new HashSet<>();
             for (TestInfo test : testsToRun) {
-                boolean hasFilters = false;
+                boolean hasIncludeFilters = false;
                 for (TestOption option : test.getOptions()) {
                     switch (option.getName()) {
                             // Handle include and exclude filter at the suite level to hide each
                             // test runner specific implementation and option names related to filtering
                         case TEST_MAPPING_INCLUDE_FILTER:
-                            hasFilters = true;
+                            hasIncludeFilters = true;
                             mappingIncludeFilters.add(
                                     String.format("%s %s", test.getName(), option.getValue()));
                             break;
                         case TEST_MAPPING_EXCLUDE_FILTER:
-                            hasFilters = true;
                             mappingExcludeFilters.add(
                                     String.format("%s %s", test.getName(), option.getValue()));
                             break;
@@ -140,7 +139,7 @@
                             break;
                     }
                 }
-                if (!hasFilters) {
+                if (!hasIncludeFilters) {
                     testNames.add(test.getName());
                 }
             }
diff --git a/tests/res/testdata/test_mapping_2 b/tests/res/testdata/test_mapping_2
index d33bc69..2a5135c 100644
--- a/tests/res/testdata/test_mapping_2
+++ b/tests/res/testdata/test_mapping_2
@@ -15,14 +15,22 @@
   ],
   "postsubmit": [
     {
+      "name": "suite/stub1",
+      "options": [
+        {
+          "exclude-filter": "filter.com"
+        }
+      ]
+    },
+    {
       "name": "suite/stub2",
       "options": [
         {
           "test-suite-tag": "just_a_name"
         },
-	{
-	  "include-filter": "filter.com"
-	}
+        {
+          "include-filter": "filter.com"
+        }
       ]
     }
   ]
diff --git a/tests/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunnerTest.java b/tests/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunnerTest.java
index c024431..bbf22c4 100644
--- a/tests/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunnerTest.java
+++ b/tests/src/com/android/tradefed/testtype/suite/TestMappingSuiteRunnerTest.java
@@ -172,7 +172,9 @@
             // include-filters.
             assertTrue(mRunner.getIncludeFilter().contains("test2"));
             assertTrue(mRunner.getIncludeFilter().contains("instrument"));
+            assertTrue(mRunner.getIncludeFilter().contains("suite/stub1"));
             // Filters are applied directly
+            assertTrue(mRunner.getExcludeFilter().contains("suite/stub1 filter.com"));
             assertTrue(mRunner.getIncludeFilter().contains("suite/stub2 filter.com"));
 
             // Check module-arg work as expected.
@@ -180,18 +182,20 @@
                     (InstrumentationTest) configMap.get("arm64-v8a instrument").getTests().get(0);
             assertEquals("some-name", test.getRunName());
 
-            assertEquals(4, configMap.size());
+            assertEquals(6, configMap.size());
             assertTrue(configMap.containsKey(ABI_1 + " instrument"));
+            assertTrue(configMap.containsKey(ABI_1 + " suite/stub1"));
             assertTrue(configMap.containsKey(ABI_1 + " suite/stub2"));
             assertTrue(configMap.containsKey(ABI_2 + " instrument"));
+            assertTrue(configMap.containsKey(ABI_2 + " suite/stub1"));
             assertTrue(configMap.containsKey(ABI_2 + " suite/stub2"));
 
             // Confirm test sources are stored in test's ConfigurationDescription.
             Map<String, Integer> testSouceCount = new HashMap<>();
+            testSouceCount.put("suite/stub1", 1);
             testSouceCount.put("suite/stub2", 1);
             testSouceCount.put("instrument", 1);
 
-            assertEquals(4, configMap.size());
             for (IConfiguration config : configMap.values()) {
                 assertTrue(testSouceCount.containsKey(config.getName()));
                 assertEquals(
@@ -419,7 +423,7 @@
             EasyMock.replay(mockBuildInfo);
 
             Collection<IRemoteTest> tests = mRunner.split(2);
-            assertEquals(4, tests.size());
+            assertEquals(6, tests.size());
             EasyMock.verify(mockBuildInfo);
         } finally {
             FileUtil.recursiveDelete(tempDir);