public async Task WhenSendingMessagesToEchoServer_ThenStatisticsAreUpdated( [LinuxInstance(InitializeScript = InitializeScripts.InstallEchoServer)] ResourceTask <InstanceLocator> vm, [Credential(Role = PredefinedRole.IapTunnelUser)] ResourceTask <ICredential> credential, [Values( 1, (int)DataMessage.MaxDataLength, (int)DataMessage.MaxDataLength * 2)] int length) { var message = new byte[length]; FillArray(message); var locator = await vm; var listener = SshRelayListener.CreateLocalListener( new IapTunnelingEndpoint( await credential, await vm, 7, IapTunnelingEndpoint.DefaultNetworkInterface, TestProject.UserAgent), new AllowAllRelayPolicy()); listener.ClientAcceptLimit = 1; // Terminate after first connection. listener.ListenAsync(CancellationToken.None).ContinueWith(_ => { }); var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(new IPEndPoint(IPAddress.Loopback, listener.LocalPort)); var clientStreamStats = new ConnectionStatistics(); var clientStream = new SocketStream(socket, clientStreamStats); using (var tokenSource = new CancellationTokenSource()) { // Write full payload. await clientStream.WriteAsync(message, 0, message.Length, tokenSource.Token); Assert.AreEqual(length, clientStreamStats.BytesTransmitted); // Read entire response. var response = new byte[length]; int totalBytesRead = 0; while (true) { var bytesRead = await clientStream.ReadAsync( response, totalBytesRead, response.Length - totalBytesRead, tokenSource.Token); totalBytesRead += bytesRead; if (bytesRead == 0 || totalBytesRead >= length) { break; } } await clientStream.CloseAsync(tokenSource.Token); await Task.Delay(50); Assert.AreEqual(length, totalBytesRead, "bytes read"); Assert.AreEqual(length, clientStreamStats.BytesReceived, "client received"); Assert.AreEqual(length, listener.Statistics.BytesReceived, "server received"); Assert.AreEqual(length, listener.Statistics.BytesTransmitted, "server sent"); } }