public async Task AsyncCallToMethodForResultGetsResultsAsExpected(int count) { using (var server = new SimpleMorseLServer <TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, logger: _logger); await client.StartAsync(); var taskMap = new Dictionary <Task <int>, int>(); var tasks = new List <Task <int> >(); for (var i = 0; i < count; i++) { var task = client.Invoke <int>("ExpectedResult", i); taskMap[task] = i; tasks.Add(task); } await Task.WhenAll(tasks); foreach (var pair in taskMap) { Assert.Equal(pair.Value, pair.Key.Result); } await client.DisposeAsync(); } }
public async void ConnectionSubscriptionRemovedOnAbnormalDisconnect() { RedisBackplane backplane = null; using (var server = new SimpleMorseLServer <TestHub>((collection, builder) => { collection.AddSingleton <IBackplane, RedisBackplane>(); collection.Configure <ConfigurationOptions>(options => { options.EndPoints.Add(REDIS_URI); }); }, (builder, provider) => { backplane = (RedisBackplane)provider.GetRequiredService <IBackplane>(); }, logger: _logger)) { await server.Start(_context.PortPool); var client = new Client.Connection(server.Uri, logger: _logger); await client.StartAsync(); client.KillConnection(); await Task.Delay(2000); Assert.DoesNotContain(client.ConnectionId, backplane.Connections.Keys); } }
public async Task ServerForcedDisconnectedClientCancelsConnectionCancellationToken() { using (var server = new SimpleMorseLServer <TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, logger: _logger); await client.StartAsync(); Assert.ThrowsAnyAsync <TaskCanceledException>(async() => await client.Invoke("WaitForCancellation")); // Give a little time for the hub method to fire and start waiting await Task.Delay(200); client.Invoke("KillMe"); // Give a little time for the hub method to fire and kill the connection await Task.Delay(200); Assert.IsType <TaskCanceledException>(TestHub.ConnectionCancellationException); // Kill the client connection await client.DisposeAsync(); } }
public async Task HubMissingMethodExceptionDoesntCausePerpetualException() { using (var server = new SimpleMorseLServer <TestHub>((s, b) => { s.Configure <Extensions.MorseLOptions>(o => o.ThrowOnInvalidMessage = false); }, logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, options: o => { o.ThrowOnInvalidMessage = true; o.RethrowUnobservedExceptions = true; o.ThrowOnMissingHubMethodInvoked = true; o.ThrowOnMissingMethodRequest = true; }, logger: _logger); await client.StartAsync(); try { await client.Invoke("SomeNonExistentMethod"); } catch (Exception) { // Ignore } client = new Connection(server.Uri); await client.StartAsync(); await client.Invoke("FooBar"); await client.DisposeAsync(); } }
public async void LongDelayUntilServerResponseDoesNotBlockClientCallbacks() { using (var server = new SimpleMorseLServer <TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, null, o => o.ThrowOnMissingHubMethodInvoked = true, logger: _logger); await client.StartAsync(); Task longRunningTask = null; bool callbackFired = false; client.On("Callback", new Type[0], (args) => { if (!longRunningTask?.IsCompleted == true) { callbackFired = true; } }); await client.Invoke("PrimeCallback"); longRunningTask = client.Invoke("LongRunningMethod"); await longRunningTask; Assert.True(callbackFired); await client.DisposeAsync(); } }
public async Task ParallelCallsToHubMethodsForResultDoesntDie(int count) { using (var server = new SimpleMorseLServer <TestHub>((s, b) => { s.Configure <Extensions.MorseLOptions>(o => o.ThrowOnInvalidMessage = false); }, logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, options: o => { o.ThrowOnInvalidMessage = true; o.RethrowUnobservedExceptions = true; o.ThrowOnMissingHubMethodInvoked = true; o.ThrowOnMissingMethodRequest = true; }, logger: _logger); await client.StartAsync(); var tasks = new List <Task>(); for (var i = 0; i < count; i++) { tasks.Add(client.Invoke <int>(nameof(TestHub.ExpectedResult), i)); } await Task.WhenAll(tasks); await client.DisposeAsync(); } }
public async void LongSendFromClientDoesNotBlockClientReceive() { using (var server = new SimpleMorseLServer <TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, null, o => o.ThrowOnMissingHubMethodInvoked = true, logger: _logger); await client.StartAsync(); bool callbackFired = false; client.On("Callback", new Type[0], (args) => { callbackFired = true; }); var hugeMessage = new StringBuilder(""); for (var i = 0; i < 1000000; i++) { hugeMessage.Append("abcdef"); } await client.Invoke("PrimeCallback"); await client.Invoke("SendHugeData", hugeMessage.ToString()); Assert.True(callbackFired); await client.DisposeAsync(); } }
public async void HubInvokingNonExistentClientMethodThrowsInClient(string methodName, params object[] arguments) { using (var server = new SimpleMorseLServer <TestHub>((s, b) => { s.Configure <Extensions.MorseLOptions>(o => { o.ThrowOnInvalidMessage = false; }); }, logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, null, o => o.ThrowOnMissingMethodRequest = true, logger: _logger); await client.StartAsync(); var expectedMethodName = string.IsNullOrWhiteSpace(methodName) ? "[Invalid Method Name]" : methodName; var expectedArgumentList = arguments?.Length > 0 ? string.Join(", ", arguments) : "[No Parameters]"; Exception exception = null; client.Error += (exc) => exception = exc; await client.Invoke <int>(nameof(TestHub.CallInvalidClientMethod), methodName, arguments); await Task.Delay(100); Assert.NotNull(exception); Assert.Equal( $"Invalid method request received; method is \"{expectedMethodName}({expectedArgumentList})\"", exception.Message); await client.DisposeAsync(); } }
public async void CallToInvalidHubMethodFromClientThrowsMissingHubMethodInClient(string methodName, params object[] arguments) { using (var server = new SimpleMorseLServer <TestHub>((s, b) => { s.Configure <Extensions.MorseLOptions>(o => { o.ThrowOnInvalidMessage = false; }); }, logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, null, o => o.ThrowOnMissingHubMethodInvoked = true, logger: _logger); await client.StartAsync(); var expectedMethodName = string.IsNullOrWhiteSpace(methodName) ? "[Invalid Method Name]" : methodName; var expectedArgumentList = arguments?.Length > 0 ? string.Join(", ", arguments) : "[No Parameters]"; var exception = await Assert.ThrowsAsync <MorseLException>(() => client.Invoke <object>(methodName, arguments)); Assert.Equal( $"Cannot find method \"{expectedMethodName}({expectedArgumentList})\"", exception.Message); await client.DisposeAsync(); } }
public async Task HubThrowingExceptionDoesntCausePerpetualException() { using (var server = new SimpleMorseLServer <TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, logger: _logger); await client.StartAsync(); try { await client.Invoke(nameof(TestHub.ThrowException)); } catch (Exception) { // Ignore } client = new Connection(server.Uri); await client.StartAsync(); await client.Invoke("FooBar"); await client.DisposeAsync(); } }
public async void ShouldNotThrowOnCallToDisposeAsyncBeforeStartAsync() { using (var server = new SimpleMorseLServer <EndToEndTests.TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, null, o => o.ThrowOnMissingHubMethodInvoked = true, logger: _logger); await client.StartAsync(); await client.DisposeAsync(); } }
public async void HubInvokingNonExistentClientMethodThrowsInHubWithMiddleware(string methodName, params object[] arguments) { var tcs = new TaskCompletionSource <Exception>(); using (var server = new SimpleMorseLServer <TestHub>((s, b) => { s.Configure <Extensions.MorseLOptions>(o => o.ThrowOnMissingClientMethodInvoked = true); b.AddMiddleware <Base64HubMiddleware>(ServiceLifetime.Transient); }, (app, services) => { app.Use(async(context, next) => { try { await next.Invoke(); } catch (Exception e) { tcs.SetResult(e); } }); }, logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection( server.Uri, options: options => options.ConnectionTimeout = TimeSpan.FromSeconds(5), logger: new TestOutputHelperLogger(_testOutputHelper)); client.AddMiddleware(new Base64ClientMiddleware()); await client.StartAsync(); await client.Invoke <int>(nameof(TestHub.CallInvalidClientMethod), methodName, arguments); var expectedMethodName = string.IsNullOrWhiteSpace(methodName) ? "[Invalid Method Name]" : methodName; var expectedArgumentList = arguments?.Length > 0 ? string.Join(", ", arguments) : "[No Parameters]"; await Task.WhenAny(tcs.Task, Task.Delay(5000)); Assert.True(tcs.Task.IsCompleted); var exception = await tcs.Task; Assert.NotNull(exception); Assert.Equal( $"Error: Cannot find method \"{expectedMethodName}({expectedArgumentList})\" from {client.ConnectionId}", exception.Message); await client.DisposeAsync(); } }
public async Task CanKillClientConnection() { using (var server = new SimpleMorseLServer <TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, logger: _logger); await client.StartAsync(); await Assert.ThrowsAnyAsync <WebSocketClosedException>(async() => await client.Invoke("KillMe")); await client.DisposeAsync(); } }
public async Task ConnectedClientHasUncanceledConnectionCancellationToken() { using (var server = new SimpleMorseLServer <TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, logger: _logger); await client.StartAsync(); await client.Invoke("VerifyCancellation"); // Kill the client connection await client.DisposeAsync(); } }
public async Task ShouldThrowOnInvokeAsyncWhenDisposed() { using (var server = new SimpleMorseLServer <EndToEndTests.TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, null, o => o.ThrowOnMissingHubMethodInvoked = true, logger: _logger); await client.StartAsync(); await client.DisposeAsync(); await AssertEx.ThrowsAsync <MorseLException>( () => client.DisposeAsync(), e => e.Message.Equals("This connection has already been disposed.", StringComparison.Ordinal)); } }
public async void ShouldThrowOnCallToStartAsyncAfterDisposeAsync() { using (var server = new SimpleMorseLServer <EndToEndTests.TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, null, o => o.ThrowOnMissingHubMethodInvoked = true, logger: _logger); await client.StartAsync(); await client.DisposeAsync(); await AssertEx.ThrowsAsync <MorseLException>( () => client.StartAsync(), e => e.Message.Equals("Cannot call StartAsync more than once.")); } }
public async void ServerClosingConnectionDuringLongSendFromClientThrowsExceptionOnInvoker() { using (var server = new SimpleMorseLServer <TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var client = new Connection(server.Uri, null, o => o.ThrowOnMissingHubMethodInvoked = true, logger: _logger); await client.StartAsync(); var task = Task.Run(() => client.Invoke("LongRunningMethod")); // Disconnect the client await client.DisposeAsync(); await Assert.ThrowsAnyAsync <MorseLException>(() => task); } }
public async void ConnectedCalledWhenClientConnectionEstablished() { using (var server = new SimpleMorseLServer <TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var tcs = new TaskCompletionSource <object>(); var client = new Connection(server.Uri, logger: _logger); client.Connected += () => tcs.TrySetResult(null); await client.StartAsync(); await Task.WhenAny(tcs.Task, Task.Delay(5000)); Assert.True(tcs.Task.IsCompletedSuccessfully); await client.DisposeAsync(); } }
public async Task SendHugePayload() { // Generate a large payload using (var server = new SimpleMorseLServer <TestHub>()) { await server.Start(_context.PortPool); var client = new Connection(server.Uri); await client.StartAsync(); var taskMap = new Dictionary <Task <int>, int>(); var tasks = new List <Task <int> >(); while (true) { await client.Invoke(nameof(TestHub.SendHugePayload), (object)new object[10].Select(x => new Payload(20000)).ToArray()); } } }
public async void ReconnectingDoesNotKillServer() { using (var server = new SimpleMorseLServer <TestHub>(logger: _logger)) { await server.Start(_context.PortPool); var connectedCalled = false; for (int i = 0; i < 10; i++) { var client = new Connection(server.Uri, logger: _logger); client.Connected += () => connectedCalled = true; await client.StartAsync(); var task = client.Invoke <object>("FooBar"); await Task.Delay(100); await client.DisposeAsync(); } Assert.True(connectedCalled); } }