aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodecTest.java73
-rw-r--r--src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetImplTest.java63
2 files changed, 110 insertions, 26 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodecTest.java b/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodecTest.java
index e9b1d647eb..9341084eec 100644
--- a/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodecTest.java
+++ b/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodecTest.java
@@ -17,18 +17,24 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetStore.InMemoryNestedSetStorageEndpoint;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetStore.NestedSetCache;
import com.google.devtools.build.lib.collect.nestedset.NestedSetStore.NestedSetStorageEndpoint;
import com.google.devtools.build.lib.skyframe.serialization.AutoRegistry;
import com.google.devtools.build.lib.skyframe.serialization.ObjectCodecs;
import com.google.devtools.build.lib.skyframe.serialization.SerializationConstants;
import com.google.devtools.build.lib.skyframe.serialization.SerializationResult;
import com.google.protobuf.ByteString;
+import java.nio.charset.Charset;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
/** Tests for {@link NestedSet} serialization. */
@@ -49,7 +55,7 @@ public class NestedSetCodecTest {
ObjectCodecs objectCodecs =
new ObjectCodecs(
AutoRegistry.get().getBuilder().setAllowDefaultCodec(true).build(), ImmutableMap.of());
- NestedSetCodecTestUtils.checkCodec(objectCodecs, false);
+ NestedSetCodecTestUtils.checkCodec(objectCodecs, false, false);
}
@Test
@@ -62,7 +68,7 @@ public class NestedSetCodecTest {
.add(new NestedSetCodecWithStore<>(NestedSetStore.inMemory()))
.build(),
ImmutableMap.of());
- NestedSetCodecTestUtils.checkCodec(objectCodecs, true);
+ NestedSetCodecTestUtils.checkCodec(objectCodecs, true, true);
}
/**
@@ -166,7 +172,68 @@ public class NestedSetCodecTest {
.setAllowDefaultCodec(true)
.add(new NestedSetCodecWithStore<>(mockNestedSetStore))
.build());
- NestedSet<String> singletonNestedSet = new NestedSet<>(Order.STABLE_ORDER, "a");
+ NestedSet<String> singletonNestedSet =
+ new NestedSetBuilder<String>(Order.STABLE_ORDER).add("a").build();
objectCodecs.serialize(singletonNestedSet);
}
+
+ @Test
+ public void testDeserializationInParallel() throws Exception {
+ NestedSetStorageEndpoint nestedSetStorageEndpoint =
+ Mockito.spy(new InMemoryNestedSetStorageEndpoint());
+ NestedSetCache emptyNestedSetCache = Mockito.mock(NestedSetCache.class);
+ NestedSetStore nestedSetStore =
+ new NestedSetStore(
+ nestedSetStorageEndpoint, emptyNestedSetCache, MoreExecutors.directExecutor());
+
+ ObjectCodecs objectCodecs =
+ new ObjectCodecs(
+ AutoRegistry.get()
+ .getBuilder()
+ .setAllowDefaultCodec(true)
+ .add(new NestedSetCodecWithStore<>(nestedSetStore))
+ .build());
+
+ NestedSet<String> subset1 =
+ new NestedSetBuilder<String>(Order.STABLE_ORDER).add("a").add("b").build();
+ SettableFuture<byte[]> subset1Future = SettableFuture.create();
+ NestedSet<String> subset2 =
+ new NestedSetBuilder<String>(Order.STABLE_ORDER).add("c").add("d").build();
+ SettableFuture<byte[]> subset2Future = SettableFuture.create();
+ NestedSet<String> set =
+ new NestedSetBuilder<String>(Order.STABLE_ORDER)
+ .addTransitive(subset1)
+ .addTransitive(subset2)
+ .build();
+
+ // We capture the arguments to #put() during serialization, so as to correctly mock results for
+ // #get()
+ ArgumentCaptor<ByteString> fingerprintCaptor = ArgumentCaptor.forClass(ByteString.class);
+ ByteString fingerprint =
+ nestedSetStore
+ .computeFingerprintAndStore(
+ (Object[]) set.getChildren(), objectCodecs.getSerializationContext())
+ .fingerprint();
+ Mockito.verify(nestedSetStorageEndpoint, Mockito.times(3))
+ .put(fingerprintCaptor.capture(), Mockito.any());
+ Mockito.doReturn(subset1Future)
+ .when(nestedSetStorageEndpoint)
+ .get(fingerprintCaptor.getAllValues().get(0));
+ Mockito.doReturn(subset2Future)
+ .when(nestedSetStorageEndpoint)
+ .get(fingerprintCaptor.getAllValues().get(1));
+
+ ListenableFuture<Object[]> deserializationFuture =
+ nestedSetStore.getContentsAndDeserialize(
+ fingerprint, objectCodecs.getDeserializationContext());
+ // At this point, we expect deserializationFuture to be waiting on both of the underlying
+ // fetches, which should have both been started.
+ assertThat(deserializationFuture.isDone()).isFalse();
+ Mockito.verify(nestedSetStorageEndpoint, Mockito.times(3)).get(Mockito.any());
+
+ // Once the underlying fetches complete, we expect deserialization to complete.
+ subset1Future.set(ByteString.copyFrom("mock bytes", Charset.defaultCharset()).toByteArray());
+ subset2Future.set(ByteString.copyFrom("mock bytes", Charset.defaultCharset()).toByteArray());
+ assertThat(deserializationFuture.isDone()).isTrue();
+ }
}
diff --git a/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetImplTest.java b/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetImplTest.java
index ff4515276b..97fbf8d336 100644
--- a/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetImplTest.java
+++ b/src/test/java/com/google/devtools/build/lib/collect/nestedset/NestedSetImplTest.java
@@ -18,6 +18,8 @@ import static org.junit.Assert.fail;
import com.google.common.collect.Lists;
import com.google.common.testing.EqualsTester;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -164,40 +166,55 @@ public class NestedSetImplTest {
public void shallowEquality() {
// Used below to check that inner nested sets can be compared by reference equality.
SetWrapper<Integer> myRef = nest(nest(flat(7, 8)), flat(9));
+ // Used to check equality for deserializing nested sets
+ ListenableFuture<Object[]> contents = Futures.immediateFuture(new Object[] {"a", "b"});
+ NestedSet<String> referenceNestedSet = NestedSet.withFuture(Order.STABLE_ORDER, contents);
+ NestedSet<String> otherReferenceNestedSet = NestedSet.withFuture(Order.STABLE_ORDER, contents);
// Each "equality group" contains elements that are equal to one another
// (according to equals() and hashCode()), yet distinct from all elements
// of all other equality groups.
new EqualsTester()
- .addEqualityGroup(flat(),
- flat(),
- nest(flat())) // Empty set elision.
- .addEqualityGroup(NestedSetBuilder.<Integer>linkOrder().build())
- .addEqualityGroup(flat(3),
- flat(3),
- flat(3, 3)) // Element de-duplication.
- .addEqualityGroup(flat(4),
- nest(flat(4))) // Automatic elision of one-element nested sets.
- .addEqualityGroup(NestedSetBuilder.<Integer>linkOrder().add(4).build())
- .addEqualityGroup(nestedSetBuilder("4").build()) // Like flat("4").
- .addEqualityGroup(flat(3, 4),
- flat(3, 4))
- // Make a couple sets deep enough that shallowEquals() fails.
- // If this test case fails because you improve the representation, just delete it.
- .addEqualityGroup(nest(nest(flat(3, 4), flat(5)), nest(flat(6, 7), flat(8))))
- .addEqualityGroup(nest(nest(flat(3, 4), flat(5)), nest(flat(6, 7), flat(8))))
- .addEqualityGroup(nest(myRef),
- nest(myRef),
- nest(myRef, myRef)) // Set de-duplication.
- .addEqualityGroup(nest(3, myRef))
- .addEqualityGroup(nest(4, myRef))
- .testEquals();
+ .addEqualityGroup(flat(), flat(), nest(flat())) // Empty set elision.
+ .addEqualityGroup(NestedSetBuilder.<Integer>linkOrder().build())
+ .addEqualityGroup(flat(3), flat(3), flat(3, 3)) // Element de-duplication.
+ .addEqualityGroup(flat(4), nest(flat(4))) // Automatic elision of one-element nested sets.
+ .addEqualityGroup(NestedSetBuilder.<Integer>linkOrder().add(4).build())
+ .addEqualityGroup(nestedSetBuilder("4").build()) // Like flat("4").
+ .addEqualityGroup(flat(3, 4), flat(3, 4))
+ // Make a couple sets deep enough that shallowEquals() fails.
+ // If this test case fails because you improve the representation, just delete it.
+ .addEqualityGroup(nest(nest(flat(3, 4), flat(5)), nest(flat(6, 7), flat(8))))
+ .addEqualityGroup(nest(nest(flat(3, 4), flat(5)), nest(flat(6, 7), flat(8))))
+ .addEqualityGroup(nest(myRef), nest(myRef), nest(myRef, myRef)) // Set de-duplication.
+ .addEqualityGroup(nest(3, myRef))
+ .addEqualityGroup(nest(4, myRef))
+ .addEqualityGroup(
+ new SetWrapper<>(referenceNestedSet), new SetWrapper<>(otherReferenceNestedSet))
+ .testEquals();
// Some things that are not tested by the above:
// - ordering among direct members
// - ordering among transitive sets
}
+ @Test
+ public void shallowInequality() {
+ assertThat(nestedSetBuilder("a").build().shallowEquals(null)).isFalse();
+ Object[] contents = {"a", "b"};
+ assertThat(
+ NestedSet.withFuture(Order.STABLE_ORDER, Futures.immediateFuture(contents))
+ .shallowEquals(null))
+ .isFalse();
+
+ // shallowEquals() should require reference equality for underlying futures
+ assertThat(
+ NestedSet.withFuture(Order.STABLE_ORDER, Futures.immediateFuture(contents))
+ .shallowEquals(
+ NestedSet.withFuture(Order.STABLE_ORDER, Futures.immediateFuture(contents))))
+ .isFalse();
+ }
+
/** Checks that the builder always return a nested set with the correct order. */
@Test
public void correctOrder() {