public async Task <BuildAttemptKey> EnsureModelInfoAsync(Build build, bool includeTests = true) { var buildInfo = build.GetBuildResultInfo(); var modelBuild = await TriageContextUtil.EnsureBuildAsync(buildInfo).ConfigureAwait(false); await TriageContextUtil.EnsureResultAsync(modelBuild, build).ConfigureAwait(false); var modelBuildAttempt = await EnsureTimeline().ConfigureAwait(false); if (includeTests) { await EnsureTestRuns().ConfigureAwait(false); } return(new BuildAttemptKey(new BuildKey(build), modelBuildAttempt.Attempt)); async Task <ModelBuildAttempt> EnsureTimeline() { try { var timeline = await Server.GetTimelineAsync(buildInfo.Project, buildInfo.Number).ConfigureAwait(false); if (timeline is null) { Logger.LogWarning("No timeline"); } else { return(await TriageContextUtil.EnsureBuildAttemptAsync(buildInfo, timeline).ConfigureAwait(false)); } } catch (Exception ex) { Logger.LogWarning($"Error getting timeline: {ex.Message}"); } return(await TriageContextUtil.EnsureBuildAttemptWithoutTimelineAsync(modelBuild, build).ConfigureAwait(false)); } async Task EnsureTestRuns() { TestRun[] testRuns; try { testRuns = await Server.ListTestRunsAsync(buildInfo.Project, buildInfo.Number).ConfigureAwait(false); } catch (Exception ex) { Logger.LogWarning($"Error getting test runs: {ex.Message}"); return; } var attempt = modelBuildAttempt?.Attempt ?? 1; foreach (var testRun in testRuns) { await EnsureTestRun(testRun, attempt).ConfigureAwait(false); } } async Task EnsureTestRun(TestRun testRun, int attempt) { try { var modelTestRun = await TriageContextUtil.FindModelTestRunAsync(modelBuild.GetBuildKey(), testRun.Id).ConfigureAwait(false); if (modelTestRun is object) { return; } // TODO: Need to record when the maximum test results are exceeded. The limit here is to // protect us from a catastrophic run that has say several million failures (this is a real // possibility const int maxTestCaseResultCount = 200; var dotNetTestRun = await QueryUtil.GetDotNetTestRunAsync( build, testRun, DotNetUtil.FailedTestOutcomes, includeSubResults : true, onError : ex => Logger.LogWarning($"Error fetching test data {ex.Message}")).ConfigureAwait(false); if (dotNetTestRun.TestCaseResults.Count > maxTestCaseResultCount) { dotNetTestRun = new DotNetTestRun( dotNetTestRun.TestRunInfo, dotNetTestRun.TestCaseResults.Take(maxTestCaseResultCount).ToReadOnlyCollection()); } var helixMap = await Server.GetHelixMapAsync(dotNetTestRun).ConfigureAwait(false); await TriageContextUtil.EnsureTestRunAsync(modelBuild, attempt, dotNetTestRun, helixMap).ConfigureAwait(false); } catch (Exception ex) { Logger.LogWarning($"Error uploading test run: {ex.Message}"); return; } } }
public async Task <ModelTestRun> EnsureTestRunAsync(ModelBuild modelBuild, int attempt, DotNetTestRun testRun, Dictionary <HelixInfo, HelixLogInfo> helixMap) { var modelTestRun = await FindModelTestRunAsync(modelBuild.GetBuildKey(), testRun.TestRun.Id).ConfigureAwait(false); if (modelTestRun is object) { return(modelTestRun); } var buildInfo = testRun.Build.GetBuildResultInfo(); modelTestRun = new ModelTestRun() { AzureOrganization = buildInfo.Organization, AzureProject = buildInfo.Project, ModelBuild = modelBuild, TestRunId = testRun.TestRun.Id, Name = testRun.TestRun.Name, Attempt = attempt, }; Context.ModelTestRuns.Add(modelTestRun); foreach (var dotnetTestCaseResult in testRun.TestCaseResults) { var testCaseResult = dotnetTestCaseResult.TestCaseResult; var testResult = new ModelTestResult() { TestFullName = testCaseResult.TestCaseTitle, Outcome = testCaseResult.Outcome, ModelTestRun = modelTestRun, ModelBuild = modelBuild, ErrorMessage = testCaseResult.ErrorMessage, IsSubResultContainer = testCaseResult.SubResults?.Length > 0, IsSubResult = false, }; AddHelixInfo(testResult); Context.ModelTestResults.Add(testResult); if (testCaseResult.SubResults is { } subResults) { foreach (var subResult in subResults) { var iterationTestResult = new ModelTestResult() { TestFullName = testCaseResult.TestCaseTitle, Outcome = subResult.Outcome, ModelTestRun = modelTestRun, ModelBuild = modelBuild, ErrorMessage = subResult.ErrorMessage, IsSubResultContainer = false, IsSubResult = true }; AddHelixInfo(iterationTestResult); Context.ModelTestResults.Add(iterationTestResult); } } void AddHelixInfo(ModelTestResult testResult) { if (dotnetTestCaseResult.HelixInfo is { } helixInfo&& helixMap.TryGetValue(helixInfo, out var helixLogInfo)) { testResult.IsHelixTestResult = true; testResult.HelixConsoleUri = helixLogInfo.ConsoleUri; testResult.HelixCoreDumpUri = helixLogInfo.CoreDumpUri; testResult.HelixRunClientUri = helixLogInfo.RunClientUri; testResult.HelixTestResultsUri = helixLogInfo.TestResultsUri; } } } await Context.SaveChangesAsync().ConfigureAwait(false); return(modelTestRun); }