Exemple #1
0
        public IActionResult Create([FromBody] ServerJob job)
        {
            lock (_jobs)
            {
                if (job == null || job.Id != 0)
                {
                    return(BadRequest());
                }
                else if (job.DriverVersion < 1)
                {
                    return(BadRequest("The driver is not compatible with this server, please update it."));
                }
                else if (job.State != ServerState.New)
                {
                    return(BadRequest("The job state should be ServerState.New. You are probably using a wrong version of the driver."));
                }

                job.Hardware        = Startup.Hardware;
                job.HardwareVersion = Startup.HardwareVersion;
                job.OperatingSystem = Startup.OperatingSystem;
                // Use server-side date and time to prevent issues fron time drifting
                job.LastDriverCommunicationUtc = DateTime.UtcNow;
                job = _jobs.Add(job);

                Response.Headers["Location"] = $"/jobs/{job.Id}";
                return(new StatusCodeResult((int)HttpStatusCode.Accepted));
            }
        }
Exemple #2
0
        /// <summary>
        /// Downloads the whole job including the measurements.
        /// </summary>
        public async Task <bool> TryUpdateJobAsync()
        {
            Log.Verbose($"GET {_serverJobUri} ...");
            var response = await _httpClient.GetAsync(_serverJobUri);

            var responseContent = await response.Content.ReadAsStringAsync();

            Log.Verbose($"{(int)response.StatusCode} {response.StatusCode} {responseContent}");

            if (response.StatusCode == HttpStatusCode.NotFound || String.IsNullOrEmpty(responseContent))
            {
                return(false);
            }
            else
            {
                try
                {
                    Job = JsonConvert.DeserializeObject <ServerJob>(responseContent);
                }
                catch
                {
                    Log.Write($"ERROR while deserializing state on {_serverJobUri}");
                    return(false);
                }

                return(true);
            }
        }
Exemple #3
0
 private Task WriteJobsToSql(ServerJob serverJob, ClientJob clientJob, DateTime utcNow, string connectionString, string tableName, string path, string session, string description, string dimension, double value)
 {
     return(RetryOnExceptionAsync(5, () =>
                                  WriteResultsToSql(
                                      utcNow,
                                      connectionString: connectionString,
                                      tableName: tableName,
                                      scenario: serverJob.Scenario,
                                      session: session,
                                      description: description,
                                      aspnetCoreVersion: serverJob.AspNetCoreVersion,
                                      runtimeVersion: serverJob.RuntimeVersion,
                                      hardware: serverJob.Hardware.Value,
                                      hardwareVersion: serverJob.HardwareVersion,
                                      operatingSystem: serverJob.OperatingSystem.Value,
                                      scheme: serverJob.Scheme,
                                      source: serverJob.Source,
                                      webHost: serverJob.WebHost,
                                      kestrelThreadCount: serverJob.KestrelThreadCount,
                                      clientThreads: clientJob.Threads,
                                      connections: clientJob.Connections,
                                      duration: clientJob.Duration,
                                      pipelineDepth: clientJob.PipelineDepth,
                                      path: path,
                                      method: clientJob.Method,
                                      headers: clientJob.Headers,
                                      dimension: dimension,
                                      value: value,
                                      runtimeStore: serverJob.UseRuntimeStore)
                                  , 5000));
 }
        private static string CloneAndRestore(string path, ServerJob job)
        {
            // It's possible that the user specified a custom branch/commit for the benchmarks repo,
            // so we need to add that to the set of sources to restore if it's not already there.
            //
            // Note that this is also going to de-dupe the repos if the same one was specified twice at
            // the command-line (last first to support overrides).
            var repos = new HashSet <Source>(job.Sources, SourceRepoComparer.Instance);

            // This will no-op if 'benchmarks' was specified by the user.
            repos.Add(_benchmarksSource);

            // Clone
            string benchmarksDir = null;
            var    dirs          = new List <string>();

            foreach (var source in repos)
            {
                var dir = Git.Clone(path, source.Repository);
                if (SourceRepoComparer.Instance.Equals(source, _benchmarksSource))
                {
                    benchmarksDir = dir;
                }

                if (!string.IsNullOrEmpty(source.BranchOrCommit))
                {
                    Git.Checkout(Path.Combine(path, dir), source.BranchOrCommit);
                }
                dirs.Add(dir);
            }

            Debug.Assert(benchmarksDir != null);

            // Modify all global.json to reference source dirs
            foreach (var repoDir in dirs)
            {
                var     globalJsonPath = Path.Combine(path, repoDir, "global.json");
                dynamic globalJson     = JsonConvert.DeserializeObject(File.ReadAllText(globalJsonPath));
                foreach (var sourceDir in dirs)
                {
                    if (sourceDir == benchmarksDir)
                    {
                        // No need to add benchmarks to global.json, since nothing should depend on it
                        continue;
                    }

                    globalJson["projects"].Add(Path.Combine("..", sourceDir, "src"));
                }
                File.WriteAllText(globalJsonPath, JsonConvert.SerializeObject(globalJson, Formatting.Indented));
            }

            // Restore in each dir
            foreach (var dir in dirs)
            {
                ProcessUtil.Run("dotnet", "restore", workingDirectory: Path.Combine(path, dir, "src"));
            }

            return(benchmarksDir);
        }
