Search in sources :

Example 36 with StringValue

use of com.google.devtools.build.skyframe.GraphTester.StringValue in project bazel by bazelbuild.

the class MemoizingEvaluatorTest method removedNodeComesBackAndInvalidates.

// Tests that a removed and then reinstated node doesn't try to invalidate its erstwhile parent
// when it is invalidated.
@Test
public void removedNodeComesBackAndInvalidates() throws Exception {
    removedNodeComesBack();
    // When leaf is invalidated again,
    tester.getOrCreate(GraphTester.skyKey("leaf"), /*markAsModified=*/
    true);
    // Then when top is evaluated, its value is as expected.
    tester.invalidate();
    assertThat(tester.evalAndGet(/*keepGoing=*/
    true, "top")).isEqualTo(new StringValue("leaf"));
}
Also used : NotComparableStringValue(com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue) StringValue(com.google.devtools.build.skyframe.GraphTester.StringValue) Test(org.junit.Test)

Example 37 with StringValue

use of com.google.devtools.build.skyframe.GraphTester.StringValue in project bazel by bazelbuild.

the class MemoizingEvaluatorTest method removedInvalidatedNodeComesBackAndOtherInvalidates.

// Tests that a removed and then reinstated node doesn't have a reverse dep on a former parent.
@Test
public void removedInvalidatedNodeComesBackAndOtherInvalidates() throws Exception {
    SkyKey top = GraphTester.skyKey("top");
    SkyKey leaf = GraphTester.skyKey("leaf");
    // When top depends on leaf,
    tester.getOrCreate(top).addDependency(leaf).setComputedValue(CONCATENATE);
    StringValue leafValue = new StringValue("leaf");
    tester.set(leaf, leafValue);
    // Then when top is evaluated, its value is as expected.
    assertThat(tester.evalAndGet(/*keepGoing=*/
    true, top)).isEqualTo(leafValue);
    // When top is changed to no longer depend on leaf,
    StringValue topValue = new StringValue("top");
    tester.getOrCreate(top, /*markAsModified=*/
    true).removeDependency(leaf).setComputedValue(null).setConstantValue(topValue);
    // And leaf is invalidated,
    tester.getOrCreate(leaf, /*markAsModified=*/
    true);
    // Then when top is evaluated, its value is as expected,
    tester.invalidate();
    assertThat(tester.evalAndGet(/*keepGoing=*/
    true, top)).isEqualTo(topValue);
    // And there is no value for leaf in the graph.
    assertThat(tester.driver.getExistingValueForTesting(leaf)).isNull();
    assertThat(tester.driver.getExistingErrorForTesting(leaf)).isNull();
    // When leaf is evaluated, so that it is present in the graph again,
    assertThat(tester.evalAndGet(/*keepGoing=*/
    true, leaf)).isEqualTo(leafValue);
    // And top is changed to depend on leaf again,
    tester.getOrCreate(top, /*markAsModified=*/
    true).addDependency(leaf).setConstantValue(null).setComputedValue(CONCATENATE);
    // Then when top is evaluated, its value is as expected.
    tester.invalidate();
    assertThat(tester.evalAndGet(/*keepGoing=*/
    true, top)).isEqualTo(leafValue);
}
Also used : NotComparableStringValue(com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue) StringValue(com.google.devtools.build.skyframe.GraphTester.StringValue) Test(org.junit.Test)

Example 38 with StringValue

use of com.google.devtools.build.skyframe.GraphTester.StringValue in project bazel by bazelbuild.

the class EagerInvalidatorTest method interruptChild.

