private void addDirectoryToZipEntryList( File directory, String currentPath, ImmutableMap.Builder<File, ZipEntry> zipEntriesBuilder) throws IOException { Preconditions.checkNotNull(currentPath); for (File inputFile : directory.listFiles()) { String childPath = currentPath + (currentPath.isEmpty() ? "" : "/") + inputFile.getName(); if (inputFile.isDirectory()) { addDirectoryToZipEntryList(inputFile, childPath, zipEntriesBuilder); } else { ZipEntry nextEntry = new ZipEntry(childPath); long fileLength = inputFile.length(); if (fileLength > maxDeflatedBytes || EXTENSIONS_NOT_TO_DEFLATE.contains(Files.getFileExtension(inputFile.getName()))) { nextEntry.setMethod(ZipEntry.STORED); nextEntry.setCompressedSize(inputFile.length()); nextEntry.setSize(inputFile.length()); HashCode crc = ByteStreams.hash(Files.newInputStreamSupplier(inputFile), Hashing.crc32()); nextEntry.setCrc(crc.padToLong()); } zipEntriesBuilder.put(inputFile, nextEntry); } } }
@Test public void testReadFetchResponse() throws IOException { final String base64EncodedData = "AAAALgAAAAEAIDAwMDAwMDAwMDEwMDAwMDAwMDAwMDA4MDAwMDAwMDAwAAAAANcwdr5kYXRh"; final RuleKey ruleKey = new RuleKey("00000000010000000000008000000000"); final String data = "data"; byte[] expectedData; try (ByteArrayOutputStream out = new ByteArrayOutputStream(); DataOutputStream dataOut = new DataOutputStream(out)) { byte[] metadata = HttpArtifactCacheBinaryProtocol.createMetadataHeader( ImmutableSet.of(ruleKey), ImmutableMap.<String, String>of(), ByteSource.wrap(data.getBytes(Charsets.UTF_8))); dataOut.writeInt(metadata.length); dataOut.write(metadata); dataOut.write(data.getBytes(Charsets.UTF_8)); expectedData = out.toByteArray(); } assertThat(expectedData, Matchers.equalTo(BaseEncoding.base64().decode(base64EncodedData))); try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(expectedData))) { FetchResponseReadResult result = HttpArtifactCacheBinaryProtocol.readFetchResponse(inputStream, outputStream); assertThat(result.getRuleKeys(), Matchers.contains(ruleKey)); assertThat(outputStream.toByteArray(), Matchers.equalTo(data.getBytes(Charsets.UTF_8))); assertThat(result.getActualHashCode(), Matchers.equalTo(HashCode.fromString("d73076be"))); assertThat(result.getExpectedHashCode(), Matchers.equalTo(HashCode.fromString("d73076be"))); assertThat(result.getMetadata(), Matchers.anEmptyMap()); assertThat(result.getResponseSizeBytes(), Matchers.equalTo(4L)); } }
@Test public void testComputeAbiKey() { ImmutableSortedMap<String, HashCode> classNamesAndHashes = ImmutableSortedMap.of( "com/example/Foo", HashCode.fromString("e4fccb7520b7795e632651323c63217c9f59f72a"), "com/example/Bar", HashCode.fromString("087b7707a5f8e0a2adf5652e3cd2072d89a197dc"), "com/example/Baz", HashCode.fromString("62b1c2510840c0de55c13f66065a98a719be0f19")); String observedSha1 = DexProducedFromJavaLibrary.computeAbiKey(classNamesAndHashes).getHash(); String expectedSha1 = Hashing.sha1() .newHasher() .putUnencodedChars("com/example/Bar") .putByte((byte) 0) .putUnencodedChars("087b7707a5f8e0a2adf5652e3cd2072d89a197dc") .putByte((byte) 0) .putUnencodedChars("com/example/Baz") .putByte((byte) 0) .putUnencodedChars("62b1c2510840c0de55c13f66065a98a719be0f19") .putByte((byte) 0) .putUnencodedChars("com/example/Foo") .putByte((byte) 0) .putUnencodedChars("e4fccb7520b7795e632651323c63217c9f59f72a") .putByte((byte) 0) .hash() .toString(); assertEquals(expectedSha1, observedSha1); }
@Test public void ruleKeyChangesIfInputContentsFromPathSourceChanges() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); SourcePathResolver pathResolver = new SourcePathResolver(resolver); FakeProjectFilesystem filesystem = new FakeProjectFilesystem(); Path output = Paths.get("output"); BuildRule rule = ExportFileBuilder.newExportFileBuilder(BuildTargetFactory.newInstance("//:rule")) .setOut("out") .setSrc(new PathSourcePath(filesystem, output)) .build(resolver, filesystem); // Build a rule key with a particular hash set for the output for the above rule. FakeFileHashCache hashCache = new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(output), HashCode.fromInt(0))); RuleKey inputKey1 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule); // Now, build a rule key with a different hash for the output for the above rule. hashCache = new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(output), HashCode.fromInt(1))); RuleKey inputKey2 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule); assertThat(inputKey1, Matchers.not(Matchers.equalTo(inputKey2))); }
@Test public void ruleKeyChangesIfInputContentsFromPathSourcePathInRuleKeyAppendableChanges() { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); SourcePathResolver pathResolver = new SourcePathResolver(resolver); final FakeProjectFilesystem filesystem = new FakeProjectFilesystem(); final Path output = Paths.get("output"); BuildRuleParams params = new FakeBuildRuleParamsBuilder("//:rule").setProjectFilesystem(filesystem).build(); BuildRule rule = new NoopBuildRule(params, pathResolver) { @AddToRuleKey RuleKeyAppendableWithInput input = new RuleKeyAppendableWithInput(new PathSourcePath(filesystem, output)); }; // Build a rule key with a particular hash set for the output for the above rule. FakeFileHashCache hashCache = new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(output), HashCode.fromInt(0))); RuleKey inputKey1 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule); // Now, build a rule key with a different hash for the output for the above rule. hashCache = new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(output), HashCode.fromInt(1))); RuleKey inputKey2 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule); assertThat(inputKey1, Matchers.not(Matchers.equalTo(inputKey2))); }
/** Get a Md5 string which is similar to OS Md5sum */ public static String md5(File file) { try { HashCode hc = Files.hash(file, Hashing.md5()); return toHex(hc.asBytes()); } catch (Exception e) { throw new RuntimeException(e); } }
private String generateHashKey(StringBuilder hashSourceBuilder, String apiKey) { String hashSource = hashSourceBuilder.toString() + apiKey; HashCode hashCode = Hashing.sha1().hashString(hashSource, Charset.defaultCharset()); Log.d( LOG_TAG, String.format("creating sha1 from [%s] resulted with hash [%s]", hashSource, hashCode)); return hashCode.toString(); }
HashCode makeHash(Hasher[] hashers) { byte[] bytes = new byte[this.bits / 8]; int i = 0; for (Hasher hasher : hashers) { HashCode newHash = hasher.hash(); i += newHash.writeBytesTo(bytes, i, newHash.bits() / 8); } return HashCode.fromBytesNoCopy(bytes); }
@Override public boolean equals(@Nullable Object object) { if (object instanceof HashCode) { HashCode that = (HashCode) object; // Undocumented: this is a non-short-circuiting equals(), in case this is a cryptographic // hash code, in which case we don't want to leak timing information return MessageDigest.isEqual(this.asBytes(), that.asBytes()); } return false; }
public void testCombineOrdered_randomHashCodes() { Random random = new Random(7); List<HashCode> hashCodes = Lists.newArrayList(); for (int i = 0; i < 10; i++) { hashCodes.add(HashCodes.fromLong(random.nextLong())); } HashCode hashCode1 = Hashing.combineOrdered(hashCodes); Collections.shuffle(hashCodes, random); HashCode hashCode2 = Hashing.combineOrdered(hashCodes); assertFalse(hashCode1.equals(hashCode2)); }
@Test public void hashTest() throws Exception { String s1 = "abcdef"; String s2 = "12345"; HashCode hash1 = murmur3Hash.newHasher().putBytes(s1.getBytes()).hash(); System.out.println(hash1); HashCode hash2 = murmur3Hash.newHasher().putBytes(s2.getBytes()).hash(); System.out.println(hash2); HashCode hash3 = murmur3Hash.newHasher().putBytes(s1.getBytes()).hash(); System.out.println(hash3); System.out.println(hash1.equals(hash2)); System.out.println(hash1.equals(hash3)); }
private boolean haveSameContents(File file, final JarFile jar, final JarEntry entry) throws IOException { HashFunction hashFun = Hashing.md5(); HashCode fileHash = Files.hash(file, hashFun); HashCode streamHash = ByteStreams.hash( new InputSupplier<InputStream>() { public InputStream getInput() throws IOException { return jar.getInputStream(entry); } }, hashFun); return fileHash.equals(streamHash); }
public static FakeFileHashCache createFromStrings( ProjectFilesystem filesystem, Map<String, String> pathsToHashes) { Map<Path, HashCode> cachedValues = new HashMap<>(); for (Map.Entry<String, String> entry : pathsToHashes.entrySet()) { // Retain the original behaviour cachedValues.put(Paths.get(entry.getKey()), HashCode.fromString(entry.getValue())); // And ensure that the absolute path is also present. if (!entry.getKey().startsWith("/")) { cachedValues.put(filesystem.resolve(entry.getKey()), HashCode.fromString(entry.getValue())); } } return new FakeFileHashCache(cachedValues); }
public static HashCode combineOrdered(Iterable<HashCode> hashCodes) { Iterator<HashCode> iterator = hashCodes.iterator(); Preconditions.checkArgument(iterator.hasNext(), "Must be at least 1 hash code to combine."); int bits = ((HashCode) iterator.next()).bits(); byte[] resultBytes = new byte[bits / 8]; for (HashCode hashCode : hashCodes) { byte[] nextBytes = hashCode.asBytes(); Preconditions.checkArgument( nextBytes.length == resultBytes.length, "All hashcodes must have the same bit length."); for (int i = 0; i < nextBytes.length; i++) { resultBytes[i] = ((byte) (resultBytes[i] * 37 ^ nextBytes[i])); } } return HashCode.fromBytesNoCopy(resultBytes); }
public static HashCode combineUnordered(Iterable<HashCode> hashCodes) { Iterator<HashCode> iterator = hashCodes.iterator(); Preconditions.checkArgument(iterator.hasNext(), "Must be at least 1 hash code to combine."); byte[] resultBytes = new byte[((HashCode) iterator.next()).bits() / 8]; for (HashCode hashCode : hashCodes) { byte[] nextBytes = hashCode.asBytes(); Preconditions.checkArgument( nextBytes.length == resultBytes.length, "All hashcodes must have the same bit length."); for (int i = 0; i < nextBytes.length; tmp102_100++) { int tmp102_100 = i; byte[] tmp102_99 = resultBytes; tmp102_99[tmp102_100] = ((byte) (tmp102_99[tmp102_100] + nextBytes[tmp102_100])); } } return HashCode.fromBytesNoCopy(resultBytes); }
@Test public void testWriteStoreRequest() throws IOException { final String base64EncodedData = "AAAAAgAgMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAIDkwMDA" + "wMDAwMDAwMDAwMDAwMDAwMDA4MDAwMDAwMDA1AAAAXgAAAAIAIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA" + "wMDAwACA5MDAwMDAwMDAwMDAwMDAwMDAwMDAwODAwMDAwMDAwNQAAAAEAA2tleQAAAAV2YWx1ZRf0zcZkYXRhZGF" + "0YQ=="; final RuleKey ruleKey = new RuleKey("00000000000000000000000000000000"); final RuleKey ruleKey2 = new RuleKey("90000000000000000000008000000005"); HttpArtifactCacheBinaryProtocol.StoreRequest storeRequest = new HttpArtifactCacheBinaryProtocol.StoreRequest( ArtifactInfo.builder() .addRuleKeys(ruleKey, ruleKey2) .setMetadata(ImmutableMap.of("key", "value")) .build(), new ByteSource() { @Override public InputStream openStream() throws IOException { return new ByteArrayInputStream("datadata".getBytes(Charsets.UTF_8)); } }); assertThat(storeRequest.getContentLength(), Matchers.is(178L)); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); StoreWriteResult writeResult = storeRequest.write(byteArrayOutputStream); assertThat( writeResult.getArtifactContentHashCode(), Matchers.equalTo(HashCode.fromString("2c0b14a4"))); assertThat(writeResult.getArtifactSizeBytes(), Matchers.is(8L)); byte[] expectedBytes = BaseEncoding.base64().decode(base64EncodedData); assertThat(byteArrayOutputStream.toByteArray(), Matchers.equalTo(expectedBytes)); }
@Test public void ruleKeyDoesNotChangeWhenOnlyDependencyRuleKeyChanges() { BuildRuleResolver resolver = new BuildRuleResolver(); SourcePathResolver pathResolver = new SourcePathResolver(resolver); Path depOutput = Paths.get("output"); FakeBuildRule dep = resolver.addToIndex( new FakeBuildRule(BuildTargetFactory.newInstance("//:dep"), pathResolver)); dep.setOutputFile(depOutput.toString()); FakeFileHashCache hashCache = new FakeFileHashCache(ImmutableMap.of(depOutput, HashCode.fromInt(0))); BuildRule rule = new FakeAbiRuleBuildRule("//:rule", pathResolver, dep); dep.setRuleKey(new RuleKey("aaaa")); RuleKey inputKey1 = new AbiRuleKeyBuilderFactory(hashCache, pathResolver).newInstance(rule).build(); dep.setRuleKey(new RuleKey("bbbb")); RuleKey inputKey2 = new AbiRuleKeyBuilderFactory(hashCache, pathResolver).newInstance(rule).build(); assertThat(inputKey1, equalTo(inputKey2)); }
/** * Non-idempotent RuleKeys are normally output as strings of 'x' characters, but when comparing * two sets of RuleKeys in textual form it is necessary to mangle one of the two sets, so that * non-idempotent RuleKeys are never considered equal. */ public String toString(boolean mangleNonIdempotent) { if (!isIdempotent()) { return new String(new char[Hashing.sha1().bits() / 4]) .replace("\0", mangleNonIdempotent ? "y" : "x"); } return hashCode.toString(); }
@Test public void ruleKeyDoesNotChangeWhenOnlyDependencyRuleKeyChanges() throws Exception { ProjectFilesystem filesystem = new FakeProjectFilesystem(); BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); SourcePathResolver pathResolver = new SourcePathResolver(resolver); Path depOutput = Paths.get("output"); FakeBuildRule dep = resolver.addToIndex( new FakeBuildRule(BuildTargetFactory.newInstance("//:dep"), filesystem, pathResolver)); dep.setOutputFile(depOutput.toString()); filesystem.writeContentsToPath("hello", dep.getPathToOutput()); FakeFileHashCache hashCache = new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(depOutput), HashCode.fromInt(0))); BuildRule rule = GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:rule")) .setOut("out") .setSrcs(ImmutableList.<SourcePath>of(new BuildTargetSourcePath(dep.getBuildTarget()))) .build(resolver, filesystem); RuleKey inputKey1 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule); RuleKey inputKey2 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule); assertThat(inputKey1, Matchers.equalTo(inputKey2)); }
@Override public void run() { for (Map.Entry<String, ConfigFileInfo> entry : watchedFileMap.entrySet()) { String filePath = entry.getKey(); ConfigFileInfo configFileInfo = entry.getValue(); try { File file = new File(filePath); long lastModified = file.lastModified(); Preconditions.checkArgument(lastModified > 0L); if (lastModified != configFileInfo.lastModifiedTimestampMillis) { configFileInfo.lastModifiedTimestampMillis = lastModified; ByteSource byteSource = Files.asByteSource(file); HashCode newContentHash = byteSource.hash(HASH_FUNCTION); if (!newContentHash.equals(configFileInfo.contentHash)) { configFileInfo.contentHash = newContentHash; LOG.info("File {} was modified at {}, notifying watchers.", filePath, lastModified); byte[] newContents = byteSource.read(); for (Function<byte[], Void> watchers : configFileInfo.changeWatchers) { try { watchers.apply(newContents); } catch (Exception e) { LOG.error( "Exception in watcher callback for {}, ignoring. New file contents were: {}", filePath, new String(newContents, Charsets.UTF_8), e); } } } else { LOG.info( "File {} was modified at {} but content hash is unchanged.", filePath, lastModified); } } else { LOG.debug("File {} not modified since {}", filePath, lastModified); } } catch (Exception e) { // We catch and log exceptions related to the update of any specific file, but // move on so others aren't affected. Issues can happen for example if the watcher // races with an external file replace operation; in that case, the next run should // pick up the update. // TODO: Consider adding a metric to track this so we can alert on failures. LOG.error("Config update check failed for {}", filePath, e); } } }
@Test public void ruleKeyChangesIfInputContentsFromBuildTargetSourcePathInRuleKeyAppendableChanges() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); SourcePathResolver pathResolver = new SourcePathResolver(resolver); final FakeProjectFilesystem filesystem = new FakeProjectFilesystem(); final BuildRule dep = GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:dep")) .setOut("out") .build(resolver, filesystem); BuildRuleParams params = new FakeBuildRuleParamsBuilder("//:rule") .setDeclaredDeps(ImmutableSortedSet.of(dep)) .setProjectFilesystem(filesystem) .build(); BuildRule rule = new NoopBuildRule(params, pathResolver) { @AddToRuleKey RuleKeyAppendableWithInput input = new RuleKeyAppendableWithInput(new BuildTargetSourcePath(dep.getBuildTarget())); }; // Build a rule key with a particular hash set for the output for the above rule. FakeFileHashCache hashCache = new FakeFileHashCache( ImmutableMap.of( filesystem.resolve(Preconditions.checkNotNull(dep.getPathToOutput())), HashCode.fromInt(0))); RuleKey inputKey1 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule); // Now, build a rule key with a different hash for the output for the above rule. hashCache = new FakeFileHashCache( ImmutableMap.of( filesystem.resolve(Preconditions.checkNotNull(dep.getPathToOutput())), HashCode.fromInt(1))); RuleKey inputKey2 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule); assertThat(inputKey1, Matchers.not(Matchers.equalTo(inputKey2))); }
private static String createStringToSign( String date, String credentialScope, HashCode hashedCanonicalRequest) { return ALGORITHM + "\n" + date + "\n" + credentialScope + "\n" + hashedCanonicalRequest.toString(); }
@Override public void endElement(String uri, String name, String qName) { if (qName.equals("Id")) { this.id = currentOrNull(currentText); } else if (qName.equals("MessageId")) { builder.id(currentOrNull(currentText)); } else if (qName.equals("MD5OfMessageBody")) { builder.md5(HashCode.fromBytes(base16().lowerCase().decode(currentOrNull(currentText)))); } currentText.setLength(0); }
private static void assertMessageDigestHashing(byte[] input, String algorithmName) { try { MessageDigest digest = MessageDigest.getInstance(algorithmName); assertEquals( HashCode.fromBytes(digest.digest(input)), ALGORITHMS.get(algorithmName).hashBytes(input)); for (int bytes = 4; bytes <= digest.getDigestLength(); bytes++) { assertEquals( HashCode.fromBytes(Arrays.copyOf(digest.digest(input), bytes)), new MessageDigestHashFunction(algorithmName, bytes, algorithmName).hashBytes(input)); } try { int maxSize = digest.getDigestLength(); new MessageDigestHashFunction(algorithmName, maxSize + 1, algorithmName); fail(); } catch (IllegalArgumentException expected) { } } catch (NoSuchAlgorithmException nsae) { throw new AssertionError(nsae); } }
/** * Order non-idempotent RuleKeys as less than all idempotent RuleKeys. * * <p>non-idempotent < idempotent */ @Override public int compareTo(RuleKey other) { if (!isIdempotent()) { if (!other.isIdempotent()) { return 0; } return -1; } else if (!other.isIdempotent()) { return 1; } return ByteBuffer.wrap(hashCode.asBytes()).compareTo(ByteBuffer.wrap(other.hashCode.asBytes())); }
@Override public AsyncLeaderElector newAsyncLeaderElector(String name) { checkNotNull(name); Map<PartitionId, AsyncLeaderElector> leaderElectors = Maps.transformValues(members, partition -> partition.newAsyncLeaderElector(name)); Hasher<String> hasher = topic -> { long hashCode = HashCode.fromBytes(topic.getBytes(Charsets.UTF_8)).asLong(); return sortedMemberPartitionIds.get(Hashing.consistentHash(hashCode, members.size())); }; return new PartitionedAsyncLeaderElector(name, leaderElectors, hasher); }
/** * This test validates that the md5sum() method returns hashes that match the official test * vectors specified in RFC 1321, The MD5 Message-Digest Algorithm. * * @throws Exception */ @Test public void testValidateMd5Sum() throws Exception { ImmutableMap<String, String> testVectors = ImmutableMap.<String, String>builder() .put("", "d41d8cd98f00b204e9800998ecf8427e") .put("a", "0cc175b9c0f1b6a831c399e269772661") .put("abc", "900150983cd24fb0d6963f7d28e17f72") .put("message digest", "f96b697d7cb7938d525a2f31aaf161d0") .put("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b") .put( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "d174ab98d277d9f5a5611c2c9f419d9f") .put( "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a") .build(); for (String testInput : testVectors.keySet()) { FileSystemUtils.writeContentAsLatin1(testFile, testInput); HashCode result = NativePosixFiles.md5sum(testFile.getPathString()); assertThat(testVectors).containsEntry(testInput, result.toString()); } }
private Builder setVal(@Nullable File file) { if (file != null) { // Compute a separate SHA-1 for the file contents and feed that into messageDigest rather // than the file contents, in order to avoid the overhead of escaping SEPARATOR in the file // content. try { byte[] fileBytes = Files.toByteArray(file); HashCode fileSha1 = Hashing.sha1().hashBytes(fileBytes); if (logElms != null) { logElms.add( String.format("file(path=\"%s\", sha1=%s):", file.getPath(), fileSha1.toString())); } feed(fileSha1.asBytes()); } catch (IOException e) { // The file is nonexistent/unreadable; generate a RuleKey that prevents accidental // caching. if (logElms != null) { logElms.add(String.format("file(path=\"%s\", sha1=random):", file.getPath())); } nonIdempotent(); } } return separate(); }
@Override public <K, V> AsyncConsistentMap<K, V> newAsyncConsistentMap(String name, Serializer serializer) { checkNotNull(name); checkNotNull(serializer); Map<PartitionId, AsyncConsistentMap<K, V>> maps = Maps.transformValues( members, partition -> partition.newAsyncConsistentMap(name, serializer)); Hasher<K> hasher = key -> { long hashCode = HashCode.fromBytes(Bytes.ensureCapacity(serializer.encode(key), 8, 0)).asLong(); return sortedMemberPartitionIds.get(Hashing.consistentHash(hashCode, members.size())); }; return new PartitionedAsyncConsistentMap<>(name, maps, hasher); }
@Test public void testObserverMethods() { JavaLibrary accumulateClassNames = createMock(JavaLibrary.class); expect(accumulateClassNames.getClassNamesToHashes()) .andReturn(ImmutableSortedMap.of("com/example/Foo", HashCode.fromString("cafebabe"))) .anyTimes(); replayAll(); BuildTarget buildTarget = BuildTargetFactory.newInstance("//foo:bar"); BuildRuleParams params = new FakeBuildRuleParamsBuilder(buildTarget).build(); DexProducedFromJavaLibrary preDexWithClasses = new DexProducedFromJavaLibrary( params, new SourcePathResolver(new BuildRuleResolver()), accumulateClassNames); assertNull(preDexWithClasses.getPathToOutput()); assertEquals(Paths.get("buck-out/gen/foo/bar.dex.jar"), preDexWithClasses.getPathToDex()); verifyAll(); }