Xamarin Public Jenkins (auto-signing) 64ac736ec5 Imported Upstream version 6.0.0.172
Former-commit-id: f3cc9b82f3e5bd8f0fd3ebc098f789556b44e9cd
2019-04-12 14:10:50 +00:00

156 lines
6.1 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// HelixBase.cs
//
// Authors:
// Alexander Köplinger <alkpli@microsoft.com>
//
// Copyright (C) 2018 Microsoft
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Microsoft.DotNet.Helix.Client;
public class HelixBase
{
protected IHelixApi _api;
public HelixBase ()
{
_api = ApiFactory.GetAuthenticated (GetEnvironmentVariable ("MONO_HELIX_API_KEY"));
}
protected string GetEnvironmentVariable (string variable)
{
return Environment.GetEnvironmentVariable (variable) ?? throw new ArgumentException ($"No value for '{variable}'.");
}
protected string McUrlEncode (string input)
{
// encodes the URL in a way Mission Control understands (% replaced with ~)
var result = WebUtility.UrlEncode (input);
return result.Replace ("%", "~");
}
public async Task<bool> WaitForJobCompletion (string correlationId)
{
bool success = false;
bool printedMcLink = false;
Console.WriteLine ($"Waiting for job '{correlationId}' to finish...");
int sleepTime = 0;
while (true)
{
await Task.Delay (sleepTime);
sleepTime = Math.Min (30000, sleepTime + 10000);
var statusContent = await _api.Job.DetailsAsync (correlationId);
if (String.IsNullOrEmpty (statusContent.JobList))
{
Console.WriteLine ("Job list isn't available yet.");
continue;
}
if (!printedMcLink)
{
var mcResultsUrl = $"https://mc.dot.net/#/user/{McUrlEncode (statusContent.Creator)}/{McUrlEncode (statusContent.Source)}/{McUrlEncode (statusContent.Type)}/{McUrlEncode (statusContent.Build)}";
Console.WriteLine ($"View test results on Mission Control: {mcResultsUrl}");
printedMcLink = true;
}
var isFinished = statusContent.WorkItems.Unscheduled == 0 &&
statusContent.WorkItems.Waiting == 0 &&
statusContent.WorkItems.Running == 0;
if (isFinished)
{
Console.WriteLine ("Job finished, fetching results...");
var resultsContent = (await _api.Aggregate.JobSummaryMethodAsync (new List<string> { "job.name" }, maxResultSets: 1, filtername: correlationId));
if (resultsContent.Count != 1)
throw new InvalidOperationException ("No results found for job.");
resultsContent[0].Validate ();
var resultData = resultsContent[0].Data;
var workItemStatus = resultData.WorkItemStatus;
var analyses = resultData.Analysis;
if (workItemStatus.ContainsKey ("none"))
{
Console.WriteLine ($"Still processing xunit data from {workItemStatus["none"]} work items. Stay tuned.");
continue;
}
if (analyses.Count > 0)
{
if (analyses.Count > 1)
throw new InvalidOperationException ("Job contains multiple analyses, this shouldn't happen.");
var analysis = analyses[0];
if (analysis.Name != "xunit")
throw new InvalidOperationException ($"Job contains unknown analysis '{analysis.Name}', this shouldn't happen.");
if (analysis.Status == null)
throw new InvalidOperationException ($"Job contains no status for analysis '{analysis.Name}', this shouldn't happen.");
analysis.Status.TryGetValue ("pass", out int? pass);
analysis.Status.TryGetValue ("skip", out int? skip);
analysis.Status.TryGetValue ("fail", out int? fail);
int? total = pass + skip + fail;
if (total == null || total == 0)
throw new InvalidOperationException ($"Job contains no test results, this shouldn't happen.");
Console.WriteLine ("");
Console.WriteLine ($"Tests run: {total}, Passed: {pass ?? 0}, Errors: 0, Failures: {fail ?? 0}, Inconclusive: 0");
Console.WriteLine ($" Not run: {skip ?? 0}, Invalid: 0, Ignored: 0, Skipped: {skip ?? 0}");
Console.WriteLine ("");
success = (fail == 0);
}
if (workItemStatus.ContainsKey ("fail"))
{
success = false;
Console.WriteLine ($"{workItemStatus["fail"]} work items failed.");
}
}
else
{
Console.WriteLine ($"Waiting for work items to finish: Unscheduled: {statusContent.WorkItems.Unscheduled}, Waiting: {statusContent.WorkItems.Waiting}, Running: {statusContent.WorkItems.Running}");
continue;
}
Console.WriteLine ($"Job {(success ? "SUCCEEDED" : "FAILED")}.");
return success;
}
}
}