Skip to content

Commit

Permalink
SerializationTester uses an addDependency method instead of
Browse files Browse the repository at this point in the history
(Des|S)erializationContext factories.

This is consistent as ObjectCodecs will eventually create context objects if needed.

PiperOrigin-RevId: 186900662
  • Loading branch information
aoeui authored and Copybara-Service committed Feb 24, 2018
1 parent 978cb00 commit bde43ec
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public class ObjectCodecs {
* Creates an instance using the supplied {@link ObjectCodecRegistry} for looking up {@link
* ObjectCodec}s.
*/
ObjectCodecs(ObjectCodecRegistry codecRegistry, ImmutableMap<Class<?>, Object> dependencies) {
public ObjectCodecs(
ObjectCodecRegistry codecRegistry, ImmutableMap<Class<?>, Object> dependencies) {
this.codecRegistry = codecRegistry;
serializationContext = new SerializationContext(codecRegistry, dependencies);
deserializationContext = new DeserializationContext(codecRegistry, dependencies);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,11 @@
import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
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.SerializationException;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import com.google.protobuf.ByteString;
import java.util.Random;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -57,10 +53,7 @@ public interface VerificationFunction<T> {
}

private final ImmutableList<Object> subjects;
private Supplier<SerializationContext> writeContextFactory =
() -> new SerializationContext(ImmutableMap.of());
private Supplier<DeserializationContext> readContextFactory =
() -> new DeserializationContext(ImmutableMap.of());
private final ImmutableMap.Builder<Class<?>, Object> dependenciesBuilder;

@SuppressWarnings("rawtypes")
private VerificationFunction verificationFunction =
Expand All @@ -71,17 +64,11 @@ public interface VerificationFunction<T> {
public SerializationTester(Object... subjects) {
Preconditions.checkArgument(subjects.length > 0);
this.subjects = ImmutableList.copyOf(subjects);
this.dependenciesBuilder = ImmutableMap.builder();
}

public SerializationTester setWriteContextFactory(
Supplier<SerializationContext> writeContextFactory) {
this.writeContextFactory = writeContextFactory;
return this;
}

public SerializationTester setReadContextFactory(
Supplier<DeserializationContext> readContextFactory) {
this.readContextFactory = readContextFactory;
public <D> SerializationTester addDependency(Class<? super D> type, D dependency) {
dependenciesBuilder.put(type, dependency);
return this;
}

Expand All @@ -98,21 +85,22 @@ public SerializationTester setRepetitions(int repetitions) {
}

public void runTests() throws Exception {
testSerializeDeserialize();
testStableSerialization();
testDeserializeJunkData();
ObjectCodecs codecs = new ObjectCodecs(AutoRegistry.get(), dependenciesBuilder.build());
testSerializeDeserialize(codecs);
testStableSerialization(codecs);
testDeserializeJunkData(codecs);
}

/** Runs serialization/deserialization tests. */
@SuppressWarnings("unchecked")
private void testSerializeDeserialize() throws Exception {
private void testSerializeDeserialize(ObjectCodecs codecs) throws Exception {
Stopwatch timer = Stopwatch.createStarted();
int totalBytes = 0;
for (int i = 0; i < repetitions; ++i) {
for (Object subject : subjects) {
byte[] serialized = toBytes(subject);
totalBytes += serialized.length;
Object deserialized = fromBytes(serialized);
ByteString serialized = codecs.serialize(subject);
totalBytes += serialized.size();
Object deserialized = codecs.deserialize(serialized);
verificationFunction.verifyDeserialized(subject, deserialized);
}
}
Expand All @@ -126,41 +114,29 @@ private void testSerializeDeserialize() throws Exception {
}

/** Runs serialized bytes stability tests. */
private void testStableSerialization() throws IOException, SerializationException {
private void testStableSerialization(ObjectCodecs codecs) throws SerializationException {
for (Object subject : subjects) {
byte[] serialized = toBytes(subject);
Object deserialized = fromBytes(serialized);
byte[] reserialized = toBytes(deserialized);
ByteString serialized = codecs.serialize(subject);
Object deserialized = codecs.deserialize(serialized);
ByteString reserialized = codecs.serialize(deserialized);
assertThat(reserialized).isEqualTo(serialized);
}
}

/** Runs junk-data recognition tests. */
private void testDeserializeJunkData() {
private static void testDeserializeJunkData(ObjectCodecs codecs) {
Random rng = new Random(0);
for (int i = 0; i < DEFAULT_JUNK_INPUTS; ++i) {
byte[] junkData = new byte[rng.nextInt(JUNK_LENGTH_UPPER_BOUND)];
rng.nextBytes(junkData);
try {
readContextFactory.get().deserialize(CodedInputStream.newInstance(junkData));
codecs.deserialize(ByteString.copyFrom(junkData));
// OK. Junk string was coincidentally parsed.
} catch (IOException | SerializationException e) {
} catch (SerializationException e) {
// OK. Deserialization of junk failed.
return;
}
}
assert_().fail("all junk was parsed successfully");
}

private Object fromBytes(byte[] bytes) throws IOException, SerializationException {
return readContextFactory.get().deserialize(CodedInputStream.newInstance(bytes));
}

private byte[] toBytes(Object subject) throws IOException, SerializationException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
CodedOutputStream codedOut = CodedOutputStream.newInstance(bytes);
writeContextFactory.get().serialize(subject, codedOut);
codedOut.flush();
return bytes.toByteArray();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import com.google.devtools.build.lib.actions.util.DummyExecutor;
import com.google.devtools.build.lib.analysis.actions.ExecutableSymlinkAction;
import com.google.devtools.build.lib.exec.SingleBuildFileCache;
import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.testutil.TestFileOutErr;
Expand Down Expand Up @@ -126,14 +124,7 @@ public void testCodec() throws Exception {
Artifact output = new Artifact(outputRoot.getRoot().getRelative("some-output"), outputRoot);
ExecutableSymlinkAction action = new ExecutableSymlinkAction(NULL_ACTION_OWNER, input, output);
new SerializationTester(action)
.setWriteContextFactory(
() ->
new SerializationContext(
ImmutableMap.of(FileSystem.class, scratch.getFileSystem())))
.setReadContextFactory(
() ->
new DeserializationContext(
ImmutableMap.of(FileSystem.class, scratch.getFileSystem())))
.addDependency(FileSystem.class, scratch.getFileSystem())
.setVerificationFunction(
(in, out) -> {
ExecutableSymlinkAction inAction = (ExecutableSymlinkAction) in;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
import com.google.devtools.build.lib.actions.Executor;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.exec.util.TestExecutorBuilder;
import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.vfs.FileSystem;
Expand Down Expand Up @@ -99,14 +97,7 @@ public void testSymlink() throws Exception {
@Test
public void testCodec() throws Exception {
new SerializationTester(action)
.setWriteContextFactory(
() ->
new SerializationContext(
ImmutableMap.of(FileSystem.class, scratch.getFileSystem())))
.setReadContextFactory(
() ->
new DeserializationContext(
ImmutableMap.of(FileSystem.class, scratch.getFileSystem())))
.addDependency(FileSystem.class, scratch.getFileSystem())
.setVerificationFunction(
(in, out) -> {
SymlinkAction inAction = (SymlinkAction) in;
Expand Down

0 comments on commit bde43ec

Please sign in to comment.