Skip to content

Commit 6eb7dbb

Browse files
c-mitacopybara-github
authored andcommitted
Generate combined coverage artifacts after exclusive tests have run.
The combined coverage report requires tests to be executed in order to be built. If it is requested as part of the build then those tests will be executed. This fixes SkyframeBuilder and SkyframeBuildView to trigger generation of the combined report (or all coverage artifacts in the case of the latter) only after all exclusive tests have been run. Fixes #6005 PiperOrigin-RevId: 550869458 Change-Id: I67d28184e59618a756b0114bf77996e3e9c26ffb
1 parent 73cef14 commit 6eb7dbb

4 files changed

Lines changed: 74 additions & 24 deletions

File tree

src/main/java/com/google/devtools/build/lib/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ java_library(
403403
"//src/main/java/com/google/devtools/build/lib/skyframe:configuration_phase_started_event",
404404
"//src/main/java/com/google/devtools/build/lib/skyframe:configured_target_key",
405405
"//src/main/java/com/google/devtools/build/lib/skyframe:configured_target_progress_receiver",
406+
"//src/main/java/com/google/devtools/build/lib/skyframe:coverage_report_value",
406407
"//src/main/java/com/google/devtools/build/lib/skyframe:default_syscall_cache",
407408
"//src/main/java/com/google/devtools/build/lib/skyframe:diff_awareness",
408409
"//src/main/java/com/google/devtools/build/lib/skyframe:execution_finished_event",

src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
// limitations under the License.
1414
package com.google.devtools.build.lib.buildtool;
1515

16+
import static com.google.common.collect.ImmutableSet.toImmutableSet;
17+
import static com.google.devtools.build.lib.skyframe.CoverageReportValue.COVERAGE_REPORT_KEY;
18+
1619
import com.google.common.annotations.VisibleForTesting;
1720
import com.google.common.base.Preconditions;
1821
import com.google.common.collect.ImmutableSet;
@@ -142,6 +145,14 @@ public void buildArtifacts(
142145
executionProgressReceiver, statusReporter);
143146
watchdog.start();
144147

148+
// We need to extract out artifacts for the combined coverage report; these should only be built
149+
// after any exclusive tests have been run, otherwise the tests get run as part of the build.
150+
ImmutableSet<Artifact> coverageReportArtifacts =
151+
artifacts.stream()
152+
.filter(artifact -> artifact.getArtifactOwner().equals(COVERAGE_REPORT_KEY))
153+
.collect(toImmutableSet());
154+
Set<Artifact> artifactsToBuild = Sets.difference(artifacts, coverageReportArtifacts);
155+
145156
targetsToBuild = Sets.difference(targetsToBuild, targetsToSkip);
146157
parallelTests = Sets.difference(parallelTests, targetsToSkip);
147158
exclusiveTests = Sets.difference(exclusiveTests, targetsToSkip);
@@ -152,7 +163,7 @@ public void buildArtifacts(
152163
reporter,
153164
resourceManager,
154165
executor,
155-
artifacts,
166+
artifactsToBuild,
156167
targetsToBuild,
157168
aspects,
158169
parallelTests,
@@ -206,6 +217,26 @@ public void buildArtifacts(
206217
detailedExitCodes.add(detailedExitCode);
207218
}
208219
}
220+
// Build coverage report
221+
if (!coverageReportArtifacts.isEmpty()) {
222+
result =
223+
skyframeExecutor.evaluateSkyKeysWithExecution(
224+
reporter,
225+
executor,
226+
Artifact.keys(coverageReportArtifacts),
227+
options,
228+
actionCacheChecker);
229+
detailedExitCode =
230+
SkyframeErrorProcessor.processResult(
231+
reporter,
232+
result,
233+
options.getOptions(KeepGoingOption.class).keepGoing,
234+
skyframeExecutor.getCyclesReporter(),
235+
bugReporter);
236+
if (detailedExitCode != null) {
237+
detailedExitCodes.add(detailedExitCode);
238+
}
239+
}
209240
} finally {
210241
watchdog.stop();
211242
skyframeExecutor.setActionExecutionProgressReportingObjects(null, null, null);

src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -668,27 +668,6 @@ public SkyframeAnalysisResult analyzeAndExecuteTargets(
668668
skyframeExecutor.resetBuildDriverFunction();
669669
skyframeExecutor.setTestTypeResolver(null);
670670

671-
// Coverage needs to be done after the list of analyzed targets/tests is known.
672-
ImmutableSet<Artifact> coverageArtifacts =
673-
coverageReportActionsWrapperSupplier.getCoverageArtifacts(
674-
buildResultListener.getAnalyzedTargets(), buildResultListener.getAnalyzedTests());
675-
eventBus.post(CoverageArtifactsKnownEvent.create(coverageArtifacts));
676-
additionalArtifactsResult =
677-
skyframeExecutor.evaluateSkyKeys(
678-
eventHandler, Artifact.keys(coverageArtifacts), keepGoing);
679-
eventBus.post(new CoverageActionFinishedEvent());
680-
if (additionalArtifactsResult.hasError()) {
681-
detailedExitCodes.add(
682-
SkyframeErrorProcessor.processErrors(
683-
additionalArtifactsResult,
684-
skyframeExecutor.getCyclesReporter(),
685-
eventHandler,
686-
keepGoing,
687-
eventBus,
688-
bugReporter,
689-
/* includeExecutionPhase= */ true)
690-
.executionDetailedExitCode());
691-
}
692671
// These attributes affect whether conflict checking will be done during the next build.
693672
if (shouldCheckForConflicts(checkForActionConflicts, newKeys)) {
694673
largestTopLevelKeySetCheckedForConflicts = newKeys;
@@ -698,8 +677,7 @@ public SkyframeAnalysisResult analyzeAndExecuteTargets(
698677

699678
// The exclusive tests whose analysis succeeded i.e. those that can be run.
700679
ImmutableSet<ConfiguredTarget> exclusiveTestsToRun = getExclusiveTests(evaluationResult);
701-
boolean continueWithExclusiveTests =
702-
(!evaluationResult.hasError() && !additionalArtifactsResult.hasError()) || keepGoing;
680+
boolean continueWithExclusiveTests = !evaluationResult.hasError() || keepGoing;
703681

704682
if (continueWithExclusiveTests && !exclusiveTestsToRun.isEmpty()) {
705683
skyframeExecutor.getIsBuildingExclusiveArtifacts().set(true);
@@ -729,6 +707,29 @@ public SkyframeAnalysisResult analyzeAndExecuteTargets(
729707
}
730708
}
731709
}
710+
// Coverage report generation should only be requested after all tests have executed.
711+
// We could generate baseline coverage artifacts earlier; it is only the timing of the
712+
// combined report that matters.
713+
ImmutableSet<Artifact> coverageArtifacts =
714+
coverageReportActionsWrapperSupplier.getCoverageArtifacts(
715+
buildResultListener.getAnalyzedTargets(), buildResultListener.getAnalyzedTests());
716+
eventBus.post(CoverageArtifactsKnownEvent.create(coverageArtifacts));
717+
additionalArtifactsResult =
718+
skyframeExecutor.evaluateSkyKeys(
719+
eventHandler, Artifact.keys(coverageArtifacts), keepGoing);
720+
eventBus.post(new CoverageActionFinishedEvent());
721+
if (additionalArtifactsResult.hasError()) {
722+
detailedExitCodes.add(
723+
SkyframeErrorProcessor.processErrors(
724+
additionalArtifactsResult,
725+
skyframeExecutor.getCyclesReporter(),
726+
eventHandler,
727+
keepGoing,
728+
eventBus,
729+
bugReporter,
730+
/* includeExecutionPhase= */ true)
731+
.executionDetailedExitCode());
732+
}
732733
} finally {
733734
// No more action execution beyond this point.
734735
skyframeExecutor.clearExecutionStatesSkymeld(eventHandler);

src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,6 +1828,23 @@ private EvaluationResult<SkyValue> evaluateSkyKeys(
18281828
return evaluateSkyKeys(eventHandler, skyKeys, false);
18291829
}
18301830

1831+
/** Evaluates sky keys that require action execution and returns their evaluation results. */
1832+
public EvaluationResult<SkyValue> evaluateSkyKeysWithExecution(
1833+
final Reporter reporter,
1834+
final Executor executor,
1835+
final Iterable<? extends SkyKey> skyKeys,
1836+
final OptionsProvider options,
1837+
final ActionCacheChecker actionCacheChecker) {
1838+
1839+
prepareSkyframeActionExecutorForExecution(reporter, executor, options, actionCacheChecker);
1840+
try {
1841+
return evaluateSkyKeys(
1842+
reporter, skyKeys, options.getOptions(KeepGoingOption.class).keepGoing);
1843+
} finally {
1844+
cleanUpAfterSingleEvaluationWithActionExecution(reporter);
1845+
}
1846+
}
1847+
18311848
/**
18321849
* Evaluates the given sky keys, blocks, and returns their evaluation results. Enables/disables
18331850
* "keep going" on evaluation errors as specified.

0 commit comments

Comments
 (0)