blob: 8c64aa258382e96424fbc93d04dfe71251e3491f [file] [log] [blame]
// Copyright 2018 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.collect.nestedset;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.base.Objects;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.devtools.build.lib.skyframe.serialization.ObjectCodecs;
import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester.VerificationFunction;
import java.io.IOException;
/** Utilities for testing NestedSet serialization. */
public class NestedSetCodecTestUtils {
private static final NestedSet<String> SHARED_NESTED_SET =
NestedSetBuilder.<String>stableOrder().add("e").build();
@AutoCodec
static class HasNestedSet {
private final NestedSet<String> nestedSetField;
@VisibleForSerialization
HasNestedSet(NestedSet<String> nestedSetField) {
this.nestedSetField = nestedSetField;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
HasNestedSet that = (HasNestedSet) o;
return Objects.equal(nestedSetField.getChildren(), that.nestedSetField.getChildren());
}
@Override
public int hashCode() {
return Objects.hashCode(nestedSetField);
}
}
/** Perform serialization/deserialization checks for several simple NestedSet examples. */
public static void checkCodec(
ObjectCodecs objectCodecs, boolean allowFutureBlocking, boolean assertSymmetricEquality)
throws Exception {
new SerializationTester(
NestedSetBuilder.emptySet(Order.STABLE_ORDER),
NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER),
NestedSetBuilder.create(Order.STABLE_ORDER, "a"),
NestedSetBuilder.create(Order.STABLE_ORDER, "a", "b", "c"),
NestedSetBuilder.<String>stableOrder()
.add("a")
.add("b")
.addTransitive(
NestedSetBuilder.<String>stableOrder()
.add("c")
.addTransitive(SHARED_NESTED_SET)
.build())
.addTransitive(
NestedSetBuilder.<String>stableOrder()
.add("d")
.addTransitive(SHARED_NESTED_SET)
.build())
.addTransitive(NestedSetBuilder.emptySet(Order.STABLE_ORDER))
.build(),
NestedSetBuilder.create(
Order.STABLE_ORDER,
new HasNestedSet(NestedSetBuilder.create(Order.STABLE_ORDER, "a"))))
.setObjectCodecs(objectCodecs)
.makeMemoizingAndAllowFutureBlocking(allowFutureBlocking)
.setVerificationFunction(verificationFunction(assertSymmetricEquality))
.runTests();
}
public static ListenableFuture<Void> writeToStoreFuture(
NestedSetStore store, NestedSet<?> nestedSet, SerializationContext serializationContext)
throws IOException, SerializationException {
return store
.computeFingerprintAndStore((Object[]) nestedSet.getChildren(), serializationContext)
.writeStatus();
}
private static VerificationFunction<NestedSet<String>> verificationFunction(
boolean assertSymmetricEquality) {
return (subject, deserialized) -> {
if (assertSymmetricEquality) {
assertThat(deserialized).isEqualTo(subject);
assertThat(subject).isEqualTo(deserialized);
}
assertThat(subject.getOrder()).isEqualTo(deserialized.getOrder());
assertThat(subject.toSet()).isEqualTo(deserialized.toSet());
verifyStructure(subject.getChildren(), deserialized.getChildren());
};
}
private static void verifyStructure(Object lhs, Object rhs) {
if (lhs == NestedSet.EMPTY_CHILDREN) {
assertThat(rhs).isSameInstanceAs(NestedSet.EMPTY_CHILDREN);
} else if (lhs instanceof Object[]) {
assertThat(rhs).isInstanceOf(Object[].class);
Object[] lhsArray = (Object[]) lhs;
Object[] rhsArray = (Object[]) rhs;
int n = lhsArray.length;
assertThat(rhsArray).hasLength(n);
for (int i = 0; i < n; ++i) {
verifyStructure(lhsArray[i], rhsArray[i]);
}
} else {
assertThat(lhs).isEqualTo(rhs);
}
}
}