blob: d9472f3e3affc9f7304fe8f7ef3e4512a04a4dac [file] [log] [blame]
/*
* Copyright 2015 The Kythe Authors. All rights reserved.
*
* 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.google.devtools.kythe.extractors.java;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.devtools.kythe.extractors.shared.CompilationDescription;
import com.google.devtools.kythe.extractors.shared.ExtractorUtils;
import com.google.devtools.kythe.proto.Analysis.CompilationUnit;
import com.google.devtools.kythe.proto.Analysis.CompilationUnit.FileInput;
import com.google.devtools.kythe.proto.Analysis.FileInfo;
import com.google.devtools.kythe.proto.Java.JavaDetails;
import com.google.protobuf.Any;
import com.google.protobuf.InvalidProtocolBufferException;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import junit.framework.TestCase;
/** Tests for {@link JavaCompilationExtractor}. */
// TODO(schroederc): replace asserts with Truth#assertThat
public class JavaExtractorTest extends TestCase {
private static final String TEST_DATA_DIR =
"kythe/javatests/com/google/devtools/kythe/extractors/java/testdata";
private static final String CORPUS = "testCorpus";
private static final String TARGET1 = "target1";
private static final ImmutableList<String> EMPTY = ImmutableList.of();
private static final FileInfo GENERATED_ANNOTATION_CLASS =
FileInfo.newBuilder()
.setPath(join("!CLASS_PATH_JAR!", "javax/annotation/Generated.class"))
// This digest depends on the external javax_annotation_jsr250_api dependency. If it is
// updated, this will also need to change.
.setDigest("e5ee743f5c6df4923a934cba33c73d3d73e19d277c8ddec5c4e7ac59788fc674")
.build();
// Due to the nature of the jsr250 dependency, this class is incidentally
// included in some compilation environments but not others.
// In order to distinguish these dependencies from "true" dependencies, use this name.
private static final FileInfo JDK_ANNOTATION_CLASS = GENERATED_ANNOTATION_CLASS;
private static final String JDK_ANNOTATION_PATH = "!CLASS_PATH_JAR!";
/** Tests the basic case of indexing a java compilation with two sources. */
public void testJavaExtractorSimple() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
List<String> sources =
Lists.newArrayList(join(TEST_DATA_DIR, "/pkg/A.java"), join(TEST_DATA_DIR, "/pkg/B.java"));
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
sources,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
// With the expected sources as explicit sources.
assertThat(unit.getSourceFileCount()).isEqualTo(2);
assertThat(unit.getSourceFileList()).containsExactly(sources.get(0), sources.get(1)).inOrder();
// With the expected sources as required inputs.
assertThat(getInfos(unit.getRequiredInputList()))
.containsExactlyElementsIn(getExpectedInfos(sources, JDK_ANNOTATION_CLASS));
// And the correct sourcepath set to replay the compilation.
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).containsExactly(TEST_DATA_DIR);
assertThat(details.getClasspathList()).containsExactly(JDK_ANNOTATION_PATH);
}
/** Tests that metadata is included when a file specifies it. */
public void testJavaExtractorMetadata() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
List<String> sources = Lists.newArrayList(join(TEST_DATA_DIR, "/pkg/M.java"));
List<String> dependencies =
Lists.newArrayList(
join(TEST_DATA_DIR, "/pkg/M.java"), join(TEST_DATA_DIR, "/pkg/M.java.meta"));
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
sources,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
// With the expected sources as explicit sources.
assertThat(unit.getSourceFileCount()).isEqualTo(1);
assertThat(unit.getSourceFileList()).containsExactly(sources.get(0));
// With the expected dependencies as required inputs.
assertThat(getInfos(unit.getRequiredInputList()))
.containsExactlyElementsIn(getExpectedInfos(dependencies, GENERATED_ANNOTATION_CLASS));
// And the correct sourcepath set to replay the compilation.
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).containsExactly(TEST_DATA_DIR);
assertThat(details.getClasspathList()).containsExactly("!CLASS_PATH_JAR!");
}
/** Tests indexing within a symlink root. */
public void testJavaExtractorSymlinkRoot() throws Exception {
Path symlinkRoot = Paths.get(System.getenv("TEST_TMPDIR"), "symlinkRoot");
symlinkRoot.toFile().delete();
Files.createSymbolicLink(symlinkRoot, Paths.get(".").toAbsolutePath());
symlinkRoot.toFile().deleteOnExit();
JavaCompilationUnitExtractor java =
new JavaCompilationUnitExtractor(CORPUS, symlinkRoot.toString());
List<String> sources =
Lists.newArrayList(join(TEST_DATA_DIR, "/pkg/A.java"), join(TEST_DATA_DIR, "/pkg/B.java"));
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
sources,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
// With the expected sources as explicit sources.
assertThat(unit.getSourceFileList()).containsExactlyElementsIn(sources).inOrder();
// With the expected sources as required inputs.
assertThat(getInfos(unit.getRequiredInputList()))
.containsExactlyElementsIn(getExpectedInfos(sources, JDK_ANNOTATION_CLASS));
// And the correct sourcepath set to replay the compilation.
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).containsExactly(TEST_DATA_DIR);
assertThat(details.getClasspathList()).containsExactly(JDK_ANNOTATION_PATH);
}
/**
* Tests the basic case of indexing a java compilation where the sources live in different folders
* eventhough they're in the same package.
*/
public void testJavaExtractorTwoSourceDirs() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
// Pick two sources in the same package that live in different directories.
List<String> sources =
Lists.newArrayList(
join(TEST_DATA_DIR, "one/pkg/A.java"), join(TEST_DATA_DIR, "two/pkg/B.java"));
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
sources,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
// With the expected sources as explicit sources.
assertThat(unit.getSourceFileCount()).isEqualTo(2);
assertThat(unit.getSourceFileList()).containsExactly(sources.get(0), sources.get(1)).inOrder();
assertThat(getInfos(unit.getRequiredInputList()))
.containsExactlyElementsIn(getExpectedInfos(sources, JDK_ANNOTATION_CLASS));
// And the correct sourcepath set to replay the compilation for both sources.
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList())
.containsExactly(join(TEST_DATA_DIR, "one"), join(TEST_DATA_DIR, "two"));
assertThat(details.getClasspathList()).containsExactly(JDK_ANNOTATION_PATH);
}
/**
* Tests java compilation with classfiles in the classpath. Test ensures that only used classfiles
* are stored.
*/
public void testJavaExtractorClassFiles() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
// Index the specified sources
List<String> sources = Lists.newArrayList(join(TEST_DATA_DIR, "child/derived/B.java"));
String parentCp = join(TEST_DATA_DIR, "parent") + "/";
List<String> classpath = Lists.newArrayList(parentCp);
String classFile = join(parentCp, "base/A.class");
// Index the specified sources and classes from the classpath
CompilationDescription description =
java.extract(
TARGET1,
sources,
classpath,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
assertThat(unit.getSourceFileCount()).isEqualTo(1);
assertThat(unit.getSourceFileList()).containsExactly(sources.get(0)).inOrder();
// Ensure the right class files are picked up from the classpath.
assertThat(getInfos(unit.getRequiredInputList()))
.containsExactlyElementsIn(getExpectedInfos(Arrays.asList(sources.get(0), classFile)));
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).containsExactly(join(TEST_DATA_DIR, "child"));
// Ensure the classpath is set for replay.
assertThat(details.getClasspathList()).containsExactly(parentCp);
}
/**
* Tests java compilation with classfiles in a jarfile on the classpath. Ensures that only used
* classfiles are stored.
*/
public void testJavaExtractorJar() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
// Index the specified sources.
List<String> sources = Lists.newArrayList(join(TEST_DATA_DIR, "child/derived/B.java"));
String parentCp = join(TEST_DATA_DIR, "jarred.jar");
List<String> classpath = Lists.newArrayList(parentCp);
// Index the specified sources and classes from inside jar on the classpath.
CompilationDescription description =
java.extract(
TARGET1,
sources,
classpath,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
assertThat(unit.getSourceFileList()).containsExactlyElementsIn(sources).inOrder();
// The classpath is adjusted to start wit !CLASS_PATH_JAR!
String classFile = join("!CLASS_PATH_JAR!", "base/A.class");
// Ensure the right class files are picked up from the classpath from within the jar.
assertThat(getInfos(unit.getRequiredInputList()))
.containsExactly(
makeFileInfo(sources.get(0)),
makeFileInfo(classFile, join(TEST_DATA_DIR, "parent/base/A.class")));
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).hasSize(1);
assertThat(details.getSourcepathList().get(0)).isEqualTo(join(TEST_DATA_DIR, "child"));
// Ensure the magic !CLASS_PATH_JAR! classpath is added.
assertThat(details.getClasspathList()).containsExactly("!CLASS_PATH_JAR!");
}
/**
* Tests case where compile errors exist in the sources under compilation. Compilation should
* still be created.
*/
public void testJavaExtractorCompileError() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
List<String> sources = Lists.newArrayList(join(TEST_DATA_DIR, "/error/Crash.java"));
// Index the specified sources, reporting compilation failure.
CompilationDescription description =
java.extract(
TARGET1,
sources,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
assertThat(unit.getRequiredInputCount()).isEqualTo(1);
assertThat(unit.getRequiredInput(0).getInfo().getPath()).isEqualTo(sources.get(0));
assertThat(unit.getRequiredInput(0).getInfo().getDigest())
.isEqualTo(ExtractorUtils.digestForPath(sources.get(0)));
assertThat(unit.getSourceFileCount()).isEqualTo(1);
assertThat(unit.getSourceFileList()).containsExactly(sources.get(0)).inOrder();
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).hasSize(1);
assertThat(details.getSourcepathList().get(0)).isEqualTo(TEST_DATA_DIR);
assertThat(details.getClasspathList()).isEmpty();
}
/** Tests that dependent files are ordered correctly. */
public void testJavaExtractorOrderedDependencies() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
List<String> sources =
Lists.newArrayList(
join(TEST_DATA_DIR, "/deps/A.java"),
join(TEST_DATA_DIR, "/deps/C.java"),
join(TEST_DATA_DIR, "/deps/B.java"));
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
sources,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
assertThat(unit.getSourceFileCount()).isEqualTo(3);
assertThat(unit.getSourceFileList())
.containsExactly(sources.get(0), sources.get(1), sources.get(2))
.inOrder();
// With the expected sources as required inputs.
assertThat(getInfos(unit.getRequiredInputList()))
.containsExactly(
JDK_ANNOTATION_CLASS,
makeFileInfo(sources.get(0)),
makeFileInfo(sources.get(2)),
makeFileInfo(sources.get(1)))
.inOrder();
}
/**
* Tests the case where one of the sources doesn't follow the java pattern of naming the path to
* the source file after the package name.
*/
public void testJavaExtractorNonConformingPath() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
List<String> sources =
Lists.newArrayList(
join(TEST_DATA_DIR, "/path/sub/A.java"), join(TEST_DATA_DIR, "/path/B.java"));
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
sources,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
assertThat(unit.getSourceFileCount()).isEqualTo(2);
assertThat(unit.getSourceFileList()).containsExactly(sources.get(0), sources.get(1)).inOrder();
// With the expected sources as required inputs.
assertThat(getInfos(unit.getRequiredInputList()))
.containsExactlyElementsIn(getExpectedInfos(sources, JDK_ANNOTATION_CLASS));
// And the correct sourcepath set to replay the compilation.
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).hasSize(1);
assertThat(details.getSourcepathList().get(0)).isEqualTo(TEST_DATA_DIR);
assertThat(details.getClasspathList()).containsExactly(JDK_ANNOTATION_PATH);
}
/**
* Tests the case where one of the sources defines a package only type that is not conforming to
* the classname matching the filename.
*/
public void testJavaExtractorAdditionalTypeDefinitions() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
List<String> sources =
Lists.newArrayList(
join(TEST_DATA_DIR, "/hitchhikers/A.java"), join(TEST_DATA_DIR, "/hitchhikers/B.java"));
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
sources,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
assertThat(unit.getSourceFileCount()).isEqualTo(2);
assertThat(unit.getSourceFileList()).containsExactly(sources.get(0), sources.get(1)).inOrder();
// With the expected sources as required inputs.
assertThat(getInfos(unit.getRequiredInputList()))
.containsExactlyElementsIn(getExpectedInfos(sources, JDK_ANNOTATION_CLASS));
// And the correct sourcepath set to replay the compilation.
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).containsExactly(TEST_DATA_DIR);
assertThat(details.getClasspathList()).containsExactly(JDK_ANNOTATION_PATH);
}
/**
* Tests that unsupported flags do not crash the extractor and source/header destination options
* are not present in the resulting {@link CompilationUnit}.
*/
public void testJavaExtractorArguments() throws Exception {
String testDir = System.getenv("TEST_TMPDIR");
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS, testDir);
File processorFile =
Paths.get(
"kythe/javatests/com/google/devtools/kythe/extractors/java/SillyProcessor_deploy.jar")
.toFile();
if (!processorFile.exists()) {
throw new AssertionError("SillyProcessor_deploy.jar does not exist");
}
List<String> origSources = testFiles("processor/Silly.java", "processor/SillyUser.java");
List<Path> outputDirs =
Arrays.asList(
Paths.get(testDir, "output-gensrc.jar.files"),
Paths.get(testDir, "output-genhdr.jar.files"),
Paths.get(testDir, "classes"));
List<String> processorpath = Arrays.asList(processorFile.getPath());
List<String> processors = Arrays.asList("processor.SillyProcessor");
List<String> options =
Arrays.asList(
"-Xdoclint:-Xdoclint:all/private", // ensure this unsupported flag is saved
"-s",
outputDirs.get(0).toString(),
"-h",
outputDirs.get(1).toString(),
"-g:lines", // ensure this conjoined arg is handled correctly
"-d",
outputDirs.get(2).toString());
for (Path dir : outputDirs) {
dir.toFile().mkdir();
}
// Copy sources from runfiles into test dir
List<String> testSources = new ArrayList<>();
for (String source : origSources) {
Path destFile = Paths.get(testDir).resolve(source);
Files.createDirectories(destFile.getParent());
Files.copy(Paths.get(source), destFile, REPLACE_EXISTING);
testSources.add(destFile.toString());
}
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
testSources,
EMPTY,
EMPTY,
EMPTY,
processorpath,
processors,
Optional.absent(),
options,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
// Check that the -s, and -h flags have been removed from the compilation's arguments, but -d
// preserved (it is required by modular builds).
assertThat(unit.getArgumentList())
.containsExactly("-Xdoclint:-Xdoclint:all/private", "-g:lines")
.inOrder();
}
/** Tests that targets that contain annotation processors are indexed correctly. */
public void testJavaExtractorAnnotationProcessing() throws Exception {
String testDir = System.getenv("TEST_TMPDIR");
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS, testDir);
File processorFile =
Paths.get(
"kythe/javatests/com/google/devtools/kythe/extractors/java/SillyProcessor_deploy.jar")
.toFile();
if (!processorFile.exists()) {
throw new AssertionError("SillyProcessor_deploy.jar does not exist");
}
List<String> origSources = testFiles("processor/Silly.java", "processor/SillyUser.java");
List<String> processorpath = Arrays.asList(processorFile.getPath());
List<String> processors = Arrays.asList("processor.SillyProcessor");
Path genSrcDir = Paths.get(testDir, "output-gensrc.jar.files");
List<String> options = Arrays.asList("-s", genSrcDir.toString());
genSrcDir.toFile().mkdir();
// Copy sources from runfiles into test dir
List<String> testSources = new ArrayList<>();
for (String source : origSources) {
Path destFile = Paths.get(testDir).resolve(source);
Files.createDirectories(destFile.getParent());
Files.copy(Paths.get(source), destFile, REPLACE_EXISTING);
testSources.add(destFile.toString());
}
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
testSources,
EMPTY,
EMPTY,
EMPTY,
processorpath,
processors,
Optional.of(genSrcDir),
options,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
String sillyGenerated = "output-gensrc.jar.files/processor/SillyGenerated.java";
assertThat(unit.getSourceFileList())
.containsExactly(origSources.get(0), origSources.get(1), sillyGenerated)
.inOrder();
// With the expected sources as required inputs.
assertThat(getInfos(unit.getRequiredInputList()))
.containsExactly(
GENERATED_ANNOTATION_CLASS,
makeFileInfo(origSources.get(0)),
makeFileInfo(origSources.get(1)),
makeFileInfo(sillyGenerated, Paths.get(testDir, sillyGenerated).toString()));
// And the correct sourcepath set to replay the compilation.
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).hasSize(2);
assertThat(details.getSourcepathList())
.containsExactly(TEST_DATA_DIR, "output-gensrc.jar.files");
assertThat(details.getClasspathList()).containsExactly("!CLASS_PATH_JAR!");
}
/** Tests that the extractor doesn't fall over when it's provided with no sources. */
public void testNoSources() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
List<String> sources = Collections.emptyList();
List<String> bootclasspath = testFiles("empty/fake-rt.jar");
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
sources,
EMPTY,
bootclasspath,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
assertThat(unit.getSourceFileCount()).isEqualTo(0);
assertThat(unit.getRequiredInputCount()).isEqualTo(0);
// And the correct classpath set to replay the compilation.
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).isEmpty();
assertThat(details.getClasspathList()).isEmpty();
}
/**
* Tests the case where one of the sources defines a package only type that is not conforming to
* the classname matching the filename.
*/
public void testEmptyCompilationUnit() throws Exception {
JavaCompilationUnitExtractor java = new JavaCompilationUnitExtractor(CORPUS);
List<String> sources = testFiles("empty/Empty.java");
List<String> bootclasspath = testFiles("empty/fake-rt.jar");
// Index the specified sources
CompilationDescription description =
java.extract(
TARGET1,
sources,
EMPTY,
bootclasspath,
EMPTY,
EMPTY,
EMPTY,
Optional.absent(),
EMPTY,
"output");
CompilationUnit unit = description.getCompilationUnit();
assertThat(unit).isNotNull();
assertThat(unit.getVName().getSignature()).isEqualTo(TARGET1);
assertThat(unit.getSourceFileCount()).isEqualTo(1);
assertThat(unit.getSourceFileList()).containsExactly(sources.get(0)).inOrder();
assertThat(unit.getRequiredInputCount()).isEqualTo(3);
List<String> requiredPaths = new ArrayList<>();
for (FileInput input : unit.getRequiredInputList()) {
requiredPaths.add(input.getInfo().getPath());
}
assertThat(requiredPaths)
.containsExactly(
sources.get(0),
"!PLATFORM_CLASS_PATH_JAR!/java/lang/Fake.class",
"!CLASS_PATH_JAR!/javax/annotation/Generated.class");
assertThat(unit.getArgumentList())
.containsNoneOf("-bootclasspath", "-sourcepath", "-cp", "-classpath");
// And the correct source/class locations set to replay the compilation.
JavaDetails details = getJavaDetails(unit);
assertThat(details.getSourcepathList()).isEmpty();
assertThat(details.getClasspathList()).containsExactly("!CLASS_PATH_JAR!");
assertThat(details.getBootclasspathList()).containsExactly("!PLATFORM_CLASS_PATH_JAR!");
}
private List<String> testFiles(String... files) {
List<String> res = new ArrayList<>();
for (String file : files) {
res.add(join(TEST_DATA_DIR, file));
}
return res;
}
private static List<FileInfo> getInfos(List<FileInput> files) {
return Lists.transform(files, FileInput::getInfo);
}
private static List<FileInfo> getExpectedInfos(List<String> files, FileInfo... extra) {
return Stream.concat(files.stream().map(JavaExtractorTest::makeFileInfo), Stream.of(extra))
.collect(Collectors.toList());
}
private static FileInfo makeFileInfo(String path) {
try {
return FileInfo.newBuilder()
.setPath(path)
.setDigest(ExtractorUtils.digestForPath(path))
.build();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static FileInfo makeFileInfo(String path, String localPath) {
try {
return FileInfo.newBuilder()
.setPath(path)
.setDigest(ExtractorUtils.digestForPath(localPath))
.build();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private JavaDetails getJavaDetails(CompilationUnit unit) throws InvalidProtocolBufferException {
for (Any any : unit.getDetailsList()) {
if (any.getTypeUrl().equals(JavaCompilationUnitExtractor.JAVA_DETAILS_URL)) {
return JavaDetails.parseFrom(any.getValue());
}
}
return null;
}
private static String join(String base, String... paths) {
return Paths.get(base, paths).toString();
}
}