use of com.facebook.buck.rules.RuleKey in project buck by facebook.
the class DefaultJavaLibraryTest method testRuleKeyIsOrderInsensitiveForSourcesAndResources.
@Test
public void testRuleKeyIsOrderInsensitiveForSourcesAndResources() throws Exception {
// Note that these filenames were deliberately chosen to have identical hashes to maximize
// the chance of order-sensitivity when being inserted into a HashMap. Just using
// {foo,bar}.{java,txt} resulted in a passing test even for the old broken code.
ProjectFilesystem filesystem = new AllExistingProjectFilesystem() {
@Override
public boolean isDirectory(Path path, LinkOption... linkOptionsk) {
return false;
}
};
BuildRuleResolver resolver1 = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathRuleFinder ruleFinder1 = new SourcePathRuleFinder(resolver1);
SourcePathResolver pathResolver1 = new SourcePathResolver(ruleFinder1);
DefaultJavaLibrary rule1 = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//lib:lib")).addSrc(Paths.get("agifhbkjdec.java")).addSrc(Paths.get("bdeafhkgcji.java")).addSrc(Paths.get("bdehgaifjkc.java")).addSrc(Paths.get("cfiabkjehgd.java")).addResource(new FakeSourcePath("becgkaifhjd.txt")).addResource(new FakeSourcePath("bkhajdifcge.txt")).addResource(new FakeSourcePath("cabfghjekid.txt")).addResource(new FakeSourcePath("chkdbafijge.txt")).build(resolver1, filesystem);
BuildRuleResolver resolver2 = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathRuleFinder ruleFinder2 = new SourcePathRuleFinder(resolver2);
SourcePathResolver pathResolver2 = new SourcePathResolver(ruleFinder2);
DefaultJavaLibrary rule2 = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//lib:lib")).addSrc(Paths.get("cfiabkjehgd.java")).addSrc(Paths.get("bdehgaifjkc.java")).addSrc(Paths.get("bdeafhkgcji.java")).addSrc(Paths.get("agifhbkjdec.java")).addResource(new FakeSourcePath("chkdbafijge.txt")).addResource(new FakeSourcePath("cabfghjekid.txt")).addResource(new FakeSourcePath("bkhajdifcge.txt")).addResource(new FakeSourcePath("becgkaifhjd.txt")).build(resolver2, filesystem);
ImmutableMap.Builder<String, String> fileHashes = ImmutableMap.builder();
for (String filename : ImmutableList.of("agifhbkjdec.java", "bdeafhkgcji.java", "bdehgaifjkc.java", "cfiabkjehgd.java", "becgkaifhjd.txt", "bkhajdifcge.txt", "cabfghjekid.txt", "chkdbafijge.txt")) {
fileHashes.put(filename, Hashing.sha1().hashString(filename, Charsets.UTF_8).toString());
}
DefaultRuleKeyFactory ruleKeyFactory = new DefaultRuleKeyFactory(0, FakeFileHashCache.createFromStrings(fileHashes.build()), pathResolver1, ruleFinder1);
DefaultRuleKeyFactory ruleKeyFactory2 = new DefaultRuleKeyFactory(0, FakeFileHashCache.createFromStrings(fileHashes.build()), pathResolver2, ruleFinder2);
RuleKey key1 = ruleKeyFactory.build(rule1);
RuleKey key2 = ruleKeyFactory2.build(rule2);
assertEquals(key1, key2);
}
use of com.facebook.buck.rules.RuleKey in project buck by facebook.
the class DefaultJavaLibraryTest method testInputBasedRuleKeyWithRecursiveExportedDeps.
/**
* Tests that input-based rule keys work properly with a Java library dep exported through
* multiple Java library dependencies.
*/
@Test
public void testInputBasedRuleKeyWithRecursiveExportedDeps() throws Exception {
ProjectFilesystem filesystem = new FakeProjectFilesystem();
// Setup a Java library which builds against another Java library dep exporting another Java
// library dep.
TargetNode<JavaLibraryDescription.Arg, ?> exportedDepNode = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:edep"), filesystem).addSrc(Paths.get("Source1.java")).build();
TargetNode<?, ?> dep2Node = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:dep2"), filesystem).addExportedDep(exportedDepNode.getBuildTarget()).build();
TargetNode<?, ?> dep1Node = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:dep1"), filesystem).addExportedDep(dep2Node.getBuildTarget()).build();
TargetNode<?, ?> libraryNode = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:lib"), filesystem).addDep(dep1Node.getBuildTarget()).build();
TargetGraph targetGraph = TargetGraphFactory.newInstance(exportedDepNode, dep2Node, dep1Node, libraryNode);
ruleResolver = new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(ruleResolver);
SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
JavaLibrary exportedDep = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:edep"));
JavaLibrary library = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:lib"));
filesystem.writeContentsToPath("JAR contents", pathResolver.getRelativePath(exportedDep.getSourcePathToOutput()));
writeAbiJar(filesystem, pathResolver.getRelativePath(ruleResolver.requireRule(exportedDep.getAbiJar().get()).getSourcePathToOutput()), "Source1.class", "ABI JAR contents");
FileHashCache originalHashCache = new StackedFileHashCache(ImmutableList.of(DefaultFileHashCache.createDefaultFileHashCache(filesystem)));
InputBasedRuleKeyFactory factory = new InputBasedRuleKeyFactory(0, originalHashCache, pathResolver, ruleFinder);
RuleKey originalRuleKey = factory.build(library);
// Now change the exported Java library dependency such that its rule key changes, and change
// its JAR contents, but keep its ABI JAR the same. This should *not* affect the input-based
// rule key of the consuming java library, since it only cares about the contents of the ABI
// JAR.
exportedDepNode = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:edep"), filesystem).addSrc(Paths.get("Source1.java")).setResourcesRoot(Paths.get("some root that changes the rule key")).build();
targetGraph = TargetGraphFactory.newInstance(exportedDepNode, dep2Node, dep1Node, libraryNode);
ruleResolver = new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
ruleFinder = new SourcePathRuleFinder(ruleResolver);
pathResolver = new SourcePathResolver(ruleFinder);
exportedDep = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:edep"));
library = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:lib"));
filesystem.writeContentsToPath("different JAR contents", pathResolver.getRelativePath(exportedDep.getSourcePathToOutput()));
FileHashCache unaffectedHashCache = new StackedFileHashCache(ImmutableList.of(DefaultFileHashCache.createDefaultFileHashCache(filesystem)));
factory = new InputBasedRuleKeyFactory(0, unaffectedHashCache, pathResolver, ruleFinder);
RuleKey unaffectedRuleKey = factory.build(library);
assertThat(originalRuleKey, equalTo(unaffectedRuleKey));
// Now actually change the exproted Java library dependency's ABI JAR. This *should* affect
// the input-based rule key of the consuming java library.
ruleResolver = new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
ruleFinder = new SourcePathRuleFinder(ruleResolver);
pathResolver = new SourcePathResolver(ruleFinder);
exportedDep = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:edep"));
library = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:lib"));
writeAbiJar(filesystem, pathResolver.getRelativePath(ruleResolver.requireRule(exportedDep.getAbiJar().get()).getSourcePathToOutput()), "Source1.class", "changed ABI JAR contents");
FileHashCache affectedHashCache = new StackedFileHashCache(ImmutableList.of(DefaultFileHashCache.createDefaultFileHashCache(filesystem)));
factory = new InputBasedRuleKeyFactory(0, affectedHashCache, pathResolver, ruleFinder);
RuleKey affectedRuleKey = factory.build(library);
assertThat(originalRuleKey, Matchers.not(equalTo(affectedRuleKey)));
}
use of com.facebook.buck.rules.RuleKey in project buck by facebook.
the class DefaultJavaLibraryTest method testInputBasedRuleKeyWithExportedDeps.
/**
* Tests that input-based rule keys work properly with a Java library dep exported by a
* first-order dep.
*/
@Test
public void testInputBasedRuleKeyWithExportedDeps() throws Exception {
ProjectFilesystem filesystem = new FakeProjectFilesystem();
// Setup a Java library which builds against another Java library dep exporting another Java
// library dep.
TargetNode<JavaLibraryDescription.Arg, ?> exportedDepNode = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:edep"), filesystem).addSrc(Paths.get("Source1.java")).build();
TargetNode<?, ?> depNode = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:dep"), filesystem).addExportedDep(exportedDepNode.getBuildTarget()).build();
TargetNode<?, ?> libraryNode = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:lib"), filesystem).addDep(depNode.getBuildTarget()).build();
TargetGraph targetGraph = TargetGraphFactory.newInstance(exportedDepNode, depNode, libraryNode);
ruleResolver = new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(ruleResolver);
SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
JavaLibrary exportedDep = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:edep"));
JavaLibrary library = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:lib"));
filesystem.writeContentsToPath("JAR contents", pathResolver.getRelativePath(exportedDep.getSourcePathToOutput()));
writeAbiJar(filesystem, pathResolver.getRelativePath(ruleResolver.requireRule(exportedDep.getAbiJar().get()).getSourcePathToOutput()), "Source1.class", "ABI JAR contents");
FileHashCache originalHashCache = new StackedFileHashCache(ImmutableList.of(DefaultFileHashCache.createDefaultFileHashCache(filesystem)));
InputBasedRuleKeyFactory factory = new InputBasedRuleKeyFactory(0, originalHashCache, pathResolver, ruleFinder);
RuleKey originalRuleKey = factory.build(library);
// Now change the exported Java library dependency such that its rule key changes, and change
// its JAR contents, but keep its ABI JAR the same. This should *not* affect the input-based
// rule key of the consuming java library, since it only cares about the contents of the ABI
// JAR.
exportedDepNode = JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:edep"), filesystem).addSrc(Paths.get("Source1.java")).setResourcesRoot(Paths.get("some root that changes the rule key")).build();
targetGraph = TargetGraphFactory.newInstance(exportedDepNode, depNode, libraryNode);
ruleResolver = new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
ruleFinder = new SourcePathRuleFinder(ruleResolver);
pathResolver = new SourcePathResolver(ruleFinder);
exportedDep = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:edep"));
library = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:lib"));
filesystem.writeContentsToPath("different JAR contents", pathResolver.getRelativePath(exportedDep.getSourcePathToOutput()));
FileHashCache unaffectedHashCache = new StackedFileHashCache(ImmutableList.of(DefaultFileHashCache.createDefaultFileHashCache(filesystem)));
factory = new InputBasedRuleKeyFactory(0, unaffectedHashCache, pathResolver, ruleFinder);
RuleKey unaffectedRuleKey = factory.build(library);
assertThat(originalRuleKey, equalTo(unaffectedRuleKey));
// Now actually change the exproted Java library dependency's ABI JAR. This *should* affect
// the input-based rule key of the consuming java library.
ruleResolver = new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
ruleFinder = new SourcePathRuleFinder(ruleResolver);
pathResolver = new SourcePathResolver(ruleFinder);
exportedDep = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:edep"));
library = (JavaLibrary) ruleResolver.requireRule(BuildTargetFactory.newInstance("//:lib"));
writeAbiJar(filesystem, pathResolver.getRelativePath(ruleResolver.requireRule(exportedDep.getAbiJar().get()).getSourcePathToOutput()), "Source1.class", "changed ABI JAR contents");
FileHashCache affectedHashCache = new StackedFileHashCache(ImmutableList.of(DefaultFileHashCache.createDefaultFileHashCache(filesystem)));
factory = new InputBasedRuleKeyFactory(0, affectedHashCache, pathResolver, ruleFinder);
RuleKey affectedRuleKey = factory.build(library);
assertThat(originalRuleKey, Matchers.not(equalTo(affectedRuleKey)));
}
use of com.facebook.buck.rules.RuleKey in project buck by facebook.
the class JavaLibrarySymbolsFinderTest method onlyNonGeneratedSrcsShouldAffectRuleKey.
@Test
@SuppressWarnings("PMD.PrematureDeclaration")
public void onlyNonGeneratedSrcsShouldAffectRuleKey() throws IOException {
TestDataHelper.createProjectWorkspaceForScenario(this, "java_library_symbols_finder", tmp).setUp();
final ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmp.getRoot());
Function<String, SourcePath> convert = src -> new PathSourcePath(projectFilesystem, Paths.get(src));
SourcePath example1 = convert.apply("Example1.java");
SourcePath example2 = convert.apply("Example2.java");
final BuildTarget fakeBuildTarget = BuildTargetFactory.newInstance("//foo:GenEx.java");
SourcePath generated = new DefaultBuildTargetSourcePath(fakeBuildTarget);
final boolean shouldRecordRequiredSymbols = true;
JavaLibrarySymbolsFinder example1Finder = new JavaLibrarySymbolsFinder(ImmutableSortedSet.of(example1), javaFileParser, shouldRecordRequiredSymbols);
JavaLibrarySymbolsFinder example2Finder = new JavaLibrarySymbolsFinder(ImmutableSortedSet.of(example2), javaFileParser, shouldRecordRequiredSymbols);
JavaLibrarySymbolsFinder example1AndGeneratedSrcFinder = new JavaLibrarySymbolsFinder(ImmutableSortedSet.of(example1, generated), javaFileParser, shouldRecordRequiredSymbols);
// Mock out calls to a SourcePathResolver so we can create a legitimate
// DefaultRuleKeyFactory.
final SourcePathRuleFinder ruleFinder = createMock(SourcePathRuleFinder.class);
final SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
expect(ruleFinder.getRule(anyObject(SourcePath.class))).andAnswer(() -> {
SourcePath input = (SourcePath) EasyMock.getCurrentArguments()[0];
if (input instanceof ExplicitBuildTargetSourcePath) {
return Optional.of(new FakeBuildRule(fakeBuildTarget, pathResolver));
} else {
return Optional.empty();
}
}).anyTimes();
// Calculates the RuleKey for a JavaSymbolsRule with the specified JavaLibrarySymbolsFinder.
final FileHashCache fileHashCache = new StackedFileHashCache(ImmutableList.of(DefaultFileHashCache.createDefaultFileHashCache(projectFilesystem)));
final DefaultRuleKeyFactory ruleKeyFactory = new DefaultRuleKeyFactory(0, fileHashCache, pathResolver, ruleFinder);
Function<JavaLibrarySymbolsFinder, RuleKey> createRuleKey = finder -> {
JavaSymbolsRule javaSymbolsRule = new JavaSymbolsRule(BuildTargetFactory.newInstance("//foo:rule"), finder, ImmutableSortedSet.of(), ObjectMappers.newDefaultInstance(), projectFilesystem);
return ruleKeyFactory.build(javaSymbolsRule);
};
RuleKey key1 = createRuleKey.apply(example1Finder);
RuleKey key2 = createRuleKey.apply(example2Finder);
RuleKey key3 = createRuleKey.apply(example1AndGeneratedSrcFinder);
assertNotNull(key1);
assertNotNull(key2);
assertNotNull(key3);
assertNotEquals("Two instances of a JavaSymbolsRule with different srcs should change the RuleKey.", key1, key2);
assertEquals("Introducing an extra generated .java file to the srcs should not change the RuleKey.", key1, key3);
}
use of com.facebook.buck.rules.RuleKey in project buck by facebook.
the class PrebuiltJarSymbolsFinderTest method contentsOfBinaryJarShouldAffectRuleKey.
@Test
public void contentsOfBinaryJarShouldAffectRuleKey() throws IOException {
// The path to the JAR file to use as the binaryJar of the PrebuiltJarSymbolsFinder.
final Path relativePathToJar = Paths.get("common.jar");
final Path absolutePathToJar = tmp.getRoot().resolve(relativePathToJar);
// Mock out calls to a SourcePathResolver so we can create a legitimate
// DefaultRuleKeyFactory.
final SourcePathRuleFinder ruleFinder = createMock(SourcePathRuleFinder.class);
final SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
createMock(SourcePathResolver.class);
expect(ruleFinder.getRule(anyObject(SourcePath.class))).andReturn(Optional.empty()).anyTimes();
// Calculates the RuleKey for a JavaSymbolsRule with a PrebuiltJarSymbolsFinder whose binaryJar
// is a JAR file with the specified entries.
Function<ImmutableSet<String>, RuleKey> createRuleKey = entries -> {
File jarFile = absolutePathToJar.toFile();
JavaSymbolsRule javaSymbolsRule;
FakeFileHashCache fileHashCache;
try {
PrebuiltJarSymbolsFinder finder = createFinderForFileWithEntries(relativePathToJar.getFileName().toString(), entries);
HashCode hash = Files.hash(jarFile, Hashing.sha1());
Map<Path, HashCode> pathsToHashes = ImmutableMap.of(absolutePathToJar, hash);
fileHashCache = new FakeFileHashCache(pathsToHashes);
javaSymbolsRule = new JavaSymbolsRule(BuildTargetFactory.newInstance("//foo:rule"), finder, ImmutableSortedSet.of(), ObjectMappers.newDefaultInstance(), new ProjectFilesystem(tmp.getRoot()));
} catch (IOException e) {
throw new RuntimeException(e);
}
RuleKey ruleKey = new DefaultRuleKeyFactory(0, fileHashCache, pathResolver, ruleFinder).build(javaSymbolsRule);
jarFile.delete();
return ruleKey;
};
RuleKey key1 = createRuleKey.apply(ImmutableSet.of("entry1", "entry2"));
RuleKey key2 = createRuleKey.apply(ImmutableSet.of("entry1", "entry2"));
RuleKey key3 = createRuleKey.apply(ImmutableSet.of("entry1", "entry2", "entry3"));
assertNotNull(key1);
assertNotNull(key2);
assertNotNull(key3);
assertEquals("Two instances of a JavaSymbolsRule with the same inputs should have the same RuleKey.", key1, key2);
assertNotEquals("Changing the contents of the binaryJar for the PrebuiltJarSymbolsFinder should change " + "the RuleKey of the JavaSymbolsRule that contains it.", key1, key3);
}
Aggregations