public async Task Test_Good_Path(TimeClient_Rfc_868.ProtocolType protocol) { var host = new HostName("localhost"); var serverOptions = new TimeServer_Rfc_868.ServerOptions() { LoggingLevel = TimeServer_Rfc_868.ServerOptions.Verbosity.None }; var clientOptions = new TimeClient_Rfc_868.ClientOptions() { LoggingLevel = TimeClient_Rfc_868.ClientOptions.Verbosity.None }; using (var server = new TimeServer_Rfc_868(serverOptions)) { bool serverOk = await server.StartAsync(); if (!serverOk) { Infrastructure.Error($"unable to start server"); return; } var client = new TimeClient_Rfc_868(clientOptions); var result = await client.WriteAsync(host, serverOptions.Service, protocol); if (!Infrastructure.IfTrueError(!result.Succeeded, "!result.Succeeded")) { Infrastructure.IfTrueError(result.Value == null, "result.Value is null"); Infrastructure.IfTrueError(result.Value != null && (result.Value.Length < 10 || result.Value.Length > 60), $"result.Value is weird size ({result.Value})"); } Infrastructure.IfTrueError(result.TimeInSeconds < 0, $"result.TimeInSeconds too small ({result.TimeInSeconds})"); Infrastructure.IfTrueError(result.TimeInSeconds > 1.50, $"result.TimeInSeconds too large ({result.TimeInSeconds})"); } }
public async Task Test_Bad_Service(TimeClient_Rfc_868.ProtocolType protocol) { var host = new HostName("localhost"); var serverOptions = new TimeServer_Rfc_868.ServerOptions() { LoggingLevel = TimeServer_Rfc_868.ServerOptions.Verbosity.None }; var clientOptions = new TimeClient_Rfc_868.ClientOptions() { LoggingLevel = TimeClient_Rfc_868.ClientOptions.Verbosity.None }; using (var server = new TimeServer_Rfc_868(serverOptions)) { bool serverOk = await server.StartAsync(); if (!serverOk) { Infrastructure.Error($"unable to start server"); return; } var client = new TimeClient_Rfc_868(clientOptions); var result = await client.WriteAsync(host, "79", protocol); Infrastructure.IfTrueError(result.Succeeded, "result.Succeeded "); Infrastructure.IfTrueError(!String.IsNullOrEmpty(result.Value), "result.Value is not null"); // ConnectionRefused is for TCP // ConnectionResetByPeer is for UDP Infrastructure.IfTrueError(result.Error != SocketErrorStatus.ConnectionRefused && result.Error != SocketErrorStatus.ConnectionResetByPeer, $"result.Error is wrong ({result.Error})"); } }
private void OnStartServers(object sender, RoutedEventArgs e) { var serverOptions = new TimeServer_Rfc_868.ServerOptions() { Service = uiService.Text }; Server = new TimeServer_Rfc_868(serverOptions); Server.LogEvent += Server_LogEvent; ServerTask = Server.StartAsync(); }
/// <summary> /// System test, not a unit tests. Creates a server, pumps a bunch of requests at it, /// and verifies that everything worked. /// </summary> /// <returns></returns> public async Task Test_Stress(TimeClient_Rfc_868.ProtocolType protocol) { string pname = protocol.ToString(); const int NLOOP = 10; const int NBUNCH = 50; const double ALLOWED_TIME = 20.0; // Normally we expect everything to be fast. No so much for a stress test! const int ALLOWED_CONN_RESET = (NLOOP * NBUNCH) * 5 / 100; // Allow 5% conn reset int NBytesSent = 0; // In the Time protocol we never send any bytes, so this will stay at zero. int NConnReset = 0; var host = new HostName("localhost"); var serverOptions = new TimeServer_Rfc_868.ServerOptions() { LoggingLevel = TimeServer_Rfc_868.ServerOptions.Verbosity.None, }; var clientOptions = new TimeClient_Rfc_868.ClientOptions() { LoggingLevel = TimeClient_Rfc_868.ClientOptions.Verbosity.None, }; using (var server = new TimeServer_Rfc_868(serverOptions)) { bool serverOk = await server.StartAsync(); if (!serverOk) { Infrastructure.Error($"Client: Stress: {pname} unable to start server"); return; } var start = DateTimeOffset.UtcNow; var client = new TimeClient_Rfc_868(clientOptions); for (int i = 0; i < NLOOP; i++) { if (i % 100 == 0 && i > 0) { Infrastructure.Log($"Client: Stress: {pname} starting loop {i} of {NLOOP}"); } var allTasks = new Task <TimeClient_Rfc_868.TimeResult> [NBUNCH]; for (int j = 0; j < allTasks.Length; j++) { allTasks[j] = client.WriteAsync(host, serverOptions.Service, protocol); } await Task.WhenAll(allTasks); for (int j = 0; j < allTasks.Length; j++) { var result = allTasks[j].Result; if (!result.Succeeded && result.Error == SocketErrorStatus.ConnectionResetByPeer) { // Connection reset by peer is an error only if we get a bunch of them. NConnReset++; Infrastructure.IfTrueError(NConnReset > ALLOWED_CONN_RESET, $"Too many connection resets {NConnReset}"); } else if (!Infrastructure.IfTrueError(!result.Succeeded, $"!result.Succeeded with error {result.Error.ToString()} for {pname}")) { Infrastructure.IfTrueError(result.Value == null, "result.Value is null"); if (result.Value != null && (result.Value.Length < 10 || result.Value.Length > 60)) { ; } Infrastructure.IfTrueError(result.Value != null && (result.Value.Length < 10 || result.Value.Length > 60), $"result.Value is weird size ({result.Value.Length}) for {pname}"); var correctTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var correctDelta = Math.Abs(result.UnixTimeSeconds - correctTime); Infrastructure.IfTrueError(correctDelta > 5, $"Time is off; got {result.UnixTimeSeconds} but expected about {correctTime} delta is {correctDelta}"); } Infrastructure.IfTrueError(result.TimeInSeconds < 0, $"result.TimeInSeconds too small {result.TimeInSeconds} for {pname}"); Infrastructure.IfTrueError(result.TimeInSeconds > ALLOWED_TIME, $"result.TimeInSeconds too large {result.TimeInSeconds} for {pname}"); } await Task.Delay(300); //TODO: pause just to make the test runs easier to figure out } // timing data var delta = DateTimeOffset.UtcNow.Subtract(start).TotalSeconds; double timePerCall = delta / (double)(NLOOP * NBUNCH); Infrastructure.Log($"Stress test average time: {NLOOP} {NBUNCH} {timePerCall} for {pname}"); // How's the server doing? const int ExpectedCount = NLOOP * NBUNCH; Infrastructure.IfTrueError(server.Stats.NConnections != ExpectedCount, $"Server got {server.Stats.NConnections} connections but expected {ExpectedCount} for {pname}"); int nr = server.Stats.NResponses; Infrastructure.IfTrueError(server.Stats.NResponses != ExpectedCount, $"Server sent {server.Stats.NResponses} responses but expected {ExpectedCount} for {pname}"); // Why is the expected not equal to the NBytesSent? Because TCP has a weird timing thing: // the server has to close down reading from the client relatively quickly and can't waste // time for the client to send bytes that probably won't come. var expectedMinBytes = protocol == TimeClient_Rfc_868.ProtocolType.Udp ? NBytesSent : NBytesSent / 2; Infrastructure.IfTrueError(server.Stats.NBytes > NBytesSent, $"Server got {server.Stats.NBytes} bytes but expected {NBytesSent} for {pname}"); Infrastructure.IfTrueError(server.Stats.NBytes < expectedMinBytes, $"Server got {server.Stats.NBytes} bytes but expected {NBytesSent} with a minimum value of {expectedMinBytes} for {pname}"); Infrastructure.IfTrueError(server.Stats.NExceptions != 0, $"Server got {server.Stats.NExceptions} exceptions but expected {0} for {pname}"); } }