@Test public void testEditingSecondaryDexClassForcesRebuildForNativeExopackage() throws IOException { workspace.replaceFileContents("java/com/sample/lib/Sample.java", "package com", "package\ncom"); workspace.resetBuildLogFile(); workspace.runBuckBuild(NATIVE_EXOPACKAGE_TARGET).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetBuiltLocally(NATIVE_EXOPACKAGE_TARGET); }
@Test public void testEditingSecondaryDexClassGetsAbiHitForDexAndNativeExopackage() throws IOException { workspace.replaceFileContents("java/com/sample/lib/Sample.java", "package com", "package\ncom"); workspace.resetBuildLogFile(); workspace.runBuckBuild(DEX_AND_NATIVE_EXOPACKAGE_TARGET).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetHadMatchingDepsAbi(DEX_AND_NATIVE_EXOPACKAGE_TARGET); }
@Test public void testEditingColorForcesRebuild() throws IOException { workspace.replaceFileContents("res/com/sample/top/res/layout/top_layout.xml", "white", "black"); workspace.resetBuildLogFile(); workspace.runBuckBuild(DEX_EXOPACKAGE_TARGET).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetBuiltLocally(DEX_EXOPACKAGE_TARGET); }
@Test public void testEditingKeystoreForcesRebuild() throws IOException { workspace.replaceFileContents("keystores/debug.keystore.properties", "my_alias", "my_alias\n"); workspace.resetBuildLogFile(); workspace.runBuckBuild(DEX_EXOPACKAGE_TARGET).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetBuiltLocally(DEX_EXOPACKAGE_TARGET); }
@Test public void testEditingPrimaryDexClassForcesRebuildForExopackage() throws IOException { workspace.replaceFileContents( "java/com/sample/app/MyApplication.java", "package com", "package\ncom"); workspace.resetBuildLogFile(); workspace.runBuckBuild(DEX_EXOPACKAGE_TARGET).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetBuiltLocally(DEX_EXOPACKAGE_TARGET); }
@Test public void testEditingStringForcesRebuild() throws IOException { workspace.replaceFileContents("res/com/sample/base/res/values/strings.xml", "Hello", "Bye"); workspace.resetBuildLogFile(); workspace.runBuckBuild(DEX_EXOPACKAGE_TARGET).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetBuiltLocally(DEX_EXOPACKAGE_TARGET); }
@Test public void testEditingThirdPartyJarForcesRebuild() throws IOException { workspace.copyFile("third-party/kiwi-2.0.jar", "third-party/kiwi-current.jar"); workspace.resetBuildLogFile(); workspace.runBuckBuild(DEX_EXOPACKAGE_TARGET).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetBuiltLocally(DEX_EXOPACKAGE_TARGET); }
@Test public void testEditingAssetForcesRebuild() throws IOException { workspace.replaceFileContents("res/com/sample/base/buck-assets/hilarity.txt", "banana", "kiwi"); workspace.resetBuildLogFile(); workspace.runBuckBuild(DEX_EXOPACKAGE_TARGET).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetBuiltLocally(DEX_EXOPACKAGE_TARGET); }
@Test public void testEditingManifestForcesRebuild() throws IOException { workspace.replaceFileContents( "apps/multidex/AndroidManifest.xml", "versionCode=\"1\"", "versionCode=\"2\""); workspace.resetBuildLogFile(); workspace.runBuckBuild(DEX_EXOPACKAGE_TARGET).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetBuiltLocally(DEX_EXOPACKAGE_TARGET); }
@Test public void testEditingImageForcesRebuild() throws IOException { workspace.copyFile( "res/com/sample/top/res/drawable/tiny_white.png", "res/com/sample/top/res/drawable/tiny_something.png"); workspace.resetBuildLogFile(); workspace.runBuckBuild(DEX_EXOPACKAGE_TARGET).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetBuiltLocally(DEX_EXOPACKAGE_TARGET); }
@Test public void testBuildLogParsing() { ImmutableList<String> buildLogLines = ImmutableList.of( "735 INFO BuildRuleFinished(//example/base:one): " + "SUCCESS MISS BUILT_LOCALLY 489e1b85f804dc0f66545f2ce06f57ee85204747", "735 INFO BuildRuleFinished(//example/base:two): " + "FAIL MISS MISSING 489e1b85f804dc0f66545f2ce06f57ee85204747", "735 INFO BuildRuleFinished(//example/base:three): " + "SUCCESS MISS MATCHING_RULE_KEY 489e1b85f804dc0f66545f2ce06f57ee85204747"); BuckBuildLog buildLog = BuckBuildLog.fromLogContents(Paths.get("/spoof"), buildLogLines); buildLog.assertTargetBuiltLocally("//example/base:one"); buildLog.assertTargetFailed("//example/base:two"); buildLog.assertTargetHadMatchingRuleKey("//example/base:three"); }
@Test public void testInferCxxBinaryWithCachedDepsGetsAllItsTransitiveDeps() throws IOException { assumeTrue(Platform.detect() != Platform.WINDOWS); ProjectWorkspace workspace = InferHelper.setupCxxInferWorkspace(this, tmp); workspace.enableDirCache(); // enable the cache BuildTarget inputBuildTarget = BuildTargetFactory.newInstance("//foo:binary_with_chain_deps"); String inputBuildTargetName = inputBuildTarget.withFlavors(CxxInferEnhancer.INFER).getFullyQualifiedName(); /* * Build the given target and check that it succeeds. */ workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); /* * Check that building after clean will use the cache */ workspace.runBuckCommand("clean").assertSuccess(); workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); for (BuildTarget buildTarget : buildLog.getAllTargets()) { buildLog.assertTargetWasFetchedFromCache(buildTarget.toString()); } /* * Check that if the file in the top target changes, then all the transitive deps will be * fetched from the cache (even those that are not direct dependencies). * Make sure there's the specs file of the dependency that has distance 2 from * the binary target. */ String sourceName = "top_chain.c"; workspace.replaceFileContents("foo/" + sourceName, "*p += 1", "*p += 10"); workspace.runBuckCommand("clean").assertSuccess(); workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); // Check all the buildrules were fetched from the cache (and there's the specs file) assertTrue( "Expected specs file for func_ret_null() in chain_dep_two.c not found", workspace .getPath( "buck-out/gen/foo/infer-analysis-chain_dep_two#default,infer-analyze/specs/" + "mockedSpec.specs") .toFile() .exists()); }
@Test public void testCxxBinaryDepfileBuildWithAddedHeader() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario( this, "cxx_binary_depfile_build_with_added_header", tmp); workspace.setUp(); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", "//:bin"); result.assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); buildLog.assertTargetBuiltLocally("//:bin#binary"); buildLog.assertTargetBuiltLocally("//:bin#compile-bin.c.o,default"); buildLog.assertTargetBuiltLocally("//:lib1#default,static"); workspace.resetBuildLogFile(); workspace.replaceFileContents("BUCK", "['lib1.h']", "['lib1.h', 'lib2.h']"); result = workspace.runBuckCommand("build", "//:bin"); result.assertSuccess(); buildLog = workspace.getBuildLog(); buildLog.assertTargetHadMatchingInputRuleKey("//:bin#binary"); buildLog.assertTargetHadMatchingDepfileRuleKey("//:bin#compile-bin.c.o,default"); buildLog.assertTargetBuiltLocally("//:lib1#default,static"); }
@Test public void testInferCxxBinaryDepsCaching() throws IOException { assumeTrue(Platform.detect() != Platform.WINDOWS); ProjectWorkspace workspace = InferHelper.setupCxxInferWorkspace(this, tmp); workspace.enableDirCache(); // enable the cache CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new CxxBuckConfig(new FakeBuckConfig())); BuildTarget inputBuildTarget = BuildTargetFactory.newInstance("//foo:binary_with_deps"); String inputBuildTargetName = inputBuildTarget.withFlavors(CxxInferEnhancer.INFER).getFullyQualifiedName(); /* * Build the given target and check that it succeeds. */ workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); /* * Check that building after clean will use the cache */ workspace.runBuckCommand("clean").assertSuccess(); workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); for (BuildTarget buildTarget : buildLog.getAllTargets()) { buildLog.assertTargetWasFetchedFromCache(buildTarget.toString()); } /* * Check that if the file in the binary target changes, then all the deps will be fetched * from the cache */ String sourceName = "src_with_deps.c"; workspace.replaceFileContents("foo/" + sourceName, "10", "30"); workspace.runBuckCommand("clean").assertSuccess(); workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); buildLog = workspace.getBuildLog(); CxxSourceRuleFactory cxxSourceRuleFactory = CxxSourceRuleFactoryHelper.of(inputBuildTarget, cxxPlatform); BuildTarget captureBuildTarget = cxxSourceRuleFactory.createInferCaptureBuildTarget(sourceName); // this is flavored, and denotes the analysis step (generates a local report) BuildTarget inferAnalysisTarget = inputBuildTarget.withFlavors(CxxInferEnhancer.INFER_ANALYZE); // this is the flavored version of the top level target (the one give in input to buck) BuildTarget inferReportTarget = inputBuildTarget.withFlavors(CxxInferEnhancer.INFER); String bt; for (BuildTarget buildTarget : buildLog.getAllTargets()) { bt = buildTarget.toString(); if (bt.equals(inferAnalysisTarget.toString()) || bt.equals(captureBuildTarget.toString()) || bt.equals(inferReportTarget.toString())) { buildLog.assertTargetBuiltLocally(bt); } else { buildLog.assertTargetWasFetchedFromCache(buildTarget.toString()); } } }
@Test public void testInferCxxBinaryWithDeps() throws IOException { assumeTrue(Platform.detect() != Platform.WINDOWS); ProjectWorkspace workspace = InferHelper.setupCxxInferWorkspace(this, tmp); CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new CxxBuckConfig(new FakeBuckConfig())); BuildTarget inputBuildTarget = BuildTargetFactory.newInstance("//foo:binary_with_deps"); String inputBuildTargetName = inputBuildTarget.withFlavors(CxxInferEnhancer.INFER).getFullyQualifiedName(); /* * Build the given target and check that it succeeds. */ workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); /* * Check that all the required build targets have been generated. */ String sourceName = "src_with_deps.c"; CxxSourceRuleFactory cxxSourceRuleFactory = CxxSourceRuleFactoryHelper.of(inputBuildTarget, cxxPlatform); // 1. create the targets of binary_with_deps // this is unflavored, but bounded to the InferCapture build rule BuildTarget topCaptureBuildTarget = cxxSourceRuleFactory.createInferCaptureBuildTarget(sourceName); // this is unflavored, but necessary to run the compiler successfully BuildTarget topHeaderSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( inputBuildTarget, cxxPlatform.getFlavor(), HeaderVisibility.PRIVATE); // this is flavored, and denotes the analysis step (generates a local report) BuildTarget topInferAnalysisTarget = inputBuildTarget.withFlavors(CxxInferEnhancer.INFER_ANALYZE); // this is flavored and corresponds to the top level target (the one give in input to buck) BuildTarget topInferReportTarget = inputBuildTarget.withFlavors(CxxInferEnhancer.INFER); // 2. create the targets of dep_one BuildTarget depOneBuildTarget = BuildTargetFactory.newInstance("//foo:dep_one"); String depOneSourceName = "dep_one.c"; String depOneSourceFull = "foo/" + depOneSourceName; CxxSourceRuleFactory depOneSourceRuleFactory = CxxSourceRuleFactoryHelper.of(depOneBuildTarget, cxxPlatform); BuildTarget depOneCaptureBuildTarget = depOneSourceRuleFactory.createInferCaptureBuildTarget(depOneSourceName); BuildTarget depOneHeaderSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( depOneBuildTarget, cxxPlatform.getFlavor(), HeaderVisibility.PRIVATE); BuildTarget depOneExportedHeaderSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( depOneBuildTarget, cxxPlatform.getFlavor(), HeaderVisibility.PUBLIC); BuildTarget depOneInferAnalysisTarget = depOneCaptureBuildTarget.withFlavors( cxxPlatform.getFlavor(), CxxInferEnhancer.INFER_ANALYZE); // 3. create the targets of dep_two BuildTarget depTwoBuildTarget = BuildTargetFactory.newInstance("//foo:dep_two"); CxxSourceRuleFactory depTwoSourceRuleFactory = CxxSourceRuleFactoryHelper.of(depTwoBuildTarget, cxxPlatform); BuildTarget depTwoCaptureBuildTarget = depTwoSourceRuleFactory.createInferCaptureBuildTarget("dep_two.c"); BuildTarget depTwoHeaderSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( depTwoBuildTarget, cxxPlatform.getFlavor(), HeaderVisibility.PRIVATE); BuildTarget depTwoExportedHeaderSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( depTwoBuildTarget, cxxPlatform.getFlavor(), HeaderVisibility.PUBLIC); BuildTarget depTwoInferAnalysisTarget = depTwoCaptureBuildTarget.withFlavors( cxxPlatform.getFlavor(), CxxInferEnhancer.INFER_ANALYZE); // Check all the targets are in the buildLog assertEquals( ImmutableSet.of( topCaptureBuildTarget, topHeaderSymlinkTreeTarget, topInferAnalysisTarget, topInferReportTarget, depOneCaptureBuildTarget, depOneHeaderSymlinkTreeTarget, depOneExportedHeaderSymlinkTreeTarget, depOneInferAnalysisTarget, depTwoCaptureBuildTarget, depTwoHeaderSymlinkTreeTarget, depTwoExportedHeaderSymlinkTreeTarget, depTwoInferAnalysisTarget), workspace.getBuildLog().getAllTargets()); /* * Check that running a build again results in no builds since nothing has changed. */ workspace.resetBuildLogFile(); // clear for new build workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); assertEquals(ImmutableSet.of(topInferReportTarget), buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(topInferReportTarget.toString()); /* * Check that if a library source file changes then the capture/analysis rules run again on * the main target and on dep_one only. */ workspace.resetBuildLogFile(); workspace.replaceFileContents(depOneSourceFull, "flag > 0", "flag < 0"); workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); buildLog = workspace.getBuildLog(); assertEquals( ImmutableSet.of( topInferAnalysisTarget, // analysis runs again topInferReportTarget, // report runs again topCaptureBuildTarget, // cached depTwoInferAnalysisTarget, // cached depOneCaptureBuildTarget, // capture of the changed file runs again depOneExportedHeaderSymlinkTreeTarget, // cached depOneHeaderSymlinkTreeTarget, // cached depOneInferAnalysisTarget), // analysis of the library runs again buildLog.getAllTargets()); buildLog.assertTargetBuiltLocally(topInferAnalysisTarget.toString()); buildLog.assertTargetBuiltLocally(topInferReportTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(topCaptureBuildTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(depTwoInferAnalysisTarget.toString()); buildLog.assertTargetBuiltLocally(depOneCaptureBuildTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(depOneExportedHeaderSymlinkTreeTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(depOneHeaderSymlinkTreeTarget.toString()); buildLog.assertTargetBuiltLocally(depOneInferAnalysisTarget.toString()); }
@Test public void testInferCxxBinaryWithoutDeps() throws IOException { assumeTrue(Platform.detect() != Platform.WINDOWS); ProjectWorkspace workspace = InferHelper.setupCxxInferWorkspace(this, tmp); CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new CxxBuckConfig(new FakeBuckConfig())); BuildTarget inputBuildTarget = BuildTargetFactory.newInstance("//foo:simple"); String inputBuildTargetName = inputBuildTarget.withFlavors(CxxInferEnhancer.INFER).getFullyQualifiedName(); /* * Build the given target and check that it succeeds. */ workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); /* * Check that all the required build targets have been generated. */ String sourceName = "simple.cpp"; String sourceFull = "foo/" + sourceName; CxxSourceRuleFactory cxxSourceRuleFactory = CxxSourceRuleFactoryHelper.of(inputBuildTarget, cxxPlatform); // this is unflavored, but bounded to the InferCapture build rule BuildTarget captureBuildTarget = cxxSourceRuleFactory.createInferCaptureBuildTarget(sourceName); // this is unflavored, but necessary to run the compiler successfully BuildTarget headerSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( inputBuildTarget, cxxPlatform.getFlavor(), HeaderVisibility.PRIVATE); // this is flavored, and denotes the analysis step (generates a local report) BuildTarget inferAnalysisTarget = inputBuildTarget.withFlavors(CxxInferEnhancer.INFER_ANALYZE); // this is flavored and corresponds to the top level target (the one give in input to buck) BuildTarget inferReportTarget = inputBuildTarget.withFlavors(CxxInferEnhancer.INFER); ImmutableSet<BuildTarget> expectedTargets = ImmutableSet.<BuildTarget>builder() .addAll( ImmutableSet.of( headerSymlinkTreeTarget, captureBuildTarget, inferAnalysisTarget, inferReportTarget)) .build(); BuckBuildLog buildLog = workspace.getBuildLog(); assertEquals(expectedTargets, buildLog.getAllTargets()); buildLog.assertTargetBuiltLocally(headerSymlinkTreeTarget.toString()); buildLog.assertTargetBuiltLocally(captureBuildTarget.toString()); buildLog.assertTargetBuiltLocally(inferAnalysisTarget.toString()); buildLog.assertTargetBuiltLocally(inferReportTarget.toString()); /* * Check that running a build again results in no builds since nothing has changed. */ workspace.resetBuildLogFile(); // clear for new build workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); buildLog = workspace.getBuildLog(); assertEquals(ImmutableSet.of(inferReportTarget), buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(inferReportTarget.toString()); /* * Check that changing the source file results in running the capture/analysis rules again. */ workspace.resetBuildLogFile(); workspace.replaceFileContents(sourceFull, "*s = 42;", ""); workspace.runBuckCommand("build", inputBuildTargetName).assertSuccess(); buildLog = workspace.getBuildLog(); assertEquals(expectedTargets, buildLog.getAllTargets()); buildLog.assertTargetBuiltLocally(captureBuildTarget.toString()); buildLog.assertTargetBuiltLocally(inferAnalysisTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(headerSymlinkTreeTarget.toString()); }
@Test public void testSimpleCxxBinaryWithDependencyOnCxxLibraryWithHeader() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "simple", tmp); workspace.setUp(); // Setup variables pointing to the sources and targets of the top-level binary rule. CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new CxxBuckConfig(new FakeBuckConfig())); BuildTarget target = BuildTargetFactory.newInstance("//foo:binary_with_dep"); CxxSourceRuleFactory cxxSourceRuleFactory = CxxSourceRuleFactoryHelper.of(target, cxxPlatform); BuildTarget binaryTarget = CxxDescriptionEnhancer.createCxxLinkTarget(target); String sourceName = "foo.cpp"; BuildTarget preprocessTarget = cxxSourceRuleFactory.createPreprocessBuildTarget( sourceName, CxxSource.Type.CXX, CxxSourceRuleFactory.PicType.PDC); BuildTarget compileTarget = cxxSourceRuleFactory.createCompileBuildTarget(sourceName, CxxSourceRuleFactory.PicType.PDC); BuildTarget headerSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( target, cxxPlatform.getFlavor(), HeaderVisibility.PRIVATE); // Setup variables pointing to the sources and targets of the library dep. BuildTarget depTarget = BuildTargetFactory.newInstance("//foo:library_with_header"); CxxSourceRuleFactory depCxxSourceRuleFactory = CxxSourceRuleFactoryHelper.of(depTarget, cxxPlatform); String depSourceName = "bar.cpp"; String depSourceFull = "foo/" + depSourceName; String depHeaderName = "bar.h"; String depHeaderFull = "foo/" + depHeaderName; BuildTarget depPreprocessTarget = depCxxSourceRuleFactory.createPreprocessBuildTarget( depSourceName, CxxSource.Type.CXX, CxxSourceRuleFactory.PicType.PDC); BuildTarget depCompileTarget = depCxxSourceRuleFactory.createCompileBuildTarget( depSourceName, CxxSourceRuleFactory.PicType.PDC); BuildTarget depHeaderSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( depTarget, cxxPlatform.getFlavor(), HeaderVisibility.PRIVATE); BuildTarget depHeaderExportedSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( depTarget, cxxPlatform.getFlavor(), HeaderVisibility.PUBLIC); BuildTarget depArchiveTarget = CxxDescriptionEnhancer.createStaticLibraryBuildTarget( depTarget, cxxPlatform.getFlavor(), CxxSourceRuleFactory.PicType.PDC); // Do a clean build, verify that it succeeds, and check that all expected targets built // successfully. workspace.runBuckCommand("build", target.toString()).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); assertEquals( ImmutableSet.of( depHeaderSymlinkTreeTarget, depHeaderExportedSymlinkTreeTarget, depPreprocessTarget, depCompileTarget, depArchiveTarget, depTarget, headerSymlinkTreeTarget, preprocessTarget, compileTarget, binaryTarget, target), buildLog.getAllTargets()); buildLog.assertTargetBuiltLocally(depHeaderSymlinkTreeTarget.toString()); buildLog.assertTargetBuiltLocally(depPreprocessTarget.toString()); buildLog.assertTargetBuiltLocally(depCompileTarget.toString()); buildLog.assertTargetBuiltLocally(depArchiveTarget.toString()); buildLog.assertTargetBuiltLocally(depTarget.toString()); buildLog.assertTargetBuiltLocally(headerSymlinkTreeTarget.toString()); buildLog.assertTargetBuiltLocally(preprocessTarget.toString()); buildLog.assertTargetBuiltLocally(compileTarget.toString()); buildLog.assertTargetBuiltLocally(binaryTarget.toString()); buildLog.assertTargetBuiltLocally(target.toString()); // Clear for new build. workspace.resetBuildLogFile(); // Update the source file. workspace.replaceFileContents(depHeaderFull, "int x", "int y"); // Check that running a build again makes the source get recompiled and the binary // re-linked, but does not cause the header rules to re-run. workspace.runBuckCommand("build", target.toString()).assertSuccess(); buildLog = workspace.getBuildLog(); assertEquals( ImmutableSet.of( depHeaderSymlinkTreeTarget, depHeaderExportedSymlinkTreeTarget, depPreprocessTarget, depCompileTarget, depArchiveTarget, depTarget, headerSymlinkTreeTarget, preprocessTarget, compileTarget, binaryTarget, target), buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(depHeaderSymlinkTreeTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(depHeaderExportedSymlinkTreeTarget.toString()); buildLog.assertTargetBuiltLocally(depPreprocessTarget.toString()); buildLog.assertTargetBuiltLocally(depCompileTarget.toString()); buildLog.assertTargetBuiltLocally(depArchiveTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(depTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(headerSymlinkTreeTarget.toString()); buildLog.assertTargetBuiltLocally(preprocessTarget.toString()); buildLog.assertTargetBuiltLocally(compileTarget.toString()); assertThat( buildLog.getLogEntry(binaryTarget).getSuccessType().get(), Matchers.not(Matchers.equalTo(BuildRuleSuccessType.MATCHING_RULE_KEY))); buildLog.assertTargetBuiltLocally(target.toString()); // Clear for new build. workspace.resetBuildLogFile(); // Update the source file. workspace.replaceFileContents(depSourceFull, "x + 5", "x + 6"); // Check that running a build again makes the source get recompiled and the binary // re-linked, but does not cause the header rules to re-run. workspace.runBuckCommand("build", target.toString()).assertSuccess(); buildLog = workspace.getBuildLog(); assertEquals( ImmutableSet.of( depHeaderSymlinkTreeTarget, depHeaderExportedSymlinkTreeTarget, depPreprocessTarget, depCompileTarget, depArchiveTarget, depTarget, compileTarget, binaryTarget, target), buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(depHeaderSymlinkTreeTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(depHeaderExportedSymlinkTreeTarget.toString()); buildLog.assertTargetBuiltLocally(depPreprocessTarget.toString()); buildLog.assertTargetBuiltLocally(depCompileTarget.toString()); buildLog.assertTargetBuiltLocally(depArchiveTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(depTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(compileTarget.toString()); buildLog.assertTargetBuiltLocally(binaryTarget.toString()); buildLog.assertTargetBuiltLocally(target.toString()); }
public void doTestSimpleCxxBinaryBuilds(String preprocessMode, boolean expectPreprocessorOutput) throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "simple", tmp); workspace.setUp(); workspace.writeContentsToPath( String.format("[cxx]\npreprocess_mode = %s\n", preprocessMode), ".buckconfig"); CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new CxxBuckConfig(new FakeBuckConfig())); BuildTarget target = BuildTargetFactory.newInstance("//foo:simple"); CxxSourceRuleFactory cxxSourceRuleFactory = CxxSourceRuleFactoryHelper.of(target, cxxPlatform); BuildTarget binaryTarget = CxxDescriptionEnhancer.createCxxLinkTarget(target); String sourceName = "simple.cpp"; String sourceFull = "foo/" + sourceName; BuildTarget preprocessTarget = cxxSourceRuleFactory.createPreprocessBuildTarget( sourceName, CxxSource.Type.CXX, CxxSourceRuleFactory.PicType.PDC); BuildTarget compileTarget = cxxSourceRuleFactory.createCompileBuildTarget(sourceName, CxxSourceRuleFactory.PicType.PDC); BuildTarget headerSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( target, cxxPlatform.getFlavor(), HeaderVisibility.PRIVATE); // Do a clean build, verify that it succeeds, and check that all expected targets built // successfully. workspace.runBuckCommand("build", target.toString()).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); ImmutableSet<BuildTarget> expectedTargets = ImmutableSet.<BuildTarget>builder() .addAll(ImmutableSet.of(headerSymlinkTreeTarget, compileTarget, binaryTarget, target)) .addAll( (expectPreprocessorOutput ? ImmutableSet.of(preprocessTarget) : ImmutableSet.<BuildTarget>of())) .build(); assertEquals(expectedTargets, buildLog.getAllTargets()); buildLog.assertTargetBuiltLocally(headerSymlinkTreeTarget.toString()); if (expectPreprocessorOutput) { buildLog.assertTargetBuiltLocally(preprocessTarget.toString()); } buildLog.assertTargetBuiltLocally(compileTarget.toString()); buildLog.assertTargetBuiltLocally(binaryTarget.toString()); buildLog.assertTargetBuiltLocally(target.toString()); // Clear for new build. workspace.resetBuildLogFile(); // Check that running a build again results in no builds since everything is up to // date. workspace.runBuckCommand("build", target.toString()).assertSuccess(); buildLog = workspace.getBuildLog(); assertEquals(ImmutableSet.of(target, binaryTarget), buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(binaryTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(target.toString()); // Clear for new build. workspace.resetBuildLogFile(); // Update the source file. workspace.replaceFileContents(sourceFull, "{}", "{ return 0; }"); // Check that running a build again makes the source get recompiled and the binary // re-linked, but does not cause the header rules to re-run. workspace.runBuckCommand("build", target.toString()).assertSuccess(); buildLog = workspace.getBuildLog(); assertEquals(expectedTargets, buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(headerSymlinkTreeTarget.toString()); if (expectPreprocessorOutput) { buildLog.assertTargetBuiltLocally(preprocessTarget.toString()); } buildLog.assertTargetBuiltLocally(compileTarget.toString()); assertThat( buildLog.getLogEntry(binaryTarget).getSuccessType().get(), Matchers.not(Matchers.equalTo(BuildRuleSuccessType.MATCHING_RULE_KEY))); buildLog.assertTargetBuiltLocally(target.toString()); // Clear for new build. workspace.resetBuildLogFile(); // Update the source file. workspace.replaceFileContents(sourceFull, "{ return 0; }", "won't compile"); // Check that running a build again makes the source get recompiled and the binary // re-linked, but does not cause the header rules to re-run. workspace.runBuckCommand("build", target.toString()).assertFailure(); buildLog = workspace.getBuildLog(); assertEquals(expectedTargets, buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(headerSymlinkTreeTarget.toString()); if (expectPreprocessorOutput) { buildLog.assertTargetBuiltLocally(preprocessTarget.toString()); } assertThat( buildLog.getLogEntry(binaryTarget).getStatus(), Matchers.equalTo(BuildRuleStatus.CANCELED)); assertThat( buildLog.getLogEntry(target).getStatus(), Matchers.equalTo(BuildRuleStatus.CANCELED)); }