/* * Copyright 2017-present Facebook, Inc. * * 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.facebook.buck.rules.keys; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertSame; import com.facebook.buck.io.ArchiveMemberPath; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.model.BuildTargetFactory; import com.facebook.buck.rules.BuildRuleType; import com.facebook.buck.rules.DefaultBuildTargetSourcePath; import com.facebook.buck.rules.RuleKey; import com.facebook.buck.rules.SourceRoot; import com.facebook.buck.util.sha1.Sha1HashCode; import com.google.common.hash.HashCode; import java.nio.file.Paths; import java.util.regex.Pattern; import org.junit.Test; public class ForwardingRuleKeyHasherTest { private static final RuleKey RULE_KEY_1 = new RuleKey("a002b39af204cdfaa5fdb67816b13867c32ac52c"); private static final BuildTarget TARGET_1 = BuildTargetFactory.newInstance(Paths.get("/root"), "//example/base:one"); private static final byte[] BYTE_ARRAY = new byte[] {42, 42}; private static final Pattern PATTERN = Pattern.compile("42"); private static final SourceRoot SOURCE_ROOT = new SourceRoot("42"); @Test public void testForwarding() { String string = "hash"; HashCode hash = createMock(HashCode.class); @SuppressWarnings("unchecked") RuleKeyHasher<String> stringHasher = createStrictMock(RuleKeyHasher.class); @SuppressWarnings("unchecked") RuleKeyHasher<HashCode> guavaHasher = createStrictMock(RuleKeyHasher.class); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putKey("42")).andReturn(guavaHasher); expect(stringHasher.putKey("42")).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putNull()).andReturn(guavaHasher); expect(stringHasher.putNull()).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putBoolean(true)).andReturn(guavaHasher); expect(stringHasher.putBoolean(true)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putBoolean(false)).andReturn(guavaHasher); expect(stringHasher.putBoolean(false)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putNumber(42)).andReturn(guavaHasher); expect(stringHasher.putNumber(42)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putNumber((long) 42)).andReturn(guavaHasher); expect(stringHasher.putNumber((long) 42)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putNumber((short) 42)).andReturn(guavaHasher); expect(stringHasher.putNumber((short) 42)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putNumber((byte) 42)).andReturn(guavaHasher); expect(stringHasher.putNumber((byte) 42)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putNumber((float) 42)).andReturn(guavaHasher); expect(stringHasher.putNumber((float) 42)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putNumber((double) 42)).andReturn(guavaHasher); expect(stringHasher.putNumber((double) 42)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putString("42")).andReturn(guavaHasher); expect(stringHasher.putString("42")).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putBytes(BYTE_ARRAY)).andReturn(guavaHasher); expect(stringHasher.putBytes(BYTE_ARRAY)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putPattern(PATTERN)).andReturn(guavaHasher); expect(stringHasher.putPattern(PATTERN)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putSha1(Sha1HashCode.of("a002b39af204cdfaa5fdb67816b13867c32ac52c"))) .andReturn(guavaHasher); expect(stringHasher.putSha1(Sha1HashCode.of("a002b39af204cdfaa5fdb67816b13867c32ac52c"))) .andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putPath(Paths.get("42/42"), HashCode.fromInt(42))).andReturn(guavaHasher); expect(stringHasher.putPath(Paths.get("42/42"), HashCode.fromInt(42))).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect( guavaHasher.putArchiveMemberPath( newArchiveMember("42/42", "42/42"), HashCode.fromInt(42))) .andReturn(guavaHasher); expect( stringHasher.putArchiveMemberPath( newArchiveMember("42/42", "42/42"), HashCode.fromInt(42))) .andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putNonHashingPath("42")).andReturn(guavaHasher); expect(stringHasher.putNonHashingPath("42")).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putSourceRoot(SOURCE_ROOT)).andReturn(guavaHasher); expect(stringHasher.putSourceRoot(SOURCE_ROOT)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putRuleKey(RULE_KEY_1)).andReturn(guavaHasher); expect(stringHasher.putRuleKey(RULE_KEY_1)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putBuildRuleType(BuildRuleType.of("42"))).andReturn(guavaHasher); expect(stringHasher.putBuildRuleType(BuildRuleType.of("42"))).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putBuildTarget(TARGET_1)).andReturn(guavaHasher); expect(stringHasher.putBuildTarget(TARGET_1)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putBuildTargetSourcePath(new DefaultBuildTargetSourcePath(TARGET_1))) .andReturn(guavaHasher); expect(stringHasher.putBuildTargetSourcePath(new DefaultBuildTargetSourcePath(TARGET_1))) .andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putContainer(RuleKeyHasher.Container.LIST, 42)).andReturn(guavaHasher); expect(stringHasher.putContainer(RuleKeyHasher.Container.LIST, 42)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putContainer(RuleKeyHasher.Container.MAP, 42)).andReturn(guavaHasher); expect(stringHasher.putContainer(RuleKeyHasher.Container.MAP, 42)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putWrapper(RuleKeyHasher.Wrapper.SUPPLIER)).andReturn(guavaHasher); expect(stringHasher.putWrapper(RuleKeyHasher.Wrapper.SUPPLIER)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putWrapper(RuleKeyHasher.Wrapper.OPTIONAL)).andReturn(guavaHasher); expect(stringHasher.putWrapper(RuleKeyHasher.Wrapper.OPTIONAL)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putWrapper(RuleKeyHasher.Wrapper.EITHER_LEFT)).andReturn(guavaHasher); expect(stringHasher.putWrapper(RuleKeyHasher.Wrapper.EITHER_LEFT)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putWrapper(RuleKeyHasher.Wrapper.EITHER_RIGHT)).andReturn(guavaHasher); expect(stringHasher.putWrapper(RuleKeyHasher.Wrapper.EITHER_RIGHT)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putWrapper(RuleKeyHasher.Wrapper.BUILD_RULE)).andReturn(guavaHasher); expect(stringHasher.putWrapper(RuleKeyHasher.Wrapper.BUILD_RULE)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putWrapper(RuleKeyHasher.Wrapper.APPENDABLE)).andReturn(guavaHasher); expect(stringHasher.putWrapper(RuleKeyHasher.Wrapper.APPENDABLE)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); expect(guavaHasher.putKey("45")).andReturn(guavaHasher); expect(stringHasher.putKey("45")).andReturn(stringHasher); expect(guavaHasher.putNull()).andReturn(guavaHasher); expect(stringHasher.putNull()).andReturn(stringHasher); expect(guavaHasher.putBoolean(true)).andReturn(guavaHasher); expect(stringHasher.putBoolean(true)).andReturn(stringHasher); expect(guavaHasher.putNumber(45)).andReturn(guavaHasher); expect(stringHasher.putNumber(45)).andReturn(stringHasher); expect(guavaHasher.putString("45")).andReturn(guavaHasher); expect(stringHasher.putString("45")).andReturn(stringHasher); expect(guavaHasher.putBytes(BYTE_ARRAY)).andReturn(guavaHasher); expect(stringHasher.putBytes(BYTE_ARRAY)).andReturn(stringHasher); expect(guavaHasher.putPattern(PATTERN)).andReturn(guavaHasher); expect(stringHasher.putPattern(PATTERN)).andReturn(stringHasher); expect(guavaHasher.putSha1(Sha1HashCode.of("a002b39af204cdfaa5fdb67816b13867c32ac52c"))) .andReturn(guavaHasher); expect(stringHasher.putSha1(Sha1HashCode.of("a002b39af204cdfaa5fdb67816b13867c32ac52c"))) .andReturn(stringHasher); expect(guavaHasher.putPath(Paths.get("45"), HashCode.fromInt(45))).andReturn(guavaHasher); expect(stringHasher.putPath(Paths.get("45"), HashCode.fromInt(45))).andReturn(stringHasher); expect(guavaHasher.putArchiveMemberPath(newArchiveMember("45", "45"), HashCode.fromInt(45))) .andReturn(guavaHasher); expect(stringHasher.putArchiveMemberPath(newArchiveMember("45", "45"), HashCode.fromInt(45))) .andReturn(stringHasher); expect(guavaHasher.putNonHashingPath("45")).andReturn(guavaHasher); expect(stringHasher.putNonHashingPath("45")).andReturn(stringHasher); expect(guavaHasher.putSourceRoot(SOURCE_ROOT)).andReturn(guavaHasher); expect(stringHasher.putSourceRoot(SOURCE_ROOT)).andReturn(stringHasher); expect(guavaHasher.putRuleKey(RULE_KEY_1)).andReturn(guavaHasher); expect(stringHasher.putRuleKey(RULE_KEY_1)).andReturn(stringHasher); expect(guavaHasher.putBuildRuleType(BuildRuleType.of("45"))).andReturn(guavaHasher); expect(stringHasher.putBuildRuleType(BuildRuleType.of("45"))).andReturn(stringHasher); expect(guavaHasher.putBuildTarget(TARGET_1)).andReturn(guavaHasher); expect(stringHasher.putBuildTarget(TARGET_1)).andReturn(stringHasher); expect(guavaHasher.putBuildTargetSourcePath(new DefaultBuildTargetSourcePath(TARGET_1))) .andReturn(guavaHasher); expect(stringHasher.putBuildTargetSourcePath(new DefaultBuildTargetSourcePath(TARGET_1))) .andReturn(stringHasher); expect(guavaHasher.putContainer(RuleKeyHasher.Container.LIST, 45)).andReturn(guavaHasher); expect(stringHasher.putContainer(RuleKeyHasher.Container.LIST, 45)).andReturn(stringHasher); expect(guavaHasher.putContainer(RuleKeyHasher.Container.MAP, 45)).andReturn(guavaHasher); expect(stringHasher.putContainer(RuleKeyHasher.Container.MAP, 45)).andReturn(stringHasher); expect(guavaHasher.putWrapper(RuleKeyHasher.Wrapper.OPTIONAL)).andReturn(guavaHasher); expect(stringHasher.putWrapper(RuleKeyHasher.Wrapper.OPTIONAL)).andReturn(stringHasher); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); replay(stringHasher, guavaHasher); newHasher(guavaHasher, stringHasher).hash(); newHasher(guavaHasher, stringHasher).putKey("42").hash(); newHasher(guavaHasher, stringHasher).putNull().hash(); newHasher(guavaHasher, stringHasher).putBoolean(true).hash(); newHasher(guavaHasher, stringHasher).putBoolean(false).hash(); newHasher(guavaHasher, stringHasher).putNumber(42).hash(); newHasher(guavaHasher, stringHasher).putNumber((long) 42).hash(); newHasher(guavaHasher, stringHasher).putNumber((short) 42).hash(); newHasher(guavaHasher, stringHasher).putNumber((byte) 42).hash(); newHasher(guavaHasher, stringHasher).putNumber((float) 42).hash(); newHasher(guavaHasher, stringHasher).putNumber((double) 42).hash(); newHasher(guavaHasher, stringHasher).putString("42").hash(); newHasher(guavaHasher, stringHasher).putBytes(BYTE_ARRAY).hash(); newHasher(guavaHasher, stringHasher).putPattern(PATTERN).hash(); newHasher(guavaHasher, stringHasher) .putSha1(Sha1HashCode.of("a002b39af204cdfaa5fdb67816b13867c32ac52c")) .hash(); newHasher(guavaHasher, stringHasher).putPath(Paths.get("42/42"), HashCode.fromInt(42)).hash(); newHasher(guavaHasher, stringHasher) .putArchiveMemberPath(newArchiveMember("42/42", "42/42"), HashCode.fromInt(42)) .hash(); newHasher(guavaHasher, stringHasher).putNonHashingPath("42").hash(); newHasher(guavaHasher, stringHasher).putSourceRoot(SOURCE_ROOT).hash(); newHasher(guavaHasher, stringHasher).putRuleKey(RULE_KEY_1).hash(); newHasher(guavaHasher, stringHasher).putBuildRuleType(BuildRuleType.of("42")).hash(); newHasher(guavaHasher, stringHasher).putBuildTarget(TARGET_1).hash(); newHasher(guavaHasher, stringHasher) .putBuildTargetSourcePath(new DefaultBuildTargetSourcePath(TARGET_1)) .hash(); newHasher(guavaHasher, stringHasher).putContainer(RuleKeyHasher.Container.LIST, 42).hash(); newHasher(guavaHasher, stringHasher).putContainer(RuleKeyHasher.Container.MAP, 42).hash(); newHasher(guavaHasher, stringHasher).putWrapper(RuleKeyHasher.Wrapper.SUPPLIER).hash(); newHasher(guavaHasher, stringHasher).putWrapper(RuleKeyHasher.Wrapper.OPTIONAL).hash(); newHasher(guavaHasher, stringHasher).putWrapper(RuleKeyHasher.Wrapper.EITHER_LEFT).hash(); newHasher(guavaHasher, stringHasher).putWrapper(RuleKeyHasher.Wrapper.EITHER_RIGHT).hash(); newHasher(guavaHasher, stringHasher).putWrapper(RuleKeyHasher.Wrapper.BUILD_RULE).hash(); newHasher(guavaHasher, stringHasher).putWrapper(RuleKeyHasher.Wrapper.APPENDABLE).hash(); newHasher(guavaHasher, stringHasher) .putKey("45") .putNull() .putBoolean(true) .putNumber(45) .putString("45") .putBytes(BYTE_ARRAY) .putPattern(PATTERN) .putSha1(Sha1HashCode.of("a002b39af204cdfaa5fdb67816b13867c32ac52c")) .putPath(Paths.get("45"), HashCode.fromInt(45)) .putArchiveMemberPath(newArchiveMember("45", "45"), HashCode.fromInt(45)) .putNonHashingPath("45") .putSourceRoot(SOURCE_ROOT) .putRuleKey(RULE_KEY_1) .putBuildRuleType(BuildRuleType.of("45")) .putBuildTarget(TARGET_1) .putBuildTargetSourcePath(new DefaultBuildTargetSourcePath(TARGET_1)) .putContainer(RuleKeyHasher.Container.LIST, 45) .putContainer(RuleKeyHasher.Container.MAP, 45) .putWrapper(RuleKeyHasher.Wrapper.OPTIONAL) .hash(); } @Test public void testHashAndOnHash() { final String string = "hash"; final HashCode hash = createMock(HashCode.class); @SuppressWarnings("unchecked") RuleKeyHasher<String> stringHasher = createStrictMock(RuleKeyHasher.class); @SuppressWarnings("unchecked") RuleKeyHasher<HashCode> guavaHasher = createStrictMock(RuleKeyHasher.class); expect(guavaHasher.hash()).andReturn(hash); expect(stringHasher.hash()).andReturn(string); replay(stringHasher, guavaHasher); ForwardingRuleKeyHasher<HashCode, String> hasher = new ForwardingRuleKeyHasher<HashCode, String>(guavaHasher, stringHasher) { @Override protected void onHash(HashCode firstHash, String secondHash) { assertSame(string, secondHash); assertSame(hash, firstHash); } }; assertSame(hash, hasher.hash()); } private ArchiveMemberPath newArchiveMember(String archivePath, String memberPath) { return ArchiveMemberPath.of(Paths.get(archivePath), Paths.get(memberPath)); } private ForwardingRuleKeyHasher<HashCode, String> newHasher( RuleKeyHasher<HashCode> guavaHasher, RuleKeyHasher<String> stringHasher) { return new ForwardingRuleKeyHasher<HashCode, String>(guavaHasher, stringHasher) { @Override protected void onHash(HashCode firstHash, String secondHash) {} }; } }