@Test
  public void ruleKeyChangesIfInputContentsFromPathSourcePathInRuleKeyAppendableChanges() {
    BuildRuleResolver resolver =
        new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    final FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
    final Path output = Paths.get("output");

    BuildRuleParams params =
        new FakeBuildRuleParamsBuilder("//:rule").setProjectFilesystem(filesystem).build();
    BuildRule rule =
        new NoopBuildRule(params, pathResolver) {
          @AddToRuleKey
          RuleKeyAppendableWithInput input =
              new RuleKeyAppendableWithInput(new PathSourcePath(filesystem, output));
        };

    // Build a rule key with a particular hash set for the output for the above rule.
    FakeFileHashCache hashCache =
        new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(output), HashCode.fromInt(0)));

    RuleKey inputKey1 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    // Now, build a rule key with a different hash for the output for the above rule.
    hashCache =
        new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(output), HashCode.fromInt(1)));

    RuleKey inputKey2 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    assertThat(inputKey1, Matchers.not(Matchers.equalTo(inputKey2)));
  }
Exemplo n.º 2
0
  @Test
  public void modifyingTheContentsOfTheFileChangesTheRuleKey() throws IOException {
    Path root = Files.createTempDirectory("root");
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem(root.toFile());
    Path temp = Paths.get("example_file");

    FileHashCache hashCache = new DefaultFileHashCache(filesystem);
    SourcePathResolver resolver = new SourcePathResolver(new BuildRuleResolver());
    RuleKeyBuilderFactory ruleKeyFactory = new DefaultRuleKeyBuilderFactory(hashCache, resolver);

    filesystem.writeContentsToPath("I like cheese", temp);

    ExportFileBuilder builder =
        ExportFileBuilder.newExportFileBuilder(BuildTargetFactory.newInstance("//some:file"))
            .setSrc(new PathSourcePath(filesystem, temp));

    ExportFile rule = (ExportFile) builder.build(new BuildRuleResolver(), filesystem);

    RuleKey original = ruleKeyFactory.newInstance(rule).build();

    filesystem.writeContentsToPath("I really like cheese", temp);

    // Create a new rule. The FileHashCache held by the existing rule will retain a reference to the
    // previous content of the file, so we need to create an identical rule.
    rule = (ExportFile) builder.build(new BuildRuleResolver(), filesystem);

    hashCache = new DefaultFileHashCache(filesystem);
    resolver = new SourcePathResolver(new BuildRuleResolver());
    ruleKeyFactory = new DefaultRuleKeyBuilderFactory(hashCache, resolver);
    RuleKey refreshed = ruleKeyFactory.newInstance(rule).build();

    assertNotEquals(original, refreshed);
  }
  @Test
  public void ruleKeyChangesIfInputContentsFromPathSourceChanges() throws Exception {
    BuildRuleResolver resolver =
        new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
    Path output = Paths.get("output");

    BuildRule rule =
        ExportFileBuilder.newExportFileBuilder(BuildTargetFactory.newInstance("//:rule"))
            .setOut("out")
            .setSrc(new PathSourcePath(filesystem, output))
            .build(resolver, filesystem);

    // Build a rule key with a particular hash set for the output for the above rule.
    FakeFileHashCache hashCache =
        new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(output), HashCode.fromInt(0)));

    RuleKey inputKey1 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    // Now, build a rule key with a different hash for the output for the above rule.
    hashCache =
        new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(output), HashCode.fromInt(1)));

    RuleKey inputKey2 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    assertThat(inputKey1, Matchers.not(Matchers.equalTo(inputKey2)));
  }
Exemplo n.º 4
0
  @Test
  public void recursiveVsNonRecursive() throws IOException, InterruptedException {
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
    Path buildFile = Paths.get("a", "BUCK");
    filesystem.mkdirs(buildFile.getParent());
    filesystem.touch(buildFile);

    Path nestedBuildFile = Paths.get("a", "b", "BUCK");
    filesystem.mkdirs(nestedBuildFile.getParent());
    filesystem.touch(nestedBuildFile);

    // Test a non-recursive spec.
    BuildFileSpec nonRecursiveSpec = BuildFileSpec.fromPath(buildFile.getParent());
    ImmutableSet<Path> expectedBuildFiles = ImmutableSet.of(filesystem.resolve(buildFile));
    Cell cell = new TestCellBuilder().setFilesystem(filesystem).build();
    ImmutableSet<Path> actualBuildFiles = nonRecursiveSpec.findBuildFiles(cell);
    assertEquals(expectedBuildFiles, actualBuildFiles);

    // Test a recursive spec.
    BuildFileSpec recursiveSpec = BuildFileSpec.fromRecursivePath(buildFile.getParent());
    expectedBuildFiles =
        ImmutableSet.of(filesystem.resolve(buildFile), filesystem.resolve(nestedBuildFile));
    actualBuildFiles = recursiveSpec.findBuildFiles(cell);
    assertEquals(expectedBuildFiles, actualBuildFiles);
  }
