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
                }
        }