Beispiel #1
0
 public Functions(DevOpsServer server, TriageContext context, GitHubClientFactory gitHubClientFactory)
 {
     Server              = server;
     Context             = context;
     TriageContextUtil   = new TriageContextUtil(context);
     GitHubClientFactory = gitHubClientFactory;
     SiteLinkUtil        = SiteLinkUtil.Published;
     HelixServer         = new HelixServer();
 }
Beispiel #2
0
 internal RuntimeInfo(
     DevOpsServer devopsServer,
     HelixServer helixServer,
     IAzureUtil azureUtil)
 {
     DevOpsServer = devopsServer;
     HelixServer  = helixServer;
     AzureUtil    = azureUtil;
     QueryUtil    = new DotNetQueryUtil(DevOpsServer, azureUtil);
 }
Beispiel #3
0
 public TrackingIssueUtil(
     HelixServer helixServer,
     DotNetQueryUtil queryUtil,
     TriageContextUtil triageContextUtil,
     ILogger logger)
 {
     HelixServer       = helixServer;
     QueryUtil         = queryUtil;
     TriageContextUtil = triageContextUtil;
     Logger            = logger;
 }
Beispiel #4
0
        private async Task <bool> TriageHelixLogsAsync(ModelBuildAttempt modelBuildAttempt, ModelTrackingIssue modelTrackingIssue)
        {
            Debug.Assert(modelBuildAttempt.ModelBuild is object);
            Debug.Assert(modelTrackingIssue.IsActive);
            Debug.Assert(modelTrackingIssue.SearchQuery is object);

            var request = new SearchHelixLogsRequest()
            {
                Limit = 100,
            };

            request.ParseQueryString(modelTrackingIssue.SearchQuery);

            var query = request.Filter(Context.ModelTestResults)
                        .Where(x => x.ModelBuild.Id == modelBuildAttempt.ModelBuild.Id && x.ModelTestRun.Attempt == modelBuildAttempt.Attempt);

            // TODO: selecting a lot of info here. Can improve perf by selecting only the needed
            // columns. The search helix logs page already optimizes this. Consider factoring out
            // the shared code.
            var testResultList = await query.ToListAsync().ConfigureAwait(false);

            var buildInfo     = modelBuildAttempt.ModelBuild.GetBuildInfo();
            var helixLogInfos = testResultList
                                .Select(x => x.GetHelixLogInfo())
                                .SelectNotNull()
                                .Select(x => (buildInfo, x));

            var results = await HelixServer.SearchHelixLogsAsync(
                helixLogInfos,
                request,
                onError : x => Logger.LogWarning(x.Message)).ConfigureAwait(false);

            var any = false;

            foreach (var result in results)
            {
                any = true;
                var modelMatch = new ModelTrackingIssueMatch()
                {
                    ModelBuildAttempt  = modelBuildAttempt,
                    ModelTrackingIssue = modelTrackingIssue,
                    HelixLogKind       = result.HelixLogKind,
                    HelixLogUri        = result.HelixLogUri,
                };
                Context.ModelTrackingIssueMatches.Add(modelMatch);
            }
            return(any);
        }
Beispiel #5
0
        public StandardTestBase(ITestOutputHelper testOutputHelper)
        {
            Connection = CreateInMemoryDatabase();
            var options = new DbContextOptionsBuilder <TriageContext>()
                          .UseSqlite(Connection)
                          .Options;

            Context                     = new TriageContext(options);
            TriageContextUtil           = new TriageContextUtil(Context);
            TestableHttpMessageHandler  = new TestableHttpMessageHandler();
            TestableLogger              = new TestableLogger(testOutputHelper);
            TestableGitHubClientFactory = new TestableGitHubClientFactory();

            var httpClient = new HttpClient(TestableHttpMessageHandler);

            Server      = new DevOpsServer("random", httpClient: httpClient);
            HelixServer = new HelixServer(httpClient: httpClient);
            QueryUtil   = new DotNetQueryUtil(Server);

            Context.Database.EnsureDeleted();
            Context.Database.EnsureCreated();
        }
