Add source information in TestMapping's TestInfo
The source defines where the test is originated in TEST_MAPPING file located
in the source tree. The information will be saved to invocation context and
used in reporting.
Bug: 116817899
Test: unittest
Change-Id: Id5cfc76cc571720e4828d391f62b2b83844ce2ad
diff --git a/src/com/android/tradefed/util/testmapping/TestInfo.java b/src/com/android/tradefed/util/testmapping/TestInfo.java
index 37d5e97..8d1e521 100644
--- a/src/com/android/tradefed/util/testmapping/TestInfo.java
+++ b/src/com/android/tradefed/util/testmapping/TestInfo.java
@@ -32,9 +32,12 @@
private String mName = null;
private List<TestOption> mOptions = new ArrayList<TestOption>();
+ // A list of locations with TEST_MAPPING files that containing the test.
+ private Set<String> mSources = new HashSet<String>();
- public TestInfo(String name) {
+ public TestInfo(String name, String source) {
mName = name;
+ mSources.add(source);
}
public String getName() {
@@ -49,6 +52,14 @@
return mOptions;
}
+ public void addSources(Set<String> sources) {
+ mSources.addAll(sources);
+ }
+
+ public Set<String> getSources() {
+ return mSources;
+ }
+
/**
* Merge with another test.
*
@@ -194,6 +205,7 @@
mergedOptions.add(option);
}
this.mOptions = mergedOptions;
+ this.addSources(test.getSources());
CLog.d("Options are merged, updated test: %s.", this);
}
diff --git a/src/com/android/tradefed/util/testmapping/TestMapping.java b/src/com/android/tradefed/util/testmapping/TestMapping.java
index 3ff8116..0baab43 100644
--- a/src/com/android/tradefed/util/testmapping/TestMapping.java
+++ b/src/com/android/tradefed/util/testmapping/TestMapping.java
@@ -59,9 +59,11 @@
* Constructor to create a {@link TestMapping} object from a path to TEST_MAPPING file.
*
* @param path The {@link Path} to a TEST_MAPPING file.
+ * @param testMappingsDir The {@link Path} to the folder of all TEST_MAPPING files for a build.
*/
- public TestMapping(Path path) {
+ public TestMapping(Path path, Path testMappingsDir) {
mTestCollection = new LinkedHashMap<>();
+ String relativePath = testMappingsDir.relativize(path.getParent()).toString();
String errorMessage = null;
try {
String content = String.join("", Files.readAllLines(path, StandardCharsets.UTF_8));
@@ -81,7 +83,7 @@
JSONArray arr = root.getJSONArray(group);
for (int i = 0; i < arr.length(); i++) {
JSONObject testObject = arr.getJSONObject(i);
- TestInfo test = new TestInfo(testObject.getString(KEY_NAME));
+ TestInfo test = new TestInfo(testObject.getString(KEY_NAME), relativePath);
if (testObject.has(KEY_OPTIONS)) {
JSONArray optionObjects = testObject.getJSONArray(KEY_OPTIONS);
for (int j = 0; j < optionObjects.length(); j++) {
@@ -179,12 +181,14 @@
Stream<Path> stream = null;
try {
testMappingsDir = ZipUtil2.extractZipToTemp(testMappingsZip, TEST_MAPPINGS_ZIP);
- stream =
- Files.walk(
- Paths.get(testMappingsDir.getAbsolutePath()),
- FileVisitOption.FOLLOW_LINKS);
+ Path testMappingsRootPath = Paths.get(testMappingsDir.getAbsolutePath());
+ stream = Files.walk(testMappingsRootPath, FileVisitOption.FOLLOW_LINKS);
stream.filter(path -> path.getFileName().toString().equals(TEST_MAPPING))
- .forEach(path -> tests.addAll((new TestMapping(path)).getTests(testGroup)));
+ .forEach(
+ path ->
+ tests.addAll(
+ (new TestMapping(path, testMappingsRootPath))
+ .getTests(testGroup)));
} catch (IOException e) {
RuntimeException runtimeException =
new RuntimeException(
diff --git a/tests/src/com/android/tradefed/util/testmapping/TestMappingTest.java b/tests/src/com/android/tradefed/util/testmapping/TestMappingTest.java
index 05d175b..a10ace5 100644
--- a/tests/src/com/android/tradefed/util/testmapping/TestMappingTest.java
+++ b/tests/src/com/android/tradefed/util/testmapping/TestMappingTest.java
@@ -52,11 +52,18 @@
tempDir = FileUtil.createTempDir("test_mapping");
String srcFile = File.separator + TEST_DATA_DIR + File.separator + "test_mapping_1";
InputStream resourceStream = this.getClass().getResourceAsStream(srcFile);
- testMappingFile = FileUtil.saveResourceFile(resourceStream, tempDir, TEST_MAPPING);
- List<TestInfo> tests = new TestMapping(testMappingFile.toPath()).getTests("presubmit");
+ File testMappingRootDir = FileUtil.createTempDir("subdir", tempDir);
+ String rootDirName = testMappingRootDir.getName();
+ testMappingFile =
+ FileUtil.saveResourceFile(resourceStream, testMappingRootDir, TEST_MAPPING);
+ List<TestInfo> tests =
+ new TestMapping(testMappingFile.toPath(), Paths.get(tempDir.getAbsolutePath()))
+ .getTests("presubmit");
assertEquals(1, tests.size());
assertEquals("test1", tests.get(0).getName());
- tests = new TestMapping(testMappingFile.toPath()).getTests("postsubmit");
+ tests =
+ new TestMapping(testMappingFile.toPath(), Paths.get(tempDir.getAbsolutePath()))
+ .getTests("postsubmit");
assertEquals(3, tests.size());
assertEquals("test2", tests.get(0).getName());
TestOption option = tests.get(0).getOptions().get(0);
@@ -64,9 +71,13 @@
assertEquals(
"annotation=android.platform.test.annotations.Presubmit", option.getValue());
assertEquals("instrument", tests.get(1).getName());
- tests = new TestMapping(testMappingFile.toPath()).getTests("othertype");
+ tests =
+ new TestMapping(testMappingFile.toPath(), Paths.get(tempDir.getAbsolutePath()))
+ .getTests("othertype");
assertEquals(1, tests.size());
assertEquals("test3", tests.get(0).getName());
+ assertEquals(1, tests.get(0).getSources().size());
+ assertTrue(tests.get(0).getSources().contains(rootDirName));
} finally {
FileUtil.recursiveDelete(tempDir);
}
@@ -81,7 +92,9 @@
tempDir = FileUtil.createTempDir("test_mapping");
File testMappingFile = Paths.get(tempDir.getAbsolutePath(), TEST_MAPPING).toFile();
FileUtil.writeToFile("bad format json file", testMappingFile);
- List<TestInfo> tests = new TestMapping(testMappingFile.toPath()).getTests("presubmit");
+ List<TestInfo> tests =
+ new TestMapping(testMappingFile.toPath(), Paths.get(tempDir.getAbsolutePath()))
+ .getTests("presubmit");
} finally {
FileUtil.recursiveDelete(tempDir);
}
@@ -131,8 +144,8 @@
*/
@Test(expected = RuntimeException.class)
public void testMergeFailByName() throws Exception {
- TestInfo test1 = new TestInfo("test1");
- TestInfo test2 = new TestInfo("test2");
+ TestInfo test1 = new TestInfo("test1", "folder1");
+ TestInfo test2 = new TestInfo("test2", "folder1");
test1.merge(test2);
}
@@ -143,14 +156,14 @@
@Test
public void testMergeSuccess() throws Exception {
// Check that the test without any option should be the merge result.
- TestInfo test1 = new TestInfo("test1");
- TestInfo test2 = new TestInfo("test1");
+ TestInfo test1 = new TestInfo("test1", "folder1");
+ TestInfo test2 = new TestInfo("test1", "folder1");
test2.addOption(new TestOption("include-filter", "value"));
test1.merge(test2);
assertTrue(test1.getOptions().isEmpty());
- test1 = new TestInfo("test1");
- test2 = new TestInfo("test1");
+ test1 = new TestInfo("test1", "folder1");
+ test2 = new TestInfo("test1", "folder1");
test1.addOption(new TestOption("include-filter", "value"));
test1.merge(test2);
assertTrue(test1.getOptions().isEmpty());
@@ -163,8 +176,8 @@
@Test
public void testMergeSuccess_2Filters() throws Exception {
// Check that the test without any option should be the merge result.
- TestInfo test1 = new TestInfo("test1");
- TestInfo test2 = new TestInfo("test1");
+ TestInfo test1 = new TestInfo("test1", "folder1");
+ TestInfo test2 = new TestInfo("test1", "folder2");
TestOption option1 = new TestOption("include-filter", "value1");
test1.addOption(option1);
TestOption option2 = new TestOption("include-filter", "value2");
@@ -173,6 +186,9 @@
assertEquals(2, test1.getOptions().size());
assertTrue(new HashSet<TestOption>(test1.getOptions()).contains(option1));
assertTrue(new HashSet<TestOption>(test1.getOptions()).contains(option2));
+ assertEquals(2, test1.getSources().size());
+ assertTrue(test1.getSources().contains("folder1"));
+ assertTrue(test1.getSources().contains("folder2"));
}
/**
@@ -182,8 +198,8 @@
@Test
public void testMergeSuccess_multiFilters() throws Exception {
// Check that the test without any option should be the merge result.
- TestInfo test1 = new TestInfo("test1");
- TestInfo test2 = new TestInfo("test1");
+ TestInfo test1 = new TestInfo("test1", "folder1");
+ TestInfo test2 = new TestInfo("test1", "folder2");
TestOption inclusiveOption1 = new TestOption("include-filter", "value1");
test1.addOption(inclusiveOption1);
TestOption exclusiveOption1 = new TestOption("exclude-filter", "exclude-value1");
@@ -213,6 +229,10 @@
// Options from test2.
assertTrue(mergedOptions.contains(inclusiveOption2));
assertTrue(mergedOptions.contains(otherOption2));
+ // Both folders are in sources
+ assertEquals(2, test1.getSources().size());
+ assertTrue(test1.getSources().contains("folder1"));
+ assertTrue(test1.getSources().contains("folder2"));
}
/**
@@ -223,8 +243,8 @@
public void testMergeSuccess_MultiFilters_dropIncludeAnnotation() throws Exception {
// Check that the test without all options except include-annotation option should be the
// merge result.
- TestInfo test1 = new TestInfo("test1");
- TestInfo test2 = new TestInfo("test1");
+ TestInfo test1 = new TestInfo("test1", "folder1");
+ TestInfo test2 = new TestInfo("test1", "folder1");
TestOption option1 = new TestOption("include-filter", "value1");
test1.addOption(option1);
TestOption optionIncludeAnnotation =
@@ -246,8 +266,8 @@
public void testMergeSuccess_MultiFilters_keepExcludeAnnotation() throws Exception {
// Check that the test without all options including exclude-annotation option should be the
// merge result.
- TestInfo test1 = new TestInfo("test1");
- TestInfo test2 = new TestInfo("test1");
+ TestInfo test1 = new TestInfo("test1", "folder1");
+ TestInfo test2 = new TestInfo("test1", "folder1");
TestOption option1 = new TestOption("include-filter", "value1");
test1.addOption(option1);
TestOption optionExcludeAnnotation1 =