1 // Copyright 2016 Google Inc. All Rights Reserved. 2 package com.android.tradefed.testtype; 3 4 import static com.android.tradefed.testtype.JackCodeCoverageReportFormat.CSV; 5 import static com.android.tradefed.testtype.JackCodeCoverageReportFormat.HTML; 6 import static com.android.tradefed.testtype.JackCodeCoverageReportFormat.XML; 7 import static org.mockito.Matchers.any; 8 import static org.mockito.Matchers.anyLong; 9 import static org.mockito.Mockito.doReturn; 10 11 import com.google.common.collect.Iterables; 12 import com.google.common.collect.Sets; 13 import com.google.common.io.Files; 14 15 import com.android.tradefed.build.IBuildInfo; 16 import com.android.tradefed.util.CommandResult; 17 import com.android.tradefed.util.CommandStatus; 18 import com.android.tradefed.util.FileUtil; 19 20 import junit.framework.TestCase; 21 22 import org.mockito.ArgumentCaptor; 23 import org.mockito.Mockito; 24 25 import java.io.File; 26 import java.io.IOException; 27 import java.util.Arrays; 28 import java.util.Collection; 29 import java.util.List; 30 import java.util.Set; 31 32 /** Unit tests for {@link JackCodeCoverageTest}. */ 33 public class JackCodeCoverageTestTest extends TestCase { 34 35 private static final File COVERAGE_FILE1 = new File("/some/example/coverage.ec"); 36 private static final File COVERAGE_FILE2 = new File("/another/example/coverage.ec"); 37 private static final File COVERAGE_FILE3 = new File("/different/extension/example.exec"); 38 39 private static final File METADATA_FILE1 = new File("/some/example/coverage.em"); 40 private static final File METADATA_FILE2 = new File("/another/example/coverage.em"); 41 private static final File METADATA_FILE3 = new File("/different/extension/example.meta"); 42 43 private static final String EMMA_METADATA_RESOURCE_PATH = "/testdata/emma_meta.zip"; 44 private static final String EMMA_METADATA_ARTIFACT_NAME = "emma_meta.zip"; 45 private static final String FOO_METADATA = 46 "/out/target/common/obj/JAVA_LIBRARIES/foo_intermediates/coverage.em"; 47 private static final String BAR_METADATA = 48 "/out/target/common/obj/APPS/bar_intermediates/coverage.em"; 49 private static final String BAZ_METADATA = 50 "/out/target/common/obj/APPS/baz_intermediates/coverage.em"; 51 52 private static final CommandResult SUCCESS = new CommandResult(CommandStatus.SUCCESS); 53 private static final File FAKE_REPORT_TOOL = new File("/path/to/jack-jacoco-reporter.jar"); 54 55 public void testGetCoverageReporter() throws IOException { 56 // Try to get the coverage reporter 57 JackCodeCoverageTest coverageTest = new JackCodeCoverageTest(); 58 File coverageReporter = coverageTest.getCoverageReporter(); 59 60 // Verify that we were able to find the coverage reporter tool and that the tool exists 61 assertNotNull(coverageReporter); 62 assertTrue(coverageReporter.exists()); 63 } 64 65 public void testGetMetadataFiles() throws IOException { 66 // Prepare test data 67 File metadataZipFile = extractResource(EMMA_METADATA_RESOURCE_PATH); 68 69 // Set up mocks 70 IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class); 71 doReturn(metadataZipFile).when(mockBuild).getFile(EMMA_METADATA_ARTIFACT_NAME); 72 JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest()); 73 doReturn(mockBuild).when(coverageTest).getBuild(); 74 doReturn(EMMA_METADATA_ARTIFACT_NAME).when(coverageTest).getMetadataZipArtifact(); 75 76 // Get the metadata files 77 Set<File> metadataFiles = null; 78 try { 79 metadataFiles = coverageTest.getMetadataFiles(); 80 } finally { 81 // Cleanup 82 FileUtil.deleteFile(metadataZipFile); 83 coverageTest.cleanup(); 84 } 85 86 // Verify that we got all of the metdata files 87 assertNotNull(metadataFiles); 88 assertEquals(3, metadataFiles.size()); 89 Set<String> expectedFiles = Sets.newHashSet(FOO_METADATA, BAR_METADATA, BAZ_METADATA); 90 for (File metadata : metadataFiles) { 91 for (String expected : expectedFiles) { 92 if (metadata.getAbsolutePath().endsWith(expected)) { 93 expectedFiles.remove(expected); 94 break; 95 } 96 } 97 } 98 assertTrue(expectedFiles.isEmpty()); 99 } 100 101 public void testGetMetadataFiles_withFilter() throws IOException { 102 // Prepare test data 103 File metadataZipFile = extractResource(EMMA_METADATA_RESOURCE_PATH); 104 105 // Set up mocks 106 IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class); 107 doReturn(metadataZipFile).when(mockBuild).getFile(EMMA_METADATA_ARTIFACT_NAME); 108 JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest()); 109 doReturn(mockBuild).when(coverageTest).getBuild(); 110 doReturn(EMMA_METADATA_ARTIFACT_NAME).when(coverageTest).getMetadataZipArtifact(); 111 doReturn(Arrays.asList("glob:**/foo_intermediates/coverage.em")).when(coverageTest) 112 .getMetadataFilesFilter(); 113 114 // Get the metadata files 115 Set<File> metadataFiles = null; 116 try { 117 metadataFiles = coverageTest.getMetadataFiles(); 118 } finally { 119 // Cleanup 120 FileUtil.deleteFile(metadataZipFile); 121 coverageTest.cleanup(); 122 } 123 124 // Verify that only the framework metadata file was returned 125 assertNotNull(metadataFiles); 126 assertEquals(1, metadataFiles.size()); 127 File metadataFile = Iterables.getOnlyElement(metadataFiles); 128 assertTrue(metadataFile.getAbsolutePath().endsWith(FOO_METADATA)); 129 } 130 131 private File extractResource(String resourcePath) throws IOException { 132 // Write the resource to a file and return it 133 File dest = FileUtil.createTempFile(Files.getNameWithoutExtension(resourcePath), 134 "." + Files.getFileExtension(resourcePath)); 135 FileUtil.writeToFile(getClass().getResourceAsStream(resourcePath), dest); 136 return dest; 137 } 138 139 private void verifyCommandLine(List<String> commandLine, File reportTool, 140 Collection<File> coverageFiles, Collection<File> metadataFiles, String format) { 141 142 // Verify positional arguments 143 assertEquals("java", commandLine.get(0)); 144 assertEquals("-jar", commandLine.get(1)); 145 assertEquals(reportTool.getAbsolutePath(), commandLine.get(2)); 146 147 // Verify the rest of the command line arguments 148 assertTrue(commandLine.contains("--report-dir")); 149 for (int i = 3; i < commandLine.size() - 1; i++) { 150 switch (commandLine.get(i)) { 151 case "--coverage-file": 152 File coverageFile = new File(commandLine.get(++i)); 153 assertTrue(String.format("Unexpected coverage file: %s", coverageFile), 154 coverageFiles.remove(coverageFile)); 155 break; 156 case "--metadata-file": 157 File metadataFile = new File(commandLine.get(++i)); 158 assertTrue(String.format("Unexpected metadata file: %s", metadataFile), 159 metadataFiles.remove(metadataFile)); 160 break; 161 case "--report-dir": 162 i++; 163 break; 164 case "--report-type": 165 assertEquals(format, commandLine.get(++i)); 166 break; 167 } 168 } 169 assertTrue(coverageFiles.isEmpty()); 170 assertTrue(metadataFiles.isEmpty()); 171 } 172 173 public void testGenerateCoverageReport_html() throws IOException { 174 // Prepare some test data 175 Set<File> coverageFiles = Sets.newHashSet(COVERAGE_FILE1, COVERAGE_FILE2, COVERAGE_FILE3); 176 Set<File> metadataFiles = Sets.newHashSet(METADATA_FILE1, METADATA_FILE2, METADATA_FILE3); 177 178 // Set up mocks 179 JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest()); 180 IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class); 181 doReturn(mockBuild).when(coverageTest).getBuild(); 182 doReturn(metadataFiles).when(coverageTest).getMetadataFiles(); 183 doReturn(FAKE_REPORT_TOOL).when(coverageTest).getCoverageReporter(); 184 doReturn(SUCCESS).when(coverageTest).runTimedCmd(anyLong(), any(String[].class)); 185 186 File report = null; 187 try { 188 // Generate a coverage report 189 report = coverageTest.generateCoverageReport(coverageFiles, HTML); 190 191 // Verify that the command was called with the right arguments 192 ArgumentCaptor<String[]> cmdLineCaptor = ArgumentCaptor.forClass(String[].class); 193 Mockito.verify(coverageTest).runTimedCmd(anyLong(), cmdLineCaptor.capture()); 194 verifyCommandLine(Arrays.asList(cmdLineCaptor.getValue()), FAKE_REPORT_TOOL, 195 coverageFiles, metadataFiles, HTML.getReporterArg()); 196 } finally { 197 FileUtil.recursiveDelete(report); 198 coverageTest.cleanup(); 199 } 200 } 201 202 public void testGenerateCoverageReport_csv() throws IOException { 203 // Prepare some test data 204 Set<File> coverageFiles = Sets.newHashSet(COVERAGE_FILE1, COVERAGE_FILE2, COVERAGE_FILE3); 205 Set<File> metadataFiles = Sets.newHashSet(METADATA_FILE1, METADATA_FILE2, METADATA_FILE3); 206 207 // Set up mocks 208 JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest()); 209 IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class); 210 doReturn(mockBuild).when(coverageTest).getBuild(); 211 doReturn(metadataFiles).when(coverageTest).getMetadataFiles(); 212 doReturn(FAKE_REPORT_TOOL).when(coverageTest).getCoverageReporter(); 213 doReturn(SUCCESS).when(coverageTest).runTimedCmd(anyLong(), any(String[].class)); 214 doReturn(new File("/copy/of/report.csv")).when(coverageTest).copyFile(any(File.class)); 215 216 // Generate a coverage report 217 coverageTest.generateCoverageReport(coverageFiles, CSV); 218 219 // Verify that the command was called with the right arguments 220 ArgumentCaptor<String[]> cmdLineCaptor = ArgumentCaptor.forClass(String[].class); 221 Mockito.verify(coverageTest).runTimedCmd(anyLong(), cmdLineCaptor.capture()); 222 verifyCommandLine(Arrays.asList(cmdLineCaptor.getValue()), FAKE_REPORT_TOOL, 223 coverageFiles, metadataFiles, CSV.getReporterArg()); 224 } 225 226 public void testGenerateCoverageReport_xml() throws IOException { 227 // Prepare some test data 228 Set<File> coverageFiles = Sets.newHashSet(COVERAGE_FILE1, COVERAGE_FILE2, COVERAGE_FILE3); 229 Set<File> metadataFiles = Sets.newHashSet(METADATA_FILE1, METADATA_FILE2, METADATA_FILE3); 230 231 // Set up mocks 232 JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest()); 233 IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class); 234 doReturn(mockBuild).when(coverageTest).getBuild(); 235 doReturn(metadataFiles).when(coverageTest).getMetadataFiles(); 236 doReturn(FAKE_REPORT_TOOL).when(coverageTest).getCoverageReporter(); 237 doReturn(SUCCESS).when(coverageTest).runTimedCmd(anyLong(), any(String[].class)); 238 doReturn(new File("/copy/of/report.xml")).when(coverageTest).copyFile(any(File.class)); 239 240 // Generate a coverage report 241 coverageTest.generateCoverageReport(coverageFiles, XML); 242 243 // Verify that the command was called with the right arguments 244 ArgumentCaptor<String[]> cmdLineCaptor = ArgumentCaptor.forClass(String[].class); 245 Mockito.verify(coverageTest).runTimedCmd(anyLong(), cmdLineCaptor.capture()); 246 verifyCommandLine(Arrays.asList(cmdLineCaptor.getValue()), FAKE_REPORT_TOOL, 247 coverageFiles, metadataFiles, XML.getReporterArg()); 248 } 249 250 public void testGenerateCoverageReport_error() throws IOException { 251 // Prepare some test data 252 Set<File> coverageFiles = Sets.newHashSet(COVERAGE_FILE1, COVERAGE_FILE2, COVERAGE_FILE3); 253 Set<File> metadataFiles = Sets.newHashSet(METADATA_FILE1, METADATA_FILE2, METADATA_FILE3); 254 String stderr = "some error message"; 255 256 // Set up mocks 257 CommandResult failed = new CommandResult(CommandStatus.FAILED); 258 failed.setStderr(stderr); 259 260 JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest()); 261 IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class); 262 doReturn(mockBuild).when(coverageTest).getBuild(); 263 doReturn(metadataFiles).when(coverageTest).getMetadataFiles(); 264 doReturn(FAKE_REPORT_TOOL).when(coverageTest).getCoverageReporter(); 265 doReturn(failed).when(coverageTest).runTimedCmd(anyLong(), any(String[].class)); 266 267 // Generate a coverage report 268 try { 269 coverageTest.generateCoverageReport(coverageFiles, HTML); 270 fail("IOException not thrown"); 271 } catch (IOException e) { 272 assertTrue(e.getMessage().contains(stderr)); 273 } 274 } 275 } 276