public void TimelineRoundTrip(string toParse, string userQuery) { var options = new SearchTimelinesRequest(); options.ParseQueryString(toParse); Assert.Equal(userQuery, options.GetQueryString()); }
public async Task <IActionResult> OnGet() { const int PageSize = 25; if (string.IsNullOrEmpty(BuildQuery)) { BuildQuery = new SearchBuildsRequest() { Definition = "runtime" }.GetQueryString(); return(Page()); } if (!SearchBuildsRequest.TryCreate(BuildQuery ?? "", out var buildsRequest, out var errorMessage) || !SearchTimelinesRequest.TryCreate(TimelineQuery ?? "", out var timelinesRequest, out errorMessage)) { ErrorMessage = errorMessage; return(Page()); } try { IQueryable <ModelTimelineIssue> query = TriageContextUtil.Context.ModelTimelineIssues; query = buildsRequest.Filter(query); query = timelinesRequest.Filter(query); var totalCount = await query.CountAsync(); query = query .OrderByDescending(x => x.ModelBuild.BuildNumber) .Skip(PageNumber * PageSize) .Take(PageSize); TimelineIssuesDisplay = await TimelineIssuesDisplay.Create( query, includeBuildColumn : true, includeIssueTypeColumn : timelinesRequest.Type is null, includeAttemptColumn : true); IncludeIssueTypeColumn = timelinesRequest.Type is null; PaginationDisplay = new PaginationDisplay( "/Search/Timelines", new Dictionary <string, string>() { { "bq", BuildQuery ?? "" }, { "tq", TimelineQuery ?? "" } }, PageNumber, totalCount / PageSize); TotalCount = totalCount; return(Page()); } catch (SqlException ex) when(ex.IsTimeoutViolation()) { ErrorMessage = "Timeout fetching data from the server"; return(Page()); } }
public async Task OnGet() { ErrorMessage = null; if (string.IsNullOrEmpty(Query)) { Query = new SearchBuildsRequest() { Started = new DateRequestValue(dayQuery: 5), BuildType = new BuildTypeRequestValue(ModelBuildKind.PullRequest, EqualsKind.NotEquals, "pr"), }.GetQueryString(); } if (string.IsNullOrEmpty(Definition)) { Definition = "roslyn-ci"; return; } var modelBuildDefinition = await FindDefinitionAsync(Definition); if (modelBuildDefinition is null) { ErrorMessage = $"Could not find definition for {Definition}"; return; } var searchBuildsRequest = new SearchBuildsRequest(); searchBuildsRequest.ParseQueryString(Query); searchBuildsRequest.Definition = null; await PopulateBuildInfoAsync(); await PopulateJobData(); HasResults = true; async Task PopulateBuildInfoAsync() { var buildQuery = TriageContextUtil.Context.ModelBuilds .Where(x => x.ModelBuildDefinitionId == modelBuildDefinition.Id && x.BuildResult.HasValue); var builds = await searchBuildsRequest.Filter(buildQuery) .Select(x => new { x.BuildResult, x.IsMergedPullRequest, x.PullRequestNumber, }) .ToListAsync(); BuildCount = builds.Count; RollingPassRate = GetPassRate(ModelBuildKind.Rolling); MergedPullRequestPassRate = GetPassRate(ModelBuildKind.MergedPullRequest); var totalPassRate = (double)(builds.Count(x => IsSuccess(x.BuildResult !.Value))) / builds.Count; TotalPassRate = totalPassRate.ToString("P2"); string?GetPassRate(ModelBuildKind kind) { var filtered = builds .Where(x => TriageContextUtil.GetModelBuildKind(x.IsMergedPullRequest, x.PullRequestNumber) == kind) .ToList(); if (filtered.Count == 0) { return(null); } var count = filtered.Count(x => IsSuccess(x.BuildResult !.Value)); var rate = (double)count / filtered.Count; return(rate.ToString("P2")); } } async Task PopulateJobData() { IQueryable <ModelTimelineIssue> query = TriageContextUtil.Context .ModelTimelineIssues .Where(x => x.IssueType == IssueType.Error && x.ModelBuild.ModelBuildDefinitionId == modelBuildDefinition.Id && x.ModelBuild.BuildResult.HasValue); query = searchBuildsRequest.Filter(query); const int limit = 1_000; var issues = await query .Select(x => new { x.JobName, x.ModelBuild.BuildResult, x.ModelBuild.IsMergedPullRequest, x.ModelBuild.PullRequestNumber }) .Take(limit) .ToListAsync(); if (issues.Count == limit) { JobLimitHit = limit; } searchBuildsRequest.Definition = Definition; foreach (var group in issues.GroupBy(x => x.JobName)) { var request = new SearchTimelinesRequest() { JobName = group.Key, Type = IssueType.Error }; var data = new JobData() { JobName = group.Key, MergedPullRequestFailureCount = GetFailureCount(ModelBuildKind.MergedPullRequest), RollingFailureCount = GetFailureCount(ModelBuildKind.Rolling), TotalFailureCount = GetFailureCount(null), JobPageBuildQuery = searchBuildsRequest.GetQueryString(), JobPageTimelineQuery = request.GetQueryString(), }; JobDataList.Add(data); int GetFailureCount(ModelBuildKind?kind) => kind is { } k ? group.Where(x => TriageContextUtil.GetModelBuildKind(x.IsMergedPullRequest, x.PullRequestNumber) == k).Count() : group.Count(); } searchBuildsRequest.Definition = null; JobDataList.Sort((x, y) => y.TotalFailureCount - x.TotalFailureCount); }