public async Task CopyToAsync_AutoFlushing(bool autoFlush, int expectedFlushes) { // Arrange const int SourceSize = (128 * 1024) - 3; var sourceBytes = Enumerable.Range(0, SourceSize).Select(i => (byte)(i % 256)).ToArray(); var source = new MemoryStream(sourceBytes); var destination = new MemoryStream(); var flushCountingDestination = new FlushCountingStream(destination); var streamCopierMock = new Mock <IStreamCopier>(); streamCopierMock .Setup(s => s.CopyAsync(source, It.IsAny <Stream>(), It.IsAny <CancellationToken>())) .Returns(async(Stream source_, Stream destination_, CancellationToken cancellation_) => { await source_.CopyToAsync(destination_, cancellation_); return(StreamCopyResult.Success, null); }); var sut = new StreamCopyHttpContent(source, streamCopierMock.Object, autoFlushHttpClientOutgoingStream: autoFlush, CancellationToken.None); // Act & Assert Assert.False(sut.ConsumptionTask.IsCompleted); Assert.False(sut.Started); await sut.CopyToAsync(flushCountingDestination); Assert.True(sut.Started); Assert.True(sut.ConsumptionTask.IsCompleted); Assert.Equal(sourceBytes, destination.ToArray()); Assert.Equal(expectedFlushes, flushCountingDestination.NumFlushes); }
public async Task CopyToAsync_AsyncSequencing() { // Arrange var source = new MemoryStream(); var destination = new MemoryStream(); var streamCopierMock = new Mock <IStreamCopier>(); var tcs = new TaskCompletionSource <(StreamCopyResult, Exception)>(); streamCopierMock .Setup(s => s.CopyAsync(source, destination, It.IsAny <CancellationToken>())) .Returns(() => tcs.Task); var sut = new StreamCopyHttpContent(source, streamCopierMock.Object, autoFlushHttpClientOutgoingStream: false, CancellationToken.None); // Act & Assert Assert.False(sut.ConsumptionTask.IsCompleted); Assert.False(sut.Started); var task = sut.CopyToAsync(destination); Assert.True(sut.Started); // This should happen synchronously Assert.False(sut.ConsumptionTask.IsCompleted); // This cannot happen until the tcs releases it tcs.TrySetResult((StreamCopyResult.Success, null)); await task; Assert.True(sut.ConsumptionTask.IsCompleted); }
public async Task CopyToAsync_AutoFlushing(bool autoFlush) { // Must be same as StreamCopier constant. const int DefaultBufferSize = 65536; const int SourceSize = (128 * 1024) - 3; var expectedFlushes = 0; if (autoFlush) { // How many buffers is needed to send the source rounded up. expectedFlushes = (SourceSize - 1) / DefaultBufferSize + 1; } // Explicit flush after headers are sent. expectedFlushes++; var sourceBytes = Enumerable.Range(0, SourceSize).Select(i => (byte)(i % 256)).ToArray(); var source = new MemoryStream(sourceBytes); var destination = new MemoryStream(); var flushCountingDestination = new FlushCountingStream(destination); var sut = new StreamCopyHttpContent(source, autoFlushHttpClientOutgoingStream: autoFlush, new Clock(), CancellationToken.None); Assert.False(sut.ConsumptionTask.IsCompleted); Assert.False(sut.Started); await sut.CopyToAsync(flushCountingDestination); Assert.True(sut.Started); Assert.True(sut.ConsumptionTask.IsCompleted); Assert.Equal(sourceBytes, destination.ToArray()); Assert.Equal(expectedFlushes, flushCountingDestination.NumFlushes); }
public async Task CopyToAsync_InvokesStreamCopier() { // Arrange const int SourceSize = (128 * 1024) - 3; var sourceBytes = Enumerable.Range(0, SourceSize).Select(i => (byte)(i % 256)).ToArray(); var source = new MemoryStream(sourceBytes); var destination = new MemoryStream(); var streamCopierMock = new Mock <IStreamCopier>(); streamCopierMock .Setup(s => s.CopyAsync(source, destination, It.IsAny <CancellationToken>())) .Returns(async() => { await source.CopyToAsync(destination); return(StreamCopyResult.Success, null); }); var sut = new StreamCopyHttpContent(source, streamCopierMock.Object, autoFlushHttpClientOutgoingStream: false, CancellationToken.None); // Act & Assert Assert.False(sut.ConsumptionTask.IsCompleted); Assert.False(sut.Started); await sut.CopyToAsync(destination); Assert.True(sut.Started); Assert.True(sut.ConsumptionTask.IsCompleted); Assert.Equal(sourceBytes, destination.ToArray()); }
public async Task CopyToAsync_AsyncSequencing() { // Arrange var source = new MemoryStream(); var destination = new MemoryStream(); var streamCopierMock = new Mock <IStreamCopier>(); var tcs = new TaskCompletionSource <bool>(); streamCopierMock .Setup(s => s.CopyAsync(source, destination, It.IsAny <CancellationToken>())) .Returns(async() => { await tcs.Task; }); var sut = new StreamCopyHttpContent(source, streamCopierMock.Object, CancellationToken.None); // Act & Assert sut.ConsumptionTask.IsCompleted.Should().BeFalse(); sut.Started.Should().BeFalse(); var task = sut.CopyToAsync(destination); sut.Started.Should().BeTrue(); // This should happen synchronously sut.ConsumptionTask.IsCompleted.Should().BeFalse(); // This cannot happen until the tcs releases it tcs.TrySetResult(true); await task; sut.ConsumptionTask.IsCompleted.Should().BeTrue(); }
public async Task CopyToAsync_InvokesStreamCopier() { // Arrange const int SourceSize = (128 * 1024) - 3; var sourceBytes = Enumerable.Range(0, SourceSize).Select(i => (byte)(i % 256)).ToArray(); var source = new MemoryStream(sourceBytes); var destination = new MemoryStream(); var streamCopierMock = new Mock <IStreamCopier>(); streamCopierMock .Setup(s => s.CopyAsync(source, destination, It.IsAny <CancellationToken>())) .Returns(() => source.CopyToAsync(destination)); var sut = new StreamCopyHttpContent(source, streamCopierMock.Object, CancellationToken.None); // Act & Assert sut.ConsumptionTask.IsCompleted.Should().BeFalse(); sut.Started.Should().BeFalse(); await sut.CopyToAsync(destination); sut.Started.Should().BeTrue(); sut.ConsumptionTask.IsCompleted.Should().BeTrue(); destination.ToArray().Should().BeEquivalentTo(sourceBytes); }
public Task ReadAsStreamAsync_Throws() { var source = new MemoryStream(); var destination = new MemoryStream(); var sut = new StreamCopyHttpContent(source, autoFlushHttpClientOutgoingStream: false, new Clock(), CancellationToken.None); Func <Task> func = () => sut.ReadAsStreamAsync(); return(Assert.ThrowsAsync <NotImplementedException>(func)); }
public Task ReadAsStreamAsync_Throws() { // Arrange var source = new MemoryStream(); var destination = new MemoryStream(); var sut = new StreamCopyHttpContent(source, new Mock <IStreamCopier>().Object, autoFlushHttpClientOutgoingStream: false, CancellationToken.None); // Act Func <Task> func = () => sut.ReadAsStreamAsync(); // Assert return(Assert.ThrowsAsync <NotImplementedException>(func)); }
public async Task ReadAsStreamAsync_Throws() { // Arrange var source = new MemoryStream(); var destination = new MemoryStream(); var sut = new StreamCopyHttpContent(source, new Mock <IStreamCopier>().Object, CancellationToken.None); // Act Func <Task> func = () => sut.ReadAsStreamAsync(); // Assert await func.Should().ThrowExactlyAsync <NotImplementedException>(); }
public void AllowDuplex_ReturnsTrue() { var source = new MemoryStream(); var sut = new StreamCopyHttpContent(source, autoFlushHttpClientOutgoingStream: false, new Clock(), CancellationToken.None); // This is an internal property that HttpClient and friends use internally and which must be true // to support duplex channels.This test helps detect regressions or changes in undocumented behavior // in .NET Core, and it passes as of .NET Core 3.1. var allowDuplexProperty = typeof(HttpContent).GetProperty("AllowDuplex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Assert.NotNull(allowDuplexProperty); var allowDuplex = (bool)allowDuplexProperty.GetValue(sut); Assert.True(allowDuplex); }
public async Task CopyToAsync_InvokesStreamCopier() { const int SourceSize = (128 * 1024) - 3; var sourceBytes = Enumerable.Range(0, SourceSize).Select(i => (byte)(i % 256)).ToArray(); var source = new MemoryStream(sourceBytes); var destination = new MemoryStream(); var sut = new StreamCopyHttpContent(source, autoFlushHttpClientOutgoingStream: false, new Clock(), CancellationToken.None); Assert.False(sut.ConsumptionTask.IsCompleted); Assert.False(sut.Started); await sut.CopyToAsync(destination); Assert.True(sut.Started); Assert.True(sut.ConsumptionTask.IsCompleted); Assert.Equal(sourceBytes, destination.ToArray()); }
public void AllowDuplex_ReturnsTrue() { // Arrange var source = new MemoryStream(); var streamCopierMock = new Mock <IStreamCopier>(); var sut = new StreamCopyHttpContent(source, streamCopierMock.Object, CancellationToken.None); // Assert // This is an internal property that HttpClient and friends use internally and which must be true // to support duplex channels.This test helps detect regressions or changes in undocumented behavior // in .NET Core, and it passes as of .NET Core 3.1. var allowDuplexProperty = typeof(HttpContent).GetProperty("AllowDuplex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); allowDuplexProperty.Should().NotBeNull(); var allowDuplex = (bool)allowDuplexProperty.GetValue(sut); allowDuplex.Should().BeTrue(); }
public async Task CopyToAsync_AutoFlushing(bool autoFlush, int expectedFlushes) { // Arrange const int SourceSize = (128 * 1024) - 3; var sourceBytes = Enumerable.Range(0, SourceSize).Select(i => (byte)(i % 256)).ToArray(); var source = new MemoryStream(sourceBytes); var destination = new MemoryStream(); var flushCountingDestination = new FlushCountingStream(destination); var sut = new StreamCopyHttpContent(source, autoFlushHttpClientOutgoingStream: autoFlush, CancellationToken.None); // Act & Assert Assert.False(sut.ConsumptionTask.IsCompleted); Assert.False(sut.Started); await sut.CopyToAsync(flushCountingDestination); Assert.True(sut.Started); Assert.True(sut.ConsumptionTask.IsCompleted); Assert.Equal(sourceBytes, destination.ToArray()); Assert.Equal(expectedFlushes, flushCountingDestination.NumFlushes); }
public async Task CopyToAsync_AsyncSequencing() { var tcs = new TaskCompletionSource <int>(TaskCreationOptions.RunContinuationsAsynchronously); var source = new Mock <Stream>(); source.Setup(s => s.ReadAsync(It.IsAny <Memory <byte> >(), It.IsAny <CancellationToken>())).Returns(() => new ValueTask <int>(tcs.Task)); var destination = new MemoryStream(); var sut = new StreamCopyHttpContent(source.Object, autoFlushHttpClientOutgoingStream: false, new Clock(), CancellationToken.None); Assert.False(sut.ConsumptionTask.IsCompleted); Assert.False(sut.Started); var task = sut.CopyToAsync(destination); Assert.True(sut.Started); // This should happen synchronously Assert.False(sut.ConsumptionTask.IsCompleted); // This cannot happen until the tcs releases it tcs.TrySetResult(0); await task; Assert.True(sut.ConsumptionTask.IsCompleted); }