Exemplo n.º 5
0
  @Test
  public void invalidSourcePathShouldGiveSpecificErrorMsg() throws NoSuchFieldException {
    Type type = TestFields.class.getField("setOfSourcePaths").getGenericType();
    TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);

    Path baratheon = Paths.get("Baratheon.java");
    Path lannister = Paths.get("Lannister.java");
    Path stark = Paths.get("Stark.java");
    Path targaryen = Paths.get("Targaryen.java");

    ImmutableList<Path> input = ImmutableList.of(baratheon, lannister, stark, targaryen);

    for (Path p : input) {
      if (!p.equals(baratheon)) {
        filesystem.touch(p);
      }
    }

    try {
      coercer.coerce(buildRuleResolver, filesystem, Paths.get(""), input);
    } catch (CoerceFailedException e) {
      String result = e.getMessage();
      String expected = "cannot coerce 'Baratheon.java'";
      for (Path p : input) {
        if (!p.equals(baratheon)) {
          assertFalse(result.contains(p.toString()));
        }
      }
      assertTrue(result.contains(expected));
    }
  }
  @Test
  public void ruleKeyChangesIfInputContentsFromBuildTargetSourcePathInRuleKeyAppendableChanges()
      throws Exception {
    BuildRuleResolver resolver =
        new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    final FakeProjectFilesystem filesystem = new FakeProjectFilesystem();

    final BuildRule dep =
        GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:dep"))
            .setOut("out")
            .build(resolver, filesystem);

    BuildRuleParams params =
        new FakeBuildRuleParamsBuilder("//:rule")
            .setDeclaredDeps(ImmutableSortedSet.of(dep))
            .setProjectFilesystem(filesystem)
            .build();
    BuildRule rule =
        new NoopBuildRule(params, pathResolver) {
          @AddToRuleKey
          RuleKeyAppendableWithInput input =
              new RuleKeyAppendableWithInput(new BuildTargetSourcePath(dep.getBuildTarget()));
        };

    // Build a rule key with a particular hash set for the output for the above rule.
    FakeFileHashCache hashCache =
        new FakeFileHashCache(
            ImmutableMap.of(
                filesystem.resolve(Preconditions.checkNotNull(dep.getPathToOutput())),
                HashCode.fromInt(0)));

    RuleKey inputKey1 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    // Now, build a rule key with a different hash for the output for the above rule.
    hashCache =
        new FakeFileHashCache(
            ImmutableMap.of(
                filesystem.resolve(Preconditions.checkNotNull(dep.getPathToOutput())),
                HashCode.fromInt(1)));

    RuleKey inputKey2 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    assertThat(inputKey1, Matchers.not(Matchers.equalTo(inputKey2)));
  }
Exemplo n.º 7
0
 @Test
 public void xctoolCommandWithAppAndLogicTests() throws Exception {
   FakeProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
   XctoolRunTestsStep step =
       new XctoolRunTestsStep(
           projectFilesystem,
           Paths.get("/path/to/xctool"),
           Optional.<Long>absent(),
           "iphonesimulator",
           Optional.of("name=iPhone 5s,OS=8.2"),
           ImmutableSet.of(Paths.get("/path/to/FooLogicTest.xctest")),
           ImmutableMap.of(Paths.get("/path/to/FooAppTest.xctest"), Paths.get("/path/to/Foo.app")),
           Paths.get("/path/to/output.json"),
           Optional.<XctoolRunTestsStep.StdoutReadingCallback>absent());
   ProcessExecutorParams xctoolParams =
       ProcessExecutorParams.builder()
           .setCommand(
               ImmutableList.of(
                   "/path/to/xctool",
                   "-reporter",
                   "json-stream",
                   "-sdk",
                   "iphonesimulator",
                   "-destination",
                   "name=iPhone 5s,OS=8.2",
                   "run-tests",
                   "-logicTest",
                   "/path/to/FooLogicTest.xctest",
                   "-appTest",
                   "/path/to/FooAppTest.xctest:/path/to/Foo.app"))
           .setDirectory(projectFilesystem.getRootPath().toAbsolutePath().toFile())
           .setRedirectOutput(ProcessBuilder.Redirect.PIPE)
           .build();
   FakeProcess fakeXctoolSuccess = new FakeProcess(0, "", "");
   FakeProcessExecutor processExecutor =
       new FakeProcessExecutor(ImmutableMap.of(xctoolParams, fakeXctoolSuccess));
   ExecutionContext executionContext =
       TestExecutionContext.newBuilder()
           .setProcessExecutor(processExecutor)
           .setEnvironment(ImmutableMap.<String, String>of())
           .build();
   assertThat(step.execute(executionContext), equalTo(0));
 }
