Fixing a bug where pending invocations were not terminated correctly

This commit is contained in:
moozzyk 2017-02-17 13:42:41 -08:00
parent 12c6a4b917
commit 9709139a27
2 changed files with 60 additions and 5 deletions

View File

@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
{
if (_connectionActive.IsCancellationRequested)
{
throw new InvalidOperationException("Connection has been terminated");
throw new InvalidOperationException("Connection has been terminated.");
}
_pendingCalls.Add(descriptor.Id, irq);
}
@ -185,11 +185,11 @@ namespace Microsoft.AspNetCore.SignalR.Client
{
if (ex != null)
{
call.Completion.TrySetCanceled();
call.Completion.TrySetException(ex);
}
else
{
call.Completion.TrySetException(ex);
call.Completion.TrySetCanceled();
}
}
_pendingCalls.Clear();

View File

@ -108,8 +108,6 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
Assert.Equal("Cannot invoke methods on disposed connections.", exception.Message);
}
// TODO: If HubConnection takes (I)Connection we could just tests if events are wired up
[Fact]
public async Task HubConnectionConnectedEventRaisedWhenTheClientIsConnected()
{
@ -167,5 +165,62 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
Assert.Null(await closedEventTcs.Task.OrTimeout());
}
}
[Fact]
public async Task CannotCallInvokeOnClosedHubConnection()
{
var mockConnection = new Mock<IConnection>();
mockConnection
.Setup(m => m.DisposeAsync())
.Callback(() => mockConnection.Raise(c => c.Closed += null, (Exception)null))
.Returns(Task.FromResult<object>(null));
var hubConnection = new HubConnection(mockConnection.Object, Mock.Of<IInvocationAdapter>(), new LoggerFactory());
await hubConnection.StartAsync(Mock.Of<ITransport>());
await hubConnection.DisposeAsync();
var exception = await Assert.ThrowsAsync<InvalidOperationException>(
async () => await hubConnection.Invoke("test", typeof(int)));
Assert.Equal("Connection has been terminated.", exception.Message);
}
[Fact]
public async Task PendingInvocationsAreCancelledWhenConnectionClosesCleanly()
{
var mockConnection = new Mock<IConnection>();
mockConnection
.Setup(m => m.DisposeAsync())
.Callback(() => mockConnection.Raise(c => c.Closed += null, (Exception)null))
.Returns(Task.FromResult<object>(null));
var hubConnection = new HubConnection(mockConnection.Object, Mock.Of<IInvocationAdapter>(), new LoggerFactory());
await hubConnection.StartAsync(Mock.Of<ITransport>());
var invokeTask = hubConnection.Invoke("testMethod", typeof(int));
await hubConnection.DisposeAsync();
await Assert.ThrowsAsync<TaskCanceledException>(async () => await invokeTask);
}
[Fact]
public async Task PendingInvocationsAreTerminatedWithExceptionWhenConnectionClosesDueToError()
{
var exception = new InvalidOperationException();
var mockConnection = new Mock<IConnection>();
mockConnection
.Setup(m => m.DisposeAsync())
.Callback(() => mockConnection.Raise(c => c.Closed += null, exception))
.Returns(Task.FromResult<object>(null));
var hubConnection = new HubConnection(mockConnection.Object, Mock.Of<IInvocationAdapter>(), new LoggerFactory());
await hubConnection.StartAsync(Mock.Of<ITransport>());
var invokeTask = hubConnection.Invoke("testMethod", typeof(int));
await hubConnection.DisposeAsync();
var thrown = await Assert.ThrowsAsync(exception.GetType(), async () => await invokeTask);
Assert.Same(exception, thrown);
}
}
}