Exemple #5
0
 public JobResult(ServerJob job, IUrlHelper urlHelper)
 {
     Id            = job.Id;
     RunId         = job.RunId;
     State         = job.State.ToString();
     DetailsUrl    = urlHelper.ActionLink("GetById", "Jobs", new { Id });
     BuildLogsUrl  = urlHelper.ActionLink("BuildLog", "Jobs", new { Id });
     OutputLogsUrl = urlHelper.ActionLink("Output", "Jobs", new { Id });
 }
        public IActionResult Create([FromBody] ServerJob job)
        {
            if (job == null || job.Id != 0 || job.State != ServerState.Waiting ||
                job.Sources.Any(source => string.IsNullOrEmpty(source.Repository)))
            {
                return(BadRequest());
            }

            job = _jobs.Add(job);

            Response.Headers["Location"] = $"/jobs/{job.Id}";
            return(new StatusCodeResult((int)HttpStatusCode.Accepted));
        }
        private static Process StartProcess(string hostname, string benchmarksRepo, ServerJob job)
        {
            var filename  = "dotnet";
            var arguments = $"run -c Release -- --scenarios {job.Scenario} --server.urls {job.Scheme.ToString().ToLowerInvariant()}://{hostname}:5000";

            if (!string.IsNullOrEmpty(job.ConnectionFilter))
            {
                arguments += $" --connectionFilter {job.ConnectionFilter}";
            }

            Log.WriteLine($"Starting process '{filename} {arguments}'");

            var process = new Process()
            {
                StartInfo =
                {
                    FileName               = filename,
                    Arguments              = arguments,
                    WorkingDirectory       = Path.Combine(benchmarksRepo, @"src\Benchmarks"),
                    RedirectStandardOutput = true,
                    UseShellExecute        = false,
                },
                EnableRaisingEvents = true
            };

            process.StartInfo.Environment.Add("COREHOST_SERVER_GC", "1");

            process.OutputDataReceived += (_, e) =>
            {
                if (e != null && e.Data != null)
                {
                    Log.WriteLine(e.Data);

                    if (job.State == ServerState.Starting && e.Data.Contains("Application started"))
                    {
                        job.State = ServerState.Running;
                        job.Url   = ComputeServerUrl(hostname, job.Scheme, job.Scenario);
                        Log.WriteLine($"Running job '{job.Id}' with scenario '{job.Scenario}'");
                    }
                }
            };

            process.Start();
            process.BeginOutputReadLine();

            return(process);
        }
Exemple #8
0
        public async Task WriteJobResultsToSqlAsync(
            ServerJob serverJob,
            ClientJob clientJob,
            string sqlConnectionString,
            string tableName,
            string path,
            string session,
            string description,
            Statistics statistics,
            bool longRunning)
        {
            var utcNow = DateTime.UtcNow;

            var scenario = serverJob.Scenario;

            foreach (var result in CsvResults)
            {
                serverJob.Scenario = $"{scenario}.{result.Class}.{result.Method}{result.Params ?? ""}";

                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "OperationsPerSecond",
                    value : result.OperationsPerSecond);

                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Allocated (KB)",
                    value : result.Allocated);
            }

            serverJob.Scenario = scenario;
        }
Exemple #9
0
        public IActionResult Create([FromBody] ServerJob job)
        {
            lock (_jobs)
            {
                if (job == null || job.Id != 0 || job.State != ServerState.Initializing)
                {
                    return(BadRequest());
                }

                job.Hardware        = Startup.Hardware;
                job.HardwareVersion = Startup.HardwareVersion;
                job.OperatingSystem = Startup.OperatingSystem;
                job = _jobs.Add(job);

                Response.Headers["Location"] = $"/jobs/{job.Id}";
                return(new StatusCodeResult((int)HttpStatusCode.Accepted));
            }
        }
Exemple #10
0
        private static async Task <int> UploadFileAsync(string filename, ServerJob serverJob, string uri)
        {
            Log.Write($"Uploading {filename} to {uri}");

            try
            {
                var outputFileSegments = filename.Split(';');
                var uploadFilename     = outputFileSegments[0];

                if (!File.Exists(uploadFilename))
                {
                    Console.WriteLine($"File '{uploadFilename}' could not be loaded.");
                    return(8);
                }

                var destinationFilename = outputFileSegments.Length > 1
                    ? outputFileSegments[1]
                    : Path.GetFileName(uploadFilename);

                using (var request = new HttpRequestMessage(HttpMethod.Post, uri))
                {
                    var fileContent = uploadFilename.StartsWith("http", StringComparison.OrdinalIgnoreCase)
                        ? new StreamContent(await _httpClient.GetStreamAsync(uploadFilename))
                        : new StreamContent(new FileStream(uploadFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 1, FileOptions.Asynchronous | FileOptions.SequentialScan));

                    using (fileContent)
                    {
                        request.Content = fileContent;
                        request.Headers.Add("id", serverJob.Id.ToString());
                        request.Headers.Add("destinationFilename", destinationFilename);

                        await _httpClient.SendAsync(request);
                    }
                }
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"An error occurred while uploading a file.", e);
            }

            return(0);
        }
Exemple #11
0
        public IActionResult Create([FromBody] ServerJob job)
        {
            lock (_jobs)
            {
                if (job == null || job.Id != 0 || job.State != ServerState.Initializing)
                {
                    return(BadRequest());
                }

                job.Hardware        = Startup.Hardware;
                job.HardwareVersion = Startup.HardwareVersion;
                job.OperatingSystem = Startup.OperatingSystem;
                // Use server-side date and time to prevent issues fron time drifting
                job.LastDriverCommunicationUtc = DateTime.UtcNow;
                job = _jobs.Add(job);

                Response.Headers["Location"] = $"/jobs/{job.Id}";
                return(new StatusCodeResult((int)HttpStatusCode.Accepted));
            }
        }