Exemplo n.º 8
0
  @Test
  public void coercePath() throws CoerceFailedException, IOException {
    String path = "hello.a";
    projectFilesystem.touch(Paths.get(path));

    SourcePath sourcePath =
        sourcePathTypeCoercer.coerce(cellRoots, projectFilesystem, pathRelativeToProjectRoot, path);

    assertEquals(new PathSourcePath(projectFilesystem, Paths.get(path)), sourcePath);
  }
Exemplo n.º 9
0
  /** Ensure that build rules with the same inputs but different deps have unique RuleKeys. */
  @Test
  public void testRuleKeyDependsOnDeps() throws Exception {
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
    FileHashCache hashCache = new DefaultFileHashCache(filesystem);
    BuildRuleResolver ruleResolver1 =
        new BuildRuleResolver(TargetGraph.EMPTY, new BuildTargetNodeToBuildRuleTransformer());
    BuildRuleResolver ruleResolver2 =
        new BuildRuleResolver(TargetGraph.EMPTY, new BuildTargetNodeToBuildRuleTransformer());
    RuleKeyBuilderFactory ruleKeyBuilderFactory1 =
        new DefaultRuleKeyBuilderFactory(hashCache, new SourcePathResolver(ruleResolver1));
    RuleKeyBuilderFactory ruleKeyBuilderFactory2 =
        new DefaultRuleKeyBuilderFactory(hashCache, new SourcePathResolver(ruleResolver2));

    // Create a dependent build rule, //src/com/facebook/buck/cli:common.
    JavaLibraryBuilder builder =
        JavaLibraryBuilder.createBuilder(
            BuildTargetFactory.newInstance("//src/com/facebook/buck/cli:common"));
    BuildRule commonJavaLibrary = builder.build(ruleResolver1);
    builder.build(ruleResolver2);

    // Create a java_library() rule with no deps.
    Path mainSrc = Paths.get("src/com/facebook/buck/cli/Main.java");
    filesystem.mkdirs(mainSrc.getParent());
    filesystem.writeContentsToPath("hello", mainSrc);
    JavaLibraryBuilder javaLibraryBuilder =
        JavaLibraryBuilder.createBuilder(
                BuildTargetFactory.newInstance("//src/com/facebook/buck/cli:cli"))
            .addSrc(mainSrc);
    BuildRule libraryNoCommon = javaLibraryBuilder.build(ruleResolver1, filesystem);

    // Create the same java_library() rule, but with a dep on //src/com/facebook/buck/cli:common.
    javaLibraryBuilder.addDep(commonJavaLibrary.getBuildTarget());
    BuildRule libraryWithCommon = javaLibraryBuilder.build(ruleResolver2, filesystem);

    // Assert that the RuleKeys are distinct.
    RuleKey r1 = ruleKeyBuilderFactory1.build(libraryNoCommon);
    RuleKey r2 = ruleKeyBuilderFactory2.build(libraryWithCommon);
    assertThat(
        "Rule keys should be distinct because the deps of the rules are different.",
        r1,
        not(equalTo(r2)));
  }
