Search in sources :

Example 6 with StringValue

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

the class MemoizingEvaluatorTest method checkNotComparableNotPruned.

private void checkNotComparableNotPruned(boolean hasEvent) throws Exception {
    initializeTester();
    SkyKey parent = GraphTester.toSkyKey("parent");
    SkyKey child = GraphTester.toSkyKey("child");
    NotComparableStringValue notComparableString = new NotComparableStringValue("not comparable");
    if (hasEvent) {
        tester.getOrCreate(child).setConstantValue(notComparableString).setWarning("shmoop");
    } else {
        tester.getOrCreate(child).setConstantValue(notComparableString);
    }
    final AtomicInteger parentEvaluated = new AtomicInteger();
    final String val = "some val";
    tester.getOrCreate(parent).addDependency(child).setComputedValue(new ValueComputer() {

        @Override
        public SkyValue compute(Map<SkyKey, SkyValue> deps, Environment env) throws InterruptedException {
            parentEvaluated.incrementAndGet();
            return new StringValue(val);
        }
    });
    assertStringValue(val, tester.evalAndGet(/*keepGoing=*/
    false, parent));
    assertThat(parentEvaluated.get()).isEqualTo(1);
    if (hasEvent) {
        assertContainsEvent(eventCollector, "shmoop");
    } else {
        assertEventCount(0, eventCollector);
    }
    tester.resetPlayedEvents();
    tester.getOrCreate(child, /*markAsModified=*/
    true);
    tester.invalidate();
    assertStringValue(val, tester.evalAndGet(/*keepGoing=*/
    false, parent));
    assertThat(parentEvaluated.get()).isEqualTo(2);
    if (hasEvent) {
        assertContainsEvent(eventCollector, "shmoop");
    } else {
        assertEventCount(0, eventCollector);
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NotComparableStringValue(com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue) Environment(com.google.devtools.build.skyframe.SkyFunction.Environment) NotComparableStringValue(com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue) StringValue(com.google.devtools.build.skyframe.GraphTester.StringValue) ValueComputer(com.google.devtools.build.skyframe.GraphTester.ValueComputer)

Example 7 with StringValue

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

the class MemoizingEvaluatorTest method cachedErrorCausesRestart.

/**
   * Tests that a race between a node being marked clean and another node requesting it is benign.
   * Here, we first evaluate errorKey, depending on invalidatedKey. Then we invalidate
   * invalidatedKey (without actually changing it) and evaluate errorKey and topKey together.
   * Through forced synchronization, we make sure that the following sequence of events happens:
   *
   * <ol>
   * <li>topKey requests errorKey;
   * <li>errorKey is marked clean;
   * <li>topKey finishes its first evaluation and registers its deps;
   * <li>topKey restarts, since it sees that its only dep, errorKey, is done;
   * <li>topKey sees the error thrown by errorKey and throws the error, shutting down the
   *     threadpool;
   * </ol>
   */
@Test
public void cachedErrorCausesRestart() throws Exception {
    // TrackingProgressReceiver does unnecessary examination of node values.
    initializeTester(new TrackingProgressReceiver() {

        @Override
        public void evaluated(SkyKey skyKey, Supplier<SkyValue> skyValueSupplier, EvaluationState state) {
            evaluated.add(skyKey);
        }
    });
    final SkyKey errorKey = GraphTester.toSkyKey("error");
    SkyKey invalidatedKey = GraphTester.toSkyKey("invalidated");
    final SkyKey topKey = GraphTester.toSkyKey("top");
    tester.getOrCreate(errorKey).addDependency(invalidatedKey).setHasError(true);
    tester.getOrCreate(invalidatedKey).setConstantValue(new StringValue("constant"));
    final CountDownLatch topSecondEval = new CountDownLatch(2);
    final CountDownLatch topRequestedError = new CountDownLatch(1);
    final CountDownLatch errorMarkedClean = new CountDownLatch(1);
    injectGraphListenerForTesting(new Listener() {

        @Override
        public void accept(SkyKey key, EventType type, Order order, Object context) {
            if (errorKey.equals(key) && type == EventType.MARK_CLEAN) {
                if (order == Order.BEFORE) {
                    TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(topRequestedError, "top didn't request");
                } else {
                    errorMarkedClean.countDown();
                    TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(topSecondEval, "top didn't restart");
                    // Make sure that the other thread notices the error and interrupts this thread.
                    try {
                        Thread.sleep(TestUtils.WAIT_TIMEOUT_MILLISECONDS);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    }, /*deterministic=*/
    false);
    EvaluationResult<StringValue> result = tester.eval(/*keepGoing=*/
    false, errorKey);
    assertThatEvaluationResult(result).hasError();
    assertThatEvaluationResult(result).hasErrorEntryForKeyThat(errorKey).hasExceptionThat().isNotNull();
    tester.getOrCreate(topKey).setBuilder(new SkyFunction() {

        @Nullable
        @Override
        public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException {
            topSecondEval.countDown();
            env.getValue(errorKey);
            topRequestedError.countDown();
            assertThat(env.valuesMissing()).isTrue();
            TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(errorMarkedClean, "error not marked clean");
            return null;
        }

        @Nullable
        @Override
        public String extractTag(SkyKey skyKey) {
            return null;
        }
    });
    tester.getOrCreate(invalidatedKey, /*markAsModified=*/
    true);
    tester.invalidate();
    EvaluationResult<StringValue> result2 = tester.eval(/*keepGoing=*/
    false, errorKey, topKey);
    assertThatEvaluationResult(result2).hasError();
    assertThatEvaluationResult(result2).hasErrorEntryForKeyThat(errorKey).hasExceptionThat().isNotNull();
    assertThatEvaluationResult(result2).hasErrorEntryForKeyThat(topKey).hasExceptionThat().isNotNull();
    assertThatEvaluationResult(result2).hasErrorEntryForKeyThat(topKey).rootCauseOfExceptionIs(errorKey);
}
Also used : Order(com.google.devtools.build.skyframe.NotifyingHelper.Order) Listener(com.google.devtools.build.skyframe.NotifyingHelper.Listener) EventType(com.google.devtools.build.skyframe.NotifyingHelper.EventType) CountDownLatch(java.util.concurrent.CountDownLatch) Environment(com.google.devtools.build.skyframe.SkyFunction.Environment) NotComparableStringValue(com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue) StringValue(com.google.devtools.build.skyframe.GraphTester.StringValue) Nullable(javax.annotation.Nullable) Test(org.junit.Test)

Example 8 with StringValue

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

the class MemoizingEvaluatorTest method failedDirtyBuildInBuilder.

@Test
public void failedDirtyBuildInBuilder() throws Exception {
    initializeTester();
    SkyKey leaf = GraphTester.toSkyKey("leaf");
    SkyKey secondError = GraphTester.toSkyKey("secondError");
    SkyKey top = GraphTester.toSkyKey("top");
    tester.getOrCreate(top).addDependency(leaf).addErrorDependency(secondError, new StringValue("recover")).setComputedValue(CONCATENATE);
    tester.set(secondError, new StringValue("secondError")).addDependency(leaf);
    tester.set(leaf, new StringValue("leafy"));
    StringValue topValue = (StringValue) tester.evalAndGet("top");
    assertEquals("leafysecondError", topValue.getValue());
    assertThat(tester.getDirtyKeys()).isEmpty();
    assertThat(tester.getDeletedKeys()).isEmpty();
    // Invalidate leaf.
    tester.getOrCreate(leaf, /*markAsModified=*/
    true);
    tester.set(leaf, new StringValue("crunchy"));
    tester.getOrCreate(secondError, /*markAsModified=*/
    true).setHasError(true);
    tester.getOrCreate(top, /*markAsModified=*/
    false).setHasError(true);
    tester.invalidate();
    EvaluationResult<StringValue> result = tester.eval(/*keepGoing=*/
    false, top);
    assertNull("value should not have completed evaluation", result.get(top));
    assertWithMessage("The error thrown by leaf should have been swallowed by the error thrown by top").that(result.getError().getRootCauses()).containsExactly(top);
}
Also used : NotComparableStringValue(com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue) StringValue(com.google.devtools.build.skyframe.GraphTester.StringValue) Test(org.junit.Test)

Example 9 with StringValue

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

the class MemoizingEvaluatorTest method twoRailLeftRightDependenciesWithFailure.

/**
   * General stress/fuzz test of the evaluator with failure. Construct a large graph, and then throw
   * exceptions during building at various points.
   */
@Test
public void twoRailLeftRightDependenciesWithFailure() throws Exception {
    initializeTester();
    SkyKey[] leftValues = new SkyKey[TEST_NODE_COUNT];
    SkyKey[] rightValues = new SkyKey[TEST_NODE_COUNT];
    for (int i = 0; i < TEST_NODE_COUNT; i++) {
        leftValues[i] = GraphTester.toSkyKey("left-" + i);
        rightValues[i] = GraphTester.toSkyKey("right-" + i);
        if (i == 0) {
            tester.getOrCreate(leftValues[i]).addDependency("leaf").setComputedValue(COPY);
            tester.getOrCreate(rightValues[i]).addDependency("leaf").setComputedValue(COPY);
        } else {
            tester.getOrCreate(leftValues[i]).addDependency(leftValues[i - 1]).addDependency(rightValues[i - 1]).setComputedValue(new PassThroughSelected(leftValues[i - 1]));
            tester.getOrCreate(rightValues[i]).addDependency(leftValues[i - 1]).addDependency(rightValues[i - 1]).setComputedValue(new PassThroughSelected(rightValues[i - 1]));
        }
    }
    tester.set("leaf", new StringValue("leaf"));
    String lastLeft = "left-" + (TEST_NODE_COUNT - 1);
    String lastRight = "right-" + (TEST_NODE_COUNT - 1);
    for (int i = 0; i < TESTED_NODES; i++) {
        try {
            tester.getOrCreate(leftValues[i], /*markAsModified=*/
            true).setHasError(true);
            tester.invalidate();
            EvaluationResult<StringValue> result = tester.eval(/*keep_going=*/
            false, lastLeft, lastRight);
            assertTrue(result.hasError());
            tester.differencer.invalidate(ImmutableList.of(leftValues[i]));
            tester.invalidate();
            result = tester.eval(/*keep_going=*/
            false, lastLeft, lastRight);
            assertTrue(result.hasError());
            tester.getOrCreate(leftValues[i], /*markAsModified=*/
            true).setHasError(false);
            tester.invalidate();
            result = tester.eval(/*keep_going=*/
            false, lastLeft, lastRight);
            assertEquals(new StringValue("leaf"), result.get(toSkyKey(lastLeft)));
            assertEquals(new StringValue("leaf"), result.get(toSkyKey(lastRight)));
        } catch (Exception e) {
            System.err.println("twoRailLeftRightDependenciesWithFailure exception on run " + i);
            throw e;
        }
    }
}
Also used : NotComparableStringValue(com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue) StringValue(com.google.devtools.build.skyframe.GraphTester.StringValue) Test(org.junit.Test)

Example 10 with StringValue

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

the class MemoizingEvaluatorTest method nodeInvalidatedThenDoubleCycle.

@Test
public void nodeInvalidatedThenDoubleCycle() throws InterruptedException {
    makeGraphDeterministic();
    // When topKey depends on depKey, and both are top-level nodes in the graph,
    final SkyKey topKey = skyKey("bKey");
    final SkyKey depKey = skyKey("aKey");
    tester.getOrCreate(topKey).addDependency(depKey).setConstantValue(new StringValue("a"));
    tester.getOrCreate(depKey).setConstantValue(new StringValue("b"));
    // Then evaluation is as expected.
    EvaluationResult<StringValue> result1 = tester.eval(/*keepGoing=*/
    true, topKey, depKey);
    assertThatEvaluationResult(result1).hasEntryThat(topKey).isEqualTo(new StringValue("a"));
    assertThatEvaluationResult(result1).hasEntryThat(depKey).isEqualTo(new StringValue("b"));
    assertThatEvaluationResult(result1).hasNoError();
    // When both nodes acquire self-edges, with topKey still also depending on depKey, in the same
    // group,
    tester.getOrCreate(depKey, /*markAsModified=*/
    true).addDependency(depKey);
    tester.getOrCreate(topKey, /*markAsModified=*/
    true).setConstantValue(null).removeDependency(depKey).setBuilder(new SkyFunction() {

        @Nullable
        @Override
        public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException {
            env.getValues(ImmutableList.of(topKey, depKey));
            assertThat(env.valuesMissing()).isTrue();
            return null;
        }

        @Nullable
        @Override
        public String extractTag(SkyKey skyKey) {
            return null;
        }
    });
    tester.invalidate();
    // Then evaluation is as expected -- topKey has removed its dep on depKey (since depKey was not
    // done when topKey found its cycle), and both topKey and depKey have cycles.
    EvaluationResult<StringValue> result2 = tester.eval(/*keepGoing=*/
    true, topKey, depKey);
    if (cyclesDetected()) {
        assertThatEvaluationResult(result2).hasErrorEntryForKeyThat(topKey).hasCycleInfoThat().containsExactly(new CycleInfo(ImmutableList.of(topKey)));
        assertThatEvaluationResult(result2).hasDirectDepsInGraphThat(topKey).containsExactly(topKey);
        assertThatEvaluationResult(result2).hasErrorEntryForKeyThat(depKey).hasCycleInfoThat().containsExactly(new CycleInfo(ImmutableList.of(depKey)));
    } else {
        assertThatEvaluationResult(result2).hasErrorEntryForKeyThat(topKey).hasCycleInfoThat().hasSize(1);
        assertThatEvaluationResult(result2).hasErrorEntryForKeyThat(depKey).hasCycleInfoThat().hasSize(1);
    }
    // When the nodes return to their original, error-free state,
    tester.getOrCreate(topKey, /*markAsModified=*/
    true).setBuilder(null).addDependency(depKey).setConstantValue(new StringValue("a"));
    tester.getOrCreate(depKey, /*markAsModified=*/
    true).removeDependency(depKey);
    tester.invalidate();
    // Then evaluation is as expected.
    EvaluationResult<StringValue> result3 = tester.eval(/*keepGoing=*/
    true, topKey, depKey);
    assertThatEvaluationResult(result3).hasEntryThat(topKey).isEqualTo(new StringValue("a"));
    assertThatEvaluationResult(result3).hasEntryThat(depKey).isEqualTo(new StringValue("b"));
    assertThatEvaluationResult(result3).hasNoError();
}
Also used : Environment(com.google.devtools.build.skyframe.SkyFunction.Environment) NotComparableStringValue(com.google.devtools.build.skyframe.GraphTester.NotComparableStringValue) StringValue(com.google.devtools.build.skyframe.GraphTester.StringValue) Nullable(javax.annotation.Nullable) 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