示例#1
0
        public void TimelineRoundTrip(string toParse, string userQuery)
        {
            var options = new SearchTimelinesRequest();

            options.ParseQueryString(toParse);
            Assert.Equal(userQuery, options.GetQueryString());
        }
示例#2
0
        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());
            }
        }
示例#3
0
        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);
            }