Exemplo n.º 10
0
  @Test
  public void coercingAbsolutePathThrows() throws CoerceFailedException, IOException {
    Path path = MorePathsForTests.rootRelativePath("hello.a");
    projectFilesystem.touch(path);

    exception.expect(CoerceFailedException.class);
    exception.expectMessage("SourcePath cannot contain an absolute path");

    sourcePathTypeCoercer.coerce(
        cellRoots, projectFilesystem, pathRelativeToProjectRoot, path.toString());
  }
  @Test
  public void shouldRewriteLineMarkers() {
    BuildRuleResolver ruleResolver =
        new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
    SourcePathResolver pathResolver = new SourcePathResolver(ruleResolver);

    Path original = Paths.get("buck-out/foo#bar/world.h");
    Path finalPath = Paths.get("SANITIZED/world.h");

    HeaderPathNormalizer.Builder normalizerBuilder =
        new HeaderPathNormalizer.Builder(pathResolver, Functions.<Path>identity());
    normalizerBuilder.addHeader(new FakeSourcePath("hello/////world.h"), original);
    HeaderPathNormalizer normalizer = normalizerBuilder.build();

    DebugPathSanitizer sanitizer =
        new DebugPathSanitizer(
            9,
            File.separatorChar,
            Paths.get("PWD"),
            ImmutableBiMap.of(Paths.get("hello"), Paths.get("SANITIZED")));
    FakeProjectFilesystem fakeProjectFilesystem = new FakeProjectFilesystem();

    CxxPreprocessorOutputTransformerFactory transformer =
        new CxxPreprocessorOutputTransformerFactory(
            fakeProjectFilesystem.getRootPath(), normalizer, sanitizer);

    // Fixup line marker lines properly.
    assertThat(
        String.format("# 12 \"%s\"", Escaper.escapePathForCIncludeString(finalPath)),
        equalTo(transformer.transformLine(String.format("# 12 \"%s\"", original))));
    assertThat(
        String.format("# 12 \"%s\" 2 1", Escaper.escapePathForCIncludeString(finalPath)),
        equalTo(transformer.transformLine(String.format("# 12 \"%s\" 2 1", original))));

    // test.h isn't in the replacement map, so shouldn't be replaced.
    assertThat("# 4 \"test.h\"", equalTo(transformer.transformLine("# 4 \"test.h\"")));

    // Don't modify non-line-marker lines.
    assertThat("int main() {", equalTo(transformer.transformLine("int main() {")));
  }
Exemplo n.º 12
0
  @Test
  public void usesFirstCache() throws IOException {
    ProjectFilesystem filesystem = FakeProjectFilesystem.createJavaOnlyFilesystem();

    Path path = Paths.get("world.txt");
    filesystem.touch(path);

    Path fullPath = filesystem.resolve(path);
    DefaultFileHashCache innerCache = new DefaultFileHashCache(filesystem);
    StackedFileHashCache cache = new StackedFileHashCache(ImmutableList.of(innerCache));
    cache.get(fullPath);
    assertTrue(innerCache.willGet(path));
  }
Exemplo n.º 13
0
  @Test
  public void coerceRelativeBuildTarget() throws CoerceFailedException, IOException {
    SourcePath sourcePath =
        sourcePathTypeCoercer.coerce(
            cellRoots, projectFilesystem, pathRelativeToProjectRoot, ":hello");

    assertEquals(
        new BuildTargetSourcePath(
            BuildTarget.of(
                UnflavoredBuildTarget.of(
                    projectFilesystem.getRootPath(), Optional.<String>absent(), "//", "hello"),
                ImmutableSortedSet.<Flavor>of())),
        sourcePath);
  }
