From 37c70a125a0282d331a1ec92397b750d50367551 Mon Sep 17 00:00:00 2001 From: ccalvarin Date: Mon, 13 Aug 2018 10:31:15 -0700 Subject: Add easy access to MessageDigests in DigestHashFunction Move the message-digest cloning to DigestHashFunction and out of Fingerprint, to make it possible to configure Fingerprint to use different hash functions. We keep the default MD5 for now, we'd like it to use the global default but want to isolate the configuration change from any change adding potential contention. RELNOTES: None. PiperOrigin-RevId: 208502993 --- .../devtools/build/lib/util/FingerprintTest.java | 2 +- .../lib/vfs/DigestHashFunctionGlobalsTest.java | 108 +++++++++++++++++++++ .../build/lib/vfs/DigestHashFunctionTest.java | 104 -------------------- .../build/lib/vfs/DigestHashFunctionsTest.java | 61 ++++++++++++ 4 files changed, 170 insertions(+), 105 deletions(-) create mode 100644 src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionGlobalsTest.java delete mode 100644 src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionTest.java create mode 100644 src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionsTest.java (limited to 'src/test') diff --git a/src/test/java/com/google/devtools/build/lib/util/FingerprintTest.java b/src/test/java/com/google/devtools/build/lib/util/FingerprintTest.java index 372b48d80c..b3fd3c4ef2 100644 --- a/src/test/java/com/google/devtools/build/lib/util/FingerprintTest.java +++ b/src/test/java/com/google/devtools/build/lib/util/FingerprintTest.java @@ -58,7 +58,7 @@ public class FingerprintTest { public void bytesFingerprint() { assertThat(new Fingerprint().addBytes("Hello World!".getBytes(UTF_8)).hexDigestAndReset()) .isEqualTo("ed076287532e86365e841e92bfc50d8c"); - assertThat(Fingerprint.md5Digest("Hello World!")) + assertThat(Fingerprint.getHexDigest("Hello World!")) .isEqualTo("ed076287532e86365e841e92bfc50d8c"); } diff --git a/src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionGlobalsTest.java b/src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionGlobalsTest.java new file mode 100644 index 0000000000..77f7b62b21 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionGlobalsTest.java @@ -0,0 +1,108 @@ +// 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.vfs; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows; + +import com.google.common.hash.Hashing; +import com.google.devtools.build.lib.vfs.DigestHashFunction.DigestFunctionConverter; +import java.lang.reflect.Field; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for DigestHashFunction, notably that the static instances can be compared with reference + * equality. + */ +@RunWith(JUnit4.class) +public class DigestHashFunctionGlobalsTest { + private final DigestFunctionConverter converter = new DigestFunctionConverter(); + + @Before + public void resetStaticDefault() throws IllegalAccessException, NoSuchFieldException { + // The default is effectively a Singleton, and it does not allow itself to be set multiple + // times. In order to test this reasonably, though, we reset the sentinel boolean to false and + // the value to null, which are the values before setDefault is called. + Field defaultHasBeenSet = DigestHashFunction.class.getDeclaredField("defaultHasBeenSet"); + defaultHasBeenSet.setAccessible(true); + defaultHasBeenSet.set(null, false); + + Field defaultValue = DigestHashFunction.class.getDeclaredField("defaultHash"); + defaultValue.setAccessible(true); + defaultValue.set(null, null); + } + + @Test + public void convertReturnsTheSameValueAsTheConstant() throws Exception { + assertThat(converter.convert("sha-256")).isSameAs(DigestHashFunction.SHA256); + assertThat(converter.convert("SHA-256")).isSameAs(DigestHashFunction.SHA256); + assertThat(converter.convert("SHA256")).isSameAs(DigestHashFunction.SHA256); + assertThat(converter.convert("sha256")).isSameAs(DigestHashFunction.SHA256); + + assertThat(converter.convert("SHA-1")).isSameAs(DigestHashFunction.SHA1); + assertThat(converter.convert("sha-1")).isSameAs(DigestHashFunction.SHA1); + assertThat(converter.convert("SHA1")).isSameAs(DigestHashFunction.SHA1); + assertThat(converter.convert("sha1")).isSameAs(DigestHashFunction.SHA1); + + assertThat(converter.convert("MD5")).isSameAs(DigestHashFunction.MD5); + assertThat(converter.convert("md5")).isSameAs(DigestHashFunction.MD5); + } + + @Test + public void lateRegistrationGetsPickedUpByConverter() throws Exception { + DigestHashFunction.register(Hashing.goodFastHash(32), "SHA-512"); + + assertThat(converter.convert("SHA-512")).isSameAs(converter.convert("sha-512")); + } + + @Test + public void lateRegistrationWithAlternativeNamesGetsPickedUpByConverter() throws Exception { + DigestHashFunction.register(Hashing.goodFastHash(64), "SHA-384", "SHA384", "SHA_384"); + + assertThat(converter.convert("SHA-384")).isSameAs(converter.convert("SHA-384")); + assertThat(converter.convert("Sha-384")).isSameAs(converter.convert("SHA-384")); + assertThat(converter.convert("sha-384")).isSameAs(converter.convert("SHA-384")); + + assertThat(converter.convert("SHA384")).isSameAs(converter.convert("SHA-384")); + assertThat(converter.convert("Sha384")).isSameAs(converter.convert("SHA-384")); + assertThat(converter.convert("sha384")).isSameAs(converter.convert("SHA-384")); + + assertThat(converter.convert("SHA_384")).isSameAs(converter.convert("SHA-384")); + assertThat(converter.convert("Sha_384")).isSameAs(converter.convert("SHA-384")); + assertThat(converter.convert("sha_384")).isSameAs(converter.convert("SHA-384")); + } + + @Test + public void unsetDefaultThrows() { + assertThrows( + DigestHashFunction.DefaultNotSetException.class, () -> DigestHashFunction.getDefault()); + } + + @Test + public void setDefaultDoesNotThrow() throws Exception { + DigestHashFunction.setDefault(DigestHashFunction.SHA1); + DigestHashFunction.getDefault(); + } + + @Test + public void cannotSetDefaultMultipleTimes() throws Exception { + DigestHashFunction.setDefault(DigestHashFunction.MD5); + assertThrows( + DigestHashFunction.DefaultAlreadySetException.class, + () -> DigestHashFunction.setDefault(DigestHashFunction.SHA1)); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionTest.java b/src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionTest.java deleted file mode 100644 index 1e4044bd31..0000000000 --- a/src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionTest.java +++ /dev/null @@ -1,104 +0,0 @@ -// 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.vfs; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows; - -import com.google.common.hash.Hashing; -import com.google.devtools.build.lib.vfs.DigestHashFunction.DigestFunctionConverter; -import java.lang.reflect.Field; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for DigestHashFunction, notably that the static instances can be compared with reference - * equality. - */ -@RunWith(JUnit4.class) -public class DigestHashFunctionTest { - private final DigestFunctionConverter converter = new DigestFunctionConverter(); - - @Before - public void resetStaticDefault() throws IllegalAccessException, NoSuchFieldException { - // The default is effectively a Singleton, and it does not allow itself to be set multiple - // times. In order to test this reasonably, though, we reset the sentinel boolean to false and - // the value to null, which are the values before setDefault is called. - Field defaultHasBeenSet = DigestHashFunction.class.getDeclaredField("defaultHasBeenSet"); - defaultHasBeenSet.setAccessible(true); - defaultHasBeenSet.set(null, false); - - Field defaultValue = DigestHashFunction.class.getDeclaredField("defaultHash"); - defaultValue.setAccessible(true); - defaultValue.set(null, null); - } - - @Test - public void convertReturnsTheSameValueAsTheConstant() throws Exception { - assertThat(converter.convert("sha-256")).isSameAs(DigestHashFunction.SHA256); - assertThat(converter.convert("SHA-256")).isSameAs(DigestHashFunction.SHA256); - assertThat(converter.convert("SHA256")).isSameAs(DigestHashFunction.SHA256); - assertThat(converter.convert("sha256")).isSameAs(DigestHashFunction.SHA256); - - assertThat(converter.convert("SHA-1")).isSameAs(DigestHashFunction.SHA1); - assertThat(converter.convert("sha-1")).isSameAs(DigestHashFunction.SHA1); - assertThat(converter.convert("SHA1")).isSameAs(DigestHashFunction.SHA1); - assertThat(converter.convert("sha1")).isSameAs(DigestHashFunction.SHA1); - - assertThat(converter.convert("MD5")).isSameAs(DigestHashFunction.MD5); - assertThat(converter.convert("md5")).isSameAs(DigestHashFunction.MD5); - } - - @Test - public void lateRegistrationGetsPickedUpByConverter() throws Exception { - DigestHashFunction.register(Hashing.goodFastHash(32), "goodFastHash32"); - - assertThat(converter.convert("goodFastHash32")).isSameAs(converter.convert("GOODFASTHASH32")); - } - - @Test - public void lateRegistrationWithAlternativeNamesGetsPickedUpByConverter() throws Exception { - DigestHashFunction.register( - Hashing.goodFastHash(64), "goodFastHash64", "goodFastHash-64", "good-fast-hash-64"); - - assertThat(converter.convert("goodFastHash64")).isSameAs(converter.convert("GOODFASTHASH64")); - assertThat(converter.convert("goodFastHash64")).isSameAs(converter.convert("goodFastHash-64")); - assertThat(converter.convert("goodFastHash64")) - .isSameAs(converter.convert("good-fast-hash-64")); - assertThat(converter.convert("goodFastHash64")) - .isSameAs(converter.convert("GOOD-fast-HASH-64")); - } - - @Test - public void unsetDefaultThrows() { - assertThrows( - DigestHashFunction.DefaultNotSetException.class, () -> DigestHashFunction.getDefault()); - } - - @Test - public void setDefaultDoesNotThrow() throws Exception { - DigestHashFunction.setDefault(DigestHashFunction.SHA1); - DigestHashFunction.getDefault(); - } - - @Test - public void cannotSetDefaultMultipleTimes() throws Exception { - DigestHashFunction.setDefault(DigestHashFunction.MD5); - assertThrows( - DigestHashFunction.DefaultAlreadySetException.class, - () -> DigestHashFunction.setDefault(DigestHashFunction.SHA1)); - } -} diff --git a/src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionsTest.java new file mode 100644 index 0000000000..6b3b19923d --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/vfs/DigestHashFunctionsTest.java @@ -0,0 +1,61 @@ +// 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.vfs; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +/** + * Tests different {@link DigestHashFunction} for consistency between the MessageDigests and the + * HashFunctions that it exposes. + */ +@RunWith(Parameterized.class) +public class DigestHashFunctionsTest { + @Parameters(name = "{index}: digestHashFunction={0}") + public static Collection hashFunctions() { + // TODO(b/112537387): Remove the array-ification and return Collection. This + // is possible in Junit4.12, but 4.11 requires the array. Bazel 0.18 will have Junit4.12, so + // this can change then. + return DigestHashFunction.getPossibleHashFunctions() + .stream() + .map(dhf -> new DigestHashFunction[] {dhf}) + .collect(ImmutableList.toImmutableList()); + } + + @Parameter public DigestHashFunction digestHashFunction; + + private void assertHashFunctionAndMessageDigestEquivalentForInput(byte[] input) { + byte[] hashFunctionOutput = digestHashFunction.getHashFunction().hashBytes(input).asBytes(); + byte[] messageDigestOutput = digestHashFunction.cloneOrCreateMessageDigest().digest(input); + assertThat(hashFunctionOutput).isEqualTo(messageDigestOutput); + } + + @Test + public void emptyDigestIsConsistent() { + assertHashFunctionAndMessageDigestEquivalentForInput(new byte[] {}); + } + + @Test + public void shortDigestIsConsistent() { + assertHashFunctionAndMessageDigestEquivalentForInput("Bazel".getBytes(StandardCharsets.UTF_8)); + } +} -- cgit v1.2.3