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

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

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

            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.ChunkId2)))
                .Returns(AllocateJobChunkSpectraS3Response.Success(Stubs.Chunk2(Stubs.NodeId2, false, false)));

            var source = new WriteRandomAccessChunkStrategy(time => { }, withAggregation: true);
            var transfers = source.GetNextTransferItems(client.Object, jobResponse).ToArray();

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

            client.VerifyAll();
            clientFactory.VerifyAll();
        }
        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 WriteRandomAccessChunkStrategy(sleeps.Add); //we don't want to really sleep in the tests
            var transfers = source.GetNextTransferItems(client.Object, jobResponse).ToArray();

            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"))
                },
                transfers,
                new TransferItemSourceHelpers.TransferItemComparer()
            );

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

            client.VerifyAll();
            clientFactory.VerifyAll();
        }
        public void TestGetNextTransferItemsRetryAfter()
        {
            var jobResponse = Stubs.BuildJobResponse(
                Stubs.Chunk1(Stubs.NodeId1, false, false)
            );

            var clientFactory = new Mock<IDs3ClientFactory>(MockBehavior.Strict);

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

            client
                .Setup(c => c.AllocateJobChunkSpectraS3(AllocateMock.Allocate(Stubs.ChunkId1)))
                .Returns(AllocateJobChunkSpectraS3Response.RetryAfter(TimeSpan.FromMinutes(5)));

            var sleeps = new List<TimeSpan>();

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

            using (var transfers = source.GetNextTransferItems(client.Object, jobResponse).GetEnumerator())
            {
                try
                {
                    Assert.True(source.RetryAfer.RetryAfterLeft == 2);
                    transfers.MoveNext(); //Should throw Ds3NoMoreRetriesException
                    Assert.Fail();
                }
                catch (Ds3NoMoreRetriesException ex)
                {
                    Assert.True(source.RetryAfer.RetryAfterLeft == 0);
                    Assert.True(ex.Message.Equals(Resources.NoMoreRetriesException));
                }
            }

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

            source = new WriteRandomAccessChunkStrategy(_ => { }, 0);
            using (var transfers = source.GetNextTransferItems(client.Object, jobResponse).GetEnumerator())
            {
                try
                {
                    Assert.True(source.RetryAfer.RetryAfterLeft == 0);
                    transfers.MoveNext(); //Should throw Ds3NoMoreRetriesException
                    Assert.Fail();
                }
                catch (Ds3NoMoreRetriesException ex)
                {
                    Assert.True(source.RetryAfer.RetryAfterLeft == 0);
                    Assert.True(ex.Message.Equals(Resources.NoMoreRetriesException));
                }
            }

            source = new WriteRandomAccessChunkStrategy(_ => { }, 1);
            using (var transfers = source.GetNextTransferItems(client.Object, jobResponse).GetEnumerator())
            {
                try
                {
                    Assert.True(source.RetryAfer.RetryAfterLeft == 1);
                    transfers.MoveNext(); //Should throw Ds3NoMoreRetriesException
                    Assert.Fail();
                }
                catch (Ds3NoMoreRetriesException ex)
                {
                    Assert.True(source.RetryAfer.RetryAfterLeft == 0);
                    Assert.True(ex.Message.Equals(Resources.NoMoreRetriesException));
                }
            }

            source = new WriteRandomAccessChunkStrategy(_ => { }, 2);
            using (var transfers = source.GetNextTransferItems(client.Object, jobResponse).GetEnumerator())
            {
                try
                {
                    Assert.True(source.RetryAfer.RetryAfterLeft == 2);
                    transfers.MoveNext(); //Should throw Ds3NoMoreRetriesException
                    Assert.Fail();
                }
                catch (Ds3NoMoreRetriesException ex)
                {
                    Assert.True(source.RetryAfer.RetryAfterLeft == 0);
                    Assert.True(ex.Message.Equals(Resources.NoMoreRetriesException));
                }
            }

            source = new WriteRandomAccessChunkStrategy(_ => { }, 100);
            using (var transfers = source.GetNextTransferItems(client.Object, jobResponse).GetEnumerator())
            {
                try
                {
                    Assert.True(source.RetryAfer.RetryAfterLeft == 100);
                    transfers.MoveNext(); //Should throw Ds3NoMoreRetriesException
                    Assert.Fail();
                }
                catch (Ds3NoMoreRetriesException ex)
                {
                    Assert.True(source.RetryAfer.RetryAfterLeft == 0);
                    Assert.True(ex.Message.Equals(Resources.NoMoreRetriesException));
                }
            }

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