Exemplo n.º 14
0
  @Test
  public void shouldSetSrcAndOutToNameParameterIfNeitherAreSet() throws IOException {
    ProjectFilesystem projectFilesystem = FakeProjectFilesystem.createJavaOnlyFilesystem();
    ExportFile exportFile =
        (ExportFile)
            ExportFileBuilder.newExportFileBuilder(target)
                .build(new BuildRuleResolver(), projectFilesystem);

    List<Step> steps = exportFile.getBuildSteps(context, new FakeBuildableContext());

    MoreAsserts.assertSteps(
        "The output directory should be created and then the file should be copied there.",
        ImmutableList.of(
            "mkdir -p /opt/src/buck/buck-out/gen",
            "cp " + projectFilesystem.resolve("example.html") + " buck-out/gen/example.html"),
        steps,
        TestExecutionContext.newInstance());
    assertEquals(Paths.get("buck-out/gen/example.html"), exportFile.getPathToOutput());
  }
  @Test
  public void createBuildRuleWithFlavoredTargetCallsEnhancerCorrectly() throws IOException {
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();

    // Setup the default values returned by the language specific enhancer.
    String language = "fake";
    Flavor flavor = ImmutableFlavor.of("fake");
    final BuildRule implicitDep = createFakeBuildRule("//implicit:dep", pathResolver);
    resolver.addToIndex(implicitDep);
    filesystem.mkdirs(implicitDep.getBuildTarget().getBasePath());
    filesystem.touch(implicitDep.getBuildTarget().getBasePath().resolve("BUCK"));
    ImmutableSet<BuildTarget> implicitDeps = ImmutableSet.of(implicitDep.getBuildTarget());
    ImmutableSet<String> options = ImmutableSet.of();

    // Create the build targets and params.
    BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift");
    BuildRuleParams unflavoredParams =
        new FakeBuildRuleParamsBuilder(unflavoredTarget).setProjectFilesystem(filesystem).build();
    BuildTarget flavoredTarget =
        BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor);
    BuildRuleParams flavoredParams =
        new FakeBuildRuleParamsBuilder(flavoredTarget).setProjectFilesystem(filesystem).build();

    // Setup a thrift source file generated by a genrule.
    final String thriftSourceName1 = "foo.thrift";
    BuildTarget genruleTarget = BuildTargetFactory.newInstance("//:genrule");
    final Genrule genrule =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(genruleTarget)
                .setOut(thriftSourceName1)
                .build(resolver);
    SourcePath thriftSource1 = new BuildTargetSourcePath(genrule.getBuildTarget());
    final ImmutableList<String> thriftServices1 = ImmutableList.of();

    // Setup a normal thrift source file.
    final String thriftSourceName2 = "bar.thrift";
    SourcePath thriftSource2 = new TestSourcePath(thriftSourceName2);
    final ImmutableList<String> thriftServices2 = ImmutableList.of();

    // Create a build rule that represents the thrift rule.
    final FakeBuildRule thriftRule = createFakeBuildRule("//thrift:target", pathResolver);
    resolver.addToIndex(thriftRule);
    filesystem.mkdirs(thriftRule.getBuildTarget().getBasePath());
    filesystem.touch(thriftRule.getBuildTarget().getBasePath().resolve("BUCK"));

    // Setup a simple description with an empty config.
    FakeBuckConfig buckConfig =
        new FakeBuckConfig(
            ImmutableMap.of(
                "thrift", ImmutableMap.of("compiler", thriftRule.getBuildTarget().toString())));
    ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig);
    ThriftLibraryDescription desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of());

    // Setup the include rules.
    final BuildRule thriftIncludeSymlinkTree =
        createFakeBuildRule(
            desc.createThriftIncludeSymlinkTreeTarget(unflavoredTarget), pathResolver);

    // Setup our language enhancer
    FakeThriftLanguageSpecificEnhancer enhancer =
        new FakeThriftLanguageSpecificEnhancer(language, flavor, implicitDeps, options) {
          @Override
          public void checkCreateBuildRuleInputs(
              ImmutableMap<String, ThriftSource> sources, ImmutableSortedSet<BuildRule> deps) {

            // Verify both thrift sources are present in the list.
            assertEquals(2, sources.size());
            ThriftSource src1 = sources.get(thriftSourceName1);
            assertNotNull(src1);
            ThriftSource src2 = sources.get(thriftSourceName2);
            assertNotNull(src2);

            // Verify the services are listed correctly for both sources.
            assertEquals(thriftServices1, src1.getServices());
            assertEquals(thriftServices2, src2.getServices());

            // Verify dependencies are setup correctly.
            assertEquals(
                ImmutableSortedSet.of(genrule, thriftRule, thriftIncludeSymlinkTree),
                src1.getCompileRule().getDeps());
            assertEquals(
                ImmutableSortedSet.of(genrule, thriftRule, thriftIncludeSymlinkTree),
                src2.getCompileRule().getDeps());

            // Verify the language specific implicit rules are added correctly.
            assertEquals(
                ImmutableSortedSet.<BuildRule>naturalOrder().add(implicitDep).build(), deps);
          }
        };

    // Recreate the description with the enhancer we setup above.
    desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of(enhancer));

    // Setup the internal structure indicating that the thrift target was set in the
    // buck config.
    // desc.setCompilerTarget(thriftRule.getBuildTarget());

    // Setup the implicit deps for the flavored build target.
    // desc.setImplicitDeps(flavoredTarget, ImmutableList.of(implicitDep.getBuildTarget()));

    // Build up the constructor arg.
    ThriftConstructorArg arg = desc.createUnpopulatedConstructorArg();
    arg.name = "thrift";
    arg.srcs =
        ImmutableMap.of(
            thriftSource1, thriftServices1,
            thriftSource2, thriftServices2);
    arg.deps = Optional.absent();
    arg.flags = Optional.absent();

    // Setup the unflavored target, which should just produce a ThriftInclude, SymlinkTree, and
    // ThriftLibrary rule.
    BuildRule rule = desc.createBuildRule(TargetGraph.EMPTY, unflavoredParams, resolver, arg);
    resolver.addToIndex(rule);

    // Now attempt to create the flavored thrift library.
    desc.createBuildRule(TargetGraph.EMPTY, flavoredParams, resolver, arg);
  }
  @Test
  public void createThriftCompilerBuildRulesHasCorrectDeps() throws IOException {
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();

    String language = "fake";
    Flavor flavor = ImmutableFlavor.of("fake");
    ImmutableSet<String> options = ImmutableSet.of();

    // Setup the default values returned by the language specific enhancer.
    BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift");
    BuildRuleParams unflavoredParams =
        new FakeBuildRuleParamsBuilder(BuildTarget.builder(unflavoredTarget).build())
            .setProjectFilesystem(filesystem)
            .build();

    // Setup a thrift source file generated by a genrule.
    BuildTarget flavoredTarget =
        BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor);
    BuildRuleParams flavoredParams =
        new FakeBuildRuleParamsBuilder(flavoredTarget).setProjectFilesystem(filesystem).build();

    // Create a path for the thrift compiler.
    Path thriftPath = Paths.get("thrift_path");
    filesystem.touch(thriftPath);

    // Setup an thrift buck config, with the path to the thrift compiler set.
    FakeBuckConfig buckConfig =
        new FakeBuckConfig(
            ImmutableMap.of("thrift", ImmutableMap.of("compiler", thriftPath.toString())),
            filesystem);
    ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig);
    ThriftLibraryDescription desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of());

    // Setup a simple thrift source.
    String sourceName = "test.thrift";
    SourcePath sourcePath = new TestSourcePath(sourceName);

    // Generate these rules using no deps.
    ImmutableMap<String, ThriftCompiler> rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, sourcePath),
            ImmutableSortedSet.<ThriftLibrary>of());

    // Now verify that the generated rule had no associated deps.
    assertSame(rules.size(), 1);
    ThriftCompiler rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(), rule.getDeps());

    // Lets do this again, but pass in a ThriftLibrary deps, wrapping some includes we need.
    Path includeRoot = desc.getIncludeRoot(unflavoredTarget);
    HeaderSymlinkTree thriftIncludeSymlinkTree =
        createFakeSymlinkTree(
            desc.createThriftIncludeSymlinkTreeTarget(unflavoredTarget), pathResolver, includeRoot);
    ThriftLibrary lib =
        new ThriftLibrary(
            unflavoredParams,
            pathResolver,
            ImmutableSortedSet.<ThriftLibrary>of(),
            thriftIncludeSymlinkTree,
            ImmutableMap.<Path, SourcePath>of());

    // Generate these rules using no deps.
    rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, sourcePath),
            ImmutableSortedSet.of(lib));

    // Now verify that the generated rule has all the deps from the passed in thrift library.
    assertSame(rules.size(), 1);
    rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(thriftIncludeSymlinkTree), rule.getDeps());

    // Setup a simple genrule that creates the thrift source and verify its dep is propagated.
    Genrule genrule =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule"))
                .setOut(sourceName)
                .build(resolver);
    SourcePath ruleSourcePath = new BuildTargetSourcePath(genrule.getBuildTarget());

    // Generate these rules using no deps and the genrule generated source.
    rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, ruleSourcePath),
            ImmutableSortedSet.<ThriftLibrary>of());

    // Now verify that the generated rule had no associated deps.
    assertSame(rules.size(), 1);
    rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(genrule), rule.getDeps());

    // Create a build rule that represents the thrift rule.
    FakeBuildRule thriftRule = createFakeBuildRule("//thrift:target", pathResolver);
    resolver.addToIndex(thriftRule);
    filesystem.mkdirs(thriftRule.getBuildTarget().getBasePath());
    filesystem.touch(thriftRule.getBuildTarget().getBasePath().resolve("BUCK"));

    // Setup an empty thrift buck config, and set compiler target.
    buckConfig =
        new FakeBuckConfig(
            ImmutableMap.of(
                "thrift", ImmutableMap.of("compiler", thriftRule.getBuildTarget().toString())),
            filesystem);
    thriftBuckConfig = new ThriftBuckConfig(buckConfig);
    desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of());

    // Generate these rules using no deps with a compiler target.
    rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, sourcePath),
            ImmutableSortedSet.<ThriftLibrary>of());

    // Now verify that the generated rule only has deps from the compiler target.
    assertSame(rules.size(), 1);
    rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(thriftRule), rule.getDeps());
  }
