public async Task SslStream_StreamToStream_Dispose_Throws() { if (this is SslStreamStreamToStreamTest_SyncBase) { // This test assumes operations complete asynchronously. return; } (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams(); using (var clientSslStream = new SslStream(DelegateDelegatingStream.NopDispose(stream1), false, AllowAnyServerCertificate)) { var serverSslStream = new SslStream(DelegateDelegatingStream.NopDispose(stream2)); await DoHandshake(clientSslStream, serverSslStream); var serverBuffer = new byte[1]; Task serverReadTask = ReadAsync(serverSslStream, serverBuffer, 0, serverBuffer.Length); await WriteAsync(serverSslStream, new byte[] { 1 }, 0, 1) .WaitAsync(TestConfiguration.PassingTestTimeout); // Shouldn't throw, the context is disposed now. // Since the server read task is in progress, the read buffer is not returned to ArrayPool. serverSslStream.Dispose(); // Read in client var clientBuffer = new byte[1]; await ReadAsync(clientSslStream, clientBuffer, 0, clientBuffer.Length); Assert.Equal(1, clientBuffer[0]); await WriteAsync(clientSslStream, new byte[] { 2 }, 0, 1); // We're inconsistent as to whether the ObjectDisposedException is thrown directly // or wrapped in an IOException. For Begin/End, it's always wrapped; for Async, // it's only wrapped on .NET Framework. if (this is SslStreamStreamToStreamTest_BeginEnd || PlatformDetection.IsNetFramework) { await Assert.ThrowsAsync <ObjectDisposedException>(() => serverReadTask); } else { IOException serverException = await Assert.ThrowsAsync <IOException>(() => serverReadTask); Assert.IsType <ObjectDisposedException>(serverException.InnerException); } await Assert.ThrowsAsync <ObjectDisposedException>(() => ReadAsync(serverSslStream, serverBuffer, 0, serverBuffer.Length)); // Now, there is no pending read, so the internal buffer will be returned to ArrayPool. serverSslStream.Dispose(); await Assert.ThrowsAsync <ObjectDisposedException>(() => ReadAsync(serverSslStream, serverBuffer, 0, serverBuffer.Length)); } }
public async Task NegotiateStream_StreamToStream_FlushAsync_Propagated() { (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams(); var tcs = new TaskCompletionSource(); using (var stream = new DelegateDelegatingStream(stream1) { FlushAsyncFunc = async cancellationToken => { await tcs.Task.WithCancellation(cancellationToken); await stream1.FlushAsync(cancellationToken); } }) using (var negotiateStream = new NegotiateStream(stream)) using (stream2) { Task task = negotiateStream.FlushAsync(); Assert.False(task.IsCompleted); tcs.SetResult(); await task; } }