File: Terminals\TerminalClientStreamTests.cs
Web Access
Project: src\tests\Aspire.Hosting.Tests\Aspire.Hosting.Tests.csproj (Aspire.Hosting.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using Aspire.Hosting.Tests.Utils;
using Microsoft.AspNetCore.InternalTesting;
 
namespace Aspire.Hosting.Tests.Terminals;
 
[Trait("Partition", "2")]
public class TerminalClientStreamTests
{
    [Fact]
    public async Task DisposeAsync_WaitsForOutstandingIoAndDoesNotDisposeTransport()
    {
        var (transport, peer) = TestDuplexStream.CreatePair();
        using var transportOwner = transport;
        using var peerOwner = peer;
        using var gated = new GatedTerminalWriteStream(transport);
        await using var stream = new TerminalClientStream(gated);
 
        var write = stream.WriteAsync("hello"u8.ToArray()).AsTask();
        await gated.WriteStarted.DefaultTimeout();
        var read = stream.ReadAsync(new byte[1]).AsTask();
 
        var dispose = stream.DisposeAsync().AsTask();
        try
        {
            await gated.WriteCancelled.DefaultTimeout();
            await Assert.ThrowsAnyAsync<OperationCanceledException>(() => read).DefaultTimeout();
            Assert.False(dispose.IsCompleted);
            Assert.False(stream.Released.IsCompleted);
            Assert.False(transport.Disposed);
            Assert.Same(dispose, stream.DisposeAsync().AsTask());
        }
        finally
        {
            gated.ReleaseWrite();
        }
 
        await Assert.ThrowsAnyAsync<OperationCanceledException>(() => write).DefaultTimeout();
        await dispose.DefaultTimeout();
        Assert.False(transport.Disposed);
        await Assert.ThrowsAsync<ObjectDisposedException>(() => stream.WriteAsync(new byte[1]).AsTask());
        await Assert.ThrowsAsync<ObjectDisposedException>(() => stream.ReadAsync(new byte[1]).AsTask());
 
        // The owner can still use or dispose the underlying transport after Hex1b releases its wrapper.
        await transport.WriteAsync("x"u8.ToArray());
        var buffer = new byte[1];
        Assert.Equal(1, await peer.ReadAsync(buffer).AsTask().DefaultTimeout());
        Assert.Equal((byte)'x', buffer[0]);
    }
}