Exemplo n.º 17
0
  @Test
  public void createLexYaccBuildRules() throws IOException {
    BuildRuleResolver resolver = new BuildRuleResolver();

    // Setup our C++ buck config with the paths to the lex/yacc binaries.
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
    Path lexPath = Paths.get("lex");
    filesystem.touch(lexPath);
    Path yaccPath = Paths.get("yacc");
    filesystem.touch(yaccPath);
    BuckConfig buckConfig =
        FakeBuckConfig.builder()
            .setSections(
                ImmutableMap.of(
                    "cxx",
                    ImmutableMap.of(
                        "lex", lexPath.toString(),
                        "yacc", yaccPath.toString())))
            .setFilesystem(filesystem)
            .build();
    CxxPlatform cxxBuckConfig = DefaultCxxPlatforms.build(new CxxBuckConfig(buckConfig));

    // Setup the target name and build params.
    UnflavoredBuildTarget target =
        BuildTargetFactory.newInstance("//:test").getUnflavoredBuildTarget();
    BuildRuleParams params = new FakeBuildRuleParamsBuilder(BuildTarget.of(target)).build();

    // Setup a genrule that generates our lex source.
    String lexSourceName = "test.ll";
    BuildTarget genruleTarget = BuildTargetFactory.newInstance("//:genrule_lex");
    Genrule genrule =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(genruleTarget).setOut(lexSourceName).build(resolver);
    SourcePath lexSource = new BuildTargetSourcePath(genrule.getBuildTarget());

    // Use a regular path for our yacc source.
    String yaccSourceName = "test.yy";
    SourcePath yaccSource = new TestSourcePath(yaccSourceName);

    // Build the rules.
    CxxHeaderSourceSpec actual =
        CxxDescriptionEnhancer.createLexYaccBuildRules(
            params,
            resolver,
            cxxBuckConfig,
            ImmutableList.<String>of(),
            ImmutableMap.of(lexSourceName, lexSource),
            ImmutableList.<String>of(),
            ImmutableMap.of(yaccSourceName, yaccSource));

    // Grab the generated lex rule and verify it has the genrule as a dep.
    Lex lex =
        (Lex) resolver.getRule(CxxDescriptionEnhancer.createLexBuildTarget(target, lexSourceName));
    assertNotNull(lex);
    assertEquals(ImmutableSortedSet.<BuildRule>of(genrule), lex.getDeps());

    // Grab the generated yacc rule and verify it has no deps.
    Yacc yacc =
        (Yacc)
            resolver.getRule(CxxDescriptionEnhancer.createYaccBuildTarget(target, yaccSourceName));
    assertNotNull(yacc);
    assertEquals(ImmutableSortedSet.<BuildRule>of(), yacc.getDeps());

    // Check the header/source spec is correct.
    Path lexOutputSource = CxxDescriptionEnhancer.getLexSourceOutputPath(target, lexSourceName);
    Path lexOutputHeader = CxxDescriptionEnhancer.getLexHeaderOutputPath(target, lexSourceName);
    Path yaccOutputPrefix =
        CxxDescriptionEnhancer.getYaccOutputPrefix(
            target, Files.getNameWithoutExtension(yaccSourceName));
    Path yaccOutputSource = Yacc.getSourceOutputPath(yaccOutputPrefix);
    Path yaccOutputHeader = Yacc.getHeaderOutputPath(yaccOutputPrefix);
    CxxHeaderSourceSpec expected =
        CxxHeaderSourceSpec.of(
            ImmutableMap.<Path, SourcePath>of(
                target.getBasePath().resolve(lexSourceName + ".h"),
                new BuildTargetSourcePath(lex.getBuildTarget(), lexOutputHeader),
                target.getBasePath().resolve(yaccSourceName + ".h"),
                new BuildTargetSourcePath(yacc.getBuildTarget(), yaccOutputHeader)),
            ImmutableMap.of(
                lexSourceName + ".cc",
                CxxSource.of(
                    CxxSource.Type.CXX,
                    new BuildTargetSourcePath(lex.getBuildTarget(), lexOutputSource),
                    ImmutableList.<String>of()),
                yaccSourceName + ".cc",
                CxxSource.of(
                    CxxSource.Type.CXX,
                    new BuildTargetSourcePath(yacc.getBuildTarget(), yaccOutputSource),
                    ImmutableList.<String>of())));
    assertEquals(expected, actual);
  }
  @Test
  public void testGetBuildStepsWhenThereAreClassesToDex() throws IOException, InterruptedException {
    SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
    FakeJavaLibrary javaLibraryRule =
        new FakeJavaLibrary(BuildTargetFactory.newInstance("//foo:bar"), pathResolver) {
          @Override
          public ImmutableSortedMap<String, HashCode> getClassNamesToHashes() {
            return ImmutableSortedMap.of("com/example/Foo", HashCode.fromString("cafebabe"));
          }

          @Override
          public Sha1HashCode getAbiKey() {
            return Sha1HashCode.of("f7f34ed13b881c6c6f663533cde4a436ea84435e");
          }
        };
    javaLibraryRule.setOutputFile("buck-out/gen/foo/bar.jar");

    BuildContext context = createMock(BuildContext.class);
    FakeBuildableContext buildableContext = new FakeBuildableContext();

    replayAll();

    ProjectFilesystem filesystem = FakeProjectFilesystem.createJavaOnlyFilesystem("/home/user");
    createFiles(filesystem, "buck-out/gen/foo/bar#dex.dex.jar", "buck-out/gen/foo/bar.jar");

    BuildTarget buildTarget = BuildTargetFactory.newInstance("//foo:bar#dex");
    BuildRuleParams params =
        new FakeBuildRuleParamsBuilder(buildTarget).setProjectFilesystem(filesystem).build();
    DexProducedFromJavaLibrary preDex =
        new DexProducedFromJavaLibrary(params, pathResolver, javaLibraryRule);
    List<Step> steps = preDex.getBuildSteps(context, buildableContext);

    verifyAll();
    resetAll();

    AndroidPlatformTarget androidPlatformTarget = createMock(AndroidPlatformTarget.class);
    expect(androidPlatformTarget.getDxExecutable()).andReturn(Paths.get("/usr/bin/dx"));

    replayAll();

    ExecutionContext executionContext =
        TestExecutionContext.newBuilder()
            .setAndroidPlatformTargetSupplier(Suppliers.ofInstance(androidPlatformTarget))
            .build();

    String expectedDxCommand =
        String.format(
            "%s --dex --no-optimize --force-jumbo --output %s %s",
            Paths.get("/usr/bin/dx"),
            Paths.get("/home/user/buck-out/gen/foo/bar#dex.dex.jar"),
            Paths.get("/home/user/buck-out/gen/foo/bar.jar"));
    MoreAsserts.assertSteps(
        "Generate bar.dex.jar.",
        ImmutableList.of(
            String.format("rm -f %s", Paths.get("/home/user/buck-out/gen/foo/bar#dex.dex.jar")),
            String.format("mkdir -p %s", Paths.get("/home/user/buck-out/gen/foo")),
            "estimate_linear_alloc",
            "(cd /home/user && " + expectedDxCommand + ")",
            "zip-scrub buck-out/gen/foo/bar#dex.dex.jar",
            "record_dx_success"),
        steps,
        executionContext);

    verifyAll();
    resetAll();

    replayAll();

    ((EstimateLinearAllocStep) steps.get(2)).setLinearAllocEstimateForTesting(250);
    Step recordArtifactAndMetadataStep = steps.get(5);
    int exitCode = recordArtifactAndMetadataStep.execute(executionContext);
    assertEquals(0, exitCode);
    assertEquals(
        "The generated .dex.jar file should be in the set of recorded artifacts.",
        ImmutableSet.of(Paths.get("buck-out/gen/foo/bar#dex.dex.jar")),
        buildableContext.getRecordedArtifacts());

    buildableContext.assertContainsMetadataMapping(
        DexProducedFromJavaLibrary.LINEAR_ALLOC_KEY_ON_DISK_METADATA, "250");

    verifyAll();
  }