diff options
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/analysis/TargetCompleteEvent.java | 16 | ||||
-rwxr-xr-x | src/test/shell/integration/build_event_stream_test.sh | 20 |
2 files changed, 34 insertions, 2 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TargetCompleteEvent.java b/src/main/java/com/google/devtools/build/lib/analysis/TargetCompleteEvent.java index 453127c9f7..e2ebbb8624 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/TargetCompleteEvent.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/TargetCompleteEvent.java @@ -16,9 +16,9 @@ package com.google.devtools.build.lib.analysis; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; -import com.google.devtools.build.lib.buildeventstream.BuildEvent; import com.google.devtools.build.lib.buildeventstream.BuildEventId; import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos; +import com.google.devtools.build.lib.buildeventstream.BuildEventWithOrderConstraint; import com.google.devtools.build.lib.buildeventstream.GenericBuildEvent; import com.google.devtools.build.lib.causes.Cause; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -30,15 +30,22 @@ import com.google.devtools.build.skyframe.SkyValue; import java.util.Collection; /** This event is fired as soon as a target is either built or fails. */ -public final class TargetCompleteEvent implements SkyValue, BuildEvent { +public final class TargetCompleteEvent implements SkyValue, BuildEventWithOrderConstraint { private final ConfiguredTarget target; private final NestedSet<Cause> rootCauses; + private final Collection<BuildEventId> postedAfter; private TargetCompleteEvent(ConfiguredTarget target, NestedSet<Cause> rootCauses) { this.target = target; this.rootCauses = (rootCauses == null) ? NestedSetBuilder.<Cause>emptySet(Order.STABLE_ORDER) : rootCauses; + + ImmutableList.Builder postedAfterBuilder = ImmutableList.builder(); + for (Cause cause : getRootCauses()) { + postedAfterBuilder.add(BuildEventId.fromCause(cause)); + } + this.postedAfter = postedAfterBuilder.build(); } /** @@ -98,4 +105,9 @@ public final class TargetCompleteEvent implements SkyValue, BuildEvent { BuildEventStreamProtos.TargetComplete.newBuilder().setSuccess(!failed()).build(); return GenericBuildEvent.protoChaining(this).setCompleted(complete).build(); } + + @Override + public Collection<BuildEventId> postedAfter() { + return postedAfter; + } } diff --git a/src/test/shell/integration/build_event_stream_test.sh b/src/test/shell/integration/build_event_stream_test.sh index 7a420c7604..9d16b69f3e 100755 --- a/src/test/shell/integration/build_event_stream_test.sh +++ b/src/test/shell/integration/build_event_stream_test.sh @@ -41,6 +41,11 @@ test_suite( name = "suite", tests = ["true"], ) +genrule( + name = "fails_to_build", + outs = ["fails_to_build.txt"], + cmd = "false", +) EOF } @@ -87,4 +92,19 @@ function test_multiple_transports() { [ -f ${outdir}/test_multiple_transports.bin ] || fail "Missing expected file test_multiple_transports.bin" } +function test_root_cause_early() { + (bazel build --experimental_build_event_text_file=$TEST_log \ + pkg:fails_to_build && fail "bazel test failed") || true + # We expect precisely one action being reported (the failed one) and + # precisely on report on a completed target; moreover, the action has + # to be reported first. + expect_log_once '^action' + expect_log_once '^completed' + expect_not_log 'success' + local naction=`grep -n '^action' $TEST_log | cut -f 1 -d :` + local ncomplete=`grep -n '^completed' $TEST_log | cut -f 1 -d :` + [ $naction -lt $ncomplete ] \ + || fail "failed action not before compelted target" +} + run_suite "Integration tests for the build event stream" |