#pragma warning disable xUnit1026 // Theory methods should use all of their parameters public void SendMessagesInBothDirections(ChannelExchange[] cases) #pragma warning restore xUnit1026 // Theory methods should use all of their parameters { var serverSentMessageHashes = new List <List <byte[]> >(); var serverReceivedMessageHashes = new List <List <byte[]> >(); var clientSentMessageHashes = new List <List <byte[]> >(); var clientReceivedMessageHashes = new List <List <byte[]> >(); async Task HandleChannelAsync(ITransportChannel c, int[] send, List <byte[]> received, List <byte[]> sent) { Log.Info("Handling channel {0}", c.Id); var receiveTask = TaskRunner.RunInBackground( async() => { while (true) { var receivedMsg = await c.TryReceiveMessageAsync().ConfigureAwait(false); if (!receivedMsg.HasValue) { break; } lock (Md5) { received.Add(Md5.ComputeHash(receivedMsg.Value)); } } }); foreach (var length in send) { var msg = TestsSuite.Random.GetRandomBytes(length); await c.SendMessageAsync(msg).ConfigureAwait(false); lock (Md5) { sent.Add(Md5.ComputeHash(msg)); } } c.Out.TryComplete(); await receiveTask.ConfigureAwait(false); Log.Info("Channel handling completed {0}. Received {1} messages.", c.Id, received.Count); } ITransportConnection clientConnection = null; ITransportConnection serverConnection = null; var serverTask = TaskRunner.RunInBackground( async() => { await Server.StartAsync().ConfigureAwait(false); serverConnection = await Server.In.ReadAsync().ConfigureAwait(false); Log.Info("Server connection created"); var channelTasks = new List <Task>(); foreach (var channelExchange in cases) { var channel = await serverConnection.CreateChannelAsync().ConfigureAwait(false); Log.Info("Server channel created"); var rec = new List <byte[]>(); var sent = new List <byte[]>(); clientReceivedMessageHashes.Add(rec); clientSentMessageHashes.Add(sent); channelTasks.Add(TaskRunner.RunInBackground(() => HandleChannelAsync(channel, channelExchange.ClientMessageLengths, rec, sent))); } await Task.WhenAll(channelTasks).ConfigureAwait(false); }); var clientTask = TaskRunner.RunInBackground( async() => { clientConnection = await Client.ConnectAsync(BrokerWorkingDir).ConfigureAwait(false); Log.Info("Client connection created"); var channelTasks = new List <Task>(); foreach (var channelExchange in cases) { var channel = await clientConnection.IncomingChannels.ReadAsync().ConfigureAwait(false); Log.Info("Client channel received"); var rec = new List <byte[]>(); var sent = new List <byte[]>(); serverReceivedMessageHashes.Add(rec); serverSentMessageHashes.Add(sent); channelTasks.Add(TaskRunner.RunInBackground(() => HandleChannelAsync(channel, channelExchange.ServerMessageLengths, rec, sent))); } await Task.WhenAll(channelTasks).ConfigureAwait(false); }); Should.CompleteIn(Task.WhenAll(serverTask, clientTask), Timeout30Sec); Should.CompleteIn(clientConnection.CompleteAsync(), Timeout1Sec); Should.CompleteIn(serverConnection.CompleteAsync(), Timeout1Sec); Log.Debug("Tasks completed"); serverReceivedMessageHashes.Count.ShouldBe(cases.Length); serverSentMessageHashes.Count.ShouldBe(cases.Length); clientReceivedMessageHashes.Count.ShouldBe(cases.Length); clientSentMessageHashes.Count.ShouldBe(cases.Length); for (int i = 0; i < serverReceivedMessageHashes.Count; i++) { serverReceivedMessageHashes[i].Count.ShouldBe(clientSentMessageHashes[i].Count); for (int j = 0; j < serverReceivedMessageHashes[i].Count; j++) { serverReceivedMessageHashes[i][j].ShouldBe(clientSentMessageHashes[i][j]); } } for (int i = 0; i < clientReceivedMessageHashes.Count; i++) { clientReceivedMessageHashes[i].Count.ShouldBe(serverSentMessageHashes[i].Count); for (int j = 0; j < clientReceivedMessageHashes[i].Count; j++) { clientReceivedMessageHashes[i][j].ShouldBe(serverSentMessageHashes[i][j]); } } }