public void Verify(AutobahnResult result)
        {
            var failures = new StringBuilder();
            foreach (var serverResult in result.Servers)
            {
                var serverExpectation = _expectations.FirstOrDefault(e => e.Server == serverResult.Server && e.Ssl == serverResult.Ssl);
                if (serverExpectation == null)
                {
                    failures.AppendLine($"Expected no results for server: {serverResult.Name} but found results!");
                }
                else
                {
                    serverExpectation.Verify(serverResult, failures);
                }
            }

            Assert.True(failures.Length == 0, "Autobahn results did not meet expectations:" + Environment.NewLine + failures.ToString());
        }
        public async Task <AutobahnResult> Run(CancellationToken cancellationToken)
        {
            var specFile = Path.GetTempFileName();

            try
            {
                // Start pinging the servers to see that they're still running
                var pingCts = new CancellationTokenSource();
                var pinger  = new Timer(state => Pinger((CancellationToken)state), pingCts.Token, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));

                Spec.WriteJson(specFile);

                // Run the test (write something to the console so people know this will take a while...)
                _logger.LogInformation("Using 'wstest' from: {WsTestPath}", Wstest.Default.Location);
                _logger.LogInformation("Now launching Autobahn Test Suite. This will take a while.");
                var exitCode = await Wstest.Default.ExecAsync("-m fuzzingclient -s " + specFile, cancellationToken, _loggerFactory.CreateLogger("wstest"));

                if (exitCode != 0)
                {
                    throw new Exception("wstest failed");
                }

                pingCts.Cancel();
            }
            finally
            {
                if (File.Exists(specFile))
                {
                    File.Delete(specFile);
                }
            }

            cancellationToken.ThrowIfCancellationRequested();

            // Parse the output.
            var outputFile = Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", Spec.OutputDirectory, "index.json");

            using (var reader = new StreamReader(File.OpenRead(outputFile)))
            {
                return(AutobahnResult.FromReportJson(JObject.Parse(await reader.ReadToEndAsync())));
            }
        }