/*
* Copyright 2012-present Facebook, Inc.
*
* 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.facebook.buck.jvm.java;
import static org.hamcrest.Matchers.matchesPattern;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import com.facebook.buck.io.MorePathsForTests;
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.StepExecutionResult;
import com.facebook.buck.step.TestExecutionContext;
import com.facebook.buck.test.CoverageReportFormat;
import com.facebook.buck.testutil.MoreAsserts;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class GenerateCodeCoverageReportStepTest {
public static final String OUTPUT_DIRECTORY = Paths.get("buck-out/gen/output").toString();
public static final Set<String> SOURCE_DIRECTORIES =
ImmutableSet.of(
MorePathsForTests.rootRelativePath("/absolute/path/to/parentDirectory1/src").toString(),
MorePathsForTests.rootRelativePath("/absolute/path/to/parentDirectory2/src").toString());
private GenerateCodeCoverageReportStep step;
private ExecutionContext context;
private ProjectFilesystem filesystem;
private Set<Path> jarFiles;
@Rule public TemporaryFolder tmp = new TemporaryFolder();
@Before
public void setUp() throws Exception {
filesystem = new ProjectFilesystem(Paths.get(".").toAbsolutePath());
jarFiles = new LinkedHashSet<>();
File jarFile = new File(tmp.getRoot(), "foo.jar");
File jar2File = new File(tmp.getRoot(), "foo2.jar");
try (InputStream jarIn =
getClass().getResourceAsStream("testdata/code_coverage_test/foo.jar")) {
Files.copy(jarIn, jarFile.toPath());
}
try (InputStream jarIn =
getClass().getResourceAsStream("testdata/code_coverage_test/foo.jar")) {
Files.copy(jarIn, jar2File.toPath());
}
jarFiles.add(jarFile.toPath());
jarFiles.add(jar2File.toPath());
assertTrue(jarFile.exists());
step =
new GenerateCodeCoverageReportStep(
new ExternalJavaRuntimeLauncher("/baz/qux/java"),
filesystem,
SOURCE_DIRECTORIES,
jarFiles,
Paths.get(OUTPUT_DIRECTORY),
CoverageReportFormat.HTML,
"TitleFoo",
Optional.empty(),
Optional.empty());
context = TestExecutionContext.newInstance();
}
@Test
public void testGetShellCommandInternal() {
ImmutableList.Builder<String> shellCommandBuilder = ImmutableList.builder();
System.setProperty(
"buck.report_generator_jar",
MorePathsForTests.rootRelativePath("/absolute/path/to/report/generator/jar").toString());
shellCommandBuilder.add(
"/baz/qux/java",
"-jar",
MorePathsForTests.rootRelativePath("/absolute/path/to/report/generator/jar").toString(),
absolutifyPath(Paths.get(OUTPUT_DIRECTORY + "/parameters.properties")));
List<String> expectedShellCommand = shellCommandBuilder.build();
MoreAsserts.assertListEquals(expectedShellCommand, step.getShellCommand(context));
}
@Test
public void testJarFileIsExtracted() throws Throwable {
final File[] extractedDir = new File[2];
step =
new GenerateCodeCoverageReportStep(
new ExternalJavaRuntimeLauncher("/baz/qux/java"),
filesystem,
SOURCE_DIRECTORIES,
jarFiles,
Paths.get(OUTPUT_DIRECTORY),
CoverageReportFormat.HTML,
"TitleFoo",
Optional.empty(),
Optional.empty()) {
@Override
StepExecutionResult executeInternal(ExecutionContext context, Set<Path> jarFiles) {
for (int i = 0; i < 2; i++) {
extractedDir[i] = new ArrayList<>(jarFiles).get(i).toFile();
assertTrue(extractedDir[i].isDirectory());
assertTrue(
new File(extractedDir[i], "com/facebook/testing/coverage/Foo.class").exists());
}
return null;
}
};
step.execute(TestExecutionContext.newInstance());
assertFalse(extractedDir[0].exists());
assertFalse(extractedDir[1].exists());
}
@Test
public void testClassesDirIsUntouched() throws Throwable {
final File classesDir = tmp.newFolder("classesDir");
jarFiles.clear();
jarFiles.add(classesDir.toPath());
step =
new GenerateCodeCoverageReportStep(
new ExternalJavaRuntimeLauncher("/baz/qux/java"),
filesystem,
SOURCE_DIRECTORIES,
jarFiles,
Paths.get(OUTPUT_DIRECTORY),
CoverageReportFormat.HTML,
"TitleFoo",
Optional.empty(),
Optional.empty()) {
@Override
StepExecutionResult executeInternal(ExecutionContext context, Set<Path> jarFiles) {
assertEquals(1, jarFiles.size());
assertEquals(classesDir.toPath(), jarFiles.iterator().next());
return null;
}
};
step.execute(TestExecutionContext.newInstance());
assertTrue(classesDir.exists());
}
@Test
public void testSaveParametersToPropertyFile() throws IOException {
byte[] actualOutput;
Set<Path> directories = ImmutableSet.of(Paths.get("foo/bar"), Paths.get("foo/bar2"));
try (ByteArrayOutputStream actualOutputStream = new ByteArrayOutputStream()) {
step.saveParametersToPropertyStream(filesystem, directories, actualOutputStream);
actualOutput = actualOutputStream.toByteArray();
}
Properties actual = new Properties();
try (ByteArrayInputStream actualInputStream = new ByteArrayInputStream(actualOutput)) {
try (InputStreamReader reader = new InputStreamReader(actualInputStream)) {
actual.load(reader);
}
}
assertEquals(
absolutifyPath(Paths.get(OUTPUT_DIRECTORY)), actual.getProperty("jacoco.output.dir"));
assertEquals("jacoco.exec", actual.getProperty("jacoco.exec.data.file"));
assertEquals("html", actual.getProperty("jacoco.format"));
assertEquals("TitleFoo", actual.getProperty("jacoco.title"));
assertEquals(
String.format(
"%s:%s", absolutifyPath(Paths.get("foo/bar")), absolutifyPath(Paths.get("foo/bar2"))),
actual.getProperty("classes.dir"));
assertEquals(
String.format(
"%s:%s", absolutifyPath(Paths.get("foo/bar")), absolutifyPath(Paths.get("foo/bar2"))),
actual.getProperty("classes.dir"));
assertThat(actual.getProperty("classes.jars"), matchesPattern("^.*foo.jar:.*foo2.jar$"));
assertEquals(
String.format(
"%s:%s",
MorePathsForTests.rootRelativePath("/absolute/path/to/parentDirectory1/src").toString(),
MorePathsForTests.rootRelativePath("/absolute/path/to/parentDirectory2/src")
.toString()),
actual.getProperty("src.dir"));
}
private static String absolutifyPath(Path relativePath) {
return String.format(
"%s%c%s",
new File(".").getAbsoluteFile().toPath().normalize(), File.separatorChar, relativePath);
}
}