Exemple #12
0
        public async Task WriteJobResultsToSqlAsync(
            ServerJob serverJob,
            ClientJob clientJob,
            string sqlConnectionString,
            string tableName,
            string path,
            string session,
            string description,
            Statistics statistics,
            bool longRunning)
        {
            var utcNow = DateTime.UtcNow;

            await WriteJobsToSql(
                serverJob : serverJob,
                clientJob : clientJob,
                utcNow : utcNow,
                connectionString : sqlConnectionString,
                tableName : tableName,
                path : serverJob.Path,
                session : session,
                description : description,
                dimension : "RequestsPerSecond",
                value : statistics.RequestsPerSecond);

            if (statistics.StartupMain != -1 && !longRunning)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Startup Main (ms)",
                    value : statistics.StartupMain);
            }

            if (statistics.FirstRequest != -1 && !longRunning)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "First Request (ms)",
                    value : statistics.FirstRequest);
            }

            await WriteJobsToSql(
                serverJob : serverJob,
                clientJob : clientJob,
                utcNow : utcNow,
                connectionString : sqlConnectionString,
                tableName : tableName,
                path : serverJob.Path,
                session : session,
                description : description,
                dimension : "WorkingSet (MB)",
                value : statistics.WorkingSet);

            await WriteJobsToSql(
                serverJob : serverJob,
                clientJob : clientJob,
                utcNow : utcNow,
                connectionString : sqlConnectionString,
                tableName : tableName,
                path : serverJob.Path,
                session : session,
                description : description,
                dimension : "CPU",
                value : statistics.Cpu);

            if (statistics.Latency != -1 && !longRunning)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    session : session,
                    description : description,
                    path : serverJob.Path,
                    dimension : "Latency (ms)",
                    value : statistics.Latency);
            }

            if (statistics.LatencyAverage != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "LatencyAverage (ms)",
                    value : statistics.LatencyAverage);
            }

            if (statistics.Latency50Percentile != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Latency50Percentile (ms)",
                    value : statistics.Latency50Percentile);
            }

            if (statistics.Latency75Percentile != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Latency75Percentile (ms)",
                    value : statistics.Latency75Percentile);
            }

            if (statistics.Latency90Percentile != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Latency90Percentile (ms)",
                    value : statistics.Latency90Percentile);
            }

            if (statistics.Latency99Percentile != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Latency99Percentile (ms)",
                    value : statistics.Latency99Percentile);
            }

            if (statistics.MaxLatency != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "MaxLatency (ms)",
                    value : statistics.MaxLatency);
            }

            if (statistics.SocketErrors != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "SocketErrors",
                    value : statistics.SocketErrors);
            }

            if (statistics.BadResponses != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "BadResponses",
                    value : statistics.BadResponses);
            }

            if (statistics.TotalRequests != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "TotalRequests",
                    value : statistics.TotalRequests);
            }

            if (statistics.Duration != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Duration (ms)",
                    value : statistics.Duration);
            }
        }
Exemple #13
0
        public async Task WriteJobResultsToSqlAsync(
            ServerJob serverJob,
            ClientJob clientJob,
            string sqlConnectionString,
            string tableName,
            string path,
            string session,
            string description,
            Statistics statistics,
            bool longRunning)
        {
            var utcNow = DateTime.UtcNow;

            await WriteJobsToSql(
                serverJob : serverJob,
                clientJob : clientJob,
                utcNow : utcNow,
                connectionString : sqlConnectionString,
                tableName : tableName,
                path : serverJob.Path,
                session : session,
                description : description,
                dimension : "RequestsPerSecond",
                value : statistics.RequestsPerSecond);

            if (statistics.StartupMain != -1 && !longRunning)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Startup Main (ms)",
                    value : statistics.StartupMain);
            }

            if (statistics.BuildTime != -1 && !longRunning)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Build Time (ms)",
                    value : statistics.BuildTime);
            }

            if (statistics.PublishedSize != -1 && !longRunning)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Published Size (KB)",
                    value : statistics.PublishedSize);
            }

            if (statistics.FirstRequest != -1 && !longRunning)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "First Request (ms)",
                    value : statistics.FirstRequest);
            }

            await WriteJobsToSql(
                serverJob : serverJob,
                clientJob : clientJob,
                utcNow : utcNow,
                connectionString : sqlConnectionString,
                tableName : tableName,
                path : serverJob.Path,
                session : session,
                description : description,
                dimension : "WorkingSet (MB)",
                value : statistics.WorkingSet);

            await WriteJobsToSql(
                serverJob : serverJob,
                clientJob : clientJob,
                utcNow : utcNow,
                connectionString : sqlConnectionString,
                tableName : tableName,
                path : serverJob.Path,
                session : session,
                description : description,
                dimension : "CPU",
                value : statistics.Cpu);

            if (statistics.Latency != -1 && !longRunning)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    session : session,
                    description : description,
                    path : serverJob.Path,
                    dimension : "Latency (ms)",
                    value : statistics.Latency);
            }

            if (statistics.LatencyAverage != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "LatencyAverage (ms)",
                    value : statistics.LatencyAverage);
            }

            if (statistics.Latency50Percentile != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Latency50Percentile (ms)",
                    value : statistics.Latency50Percentile);
            }

            if (statistics.Latency75Percentile != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Latency75Percentile (ms)",
                    value : statistics.Latency75Percentile);
            }

            if (statistics.Latency90Percentile != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Latency90Percentile (ms)",
                    value : statistics.Latency90Percentile);
            }

            if (statistics.Latency99Percentile != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Latency99Percentile (ms)",
                    value : statistics.Latency99Percentile);
            }

            if (statistics.MaxLatency != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "MaxLatency (ms)",
                    value : statistics.MaxLatency);
            }

            if (statistics.SocketErrors != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "SocketErrors",
                    value : statistics.SocketErrors);
            }

            if (statistics.BadResponses != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "BadResponses",
                    value : statistics.BadResponses);
            }

            if (statistics.TotalRequests != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "TotalRequests",
                    value : statistics.TotalRequests);
            }

            if (statistics.Duration != -1)
            {
                await WriteJobsToSql(
                    serverJob : serverJob,
                    clientJob : clientJob,
                    utcNow : utcNow,
                    connectionString : sqlConnectionString,
                    tableName : tableName,
                    path : serverJob.Path,
                    session : session,
                    description : description,
                    dimension : "Duration (ms)",
                    value : statistics.Duration);
            }

            if (statistics.Other.Any())
            {
                foreach (var counter in Program.Counters)
                {
                    if (!statistics.Other.ContainsKey(counter.Name))
                    {
                        continue;
                    }

                    if (statistics.Other[counter.Name] != -1)
                    {
                        await WriteJobsToSql(
                            serverJob : serverJob,
                            clientJob : clientJob,
                            utcNow : utcNow,
                            connectionString : sqlConnectionString,
                            tableName : tableName,
                            path : serverJob.Path,
                            session : session,
                            description : description,
                            dimension : counter.DisplayName,
                            value : statistics.Other[counter.Name]);
                    }
                }
            }
        }
 private Task WriteJobsToSql(ServerJob serverJob, ClientJob clientJob, DateTime utcNow, string connectionString, string tableName, string path, string session, string description, string dimension, double value)
 {
     return(RetryOnExceptionAsync(5, (retry) => WriteJobResultToSqlAsync(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, dimension, value, retry)));
 }
