aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test
diff options
context:
space:
mode:
authorGravatar janakr <janakr@google.com>2018-08-14 21:38:51 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-08-14 21:40:26 -0700
commit7574d84e61086b5835a2b2cc003ca72fcfcf4fe4 (patch)
treec1fdc7992d6ffe9168112e5474917b0cb854a7c7 /src/test
parent8dece49bed76b5f372ff5d3a3f25a32b2a9c1f52 (diff)
Filter out events from analysis when constructing execution-phase values in Skyframe.
This avoids some unnecessary iteration over already-emitted events that can show up in profiles, and allows us to store execution-phase values a bit more compactly, since we don't need to carry around wrapper objects and nested sets everywhere. This crucially depends on the fact that we can't build a target in the execution phase without first having analyzed it in a separate Skyframe call. Skyframe normally propagates all events/posts up the graph because it must be able to emit them if a user requests a node that only transitively depends on the node that emitted an event. However, because we do analysis in a separate Skyframe call, any warnings/posts associated with the analysis nodes will be emitted then, and we don't need to propagate them into execution. PiperOrigin-RevId: 208767078
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java69
-rwxr-xr-xsrc/test/shell/integration/execution_phase_tests.sh24
2 files changed, 93 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java b/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java
index 3fc2e27ff7..a2fa72ce7f 100644
--- a/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java
+++ b/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.fail;
import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -114,12 +115,14 @@ public class MemoizingEvaluatorTest {
Differencer differencer,
EvaluationProgressReceiver progressReceiver,
GraphInconsistencyReceiver graphInconsistencyReceiver,
+ EventFilter eventFilter,
boolean keepEdges) {
return new InMemoryMemoizingEvaluator(
functions,
differencer,
progressReceiver,
graphInconsistencyReceiver,
+ eventFilter,
emittedEventState,
true);
}
@@ -4057,6 +4060,62 @@ public class MemoizingEvaluatorTest {
assertThat(parentEvaluated.getCount()).isEqualTo(1);
}
+ @Test
+ public void depEventPredicate() throws Exception {
+ if (!eventsStored()) {
+ return;
+ }
+ SkyKey parent = GraphTester.toSkyKey("parent");
+ SkyKey excludedDep = GraphTester.toSkyKey("excludedDep");
+ SkyKey includedDep = GraphTester.toSkyKey("includedDep");
+ tester.setEventFilter(
+ new EventFilter() {
+ @Override
+ public boolean storeEventsAndPosts() {
+ return true;
+ }
+
+ @Override
+ public boolean apply(Event input) {
+ return true;
+ }
+
+ @Override
+ public Predicate<SkyKey> depEdgeFilterForEventsAndPosts(SkyKey primaryKey) {
+ if (primaryKey.equals(parent)) {
+ return includedDep::equals;
+ } else {
+ return Predicates.alwaysTrue();
+ }
+ }
+ });
+ tester.initialize(/*keepEdges=*/ true);
+ tester
+ .getOrCreate(parent)
+ .addDependency(excludedDep)
+ .addDependency(includedDep)
+ .setComputedValue(CONCATENATE);
+ tester
+ .getOrCreate(excludedDep)
+ .setWarning("excludedDep warning")
+ .setConstantValue(new StringValue("excludedDep"));
+ tester
+ .getOrCreate(includedDep)
+ .setWarning("includedDep warning")
+ .setConstantValue(new StringValue("includedDep"));
+ tester.eval(/*keepGoing=*/ false, includedDep, excludedDep);
+ assertThatEvents(eventCollector).containsExactly("excludedDep warning", "includedDep warning");
+ eventCollector.clear();
+ emittedEventState.clear();
+ tester.eval(/*keepGoing=*/ true, parent);
+ assertThatEvents(eventCollector).containsExactly("includedDep warning");
+ assertThat(
+ ValueWithMetadata.getEvents(
+ tester.driver.getEntryForTesting(parent).getValueMaybeWithMetadata()))
+ .containsExactly(
+ new TaggedEvents(null, ImmutableList.of(Event.warn("includedDep warning"))));
+ }
+
// Tests that we have a sane implementation of error transience.
@Test
public void errorTransienceBug() throws Exception {
@@ -5055,6 +5114,7 @@ public class MemoizingEvaluatorTest {
private TrackingProgressReceiver progressReceiver = new TrackingProgressReceiver();
private GraphInconsistencyReceiver graphInconsistencyReceiver =
GraphInconsistencyReceiver.THROWING;
+ private EventFilter eventFilter = InMemoryMemoizingEvaluator.DEFAULT_STORED_EVENT_FILTER;
public void initialize(boolean keepEdges) {
this.differencer = getRecordingDifferencer();
@@ -5064,6 +5124,7 @@ public class MemoizingEvaluatorTest {
differencer,
progressReceiver,
graphInconsistencyReceiver,
+ eventFilter,
keepEdges);
this.driver = getBuildDriver(evaluator);
}
@@ -5077,6 +5138,14 @@ public class MemoizingEvaluatorTest {
}
/**
+ * Sets the {@link #eventFilter}. {@link #initialize} must be called after this to have any
+ * effect.
+ */
+ public void setEventFilter(EventFilter eventFilter) {
+ this.eventFilter = eventFilter;
+ }
+
+ /**
* Sets the {@link #graphInconsistencyReceiver}. {@link #initialize} must be called after this
* to have any effect.
*/
diff --git a/src/test/shell/integration/execution_phase_tests.sh b/src/test/shell/integration/execution_phase_tests.sh
index 3f25c5df09..7266060b50 100755
--- a/src/test/shell/integration/execution_phase_tests.sh
+++ b/src/test/shell/integration/execution_phase_tests.sh
@@ -268,4 +268,28 @@ function test_jobs_default_auto() {
"--jobs was not set to auto by default"
}
+function test_analysis_warning_cached() {
+ mkdir -p "foo" "bar" || fail "Could not create directories"
+ cat > foo/BUILD <<'EOF' || fail "foo/BUILD"
+cc_library(
+ name = 'foo',
+ deprecation = 'foo warning',
+ srcs = ['foo.cc'],
+ visibility = ['//visibility:public']
+)
+EOF
+ cat > bar/BUILD <<'EOF' || fail "bar/BUILD"
+cc_library(name = 'bar', srcs = ['bar.cc'], deps = ['//foo:foo'])
+EOF
+ touch foo/foo.cc bar/bar.cc || fail "Couldn't touch"
+ bazel build --nobuild //bar:bar >& "$TEST_log" || fail "Expected success"
+ expect_log "WARNING: .*: foo warning"
+ bazel build //bar:bar >& "$TEST_log" || fail "Expected success"
+ expect_log "WARNING: .*: foo warning"
+ echo "// comment" >> bar/bar.cc || fail "Couldn't change contents"
+ bazel build //bar:bar >& "$TEST_log" || fail "Expected success"
+ expect_log "WARNING: .*: foo warning"
+}
+
+
run_suite "Integration tests of ${PRODUCT_NAME} using the execution phase."