public async Task ShouldNotFlushUnderlyingStreamIfReadOnly(bool underlyingCanSeek) { var underlying = new DelegateStream( canReadFunc: () => true, canWriteFunc: () => false, canSeekFunc: () => underlyingCanSeek, readFunc: (_, __, ___) => 123, writeFunc: (_, __, ___) => { throw new NotSupportedException(); }, seekFunc: (_, __) => 123L ); var wrapper = new CallTrackingStream(underlying); var buffered = new BufferedStream(wrapper); buffered.ReadByte(); buffered.Flush(); Assert.Equal(0, wrapper.TimesCalled(nameof(wrapper.Flush))); await buffered.FlushAsync(); Assert.Equal(0, wrapper.TimesCalled(nameof(wrapper.FlushAsync))); }
public async Task ShouldAlwaysFlushUnderlyingStreamIfWritable(bool underlyingCanRead, bool underlyingCanSeek) { var underlying = new DelegateStream( canReadFunc: () => underlyingCanRead, canWriteFunc: () => true, canSeekFunc: () => underlyingCanSeek, readFunc: (_, __, ___) => 123, writeFunc: (_, __, ___) => { }, seekFunc: (_, __) => 123L ); var wrapper = new CallTrackingStream(underlying); var buffered = new BufferedStream(wrapper); buffered.Flush(); Assert.Equal(1, wrapper.TimesCalled(nameof(wrapper.Flush))); await buffered.FlushAsync(); Assert.Equal(1, wrapper.TimesCalled(nameof(wrapper.FlushAsync))); buffered.WriteByte(0); buffered.Flush(); Assert.Equal(2, wrapper.TimesCalled(nameof(wrapper.Flush))); await buffered.FlushAsync(); Assert.Equal(2, wrapper.TimesCalled(nameof(wrapper.FlushAsync))); }
public async Task DisposeAsync_Connected_ClosesStream() { (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams(); var trackingStream1 = new CallTrackingStream(stream1); var trackingStream2 = new CallTrackingStream(stream2); var clientStream = new SslStream(trackingStream1, false, delegate { return(true); }); var serverStream = new SslStream(trackingStream2, false, delegate { return(true); }); using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate()) { await TestConfiguration.WhenAllOrAnyFailedWithTimeout( clientStream.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false)), serverStream.AuthenticateAsServerAsync(certificate)); } Assert.Equal(0, trackingStream1.TimesCalled(nameof(Stream.DisposeAsync))); await clientStream.DisposeAsync(); Assert.NotEqual(0, trackingStream1.TimesCalled(nameof(Stream.DisposeAsync))); Assert.Equal(0, trackingStream2.TimesCalled(nameof(Stream.DisposeAsync))); await serverStream.DisposeAsync(); Assert.NotEqual(0, trackingStream2.TimesCalled(nameof(Stream.DisposeAsync))); }
public void IfCanSeekIsFalseLengthAndPositionShouldNotBeCalled() { var baseStream = new DelegateStream( canReadFunc: () => true, canSeekFunc: () => false, readFunc: (buffer, offset, count) => 0); var trackingStream = new CallTrackingStream(baseStream); var dest = Stream.Null; trackingStream.CopyTo(dest); Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.CanSeek)), 0, 1); Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Length))); Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Position))); // We can't override CopyTo since it's not virtual, so checking TimesCalled // for CopyTo will result in 0. Instead, we check that Read was called, // and validate the parameters passed there. Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.Read))); byte[] outerBuffer = trackingStream.ReadBuffer; int outerOffset = trackingStream.ReadOffset; int outerCount = trackingStream.ReadCount; Assert.NotNull(outerBuffer); Assert.InRange(outerOffset, 0, outerBuffer.Length - outerCount); Assert.InRange(outerCount, 1, int.MaxValue); // the buffer can't be size 0 }
public void NegotiateStream_StreamToStream_Flush_Propagated() { (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams(); using (var stream = new CallTrackingStream(stream1)) using (var negotiateStream = new NegotiateStream(stream)) using (stream2) { Assert.Equal(0, stream.TimesCalled(nameof(Stream.Flush))); negotiateStream.Flush(); Assert.NotEqual(0, stream.TimesCalled(nameof(Stream.Flush))); } }
public void IfCanSeekIsTrueLengthAndPositionShouldOnlyBeCalledOnce() { var baseStream = new DelegateStream( canReadFunc: () => true, canSeekFunc: () => true, readFunc: (buffer, offset, count) => 0, lengthFunc: () => 0L, positionGetFunc: () => 0L); var trackingStream = new CallTrackingStream(baseStream); var dest = Stream.Null; trackingStream.CopyTo(dest); Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.Length)), 0, 1); Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.Position)), 0, 1); }
public async void AsyncIfCanSeekIsFalseLengthAndPositionShouldNotBeCalled() { var baseStream = new DelegateStream( canReadFunc: () => true, canSeekFunc: () => false, readFunc: (buffer, offset, count) => 0); var trackingStream = new CallTrackingStream(baseStream); var dest = Stream.Null; await trackingStream.CopyToAsync(dest); Assert.InRange(trackingStream.TimesCalled(nameof(trackingStream.CanSeek)), 0, 1); Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Length))); Assert.Equal(0, trackingStream.TimesCalled(nameof(trackingStream.Position))); Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.CopyToAsync))); Assert.Same(dest, trackingStream.CopyToAsyncDestination); Assert.InRange(trackingStream.CopyToAsyncBufferSize, 1, int.MaxValue); Assert.Equal(CancellationToken.None, trackingStream.CopyToAsyncCancellationToken); }
public async void AsyncIfLengthIsGreaterThanPositionAndDoesNotOverflowEverythingShouldGoNormally(long length, long position) { const int ReadLimit = 7; // Lambda state byte[] outerBuffer = null; int? outerOffset = null; int? outerCount = null; int readsLeft = ReadLimit; var srcBase = new DelegateStream( canReadFunc: () => true, canSeekFunc: () => true, lengthFunc: () => length, positionGetFunc: () => position, readFunc: (buffer, offset, count) => { Assert.NotNull(buffer); Assert.InRange(offset, 0, buffer.Length - count); Assert.InRange(count, 1, int.MaxValue); // CopyTo should always pass in the same buffer/offset/count if (outerBuffer != null) Assert.Same(outerBuffer, buffer); else outerBuffer = buffer; if (outerOffset != null) Assert.Equal(outerOffset, offset); else outerOffset = offset; if (outerCount != null) Assert.Equal(outerCount, count); else outerCount = count; return --readsLeft; // CopyTo will call Read on this ReadLimit times before stopping }); var src = new CallTrackingStream(srcBase); var destBase = new DelegateStream( canWriteFunc: () => true, writeFunc: (buffer, offset, count) => { Assert.Same(outerBuffer, buffer); Assert.Equal(outerOffset, offset); Assert.Equal(readsLeft, count); }); var dest = new CallTrackingStream(destBase); await src.CopyToAsync(dest); // Since we override CopyToAsync in CallTrackingStream, // src.Read will actually not get called ReadLimit // times, src.Inner.Read will. So, we just assert that // CopyToAsync was called once for src. Assert.Equal(1, src.TimesCalled(nameof(src.CopyToAsync))); Assert.Equal(ReadLimit - 1, dest.TimesCalled(nameof(dest.WriteAsync))); // dest.WriteAsync will still get called repeatedly }
public void IfLengthIsGreaterThanPositionAndDoesNotOverflowEverythingShouldGoNormally(long length, long position) { const int ReadLimit = 7; // Lambda state byte[] outerBuffer = null; int? outerOffset = null; int? outerCount = null; int readsLeft = ReadLimit; var srcBase = new DelegateStream( canReadFunc: () => true, canSeekFunc: () => true, lengthFunc: () => length, positionGetFunc: () => position, readFunc: (buffer, offset, count) => { Assert.NotNull(buffer); Assert.InRange(offset, 0, buffer.Length - count); Assert.InRange(count, 1, int.MaxValue); // CopyTo should always pass in the same buffer/offset/count if (outerBuffer != null) Assert.Same(outerBuffer, buffer); else outerBuffer = buffer; if (outerOffset != null) Assert.Equal(outerOffset, offset); else outerOffset = offset; if (outerCount != null) Assert.Equal(outerCount, count); else outerCount = count; return --readsLeft; // CopyTo will call Read on this ReadLimit times before stopping }); var src = new CallTrackingStream(srcBase); var destBase = new DelegateStream( canWriteFunc: () => true, writeFunc: (buffer, offset, count) => { Assert.Same(outerBuffer, buffer); Assert.Equal(outerOffset, offset); Assert.Equal(readsLeft, count); }); var dest = new CallTrackingStream(destBase); src.CopyTo(dest); Assert.Equal(ReadLimit, src.TimesCalled(nameof(src.Read))); Assert.Equal(ReadLimit - 1, dest.TimesCalled(nameof(dest.Write))); }
public void IfLengthMinusPositionPositiveOverflowsBufferSizeShouldStillBePositive(long length, long position) { // The new implementation of Stream.CopyTo calculates the bytes left // in the Stream by calling Length - Position. This can overflow to a // negative number, so this tests that if that happens we don't send // in a negative bufferSize. var baseStream = new DelegateStream( canReadFunc: () => true, canSeekFunc: () => true, lengthFunc: () => length, positionGetFunc: () => position, readFunc: (buffer, offset, count) => 0); var trackingStream = new CallTrackingStream(baseStream); var dest = Stream.Null; trackingStream.CopyTo(dest); // CopyTo is not virtual, so we can't override it in // CallTrackingStream and record the arguments directly. // Instead, validate the arguments passed to Read. Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.Read))); byte[] outerBuffer = trackingStream.ReadBuffer; int outerOffset = trackingStream.ReadOffset; int outerCount = trackingStream.ReadCount; Assert.NotNull(outerBuffer); Assert.InRange(outerOffset, 0, outerBuffer.Length - outerCount); Assert.InRange(outerCount, 1, int.MaxValue); }
public void IfLengthIsLessThanOrEqualToPositionCopyToShouldStillBeCalledWithAPositiveBufferSize(long length, long position) { // Streams with their Lengths <= their Positions, e.g. // new MemoryStream { Position = 3 }.SetLength(1) // should still be called CopyTo{Async} on with a // bufferSize of at least 1. var baseStream = new DelegateStream( canReadFunc: () => true, canSeekFunc: () => true, lengthFunc: () => length, positionGetFunc: () => position, readFunc: (buffer, offset, count) => 0); var trackingStream = new CallTrackingStream(baseStream); var dest = Stream.Null; trackingStream.CopyTo(dest); // CopyTo is not virtual, so we can't override it in // CallTrackingStream and record the arguments directly. // Instead, validate the arguments passed to Read. Assert.Equal(1, trackingStream.TimesCalled(nameof(trackingStream.Read))); byte[] outerBuffer = trackingStream.ReadBuffer; int outerOffset = trackingStream.ReadOffset; int outerCount = trackingStream.ReadCount; Assert.NotNull(outerBuffer); Assert.InRange(outerOffset, 0, outerBuffer.Length - outerCount); Assert.InRange(outerCount, 1, int.MaxValue); }