Exemple #15
0
 public Task WriteJobResultsToSqlAsync(ServerJob serverJob, ClientJob clientJob, string connectionString, string tableName, string path, string session, string description, Statistics statistics, bool longRunning)
 {
     return(Task.CompletedTask);
 }
        public async Task WriteJobResultsToSqlAsync(ServerJob serverJob, ClientJob clientJob, string connectionString, string tableName, string path, string session, string description, Statistics statistics, bool longRunning)
        {
            var utcNow = DateTime.UtcNow;

            await WriteJobsToSql(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, "RequestsPerSecond", statistics.RequestsPerSecond);

            await WriteJobsToSql(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, "CPU", statistics.Cpu);

            await WriteJobsToSql(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, "WorkingSet (MB)", statistics.WorkingSet);

            if (statistics.LatencyAverage != -1)
            {
                await WriteJobsToSql(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, "Latency Average (ms)", statistics.LatencyAverage);
            }

            if (statistics.Latency50Percentile != -1)
            {
                await WriteJobsToSql(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, "Latency50Percentile (ms)", statistics.Latency50Percentile);
            }

            if (statistics.Latency75Percentile != -1)
            {
                await WriteJobsToSql(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, "Latency75Percentile (ms)", statistics.Latency75Percentile);
            }

            if (statistics.Latency90Percentile != -1)
            {
                await WriteJobsToSql(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, "Latency90Percentile (ms)", statistics.Latency90Percentile);
            }

            if (statistics.Latency99Percentile != -1)
            {
                await WriteJobsToSql(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, "Latency99Percentile (ms)", statistics.Latency99Percentile);
            }

            if (statistics.MaxLatency != -1)
            {
                await WriteJobsToSql(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, "MaxLatency (ms)", statistics.MaxLatency);
            }

            if (statistics.Other.Any())
            {
                foreach (var counter in Program.Counters)
                {
                    if (!statistics.Other.ContainsKey(counter.Name))
                    {
                        continue;
                    }

                    if (statistics.Other[counter.Name] != -1)
                    {
                        await WriteJobsToSql(
                            serverJob : serverJob,
                            clientJob : clientJob,
                            utcNow : utcNow,
                            connectionString : connectionString,
                            tableName : tableName,
                            path : serverJob.Path,
                            session : session,
                            description : description,
                            dimension : counter.DisplayName,
                            value : statistics.Other[counter.Name]);
                    }
                }
            }
        }
Exemple #17
0
 public JobConnection(ServerJob definition, Uri serverUri)
 {
     Job            = definition;
     _serverUri     = serverUri;
     _serverJobsUri = new Uri(_serverUri, "/jobs");
 }
