aspnetcore/test/Microsoft.AspNetCore.Socket.../ConnectionManagerTests.cs

190 lines
7.0 KiB
C#

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Tests.Common;
using Microsoft.AspNetCore.Sockets.Internal;
using Microsoft.Extensions.Logging;
using Xunit;
namespace Microsoft.AspNetCore.Sockets.Tests
{
public class ConnectionManagerTests
{
[Fact]
public void NewConnectionsHaveConnectionId()
{
var connectionManager = CreateConnectionManager();
var state = connectionManager.CreateConnection();
Assert.NotNull(state.Connection);
Assert.NotNull(state.Connection.ConnectionId);
Assert.Equal(ConnectionState.ConnectionStatus.Inactive, state.Status);
Assert.Null(state.ApplicationTask);
Assert.Null(state.TransportTask);
Assert.Null(state.Cancellation);
Assert.Null(state.RequestId);
Assert.NotNull(state.Connection.Transport);
}
[Fact]
public void NewConnectionsCanBeRetrieved()
{
var connectionManager = CreateConnectionManager();
var state = connectionManager.CreateConnection();
Assert.NotNull(state.Connection);
Assert.NotNull(state.Connection.ConnectionId);
ConnectionState newState;
Assert.True(connectionManager.TryGetConnection(state.Connection.ConnectionId, out newState));
Assert.Same(newState, state);
}
[Fact]
public void AddNewConnection()
{
var connectionManager = CreateConnectionManager();
var state = connectionManager.CreateConnection();
var transport = state.Connection.Transport;
Assert.NotNull(state.Connection);
Assert.NotNull(state.Connection.ConnectionId);
Assert.NotNull(transport);
ConnectionState newState;
Assert.True(connectionManager.TryGetConnection(state.Connection.ConnectionId, out newState));
Assert.Same(newState, state);
Assert.Same(transport, newState.Connection.Transport);
}
[Fact]
public void RemoveConnection()
{
var connectionManager = CreateConnectionManager();
var state = connectionManager.CreateConnection();
var transport = state.Connection.Transport;
Assert.NotNull(state.Connection);
Assert.NotNull(state.Connection.ConnectionId);
Assert.NotNull(transport);
ConnectionState newState;
Assert.True(connectionManager.TryGetConnection(state.Connection.ConnectionId, out newState));
Assert.Same(newState, state);
Assert.Same(transport, newState.Connection.Transport);
connectionManager.RemoveConnection(state.Connection.ConnectionId);
Assert.False(connectionManager.TryGetConnection(state.Connection.ConnectionId, out newState));
}
[Fact]
public async Task CloseConnectionsEndsAllPendingConnections()
{
var connectionManager = CreateConnectionManager();
var state = connectionManager.CreateConnection();
state.ApplicationTask = Task.Run(async () =>
{
Assert.False(await state.Connection.Transport.Input.WaitToReadAsync());
});
state.TransportTask = Task.Run(async () =>
{
Assert.False(await state.Application.Input.WaitToReadAsync());
});
connectionManager.CloseConnections();
await state.DisposeAsync();
}
[Fact]
public async Task DisposingConnectionMultipleTimesWaitsOnConnectionClose()
{
var connectionManager = CreateConnectionManager();
var state = connectionManager.CreateConnection();
var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
state.ApplicationTask = tcs.Task;
state.TransportTask = tcs.Task;
var firstTask = state.DisposeAsync();
var secondTask = state.DisposeAsync();
Assert.False(firstTask.IsCompleted);
Assert.False(secondTask.IsCompleted);
tcs.TrySetResult(null);
await Task.WhenAll(firstTask, secondTask).OrTimeout();
}
[Fact]
public async Task DisposingConnectionMultipleGetsExceptionFromTransportOrApp()
{
var connectionManager = CreateConnectionManager();
var state = connectionManager.CreateConnection();
var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
state.ApplicationTask = tcs.Task;
state.TransportTask = tcs.Task;
var firstTask = state.DisposeAsync();
var secondTask = state.DisposeAsync();
Assert.False(firstTask.IsCompleted);
Assert.False(secondTask.IsCompleted);
tcs.TrySetException(new InvalidOperationException("Error"));
var exception = await Assert.ThrowsAsync<InvalidOperationException>(async () => await firstTask.OrTimeout());
Assert.Equal("Error", exception.Message);
exception = await Assert.ThrowsAsync<InvalidOperationException>(async () => await secondTask.OrTimeout());
Assert.Equal("Error", exception.Message);
}
[Fact]
public async Task DisposingConnectionMultipleGetsCancellation()
{
var connectionManager = CreateConnectionManager();
var state = connectionManager.CreateConnection();
var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
state.ApplicationTask = tcs.Task;
state.TransportTask = tcs.Task;
var firstTask = state.DisposeAsync();
var secondTask = state.DisposeAsync();
Assert.False(firstTask.IsCompleted);
Assert.False(secondTask.IsCompleted);
tcs.TrySetCanceled();
await Assert.ThrowsAsync<TaskCanceledException>(async () => await firstTask.OrTimeout());
await Assert.ThrowsAsync<TaskCanceledException>(async () => await secondTask.OrTimeout());
}
[Fact]
public async Task DisposeInactiveConnection()
{
var connectionManager = CreateConnectionManager();
var state = connectionManager.CreateConnection();;
Assert.NotNull(state.Connection);
Assert.NotNull(state.Connection.ConnectionId);
Assert.NotNull(state.Connection.Transport);
await state.DisposeAsync();
Assert.Equal(state.Status, ConnectionState.ConnectionStatus.Disposed);
}
private static ConnectionManager CreateConnectionManager()
{
return new ConnectionManager(new Logger<ConnectionManager>(new LoggerFactory()));
}
}
}