Beispiel #6
0
        public async Task OnGet()
        {
            const int pageSize = 50;

            ErrorMessage = null;

            if (string.IsNullOrEmpty(BuildQuery))
            {
                BuildQuery = new SearchBuildsRequest()
                {
                    Definition = "runtime",
                    Started    = new DateRequestValue(dayQuery: 3),
                }.GetQueryString();
                return;
            }

            if (!SearchBuildsRequest.TryCreate(BuildQuery, out var buildsRequest, out var errorMessage) ||
                !SearchHelixLogsRequest.TryCreate(LogQuery ?? "", out var logsRequest, out errorMessage))
            {
                ErrorMessage = errorMessage;
                return;
            }

            // Helix logs are only kept for failed builds. If the user doesn't specify a specific result type,
            // like say cancelled, then just search all non succeeded builds.
            if (buildsRequest.Result is null)
            {
                buildsRequest.Result = new BuildResultRequestValue(BuildResult.Succeeded, EqualsKind.NotEquals);
                BuildQuery           = buildsRequest.GetQueryString();
            }

            if (logsRequest.HelixLogKinds.Count == 0)
            {
                logsRequest.HelixLogKinds.Add(HelixLogKind.Console);
                LogQuery = logsRequest.GetQueryString();
            }

            if (string.IsNullOrEmpty(logsRequest.Text))
            {
                ErrorMessage = @"Must specify text to search for 'text: ""StackOverflowException""'";
                return;
            }

            try
            {
                IQueryable <ModelTestResult> query = TriageContextUtil.Context.ModelTestResults.Where(x => x.IsHelixTestResult);
                query = buildsRequest.Filter(query);
                var totalBuildCount = await query.CountAsync();

                var modelResults = await query
                                   .Skip(PageNumber *pageSize)
                                   .Take(pageSize)
                                   .Select(x => new
                {
                    x.ModelBuild.BuildNumber,
                    x.ModelBuild.AzureOrganization,
                    x.ModelBuild.AzureProject,
                    x.ModelBuild.StartTime,
                    x.ModelBuild.GitHubOrganization,
                    x.ModelBuild.GitHubRepository,
                    x.ModelBuild.GitHubTargetBranch,
                    x.ModelBuild.PullRequestNumber,
                    x.HelixConsoleUri,
                    x.HelixCoreDumpUri,
                    x.HelixRunClientUri,
                    x.HelixTestResultsUri,
                })
                                   .ToListAsync();

                var toQuery = modelResults
                              .Select(x => (
                                          new BuildInfo(x.AzureOrganization, x.AzureProject, x.BuildNumber,
                                                        new GitHubBuildInfo(x.GitHubOrganization, x.GitHubRepository, x.PullRequestNumber, x.GitHubTargetBranch)),
                                          new HelixLogInfo(
                                              runClientUri: x.HelixRunClientUri,
                                              consoleUri: x.HelixConsoleUri,
                                              coreDumpUri: x.HelixCoreDumpUri,
                                              testResultsUri: x.HelixTestResultsUri)));

                var helixServer  = new HelixServer();
                var errorBuilder = new StringBuilder();
                var results      = await helixServer.SearchHelixLogsAsync(
                    toQuery,
                    logsRequest,
                    ex => errorBuilder.AppendLine(ex.Message));

                foreach (var result in results)
                {
                    HelixLogs.Add(new HelixLogData()
                    {
                        BuildNumber  = result.BuildInfo.Number,
                        Line         = result.Line,
                        HelixLogKind = result.HelixLogKind.GetDisplayFileName(),
                        HelixLogUri  = result.HelixLogUri,
                    });
                }

                if (errorBuilder.Length > 0)
                {
                    ErrorMessage = errorBuilder.ToString();
                }

                PaginationDisplay = new PaginationDisplay(
                    "/Search/HelixLogs",
                    new Dictionary <string, string>()
                {
                    { "bq", BuildQuery },
                    { "lq", LogQuery ?? "" },
                },
                    PageNumber,
                    totalBuildCount / pageSize);
                BuildResultText = $"Results for {PageNumber * pageSize}-{(PageNumber * pageSize) + pageSize} of {totalBuildCount} builds";
                DidSearch       = true;
            }
            catch (SqlException ex) when(ex.IsTimeoutViolation())
            {
                ErrorMessage = "Timeout fetching data from the server";
            }
        }
Beispiel #7
0
 public static async Task <List <SearchHelixLogsResult> > SearchHelixLogsAsync(
     this HelixServer helixServer,
     IEnumerable <(BuildInfo BuildInfo, HelixLogInfo HelixLogInfo)> builds,