Exemple #18
0
        public async Task <string> StartAsync(
            string jobName,
            CommandOption _outputArchiveOption,
            CommandOption _buildArchiveOption
            )
        {
            _jobName = jobName;

            var content = JsonConvert.SerializeObject(Job);

            Log.Write($"Starting job '{_jobName}' ...");

            Log.Verbose($"POST {_serverJobsUri} {content} ...");

            var response = await _httpClient.PostAsync(_serverJobsUri, new StringContent(content, Encoding.UTF8, "application/json"));

            var responseContent = await response.Content.ReadAsStringAsync();

            Log.Verbose($"{(int)response.StatusCode} {response.StatusCode}");

            response.EnsureSuccessStatusCode();

            _serverJobUri = new Uri(_serverUri, response.Headers.Location).ToString();

            Log.Write($"Fetching job: {_serverJobUri}");

            // When a job is submitted it has the state New
            // Waiting for the job to be selected (Initializing), then upload custom files and send the start

            while (true)
            {
                Log.Verbose($"GET {_serverJobUri} ...");
                response = await _httpClient.GetAsync(_serverJobUri);

                responseContent = await response.Content.ReadAsStringAsync();

                response.EnsureSuccessStatusCode();

                Job = JsonConvert.DeserializeObject <ServerJob>(responseContent);

                #region Ensure the job is valid

                if (Job.ServerVersion < 3)
                {
                    throw new Exception($"Invalid server version ({Job.ServerVersion}), please update your server to match this driver version.");
                }

                if (!Job.Hardware.HasValue)
                {
                    throw new InvalidOperationException("Server is required to set ServerJob.Hardware.");
                }

                if (String.IsNullOrWhiteSpace(Job.HardwareVersion))
                {
                    throw new InvalidOperationException("Server is required to set ServerJob.HardwareVersion.");
                }

                if (!Job.OperatingSystem.HasValue)
                {
                    throw new InvalidOperationException("Server is required to set ServerJob.OperatingSystem.");
                }

                #endregion

                if (Job.State == ServerState.Initializing)
                {
                    Log.Write($"Job has been selected by the server ...");

                    StartKeepAlive();

                    // Uploading source code
                    if (!String.IsNullOrEmpty(Job.Source.LocalFolder))
                    {
                        // Zipping the folder
                        var tempFilename = Path.GetTempFileName();
                        File.Delete(tempFilename);

                        Log.Write("Zipping the source folder in " + tempFilename);

                        var sourceDir = Job.Source.LocalFolder;

                        if (!File.Exists(Path.Combine(sourceDir, ".gitignore")))
                        {
                            ZipFile.CreateFromDirectory(sourceDir, tempFilename);
                        }
                        else
                        {
                            Log.Verbose(".gitignore file found");
                            DoCreateFromDirectory(sourceDir, tempFilename);
                        }

                        var result = await UploadFileAsync(tempFilename, Job, _serverJobUri + "/source");

                        File.Delete(tempFilename);

                        if (result != 0)
                        {
                            throw new Exception("Error while uploading source files");
                        }
                    }

                    // Upload custom package contents
                    if (_outputArchiveOption.HasValue())
                    {
                        foreach (var outputArchiveValue in _outputArchiveOption.Values)
                        {
                            var outputFileSegments = outputArchiveValue.Split(';', 2, StringSplitOptions.RemoveEmptyEntries);

                            string localArchiveFilename = outputFileSegments[0];

                            var tempFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

                            if (Directory.Exists(tempFolder))
                            {
                                Directory.Delete(tempFolder, true);
                            }

                            Directory.CreateDirectory(tempFolder);

                            _temporaryFolders.Add(tempFolder);

                            // Download the archive, while pinging the server to keep the job alive
                            if (outputArchiveValue.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                            {
                                localArchiveFilename = await DownloadTemporaryFileAsync(localArchiveFilename, _serverJobUri);
                            }

                            ZipFile.ExtractToDirectory(localArchiveFilename, tempFolder);

                            if (outputFileSegments.Length > 1)
                            {
                                Job.Options.OutputFiles.Add(Path.Combine(tempFolder, "*.*") + ";" + outputFileSegments[1]);
                            }
                            else
                            {
                                Job.Options.OutputFiles.Add(Path.Combine(tempFolder, "*.*"));
                            }
                        }
                    }

                    // Upload custom build package contents
                    if (_buildArchiveOption.HasValue())
                    {
                        foreach (var buildArchiveValue in _buildArchiveOption.Values)
                        {
                            var buildFileSegments = buildArchiveValue.Split(';', 2, StringSplitOptions.RemoveEmptyEntries);

                            string localArchiveFilename = buildFileSegments[0];

                            var tempFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

                            if (Directory.Exists(tempFolder))
                            {
                                Directory.Delete(tempFolder, true);
                            }

                            Directory.CreateDirectory(tempFolder);

                            _temporaryFolders.Add(tempFolder);

                            // Download the archive, while pinging the server to keep the job alive
                            if (buildArchiveValue.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                            {
                                localArchiveFilename = await DownloadTemporaryFileAsync(localArchiveFilename, _serverJobUri);
                            }

                            ZipFile.ExtractToDirectory(localArchiveFilename, tempFolder);

                            if (buildFileSegments.Length > 1)
                            {
                                Job.Options.BuildFiles.Add(Path.Combine(tempFolder, "*.*") + ";" + buildFileSegments[1]);
                            }
                            else
                            {
                                Job.Options.BuildFiles.Add(Path.Combine(tempFolder, "*.*"));
                            }
                        }
                    }

                    // Uploading build files
                    if (Job.Options.BuildFiles.Any())
                    {
                        foreach (var buildFileValue in Job.Options.BuildFiles)
                        {
                            var buildFileSegments = buildFileValue.Split(';', 2, StringSplitOptions.RemoveEmptyEntries);

                            var shouldSearchRecursively = buildFileSegments[0].Contains("*.*");

                            foreach (var resolvedFile in Directory.GetFiles(Path.GetDirectoryName(buildFileSegments[0]), Path.GetFileName(buildFileSegments[0]), shouldSearchRecursively ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                            {
                                var resolvedFileWithDestination = resolvedFile;

                                if (buildFileSegments.Length > 1)
                                {
                                    resolvedFileWithDestination += ";" + buildFileSegments[1] + Path.GetDirectoryName(resolvedFile).Substring(Path.GetDirectoryName(buildFileSegments[0]).Length) + "/" + Path.GetFileName(resolvedFileWithDestination);
                                }

                                var result = await UploadFileAsync(resolvedFileWithDestination, Job, _serverJobUri + "/build");

                                if (result != 0)
                                {
                                    throw new Exception("Error while uploading build files");
                                }
                            }
                        }
                    }

                    // Uploading attachments
                    if (Job.Options.OutputFiles.Any())
                    {
                        foreach (var outputFileValue in Job.Options.OutputFiles)
                        {
                            var outputFileSegments = outputFileValue.Split(';', 2, StringSplitOptions.RemoveEmptyEntries);

                            var shouldSearchRecursively = outputFileSegments[0].Contains("*.*");

                            foreach (var resolvedFile in Directory.GetFiles(Path.GetDirectoryName(outputFileSegments[0]), Path.GetFileName(outputFileSegments[0]), shouldSearchRecursively ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                            {
                                var resolvedFileWithDestination = resolvedFile;

                                if (outputFileSegments.Length > 1)
                                {
                                    resolvedFileWithDestination += ";" + outputFileSegments[1] + Path.GetDirectoryName(resolvedFile).Substring(Path.GetDirectoryName(outputFileSegments[0]).Length) + "/" + Path.GetFileName(resolvedFileWithDestination);
                                }

                                var result = await UploadFileAsync(resolvedFileWithDestination, Job, _serverJobUri + "/attachment");

                                if (result != 0)
                                {
                                    throw new Exception("Error while uploading output files");
                                }
                            }
                        }
                    }

                    response = await _httpClient.PostAsync(_serverJobUri + "/start", new StringContent(""));

                    responseContent = await response.Content.ReadAsStringAsync();

                    Log.Verbose($"{(int)response.StatusCode} {response.StatusCode}");
                    response.EnsureSuccessStatusCode();

                    Job = JsonConvert.DeserializeObject <ServerJob>(responseContent);

                    Log.Write($"Job is now building ...");

                    break;
                }
                else
                {
                    await Task.Delay(1000);
                }
            }

            // Tracking the job until it stops

            // TODO: Add a step on the server before build and start, such that start can be as fast as possible
            // "start" => "build"
            // + new start call

            while (true)
            {
                var previousJob = Job;

                Log.Verbose($"GET {_serverJobUri} ...");
                response = await _httpClient.GetAsync(_serverJobUri);

                responseContent = await response.Content.ReadAsStringAsync();

                Log.Verbose($"{(int)response.StatusCode} {response.StatusCode} {responseContent}");

                if (response.StatusCode == HttpStatusCode.NotFound)
                {
                    throw new Exception("Job not found");
                }

                Job = JsonConvert.DeserializeObject <ServerJob>(responseContent);


                if (Job.State == ServerState.Running)
                {
                    if (previousJob.State != ServerState.Running)
                    {
                        Log.Write($"Job is running");
                        _runningUtc = DateTime.UtcNow;
                    }

                    return(Job.Url);
                }
                else if (Job.State == ServerState.Failed)
                {
                    Log.Write($"Job failed on benchmark server, stopping ...");

                    Log.Write(Job.Error, notime: true, error: true);

                    // Returning will also send a Delete message to the server
                    return(null);
                }
                else if (Job.State == ServerState.NotSupported)
                {
                    Log.Write("Server does not support this job configuration.");
                    return(null);
                }
                else if (Job.State == ServerState.Stopped)
                {
                    Log.Write($"Job finished");

                    // If there is no ReadyStateText defined, the server will never be in Running state
                    // and we'll reach the Stopped state eventually, but that's a normal behavior.
                    if (Job.WaitForExit)
                    {
                        return(Job.Url);
                    }

                    throw new Exception("Job finished unnexpectedly");
                }
                else
                {
                    await Task.Delay(1000);
                }
            }
        }
Exemple #19
0
        internal override bool Query()
        {
            using (SQLConnection sql = new SQLConnection(instance))
            {
                sql.BuildConnectionString(credentials);
                if (!sql.Connect())
                {
                    return(false);
                }

                if (!_Check(sql))
                {
                    return(false);
                }

                StringBuilder sb = new StringBuilder();
                sb.Append(QUERY2_1);
                if (!string.IsNullOrEmpty(keywordFilter))
                {
                    sb.Append(keywordFilter);
                }
                if (!string.IsNullOrEmpty(subsystemFilter))
                {
                    sb.Append(subsystemFilter);
                }
                if (!string.IsNullOrEmpty(proxyCredFilter))
                {
                    sb.Append(proxyCredFilter);
                }
                if (!string.IsNullOrEmpty(usingProxyCredFilter))
                {
                    sb.Append(usingProxyCredFilter);
                }
                table = sql.Query(sb.ToString());
            }

            foreach (DataRow row in table.AsEnumerable())
            {
                try
                {
                    ServerJob sj = new ServerJob
                    {
                        ComputerName     = computerName,
                        Instance         = instance,
                        DatabaseName     = database,
                        Job_Id           = (int)row["Job_Id"],
                        Job_Name         = (string)row["Job_Name"],
                        Job_Description  = (string)row["Job_Description"],
                        Job_Owner        = (string)row["Job_Owner"],
                        Proxy_Id         = (int)row["Proxy_Id"],
                        Proxy_Credential = (string)row["Proxy_Credential"],
                        Date_Created     = (string)row["Date_Created"],
                        Last_Run_Date    = (DateTime)row["Last_Run_Date"],
                        Enabled          = (bool)row["Enabled"],
                        Server           = (string)row["Server"],
                        Step_Name        = (string)row["Step_Name"],
                        SubSystem        = (string)row["SubSystem"],
                        Command          = (string)row["Command"]
                    };
#if DEBUG
                    Misc.PrintStruct <ServerJob>(sj);
#endif
                    serverJobs.Add(sj);
                }
                catch (Exception ex)
                {
                    if (ex is ArgumentNullException)
                    {
                        Console.WriteLine("Empty Response");
                    }
                    else
                    {
                        Console.WriteLine(ex.Message);
                    }
                    return(false);
                }
            }
            return(true);
        }
Exemple #20
0
        private async Task WriteJobResultToSqlAsync(ServerJob serverJob, ClientJob clientJob, DateTime utcNow, string connectionString, string tableName, string path, string session, string description, Statistics statistics, bool longRunning, string dimension, double value, bool checkExisting)
        {
            if (checkExisting)
            {
                if (await CheckForRow(connectionString, tableName, utcNow, dimension, session) == true)
                {
                    return;
                }
            }

            string insertCmd =
                @"
                INSERT INTO [dbo].[" + tableName + @"]
                           ([DateTime]
                           ,[Session]
                           ,[Description]
                           ,[AspNetCoreVersion]
                           ,[RuntimeVersion]
                           ,[Scenario]
                           ,[Hardware]
                           ,[HardwareVersion]
                           ,[OperatingSystem]
                           ,[Framework]
                           ,[RuntimeStore]
                           ,[Scheme]
                           ,[Sources]
                           ,[WebHost]
                           ,[Transport]
                           ,[HubProtocol]
                           ,[ClientProperties]
                           ,[Connections]
                           ,[Duration]
                           ,[Path]
                           ,[Headers]
                           ,[Dimension]
                           ,[Value])
                     VALUES
                           (@DateTime
                           ,@Session
                           ,@Description
                           ,@AspNetCoreVersion
                           ,@RuntimeVersion
                           ,@Scenario
                           ,@Hardware
                           ,@HardwareVersion
                           ,@OperatingSystem
                           ,@Framework
                           ,@RuntimeStore
                           ,@Scheme
                           ,@Sources
                           ,@WebHost
                           ,@Transport
                           ,@HubProtocol
                           ,@ClientProperties
                           ,@Connections
                           ,@Duration
                           ,@Path
                           ,@Headers
                           ,@Dimension
                           ,@Value)
                ";

            using (var connection = new SqlConnection(connectionString))
            {
                await connection.OpenAsync();

                var transaction = connection.BeginTransaction();

                try
                {
                    var command = new SqlCommand(insertCmd, connection, transaction);
                    var p       = command.Parameters;
                    p.AddWithValue("@DateTime", utcNow);
                    p.AddWithValue("@Session", session);
                    p.AddWithValue("@Description", description);
                    p.AddWithValue("@AspNetCoreVersion", serverJob.AspNetCoreVersion);
                    p.AddWithValue("@RuntimeVersion", serverJob.RuntimeVersion);
                    p.AddWithValue("@Scenario", serverJob.Scenario.ToString());
                    p.AddWithValue("@Hardware", serverJob.Hardware.ToString());
                    p.AddWithValue("@HardwareVersion", serverJob.HardwareVersion);
                    p.AddWithValue("@OperatingSystem", serverJob.OperatingSystem.ToString());
                    p.AddWithValue("@Framework", "Core");
                    p.AddWithValue("@RuntimeStore", serverJob.UseRuntimeStore);
                    p.AddWithValue("@Scheme", serverJob.Scheme.ToString().ToLowerInvariant());
                    p.AddWithValue("@Sources", serverJob.Source != null ? ConvertToSqlString(serverJob.Source) : (object)DBNull.Value);
                    p.AddWithValue("@WebHost", serverJob.WebHost.ToString());
                    p.AddWithValue("@Transport", clientJob.ClientProperties["TransportType"]);
                    p.AddWithValue("@HubProtocol", clientJob.ClientProperties["HubProtocol"]);
                    p.AddWithValue("@ClientProperties", JsonConvert.SerializeObject(clientJob.ClientProperties));
                    p.AddWithValue("@Connections", clientJob.Connections);
                    p.AddWithValue("@Duration", clientJob.Duration);
                    p.AddWithValue("@Path", string.IsNullOrEmpty(path) ? (object)DBNull.Value : path);
                    p.AddWithValue("@Headers", clientJob.Headers.Any() ? JsonConvert.SerializeObject(clientJob.Headers) : (object)DBNull.Value);
                    p.AddWithValue("@Dimension", dimension);
                    p.AddWithValue("@Value", value);
                    await command.ExecuteNonQueryAsync();

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
                finally
                {
                    transaction.Dispose();
                }
            }
        }
        public static int Main(string[] args)
        {
            var app = new CommandLineApplication()
            {
                Name        = "BenchmarksDriver",
                FullName    = "ASP.NET Benchmark Driver",
                Description = "Driver for ASP.NET Benchmarks"
            };

            app.HelpOption("-?|-h|--help");

            // Driver Options
            var serverOption = app.Option("-s|--server",
                                          "URL of benchmark server", CommandOptionType.SingleValue);
            var clientOption = app.Option("-c|--client",
                                          "URL of benchmark client", CommandOptionType.SingleValue);
            var sqlConnectionStringOption = app.Option("-q|--sql",
                                                       "Connection string of SQL Database to store results", CommandOptionType.SingleValue);

            // ServerJob Options
            var connectionFilterOption = app.Option("-f|--connectionFilter",
                                                    "Assembly-qualified name of the ConnectionFilter", CommandOptionType.SingleValue);
            var scenarioOption = app.Option("-n|--scenario",
                                            "Benchmark scenario to run", CommandOptionType.SingleValue);
            var schemeOption = app.Option("-m|--scheme",
                                          "Scheme (http or https).  Default is http.", CommandOptionType.SingleValue);
            var sourceOption = app.Option("-o|--source",
                                          "Source dependency. Format is 'repo@branchOrCommit'. " +
                                          "Repo can be a full URL, or a short name under https://github.com/aspnet.",
                                          CommandOptionType.MultipleValue);

            // ClientJob Options
            var connectionsOption = app.Option("--connections",
                                               "Number of connections used by client", CommandOptionType.SingleValue);
            var durationOption = app.Option("--duration",
                                            "Duration of test in seconds", CommandOptionType.SingleValue);
            var pipelineDepthOption = app.Option("--pipelineDepth",
                                                 "Depth of pipeline used by client", CommandOptionType.SingleValue);
            var threadsOption = app.Option("--threads",
                                           "Number of threads used by client", CommandOptionType.SingleValue);
            var headerOption = app.Option("--header",
                                          "Header added to request", CommandOptionType.MultipleValue);

            app.OnExecute(() =>
            {
                var schemeValue = schemeOption.Value();
                if (string.IsNullOrEmpty(schemeValue))
                {
                    schemeValue = "http";
                }

                var server = serverOption.Value();
                var client = clientOption.Value();
                var sqlConnectionString = sqlConnectionStringOption.Value();

                Scheme scheme;
                Scenario scenario;
                if (!Enum.TryParse(schemeValue, ignoreCase: true, result: out scheme) ||
                    !Enum.TryParse(scenarioOption.Value(), ignoreCase: true, result: out scenario) ||
                    string.IsNullOrWhiteSpace(server) ||
                    string.IsNullOrWhiteSpace(client))
                {
                    app.ShowHelp();
                    return(2);
                }

                var serverJob = new ServerJob()
                {
                    Scheme   = scheme,
                    Scenario = scenario,
                };

                if (connectionFilterOption.HasValue())
                {
                    serverJob.ConnectionFilter = connectionFilterOption.Value();
                }

                var sources = new List <Source>();
                foreach (var source in sourceOption.Values)
                {
                    var split      = source.IndexOf('@');
                    var repository = (split == -1) ? source : source.Substring(0, split);
                    var branch     = (split == -1) ? null : source.Substring(split + 1);

                    if (!repository.Contains(":"))
                    {
                        repository = $"https://github.com/aspnet/{repository}.git";
                    }

                    sources.Add(new Source()
                    {
                        BranchOrCommit = branch, Repository = repository
                    });
                }
                serverJob.Sources = sources;

                // Override default ClientJob settings if options are set
                if (connectionsOption.HasValue())
                {
                    _clientJobs.Values.ToList().ForEach(c => c.Connections = int.Parse(connectionsOption.Value()));
                }
                if (threadsOption.HasValue())
                {
                    _clientJobs.Values.ToList().ForEach(c => c.Threads = int.Parse(threadsOption.Value()));
                }
                if (durationOption.HasValue())
                {
                    _clientJobs.Values.ToList().ForEach(c => c.Duration = int.Parse(durationOption.Value()));
                }
                if (pipelineDepthOption.HasValue())
                {
                    _clientJobs.Values.ToList().ForEach(c => c.PipelineDepth = int.Parse(pipelineDepthOption.Value()));
                }
                if (headerOption.HasValue())
                {
                    _clientJobs.Values.ToList().ForEach(c => c.Headers = headerOption.Values.ToArray());
                }

                return(Run(new Uri(server), new Uri(client), sqlConnectionString, serverJob).Result);
            });

            return(app.Execute(args));
        }
        private static async Task <int> Run(Uri serverUri, Uri clientUri, string sqlConnectionString, ServerJob serverJob)
        {
            var scenario                 = serverJob.Scenario;
            var serverJobsUri            = new Uri(serverUri, "/jobs");
            Uri serverJobUri             = null;
            HttpResponseMessage response = null;
            string responseContent       = null;

            try
            {
                Log($"Starting scenario {scenario} on benchmark server...");

                var content = JsonConvert.SerializeObject(serverJob);
                LogVerbose($"POST {serverJobsUri} {content}...");

                response = await _httpClient.PostAsync(serverJobsUri, new StringContent(content, Encoding.UTF8, "application/json"));

                responseContent = await response.Content.ReadAsStringAsync();

                LogVerbose($"{(int)response.StatusCode} {response.StatusCode}");
                response.EnsureSuccessStatusCode();

                serverJobUri = new Uri(serverUri, response.Headers.Location);

                var serverBenchmarkUri = (string)null;
                while (true)
                {
                    LogVerbose($"GET {serverJobUri}...");
                    response = await _httpClient.GetAsync(serverJobUri);

                    responseContent = await response.Content.ReadAsStringAsync();

                    LogVerbose($"{(int)response.StatusCode} {response.StatusCode} {responseContent}");

                    serverJob = JsonConvert.DeserializeObject <ServerJob>(responseContent);

                    if (serverJob.State == ServerState.Running)
                    {
                        serverBenchmarkUri = serverJob.Url;
                        break;
                    }
                    else if (serverJob.State == ServerState.Failed)
                    {
                        throw new InvalidOperationException("Server job failed");
                    }
                    else
                    {
                        await Task.Delay(1000);
                    }
                }

                Log("Warmup");
                await RunClientJob(scenario, clientUri, serverBenchmarkUri);

                Log("Benchmark");
                var clientJob = await RunClientJob(scenario, clientUri, serverBenchmarkUri);

                if (clientJob.State == ClientState.Completed && !string.IsNullOrWhiteSpace(sqlConnectionString))
                {
                    await WriteResultsToSql(sqlConnectionString, scenario, serverJob.Scheme, serverJob.ConnectionFilter, clientJob.Threads,
                                            clientJob.Connections, clientJob.Duration, clientJob.PipelineDepth, clientJob.Headers, clientJob.RequestsPerSecond);
                }
            }
            finally
            {
                if (serverJobUri != null)
                {
                    Log($"Stopping scenario {scenario} on benchmark server...");

                    LogVerbose($"DELETE {serverJobUri}...");
                    response = _httpClient.DeleteAsync(serverJobUri).Result;
                    LogVerbose($"{(int)response.StatusCode} {response.StatusCode}");
                    response.EnsureSuccessStatusCode();
                }
            }

            return(0);
        }
Exemple #23
0
        public async Task WriteJobResultsToSqlAsync(ServerJob serverJob, ClientJob clientJob, string connectionString, string tableName, string path, string session, string description, Statistics statistics, bool longRunning)
        {
            var utcNow = DateTime.UtcNow;

            await RetryOnExceptionAsync(5, async (retry) =>
            {
                await WriteJobResultToSqlAsync(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, statistics, longRunning, "RequestsPerSecond", statistics.RequestsPerSecond, retry);
            });

            await RetryOnExceptionAsync(5, async (retry) =>
            {
                await WriteJobResultToSqlAsync(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, statistics, longRunning, "CPU", statistics.Cpu, retry);
            });

            await RetryOnExceptionAsync(5, async (retry) =>
            {
                await WriteJobResultToSqlAsync(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, statistics, longRunning, "WorkingSet (MB)", statistics.WorkingSet, retry);
            });

            if (statistics.LatencyAverage != -1)
            {
                await RetryOnExceptionAsync(5, async (retry) =>
                {
                    await WriteJobResultToSqlAsync(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, statistics, longRunning, "Latency Average (ms)", statistics.LatencyAverage, retry);
                });
            }

            if (statistics.Latency50Percentile != -1)
            {
                await RetryOnExceptionAsync(5, async (retry) =>
                {
                    await WriteJobResultToSqlAsync(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, statistics, longRunning, "Latency50Percentile (ms)", statistics.Latency50Percentile, retry);
                });
            }

            if (statistics.Latency75Percentile != -1)
            {
                await RetryOnExceptionAsync(5, async (retry) =>
                {
                    await WriteJobResultToSqlAsync(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, statistics, longRunning, "Latency75Percentile (ms)", statistics.Latency75Percentile, retry);
                });
            }

            if (statistics.Latency90Percentile != -1)
            {
                await RetryOnExceptionAsync(5, async (retry) =>
                {
                    await WriteJobResultToSqlAsync(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, statistics, longRunning, "Latency90Percentile (ms)", statistics.Latency90Percentile, retry);
                });
            }

            if (statistics.Latency99Percentile != -1)
            {
                await RetryOnExceptionAsync(5, async (retry) =>
                {
                    await WriteJobResultToSqlAsync(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, statistics, longRunning, "Latency99Percentile (ms)", statistics.Latency99Percentile, retry);
                });
            }

            if (statistics.MaxLatency != -1)
            {
                await RetryOnExceptionAsync(5, async (retry) =>
                {
                    await WriteJobResultToSqlAsync(serverJob, clientJob, utcNow, connectionString, tableName, path, session, description, statistics, longRunning, "MaxLatency (ms)", statistics.MaxLatency, retry);
                });
            }
        }