@Test
public void interruptChild() throws Exception {
    graph = new InMemoryGraphImpl();
    // More values than the invalidator has threads.
    int numValues = 50;
    final SkyKey[] family = new SkyKey[numValues];
    final SkyKey child = GraphTester.skyKey("child");
    final StringValue childValue = new StringValue("child");
    tester.set(child, childValue);
    family[0] = child;
    for (int i = 1; i < numValues; i++) {
        SkyKey member = skyKey(Integer.toString(i));
        tester.getOrCreate(member).addDependency(family[i - 1]).setComputedValue(CONCATENATE);
        family[i] = member;
    }
    SkyKey parent = GraphTester.skyKey("parent");
    tester.getOrCreate(parent).addDependency(family[numValues - 1]).setComputedValue(CONCATENATE);
    eval(/*keepGoing=*/
    false, parent);
    final Thread mainThread = Thread.currentThread();
    final AtomicReference<SkyKey> badKey = new AtomicReference<>();
    DirtyTrackingProgressReceiver receiver = new DirtyTrackingProgressReceiver(new EvaluationProgressReceiver() {

        @Override
        public void invalidated(SkyKey skyKey, InvalidationState state) {
            if (skyKey.equals(child)) {
                // Interrupt on the very first invalidate
                mainThread.interrupt();
            } else if (!skyKey.functionName().equals(NODE_TYPE)) {
                // All other invalidations should have the GraphTester's key type.
                // Exceptions thrown here may be silently dropped, so keep track of errors ourselves.
                badKey.set(skyKey);
            }
            try {
                assertTrue(visitor.get().getInterruptionLatchForTestingOnly().await(2, TimeUnit.HOURS));
            } catch (InterruptedException e) {
            // We may well have thrown here because by the time we try to await, the main
            // thread is already interrupted.
            }
        }

        @Override
        public void enqueueing(SkyKey skyKey) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void computed(SkyKey skyKey, long elapsedTimeNanos) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void evaluated(SkyKey skyKey, Supplier<SkyValue> skyValueSupplier, EvaluationState state) {
            throw new UnsupportedOperationException();
        }
    });
    try {
        invalidateWithoutError(receiver, child);
        fail();
    } catch (InterruptedException e) {
    // Expected.
    }
    assertNull(badKey.get());
    assertFalse(state.isEmpty());
    final Set<SkyKey> invalidated = Sets.newConcurrentHashSet();
    assertFalse(isInvalidated(parent));
    assertNotNull(graph.get(null, Reason.OTHER, parent).getValue());
    receiver = new DirtyTrackingProgressReceiver(new EvaluationProgressReceiver() {

        @Override
        public void invalidated(SkyKey skyKey, InvalidationState state) {
            invalidated.add(skyKey);
        }

        @Override
        public void enqueueing(SkyKey skyKey) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void computed(SkyKey skyKey, long elapsedTimeNanos) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void evaluated(SkyKey skyKey, Supplier<SkyValue> skyValueSupplier, EvaluationState state) {
            throw new UnsupportedOperationException();
        }
    });
    invalidateWithoutError(receiver);
    assertTrue(invalidated.contains(parent));
    assertThat(state.getInvalidationsForTesting()).isEmpty();
    // Regression test coverage:
    // "all pending values are marked changed on interrupt".
    assertTrue(isInvalidated(child));
    assertChanged(child);
    for (int i = 1; i < numValues; i++) {
        assertDirtyAndNotChanged(family[i]);
    }
    assertDirtyAndNotChanged(parent);
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) DirtyingInvalidationState(com.google.devtools.build.skyframe.InvalidatingNodeVisitor.DirtyingInvalidationState) InvalidationState(com.google.devtools.build.skyframe.InvalidatingNodeVisitor.InvalidationState) Supplier(com.google.common.base.Supplier) StringValue(com.google.devtools.build.skyframe.GraphTester.StringValue) Test(org.junit.Test)

Example 39 with StringValue

use of com.google.devtools.build.skyframe.GraphTester.StringValue in project bazel by bazelbuild.

the class MemoizingEvaluatorTest method passThenFailToBuild.

/**
   * Regression test: tests that pass before other build actions fail yield crash in non -k builds.
   */
@Test
public void passThenFailToBuild() throws Exception {
    CountDownLatch blocker = new CountDownLatch(1);
    SkyKey successKey = GraphTester.toSkyKey("success");
    tester.getOrCreate(successKey).setBuilder(new ChainedFunction(/*notifyStart=*/
    null, /*waitToFinish=*/
    null, /*notifyFinish=*/
    blocker, /*waitForException=*/
    false, new StringValue("yippee"), /*deps=*/
    ImmutableList.<SkyKey>of()));
    SkyKey slowFailKey = GraphTester.toSkyKey("slow_then_fail");
    tester.getOrCreate(slowFailKey).setBuilder(new ChainedFunction(/*notifyStart=*/
    null, /*waitToFinish=*/
    blocker, /*notifyFinish=*/
    null, /*waitForException=*/
    false, /*value=*/
    null, /*deps=*/
    ImmutableList.<SkyKey>of()));
    EvaluationResult<StringValue> result = tester.eval(/*keepGoing=*/
    false, successKey, slowFailKey);
    assertThat(result.getError().getRootCauses()).containsExactly(slowFailKey);
    assertThat(result.values()).containsExactly(new StringValue("yippee"));
}
Also used : CountDownLatch(java.util.concurrent.CountDownLatch) NotComparableStringValue(com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue) StringValue(com.google.devtools.build.skyframe.GraphTester.StringValue) Test(org.junit.Test)

Example 40 with StringValue

use of com.google.devtools.build.skyframe.GraphTester.StringValue in project bazel by bazelbuild.

