public void HashOfChunksInNodeMatchesChunkHashAlgorithm() { using (var nodeHasher = new DedupNodeHashAlgorithm()) using (var chunkHasher = new DedupChunkHashAlgorithm()) { byte[] bytes = new byte[2 * DedupNode.MaxDirectChildrenPerNode * (64 * 1024 /* avg chunk size */)]; var r = new Random(Seed: 0); r.NextBytes(bytes); nodeHasher.ComputeHash(bytes, 0, bytes.Length); var node = nodeHasher.GetNode(); Assert.NotNull(node.Height); Assert.Equal((uint)2, node.Height.Value); ulong offset = 0; foreach (var chunkInNode in node.EnumerateChunkLeafsInOrder()) { byte[] chunkHash = chunkHasher.ComputeHash(bytes, (int)offset, (int)chunkInNode.TransitiveContentBytes); Assert.Equal(chunkHash, chunkInNode.Hash); offset += chunkInNode.TransitiveContentBytes; } } }
private void HashOfChunksInNodeMatchesChunkHashAlgorithmInner(int expectedChunkCount, ChunkerConfiguration config, IChunker chunker) { using (DedupNodeOrChunkHashAlgorithm nodeHasher = new DedupNodeOrChunkHashAlgorithm(chunker)) using (DedupChunkHashAlgorithm chunkHasher = new DedupChunkHashAlgorithm()) { byte[] bytes = new byte[expectedChunkCount * config.AvgChunkSize]; nodeHasher.SetInputLength(bytes.Length); var r = new Random(Seed: 0); r.NextBytes(bytes); nodeHasher.ComputeHash(bytes, 0, bytes.Length); var node = nodeHasher.GetNode(); Assert.NotNull(node.Height); if (expectedChunkCount >= 2 * DedupNode.MaxDirectChildrenPerNode) { Assert.Equal((uint)2, node.Height.Value); } ulong offset = 0; int chunkCount = 0; foreach (var chunkInNode in node.EnumerateChunkLeafsInOrder()) { byte[] chunkHash = chunkHasher.ComputeHash(bytes, (int)offset, (int)chunkInNode.TransitiveContentBytes); Assert.Equal(chunkHash.ToHex(), chunkInNode.Hash.ToHex()); offset += chunkInNode.TransitiveContentBytes; chunkCount += 1; } Assert.Equal(offset, node.TransitiveContentBytes); double ratio = (1.0 * expectedChunkCount) / chunkCount; Assert.True(Math.Abs(ratio - 1.0) < 0.3); // within 30% of expected } }