Exemple #1
0
        public async Task Integration_NewClient_MiniLoad(int threadCount, int messageCount)
        {
            // TODO: Transform this test into a theory and do multi-message, multi-thread, multi-client, etc.
            var logger = XUnitLogger.CreateLogger(_outputHelper);

            using (var webSocketFeature = new TestWebSocketConnectionFeature())
            {
                // Bot / server setup
                var botRequestHandler = new Mock <RequestHandler>();

                botRequestHandler
                .Setup(r => r.ProcessRequestAsync(It.IsAny <ReceiveRequest>(), null, null, CancellationToken.None))
                .ReturnsAsync(() => new StreamingResponse()
                {
                    StatusCode = 200
                });

                var socket = await webSocketFeature.AcceptAsync().ConfigureAwait(false);

                var connection = new WebSocketStreamingConnection(socket, logger);
                var serverTask = Task.Run(() => connection.ListenAsync(botRequestHandler.Object));
                await Task.Delay(TimeSpan.FromSeconds(1));

                //Parallel.For(0, clientCount, async i =>
                {
                    // Client / channel setup
                    var clientRequestHandler = new Mock <RequestHandler>();

                    clientRequestHandler
                    .Setup(r => r.ProcessRequestAsync(It.IsAny <ReceiveRequest>(), null, null, CancellationToken.None))
                    .ReturnsAsync(() => new StreamingResponse()
                    {
                        StatusCode = 200
                    });

                    using (var client = new WebSocketClient($"wss://test", clientRequestHandler.Object, logger: logger))
                    {
                        var clientTask = client.ConnectInternalAsync(webSocketFeature.Client, CancellationToken.None);

                        // Send request bot (server) -> channel (client)
                        const string path = "api/version";
                        const string botToClientPayload = "Hello human, I'm Bender!";

                        Func <int, Task> testFlow = async(i) =>
                        {
                            var request = StreamingRequest.CreatePost(path, new StringContent(botToClientPayload));

                            var stopwatch          = Stopwatch.StartNew();
                            var responseFromClient = await connection.SendStreamingRequestAsync(request).ConfigureAwait(false);

                            stopwatch.Stop();

                            Assert.Equal(200, responseFromClient.StatusCode);
                            logger.LogInformation($"Server->Client {i} latency: {stopwatch.ElapsedMilliseconds}. Status code: {responseFromClient.StatusCode}");

                            const string clientToBotPayload = "Hello bot, I'm Calculon!";
                            var          clientRequest      = StreamingRequest.CreatePost(path, new StringContent(clientToBotPayload));

                            stopwatch = Stopwatch.StartNew();

                            // Send request bot channel (client) -> (server)
                            var clientToBotResult = await client.SendAsync(clientRequest).ConfigureAwait(false);

                            stopwatch.Stop();

                            Assert.Equal(200, clientToBotResult.StatusCode);

                            logger.LogInformation($"Client->Server {i} latency: {stopwatch.ElapsedMilliseconds}. Status code: {responseFromClient.StatusCode}");
                        };

                        await testFlow(-1).ConfigureAwait(false);

                        var tasks = new List <Task>();

                        using (var throttler = new SemaphoreSlim(threadCount))
                        {
                            for (int j = 0; j < messageCount; j++)
                            {
                                await throttler.WaitAsync().ConfigureAwait(false);

                                // using Task.Run(...) to run the lambda in its own parallel
                                // flow on the threadpool
                                tasks.Add(
                                    Task.Run(async() =>
                                {
                                    try
                                    {
                                        await testFlow(j).ConfigureAwait(false);
                                    }
                                    finally
                                    {
                                        throttler.Release();
                                    }
                                }));
                            }

                            await Task.WhenAll(tasks).ConfigureAwait(false);
                        }

                        await client.DisconnectAsync().ConfigureAwait(false);

                        await clientTask.ConfigureAwait(false);
                    }

                    await serverTask.ConfigureAwait(false);
                }
            }
        }