154 lines
6.4 KiB
C#
154 lines
6.4 KiB
C#
|
// Licensed to the .NET Foundation under one or more agreements.
|
|||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
|||
|
// See the LICENSE file in the project root for more information.
|
|||
|
|
|||
|
using Newtonsoft.Json;
|
|||
|
using Newtonsoft.Json.Serialization;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Globalization;
|
|||
|
using System.Linq;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using System.Text;
|
|||
|
using RuntimeEnvironment = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment;
|
|||
|
|
|||
|
namespace Reporting
|
|||
|
{
|
|||
|
public class Reporter
|
|||
|
{
|
|||
|
private Run run;
|
|||
|
private Os os;
|
|||
|
private Build build;
|
|||
|
private List<Test> tests = new List<Test>();
|
|||
|
protected IEnvironment environment;
|
|||
|
|
|||
|
private Reporter() { }
|
|||
|
|
|||
|
public void AddTest(Test test)
|
|||
|
{
|
|||
|
if (tests.Any(t => t.Name.Equals(test.Name)))
|
|||
|
throw new Exception($"Duplicate test name, {test.Name}");
|
|||
|
tests.Add(test);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get a Reporter. Relies on environment variables.
|
|||
|
/// </summary>
|
|||
|
/// <param name="environment">Optional environment variable provider</param>
|
|||
|
/// <returns>A Reporter instance or null if the environment is incorrect.</returns>
|
|||
|
public static Reporter CreateReporter(IEnvironment environment = null)
|
|||
|
{
|
|||
|
var ret = new Reporter();
|
|||
|
ret.environment = environment == null ? new EnvironmentProvider() : environment;
|
|||
|
if (ret.InLab)
|
|||
|
{
|
|||
|
ret.Init();
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
private void Init()
|
|||
|
{
|
|||
|
run = new Run
|
|||
|
{
|
|||
|
CorrelationId = environment.GetEnvironmentVariable("HELIX_CORRELATION_ID"),
|
|||
|
PerfRepoHash = environment.GetEnvironmentVariable("PERFLAB_PERFHASH"),
|
|||
|
Name = environment.GetEnvironmentVariable("PERFLAB_RUNNAME"),
|
|||
|
Queue = environment.GetEnvironmentVariable("PERFLAB_QUEUE"),
|
|||
|
};
|
|||
|
Boolean.TryParse(environment.GetEnvironmentVariable("PERFLAB_HIDDEN"), out bool hidden);
|
|||
|
run.Hidden = hidden;
|
|||
|
var configs = environment.GetEnvironmentVariable("PERFLAB_CONFIGS");
|
|||
|
if (!String.IsNullOrEmpty(configs)) // configs should be optional.
|
|||
|
{
|
|||
|
foreach (var kvp in configs.Split(';'))
|
|||
|
{
|
|||
|
var split = kvp.Split('=');
|
|||
|
run.Configurations.Add(split[0], split[1]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
os = new Os()
|
|||
|
{
|
|||
|
Name = $"{RuntimeEnvironment.OperatingSystem} {RuntimeEnvironment.OperatingSystemVersion}",
|
|||
|
Architecture = RuntimeInformation.OSArchitecture.ToString(),
|
|||
|
Locale = CultureInfo.CurrentUICulture.ToString()
|
|||
|
};
|
|||
|
|
|||
|
build = new Build
|
|||
|
{
|
|||
|
Repo = environment.GetEnvironmentVariable("PERFLAB_REPO"),
|
|||
|
Branch = environment.GetEnvironmentVariable("PERFLAB_BRANCH"),
|
|||
|
Architecture = environment.GetEnvironmentVariable("PERFLAB_BUILDARCH"),
|
|||
|
Locale = environment.GetEnvironmentVariable("PERFLAB_LOCALE"),
|
|||
|
GitHash = environment.GetEnvironmentVariable("PERFLAB_HASH"),
|
|||
|
BuildName = environment.GetEnvironmentVariable("PERFLAB_BUILDNUM"),
|
|||
|
TimeStamp = DateTime.Parse(environment.GetEnvironmentVariable("PERFLAB_BUILDTIMESTAMP")),
|
|||
|
};
|
|||
|
build.AdditionalData["productVersion"] = environment.GetEnvironmentVariable("DOTNET_VERSION");
|
|||
|
}
|
|||
|
public string GetJson()
|
|||
|
{
|
|||
|
if (!InLab)
|
|||
|
{
|
|||
|
return null;
|
|||
|
}
|
|||
|
var jsonobj = new
|
|||
|
{
|
|||
|
build,
|
|||
|
os,
|
|||
|
run,
|
|||
|
tests
|
|||
|
};
|
|||
|
var settings = new JsonSerializerSettings();
|
|||
|
var resolver = new DefaultContractResolver();
|
|||
|
resolver.NamingStrategy = new CamelCaseNamingStrategy() { ProcessDictionaryKeys = false };
|
|||
|
settings.ContractResolver = resolver;
|
|||
|
return JsonConvert.SerializeObject(jsonobj, Formatting.Indented, settings);
|
|||
|
}
|
|||
|
|
|||
|
public string WriteResultTable()
|
|||
|
{
|
|||
|
StringBuilder ret = new StringBuilder();
|
|||
|
foreach (var test in tests)
|
|||
|
{
|
|||
|
var defaultCounter = test.Counters.Single(c => c.DefaultCounter);
|
|||
|
var topCounters = test.Counters.Where(c => c.TopCounter && !c.DefaultCounter);
|
|||
|
var restCounters = test.Counters.Where(c => !(c.TopCounter || c.DefaultCounter));
|
|||
|
var counterWidth = Math.Max(test.Counters.Max(c => c.Name.Length) + 1, 15);
|
|||
|
var resultWidth = Math.Max(test.Counters.Max(c => c.Results.Max().ToString("F3").Length + c.MetricName.Length) + 2, 15);
|
|||
|
ret.AppendLine(test.Name);
|
|||
|
ret.AppendLine($"{LeftJustify("Metric", counterWidth)}|{LeftJustify("Average",resultWidth)}|{LeftJustify("Min", resultWidth)}|{LeftJustify("Max",resultWidth)}");
|
|||
|
ret.AppendLine($"{new String('-', counterWidth)}|{new String('-', resultWidth)}|{new String('-', resultWidth)}|{new String('-', resultWidth)}");
|
|||
|
|
|||
|
|
|||
|
ret.AppendLine(Print(defaultCounter, counterWidth, resultWidth));
|
|||
|
foreach(var counter in topCounters)
|
|||
|
{
|
|||
|
ret.AppendLine(Print(counter, counterWidth, resultWidth));
|
|||
|
}
|
|||
|
foreach (var counter in restCounters)
|
|||
|
{
|
|||
|
ret.AppendLine(Print(counter, counterWidth, resultWidth));
|
|||
|
}
|
|||
|
}
|
|||
|
return ret.ToString();
|
|||
|
}
|
|||
|
private string Print(Counter counter, int counterWidth, int resultWidth)
|
|||
|
{
|
|||
|
string average = $"{counter.Results.Average():F3} {counter.MetricName}";
|
|||
|
string max = $"{counter.Results.Max():F3} {counter.MetricName}";
|
|||
|
string min = $"{counter.Results.Min():F3} {counter.MetricName}";
|
|||
|
return $"{LeftJustify(counter.Name, counterWidth)}|{LeftJustify(average, resultWidth)}|{LeftJustify(min, resultWidth)}|{LeftJustify(max, resultWidth)}";
|
|||
|
}
|
|||
|
|
|||
|
private string LeftJustify(string str, int width)
|
|||
|
{
|
|||
|
return String.Format("{0,-" + width + "}", str);
|
|||
|
}
|
|||
|
|
|||
|
public bool InLab => environment.GetEnvironmentVariable("PERFLAB_INLAB")?.Equals("1") ?? false;
|
|||
|
}
|
|||
|
}
|