the class MemoizingEvaluatorTest method incompleteDirectDepsAreClearedBeforeInvalidation.

/**
   * Regression test: error on clearMaybeDirtyValue. We do an evaluation of topKey, which registers
   * dependencies on midKey and errorKey. midKey enqueues slowKey, and waits. errorKey throws an
   * error, which bubbles up to topKey. If topKey does not unregister its dependence on midKey, it
   * will have a dangling reference to midKey after unfinished values are cleaned from the graph.
   * Note that slowKey will wait until errorKey has thrown and the threadpool has caught the
   * exception before returning, so the Evaluator will already have stopped enqueuing new jobs, so
   * midKey is not evaluated.
   */
@Test
public void incompleteDirectDepsAreClearedBeforeInvalidation() throws Exception {
    initializeTester();
    CountDownLatch slowStart = new CountDownLatch(1);
    CountDownLatch errorFinish = new CountDownLatch(1);
    SkyKey errorKey = GraphTester.toSkyKey("error");
    tester.getOrCreate(errorKey).setBuilder(new ChainedFunction(/*notifyStart=*/
    null, /*waitToFinish=*/
    slowStart, /*notifyFinish=*/
    errorFinish, /*waitForException=*/
    false, /*value=*/
    null, /*deps=*/
    ImmutableList.<SkyKey>of()));
    SkyKey slowKey = GraphTester.toSkyKey("slow");
    tester.getOrCreate(slowKey).setBuilder(new ChainedFunction(/*notifyStart=*/
    slowStart, /*waitToFinish=*/
    errorFinish, /*notifyFinish=*/
    null, /*waitForException=*/
    true, new StringValue("slow"), /*deps=*/
    ImmutableList.<SkyKey>of()));
    SkyKey midKey = GraphTester.toSkyKey("mid");
    tester.getOrCreate(midKey).addDependency(slowKey).setComputedValue(COPY);
    SkyKey topKey = GraphTester.toSkyKey("top");
    tester.getOrCreate(topKey).addDependency(midKey).addDependency(errorKey).setComputedValue(CONCATENATE);
    // slowKey starts -> errorKey finishes, written to graph -> slowKey finishes & (Visitor aborts)
    // -> topKey builds.
    EvaluationResult<StringValue> result = tester.eval(/*keepGoing=*/
    false, topKey);
    assertThat(result.getError().getRootCauses()).containsExactly(errorKey);
    // Make sure midKey didn't finish building.
    assertEquals(null, tester.getExistingValue(midKey));
    // Give slowKey a nice ordinary builder.
    tester.getOrCreate(slowKey, /*markAsModified=*/
    false).setBuilder(null).setConstantValue(new StringValue("slow"));
    // Put midKey into the graph. It won't have a reverse dependence on topKey.
    tester.evalAndGet(/*keepGoing=*/
    false, midKey);
    tester.differencer.invalidate(ImmutableList.of(errorKey));
    // topKey should not access midKey as if it were already registered as a dependency.
    tester.eval(/*keepGoing=*/
    false, topKey);
}
Also used : CountDownLatch(java.util.concurrent.CountDownLatch) NotComparableStringValue(com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue) StringValue(com.google.devtools.build.skyframe.GraphTester.StringValue) Test(org.junit.Test)

Aggregations

StringValue (com.google.devtools.build.skyframe.GraphTester.StringValue)130 Test (org.junit.Test)114 NotComparableStringValue (com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue)97 CountDownLatch (java.util.concurrent.CountDownLatch)30 Environment (com.google.devtools.build.skyframe.SkyFunction.Environment)22 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)14 EventType (com.google.devtools.build.skyframe.NotifyingHelper.EventType)11 Listener (com.google.devtools.build.skyframe.NotifyingHelper.Listener)11 Order (com.google.devtools.build.skyframe.NotifyingHelper.Order)11 Nullable (javax.annotation.Nullable)10 ErrorInfoSubjectFactory.assertThatErrorInfo (com.google.devtools.build.skyframe.ErrorInfoSubjectFactory.assertThatErrorInfo)9 ArrayList (java.util.ArrayList)7 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)7 ImmutableMap (com.google.common.collect.ImmutableMap)6 Map (java.util.Map)6 TestThread (com.google.devtools.build.lib.testutil.TestThread)5 Supplier (com.google.common.base.Supplier)3 Event (com.google.devtools.build.lib.events.Event)3 MoreAsserts.assertContainsEvent (com.google.devtools.build.lib.testutil.MoreAsserts.assertContainsEvent)3 TestFunction (com.google.devtools.build.skyframe.GraphTester.TestFunction)3