use of com.google.devtools.build.skyframe.GraphTester.StringValue in project bazel by bazelbuild.
the class MemoizingEvaluatorTest method dirtyThenDeleted.
@Test
public void dirtyThenDeleted() throws Exception {
initializeTester();
SkyKey topKey = GraphTester.skyKey("top");
SkyKey leafKey = GraphTester.skyKey("leaf");
tester.getOrCreate(topKey).addDependency(leafKey).setComputedValue(CONCATENATE);
tester.set(leafKey, new StringValue("leafy"));
assertThat(tester.evalAndGet(/*keepGoing=*/
false, topKey)).isEqualTo(new StringValue("leafy"));
tester.getOrCreate(topKey, /*markAsModified=*/
true);
tester.invalidate();
assertThat(tester.evalAndGet(/*keepGoing=*/
false, leafKey)).isEqualTo(new StringValue("leafy"));
tester.delete("top");
tester.getOrCreate(leafKey, /*markAsModified=*/
true);
tester.invalidate();
assertThat(tester.evalAndGet(/*keepGoing=*/
false, leafKey)).isEqualTo(new StringValue("leafy"));
}
use of com.google.devtools.build.skyframe.GraphTester.StringValue in project bazel by bazelbuild.
the class MemoizingEvaluatorTest method deleteInvalidatedValue.
@Test
public void deleteInvalidatedValue() throws Exception {
initializeTester();
SkyKey top = GraphTester.toSkyKey("top");
SkyKey toDelete = GraphTester.toSkyKey("toDelete");
// Must be a concatenation -- COPY doesn't actually copy.
tester.getOrCreate(top).addDependency(toDelete).setComputedValue(CONCATENATE);
tester.set(toDelete, new StringValue("toDelete"));
SkyValue value = tester.evalAndGet("top");
SkyKey forceInvalidation = GraphTester.toSkyKey("forceInvalidation");
tester.set(forceInvalidation, new StringValue("forceInvalidation"));
tester.getOrCreate(toDelete, /*markAsModified=*/
true);
tester.invalidate();
tester.eval(/*keepGoing=*/
false, forceInvalidation);
tester.delete("toDelete");
WeakReference<SkyValue> ref = new WeakReference<>(value);
value = null;
tester.eval(/*keepGoing=*/
false, forceInvalidation);
// So that invalidation receiver doesn't hang on to reference.
tester.invalidate();
GcFinalization.awaitClear(ref);
}
use of com.google.devtools.build.skyframe.GraphTester.StringValue in project bazel by bazelbuild.
the class MemoizingEvaluatorTest method dirtyAndChangedValueIsChanged.
/**
* Test whether a value that was already marked changed will be incorrectly marked dirty, not
* changed, if another thread tries to mark it just dirty. To exercise this, we need to have a
* race condition where both threads see that the value is not dirty yet, then the "changed"
* thread marks the value changed before the "dirty" thread marks the value dirty. To accomplish
* this, we use a countdown latch to make the "dirty" thread wait until the "changed" thread is
* done, and another countdown latch to make both of them wait until they have both checked if the
* value is currently clean.
*/
@Test
public void dirtyAndChangedValueIsChanged() throws Exception {
final SkyKey parent = GraphTester.toSkyKey("parent");
final AtomicBoolean blockingEnabled = new AtomicBoolean(false);
final CountDownLatch waitForChanged = new CountDownLatch(1);
// changed thread checks value entry once (to see if it is changed). dirty thread checks twice,
// to see if it is changed, and if it is dirty.
final CountDownLatch threadsStarted = new CountDownLatch(3);
injectGraphListenerForTesting(new Listener() {
@Override
public void accept(SkyKey key, EventType type, Order order, Object context) {
if (!blockingEnabled.get()) {
return;
}
if (!key.equals(parent)) {
return;
}
if (type == EventType.IS_CHANGED && order == Order.BEFORE) {
threadsStarted.countDown();
}
// Dirtiness only checked by dirty thread.
if (type == EventType.IS_DIRTY && order == Order.BEFORE) {
threadsStarted.countDown();
}
if (type == EventType.MARK_DIRTY) {
TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(threadsStarted, "Both threads did not query if value isChanged in time");
boolean isChanged = (Boolean) context;
if (order == Order.BEFORE && !isChanged) {
TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(waitForChanged, "'changed' thread did not mark value changed in time");
return;
}
if (order == Order.AFTER && isChanged) {
waitForChanged.countDown();
}
}
}
}, /*deterministic=*/
false);
SkyKey leaf = GraphTester.toSkyKey("leaf");
tester.set(leaf, new StringValue("leaf"));
tester.getOrCreate(parent).addDependency(leaf).setComputedValue(CONCATENATE);
EvaluationResult<StringValue> result;
result = tester.eval(/*keepGoing=*/
false, parent);
assertEquals("leaf", result.get(parent).getValue());
// Invalidate leaf, but don't actually change it. It will transitively dirty parent
// concurrently with parent directly dirtying itself.
tester.getOrCreate(leaf, /*markAsModified=*/
true);
SkyKey other2 = GraphTester.toSkyKey("other2");
tester.set(other2, new StringValue("other2"));
// Invalidate parent, actually changing it.
tester.getOrCreate(parent, /*markAsModified=*/
true).addDependency(other2);
tester.invalidate();
blockingEnabled.set(true);
result = tester.eval(/*keepGoing=*/
false, parent);
assertEquals("leafother2", result.get(parent).getValue());
assertEquals(0, waitForChanged.getCount());
assertEquals(0, threadsStarted.getCount());
}
use of com.google.devtools.build.skyframe.GraphTester.StringValue in project bazel by bazelbuild.
the class MemoizingEvaluatorTest method incrementalSimpleDependency.
@Test
public void incrementalSimpleDependency() throws Exception {
tester.getOrCreate("ab").addDependency("a").setComputedValue(COPY);
tester.set("a", new StringValue("me"));
tester.evalAndGet("ab");
tester.set("a", new StringValue("other"));
tester.invalidate();
StringValue value = (StringValue) tester.evalAndGet("ab");
assertEquals("other", value.getValue());
}
use of com.google.devtools.build.skyframe.GraphTester.StringValue in project bazel by bazelbuild.
the class MemoizingEvaluatorTest method dirtyDepIgnoresChildren.
@Test
public void dirtyDepIgnoresChildren() throws Exception {
initializeTester();
SkyKey leaf = GraphTester.toSkyKey("leaf");
SkyKey mid = GraphTester.toSkyKey("mid");
SkyKey top = GraphTester.toSkyKey("top");
tester.set(mid, new StringValue("ignore"));
tester.getOrCreate(top).addDependency(mid).setComputedValue(COPY);
tester.getOrCreate(mid).addDependency(leaf);
tester.set(leaf, new StringValue("leafy"));
StringValue topValue = (StringValue) tester.evalAndGet("top");
assertEquals("ignore", topValue.getValue());
assertThat(tester.getDirtyKeys()).isEmpty();
assertThat(tester.getDeletedKeys()).isEmpty();
// Change leaf.
tester.set(leaf, new StringValue("crunchy"));
tester.invalidate();
topValue = (StringValue) tester.evalAndGet("top");
assertEquals("ignore", topValue.getValue());
assertThat(tester.getDirtyKeys()).containsExactly(leaf);
assertThat(tester.getDeletedKeys()).isEmpty();
tester.set(leaf, new StringValue("smushy"));
tester.invalidate();
topValue = (StringValue) tester.evalAndGet("top");
assertEquals("ignore", topValue.getValue());
assertThat(tester.getDirtyKeys()).containsExactly(leaf);
assertThat(tester.getDeletedKeys()).isEmpty();
}
Aggregations