示例#1
0
        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();
            }
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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();
            }
        }
示例#4
0
        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();
            }
        }
示例#5
0
        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();
            }
        }
示例#6
0
        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();
            }
        }
示例#7
0
        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();
            }
        }
示例#8
0
        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();
            }
        }
示例#9
0
        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();
            }
        }
示例#10
0
        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();
            }
        }
示例#11
0
        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();
            }
        }
示例#12
0
        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();
            }
        }
示例#13
0
        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();
            }
        }
示例#14
0
        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();
            }
        }
示例#15
0
        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));
            }
        }
示例#16
0
        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."));
            }
        }
示例#17
0
        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);
            }
        }
示例#18
0
        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();
            }
        }
示例#19
0
        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());
                }
            }
        }
示例#20
0
        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);
            }
        }