/* * Copyright 2016-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.autodeps; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import com.facebook.buck.io.ProjectFilesystem; import com.facebook.buck.jvm.java.JavaFileParser; import com.facebook.buck.jvm.java.JavacOptions; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.model.BuildTargetFactory; import com.facebook.buck.rules.DefaultBuildTargetSourcePath; import com.facebook.buck.rules.ExplicitBuildTargetSourcePath; import com.facebook.buck.rules.FakeBuildRule; import com.facebook.buck.rules.PathSourcePath; import com.facebook.buck.rules.RuleKey; import com.facebook.buck.rules.SourcePath; import com.facebook.buck.rules.SourcePathResolver; import com.facebook.buck.rules.SourcePathRuleFinder; import com.facebook.buck.rules.keys.DefaultRuleKeyFactory; import com.facebook.buck.testutil.integration.TemporaryPaths; import com.facebook.buck.testutil.integration.TestDataHelper; import com.facebook.buck.util.cache.DefaultFileHashCache; import com.facebook.buck.util.cache.FileHashCache; import com.facebook.buck.util.cache.StackedFileHashCache; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import java.io.IOException; import java.nio.file.Paths; import java.util.Optional; import java.util.stream.Stream; import org.easymock.EasyMock; import org.junit.Rule; import org.junit.Test; public class JavaLibrarySymbolsFinderTest { @Rule public TemporaryPaths tmp = new TemporaryPaths(); private static final JavaFileParser javaFileParser = JavaFileParser.createJavaFileParser( JavacOptions.builder().setSourceLevel("7").setTargetLevel("7").build()); @Test public void extractSymbolsFromSrcs() throws InterruptedException, IOException { TestDataHelper.createProjectWorkspaceForScenario(this, "java_library_symbols_finder", tmp) .setUp(); ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmp.getRoot()); ImmutableSortedSet<SourcePath> srcs = ImmutableSortedSet.<SourcePath>naturalOrder() .addAll( Stream.of("Example1.java", "Example2.java") .map(Paths::get) .map(p -> new PathSourcePath(projectFilesystem, p)) .iterator()) .add(new DefaultBuildTargetSourcePath(BuildTargetFactory.newInstance("//foo:bar"))) .build(); JavaLibrarySymbolsFinder finder = new JavaLibrarySymbolsFinder(srcs, javaFileParser /* shouldRecordRequiredSymbols */); Symbols symbols = finder.extractSymbols(); assertEquals( ImmutableSet.of("com.example.Example1", "com.example.Example2"), ImmutableSet.copyOf(symbols.provided)); } @Test @SuppressWarnings("PMD.PrematureDeclaration") public void onlyNonGeneratedSrcsShouldAffectRuleKey() throws InterruptedException, 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); JavaLibrarySymbolsFinder example1Finder = new JavaLibrarySymbolsFinder(ImmutableSortedSet.of(example1), javaFileParser); JavaLibrarySymbolsFinder example2Finder = new JavaLibrarySymbolsFinder(ImmutableSortedSet.of(example2), javaFileParser); JavaLibrarySymbolsFinder example1AndGeneratedSrcFinder = new JavaLibrarySymbolsFinder(ImmutableSortedSet.of(example1, generated), javaFileParser); // 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, 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); } }