public void TestGetNextTransferItems()
        {
            var jobResponse = Stubs.BuildJobResponse(
                Stubs.Chunk1(Stubs.NodeId1, false, false),
                Stubs.Chunk2(Stubs.NodeId2, false, false)
            );

            var node1Client = new Mock<IDs3Client>(MockBehavior.Strict).Object;

            var clientFactory = new Mock<IDs3ClientFactory>(MockBehavior.Strict);
            clientFactory.Setup(cf => cf.GetClientForNodeId(Stubs.NodeId1)).Returns(node1Client);
            clientFactory.Setup(cf => cf.GetClientForNodeId(Stubs.NodeId2)).Returns(node1Client);

            var client = new Mock<IDs3Client>(MockBehavior.Strict);
            client.Setup(c => c.BuildFactory(Stubs.Nodes)).Returns(clientFactory.Object);

            client
                .SetupSequence(c => c.AllocateJobChunkSpectraS3(AllocateMock.Allocate(Stubs.ChunkId1)))
                .Returns(AllocateJobChunkSpectraS3Response.RetryAfter(TimeSpan.FromMinutes(5)))
                .Returns(AllocateJobChunkSpectraS3Response.Success(Stubs.Chunk1(Stubs.NodeId1, false, false)));

            client
                .SetupSequence(c => c.AllocateJobChunkSpectraS3(AllocateMock.Allocate(Stubs.ChunkId2)))
                .Returns(AllocateJobChunkSpectraS3Response.RetryAfter(TimeSpan.FromMinutes(5)))
                .Returns(AllocateJobChunkSpectraS3Response.Success(Stubs.Chunk2(Stubs.NodeId2, false, false)));

            var sleeps = new List<TimeSpan>();

            var source = new WriteStreamChunkStrategy(sleeps.Add); //we don't want to really sleep in the tests

            var transfers = source.GetNextTransferItems(client.Object, jobResponse).GetEnumerator();
            var transfered = new TransferItem[4];
            for (var i = 0; i < 4; i++)
            {
                Assert.True(transfers.MoveNext());
                transfered[i] = transfers.Current;
                source.CompleteBlob(transfers.Current.Blob);
            }

            CollectionAssert.AreEqual(
                new[]
                {
                    new TransferItem(node1Client, new Blob(Range.ByLength(0, 15), "bar")),
                    new TransferItem(node1Client, new Blob(Range.ByLength(0, 10), "foo")),
                    new TransferItem(node1Client, new Blob(Range.ByLength(10, 10), "foo")),
                    new TransferItem(node1Client, new Blob(Range.ByLength(15, 20), "bar"))
                },
                transfered,
                new TransferItemSourceHelpers.TransferItemComparer()
            );

            CollectionAssert.AreEqual(
                new[] {TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)},
                sleeps
            );

            client.VerifyAll();
            clientFactory.VerifyAll();
        }
        public void TestGetNextTransferItems()
        {
            var jobResponse1 = JobResponseStubs.BuildJobResponse(
                JobResponseStubs.Chunk1(JobResponseStubs.NodeId1, false, false),
                JobResponseStubs.Chunk2(JobResponseStubs.NodeId1, false, false),
                JobResponseStubs.Chunk3(JobResponseStubs.NodeId1, false, false)
            );

            var node1Client = new Mock<IDs3Client>(MockBehavior.Strict).Object;

            var clientFactory = new Mock<IDs3ClientFactory>(MockBehavior.Strict);
            clientFactory.Setup(cf => cf.GetClientForNodeId(JobResponseStubs.NodeId1)).Returns(node1Client);

            var client = new Mock<IDs3Client>(MockBehavior.Strict);
            client.Setup(c => c.BuildFactory(JobResponseStubs.Nodes)).Returns(clientFactory.Object);

            client
                .SetupSequence(
                    c =>
                        c.GetJobChunksReadyForClientProcessingSpectraS3(
                            AllocateMock.AvailableChunks(JobResponseStubs.JobId)))
                .Returns(GetJobChunksReadyForClientProcessingSpectraS3Response.RetryAfter(TimeSpan.FromMinutes(5)))
                .Returns(GetJobChunksReadyForClientProcessingSpectraS3Response.Success(TimeSpan.FromMinutes(5),
                    jobResponse1));

            var sleeps = new List<TimeSpan>();

            var source = new ReadStreamChunkStrategy(sleeps.Add);

            using (var transfers = source.GetNextTransferItems(client.Object, jobResponse1).GetEnumerator())
            {
                var transfered = new TransferItem[6];
                for (var i = 0; i < 6; i++)
                {
                    Assert.True(transfers.MoveNext());
                    transfered[i] = transfers.Current;
                    source.CompleteBlob(transfers.Current.Blob);
                }

                Assert.False(transfers.MoveNext());

                CollectionAssert.AreEqual(
                    new[]
                    {
                        new TransferItem(node1Client, new Blob(Range.ByLength(0, 15), "bar")),
                        new TransferItem(node1Client, new Blob(Range.ByLength(0, 10), "foo")),
                        new TransferItem(node1Client, new Blob(Range.ByLength(0, 10), "hello")),
                        new TransferItem(node1Client, new Blob(Range.ByLength(10, 10), "foo")),
                        new TransferItem(node1Client, new Blob(Range.ByLength(15, 20), "bar")),
                        new TransferItem(node1Client, new Blob(Range.ByLength(35, 11), "bar"))
                    },
                    transfered,
                    new TransferItemSourceHelpers.TransferItemComparer()
                );

                CollectionAssert.AreEqual(
                    new[] {TimeSpan.FromMinutes(5)},
                    sleeps
                );
            }

            client.VerifyAll();
            clientFactory.VerifyAll();
        }