internal async Task <Response <Stream> > DownloadStreamingInternal(Uri sourceEndpoint, HttpRange range, bool async, CancellationToken cancellationToken)
        {
            Argument.AssertNotNull(sourceEndpoint, nameof(sourceEndpoint));

            Response <Stream> response;

            if (async)
            {
                response = await StartDownloadAsync(sourceEndpoint, range, cancellationToken : cancellationToken).ConfigureAwait(false);
            }
            else
            {
                response = StartDownload(sourceEndpoint, range, cancellationToken: cancellationToken);
            }

            Stream stream = RetriableStream.Create(
                response.Value,
                startOffset => StartDownload(sourceEndpoint, range, startOffset, cancellationToken).Value,
                async startOffset => (await StartDownloadAsync(sourceEndpoint, range, startOffset, cancellationToken).ConfigureAwait(false)).Value,
                _client._pipeline.ResponseClassifier,
                Constants.ContentDownloader.RetriableStreamRetries
                );

            return(Response.FromValue(stream, response.GetRawResponse()));
        }
        public async Task DoesntRetryNonRetryableExceptions()
        {
            var stream1 = new MockReadStream(100, throwAfter: 50);
            var stream2 = new MockReadStream(50, offset: 50, throwAfter: 0, throwIOException: false);

            var mockTransport = new MockTransport(
                new MockResponse(200)
            {
                ContentStream = stream1
            },
                new MockResponse(200)
            {
                ContentStream = stream2
            }
                );
            var pipeline = new HttpPipeline(mockTransport);

            var reliableStream = await RetriableStream.Create(offset => SendTestRequestAsync(pipeline, offset), new ResponseClassifier(), maxRetries : 5);

            Assert.AreEqual(25, await reliableStream.ReadAsync(_buffer, 0, 25));
            Assert.AreEqual(100, reliableStream.Length);
            Assert.AreEqual(25, reliableStream.Position);

            Assert.AreEqual(25, await reliableStream.ReadAsync(_buffer, 25, 25));
            Assert.AreEqual(100, reliableStream.Length);
            Assert.AreEqual(50, reliableStream.Position);

            Assert.ThrowsAsync <InvalidOperationException>(() => reliableStream.ReadAsync(_buffer, 50, 50));

            AssertReads(_buffer, 50);
        }
        public async Task DoesntCallLengthPrematurely()
        {
            var stream1 = new NoLengthStream();
            var stream2 = new MockReadStream(50);

            var mockTransport = new MockTransport(
                new MockResponse(200)
            {
                ContentStream = stream1
            },
                new MockResponse(200)
            {
                ContentStream = stream2
            }
                );
            var pipeline = new HttpPipeline(mockTransport);

            var reliableStream = RetriableStream.Create(await SendTestRequestAsync(pipeline, 0), offset => SendTestRequestAsync(pipeline, offset), new ResponseClassifier(), maxRetries: 5);

            Assert.AreEqual(50, await reliableStream.ReadAsync(_buffer, 0, 50));
            Assert.AreEqual(50, reliableStream.Position);

            Assert.AreEqual(0, await reliableStream.ReadAsync(_buffer, 0, 50));

            Assert.Throws <NotSupportedException>(() => _ = reliableStream.Length);

            AssertReads(_buffer, 50);
        }
        public async Task MaintainsGlobalLengthAndPosition()
        {
            var stream1 = new MockReadStream(100, throwAfter: 50);
            var stream2 = new MockReadStream(50, offset: 50, throwIOException: false);

            var mockTransport = new MockTransport(
                new MockResponse(200)
            {
                ContentStream = stream1
            },
                new MockResponse(200)
            {
                ContentStream = stream2
            }
                );
            var pipeline = new HttpPipeline(mockTransport);

            var reliableStream = await RetriableStream.Create(offset => SendTestRequestAsync(pipeline, offset), new ResponseClassifier(), maxRetries : 5);

            Assert.AreEqual(25, await reliableStream.ReadAsync(_buffer, 0, 25));
            Assert.AreEqual(100, reliableStream.Length);
            Assert.AreEqual(25, reliableStream.Position);

            Assert.AreEqual(25, await reliableStream.ReadAsync(_buffer, 25, 25));
            Assert.AreEqual(100, reliableStream.Length);
            Assert.AreEqual(50, reliableStream.Position);

            Assert.AreEqual(50, await reliableStream.ReadAsync(_buffer, 50, 50));
            Assert.AreEqual(100, reliableStream.Length);
            Assert.AreEqual(100, reliableStream.Position);

            Assert.AreEqual(0, await reliableStream.ReadAsync(_buffer, 0, 50));
            AssertReads(_buffer, 100);
        }
        public async Task ThrowsIfSendingRetryRequestThrows()
        {
            var stream1       = new MockReadStream(100, throwAfter: 50);
            var mockTransport = new MockTransport(new MockResponse(200)
            {
                ContentStream = stream1
            });

            var pipeline = new HttpPipeline(mockTransport);

            var reliableStream = await RetriableStream.Create(
                async offset =>
            {
                if (offset == 0)
                {
                    return(await SendTestRequestAsync(pipeline, offset));
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }, new ResponseClassifier(), maxRetries : 5);

            await reliableStream.ReadAsync(_buffer, 0, 25);

            await reliableStream.ReadAsync(_buffer, 25, 25);

            AssertReads(_buffer, 50);
            Assert.ThrowsAsync <InvalidOperationException>(() => reliableStream.ReadAsync(_buffer, 50, 50));
        }
 private Task <Stream> CreateAsync(
     Func <long, Response> responseFactory,
     Func <long, Task <Response> > asyncResponseFactory,
     ResponseClassifier responseClassifier,
     int maxRetries)
 {
     return(IsAsync ?
            RetriableStream.CreateAsync(responseFactory, asyncResponseFactory, responseClassifier, maxRetries) :
            Task.FromResult(RetriableStream.Create(responseFactory, asyncResponseFactory, responseClassifier, maxRetries)));
 }
        public async Task RetriesMaxCountAndThrowsAggregateException()
        {
            var mockTransport = new MockTransport(
                new MockResponse(200)
            {
                ContentStream = new MockReadStream(100, throwAfter: 1)
            },
                new MockResponse(200)
            {
                ContentStream = new MockReadStream(100, throwAfter: 1, offset: 1)
            },
                new MockResponse(200)
            {
                ContentStream = new MockReadStream(100, throwAfter: 1, offset: 2)
            },
                new MockResponse(200)
            {
                ContentStream = new MockReadStream(100, throwAfter: 1, offset: 3)
            }
                );

            var pipeline = new HttpPipeline(mockTransport);

            var reliableStream = await RetriableStream.Create(
                async offset =>
            {
                if (offset == 0)
                {
                    return(await SendTestRequestAsync(pipeline, offset));
                }

                throw new InvalidOperationException();
            }, new ResponseClassifier(), maxRetries : 3);

            var aggregateException = Assert.ThrowsAsync <AggregateException>(() => reliableStream.ReadAsync(_buffer, 0, 4));

            StringAssert.StartsWith("Retry failed after 4 tries", aggregateException.Message);
            Assert.AreEqual(4, aggregateException.InnerExceptions.Count);
            Assert.AreEqual("Failed at 0", aggregateException.InnerExceptions[0].Message);
            Assert.AreEqual("Failed at 1", aggregateException.InnerExceptions[1].Message);
            Assert.AreEqual("Failed at 2", aggregateException.InnerExceptions[2].Message);
            Assert.AreEqual("Failed at 3", aggregateException.InnerExceptions[3].Message);
            Assert.AreEqual(4, mockTransport.Requests.Count);
        }
示例#8
0
 public void ThrowsForLengthOnNonSeekableStream()
 {
     Assert.Throws <NotSupportedException>(() => _ = RetriableStream.Create(
                                               _ => new MockReadStream(100, canSeek: false),
                                               _ => default,