diff options
author | brandjon <brandjon@google.com> | 2017-09-28 21:04:17 -0400 |
---|---|---|
committer | John Cater <jcater@google.com> | 2017-09-29 12:14:31 -0400 |
commit | e087d317d24094e674cf7fae0284c81d6ff8bd02 (patch) | |
tree | 6acc238fff3d86ed4ed774d6a2b46239423a0875 /src/main/java/com/google/devtools/build | |
parent | 5afd9ee197e0c9a7ef8d040cc2c2e68cc16aa8eb (diff) |
Move serialization test utilities from test/ to main/
This is so other packages can depend on them without violating our style guide. (Dependencies on test/ packages should be limited to aggregating test suites.)
The target is also renamed from ".../serialization:serialization-test-base" to a new subpackage, ".../serialization/testutils:testutils".
RELNOTES: None
PiperOrigin-RevId: 170426906
Diffstat (limited to 'src/main/java/com/google/devtools/build')
5 files changed, 238 insertions, 1 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/BUILD index b747a567af..45e652f460 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/BUILD +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/BUILD @@ -2,7 +2,9 @@ package(default_visibility = ["//src:__subpackages__"]) filegroup( name = "srcs", - srcs = glob(["**"]), + srcs = glob(["**"]) + [ + "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils:srcs", + ], ) java_library( diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/AbstractObjectCodecTest.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/AbstractObjectCodecTest.java new file mode 100644 index 0000000000..117f4d8bac --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/AbstractObjectCodecTest.java @@ -0,0 +1,109 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.skyframe.serialization.testutils; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.SerializationException; +import com.google.protobuf.CodedInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Test; + +/** Common ObjectCodec tests. */ +public abstract class AbstractObjectCodecTest<T> { + + @Nullable protected ObjectCodec<T> underTest; + @Nullable protected ImmutableList<T> subjects; + + /** + * Override to false to skip testDeserializeBadDataThrowsSerializationException(). Codecs that + * cannot distinguish good and bad data should do this. + */ + protected boolean shouldTestDeserializeBadData = true; + + /** Construct with the given codec and subjects. */ + protected AbstractObjectCodecTest( + ObjectCodec<T> underTest, @SuppressWarnings("unchecked") T... subjects) { + this.underTest = underTest; + this.subjects = ImmutableList.copyOf(subjects); + } + + /** + * Construct without a codec and subjects. They must be set in the subclass's constructor instead. + * + * <p>This is useful if the logic for creating the codec and/or subjects is non-trivial. Using + * this super constructor, the logic can be placed in the subclass's constructor; whereas if using + * the above super constructor, the logic must be factored into a static method. + */ + protected AbstractObjectCodecTest() {} + + @Before + public void checkInitialized() { + Preconditions.checkNotNull(underTest); + Preconditions.checkNotNull(subjects); + } + + @Test + public void testSuccessfulSerializationDeserialization() throws Exception { + for (T subject : subjects) { + byte[] serialized = toBytes(subject); + Object deserialized = fromBytes(serialized); + verifyDeserialization(deserialized, subject); + } + } + + @Test + public void testSerializationRoundTripBytes() throws Exception { + for (T subject : subjects) { + byte[] serialized = toBytes(subject); + T deserialized = fromBytes(serialized); + byte[] reserialized = toBytes(deserialized); + assertThat(reserialized).isEqualTo(serialized); + } + } + + @Test + public void testDeserializeBadDataThrowsSerializationException() { + if (!shouldTestDeserializeBadData) { + return; + } + try { + underTest.deserialize(CodedInputStream.newInstance("junk".getBytes(StandardCharsets.UTF_8))); + fail("Expected exception"); + } catch (SerializationException | IOException e) { + // Expected. + } + } + + protected T fromBytes(byte[] bytes) throws SerializationException, IOException { + return TestUtils.fromBytes(underTest, bytes); + } + + /** Serialize subject using the {@link ObjectCodec} under test. */ + protected byte[] toBytes(T subject) throws IOException, SerializationException { + return TestUtils.toBytes(underTest, subject); + } + + protected void verifyDeserialization(Object deserialized, T subject) { + assertThat(deserialized).isEqualTo(subject); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/BUILD new file mode 100644 index 0000000000..d193666032 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/BUILD @@ -0,0 +1,23 @@ +package(default_visibility = ["//src:__subpackages__"]) + +filegroup( + name = "srcs", + srcs = glob(["**"]), +) + +java_library( + name = "testutils", + testonly = 1, + srcs = glob(["*.java"]), + deps = [ + "//src/main/java/com/google/devtools/build/lib:syntax", + "//src/main/java/com/google/devtools/build/lib/skyframe/serialization", + "//src/main/java/com/google/devtools/build/lib/vfs", + "//src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs", + "//third_party:guava", + "//third_party:jsr305", + "//third_party:junit4", + "//third_party:truth", + "//third_party/protobuf:protobuf_java", + ], +) diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java new file mode 100644 index 0000000000..ee019b8c49 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java @@ -0,0 +1,38 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.skyframe.serialization.testutils; + +import com.google.devtools.build.lib.vfs.FileSystem; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.RootedPath; +import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem; + +/** Common FileSystem related items for serialization tests. */ +public class FsUtils { + + public static final FileSystem TEST_FILESYSTEM = new InMemoryFileSystem(); + + public static final RootedPath TEST_ROOT = + RootedPath.toRootedPath( + TEST_FILESYSTEM.getPath(PathFragment.create("/anywhere/at/all")), + PathFragment.create("all/at/anywhere")); + + private FsUtils() {} + + /** Returns path relative to {@link #TEST_ROOT}. */ + public static PathFragment rootPathRelative(String path) { + return TEST_ROOT.getRelativePath().getRelative(path); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/TestUtils.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/TestUtils.java new file mode 100644 index 0000000000..1b0f1814ac --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/TestUtils.java @@ -0,0 +1,65 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.skyframe.serialization.testutils; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.SerializationException; +import com.google.devtools.build.lib.syntax.Environment.Frame; +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** Helpers for serialization tests. */ +public class TestUtils { + + private TestUtils() {} + + /** Serialize a value to a new byte array. */ + public static <T> byte[] toBytes(ObjectCodec<T> codec, T value) + throws IOException, SerializationException { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + CodedOutputStream codedOut = CodedOutputStream.newInstance(bytes); + codec.serialize(value, codedOut); + codedOut.flush(); + return bytes.toByteArray(); + } + + /** Deserialize a value from a byte array. */ + public static <T> T fromBytes(ObjectCodec<T> codec, byte[] bytes) + throws SerializationException, IOException { + return codec.deserialize(CodedInputStream.newInstance(bytes)); + } + + /** + * Asserts that two {@link Frame}s have the same structure. Needed because {@link Frame} doesn't + * override {@link Object#equals}. + */ + public static void assertFramesEqual(Frame frame1, Frame frame2) { + assertThat(frame1.mutability().getAnnotation()) + .isEqualTo(frame2.mutability().getAnnotation()); + assertThat(frame1.getLabel()).isEqualTo(frame2.getLabel()); + assertThat(frame1.getTransitiveBindings()) + .containsExactlyEntriesIn(frame2.getTransitiveBindings()).inOrder(); + if (frame1.getParent() == null || frame2.getParent() == null) { + assertThat(frame1.getParent()).isNull(); + assertThat(frame2.getParent()).isNull(); + } else { + assertFramesEqual(frame1.getParent(), frame2.getParent()); + } + } +} |