For mismatched confgs, show values that are not misatched in black, css and c# cleanup.

This commit is contained in:
Sean Stolberg 2018-08-20 21:31:37 -07:00
Родитель 9cb7db7445
Коммит 5ccdb266a6
11 изменённых файлов: 59 добавлений и 190 удалений

Просмотреть файл

@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">SOLUTION</s:String>
<s:Int64 x:Key="/Default/Environment/SearchAndNavigation/DefaultOccurrencesGroupingIndex/@EntryValue">2</s:Int64></wpf:ResourceDictionary>

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using System.Globalization;
namespace UnityPerformanceBenchmarkReporter
{
@ -14,7 +15,7 @@ namespace UnityPerformanceBenchmarkReporter
}
else
{
var s = Convert.ToString(d);
var s = Convert.ToString(d, CultureInfo.InvariantCulture);
var parts = s.Split('.');
if (parts.Length <= 1 || parts[1].Length <= digits)
{

Просмотреть файл

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityPerformanceBenchmarkReporter.Entities;
namespace UnityPerformanceBenchmarkReporter
@ -452,103 +451,5 @@ namespace UnityPerformanceBenchmarkReporter
infoResultFiles[infoResultFiles.Length - 1] = resultPath;
}
}
private void WriteWarningMessage(string msg)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(msg);
Console.ResetColor();
}
private void WriteWarningMessage(string msg, string[] playerResultFiles, Dictionary<string, Dictionary<string, string>> mismatchedPlayerValues)
{
var sb = new StringBuilder();
sb.Append(msg + "\r\n");
sb.Append(GetLine());
var tableHeader = new string[playerResultFiles.Length + 1];
tableHeader[0] = "Name";
playerResultFiles.CopyTo(tableHeader, 1);
sb.Append(GetRow(tableHeader));
sb.Append(GetLine());
foreach (var mismatchPlayerValue in mismatchedPlayerValues)
{
string [] rowData = new string[tableHeader.Length];
rowData[0] = mismatchPlayerValue.Key;
for (int i = 0; i < playerResultFiles.Length; i++)
{
if (mismatchPlayerValue.Value.Any(v => v.Key.Equals(playerResultFiles[i])))
{
rowData[i + 1] = mismatchPlayerValue.Value.First(v => v.Key.Equals(playerResultFiles[i])).Value;
}
else
{
rowData[i + 1] = string.Empty;
}
}
sb.Append(GetRow(rowData));
}
sb.Append(GetLine());
WriteWarningMessage(sb.ToString());
}
static int _tableWidth = 100;
private string GetLine()
{
return string.Format("{0}\r\n", new string('-', _tableWidth));
}
private string GetRow(params string[] columns)
{
int width = (_tableWidth - columns.Length) / columns.Length;
string row = "|";
foreach (string column in columns)
{
row += AlignCentre(column, width) + "|";
}
return string.Format("{0}\r\n", row);
}
private string AlignCentre(string alignText, int width)
{
var text = alignText;
if (text.Length > width)
{
var startIndex = text.Length - width + 3;
var length = width - 3;
var substring = text.Substring(startIndex, length);
text = "..." + substring;
}
if (string.IsNullOrEmpty(text))
{
return new string(' ', width);
}
else
{
return text.PadRight(width - (width - text.Length) / 2).PadLeft(width);
}
}
public string ResizeString(string resizeText, int width)
{
var text = resizeText;
if (text.Length > width)
{
var startIndex = text.Length - width + 3;
var length = width - 3;
var substring = text.Substring(startIndex, length);
text = "..." + substring;
}
return text;
}
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Options;
@ -7,10 +8,10 @@ namespace UnityPerformanceBenchmarkReporter
public class OptionsParser
{
private bool help;
private readonly string about = "The Unity Performance Benchmark Reporter enables the comparison of performance metric baselines and subsequent performance metrics (as generated using the Unity Test Runner with the Unity Performance Testing Extension package) in an html report utilizing graphical visualizations.";
private readonly string about = "The Unity Performance Benchmark Reporter enables the comparison of performance metric baselines and subsequent performance metrics (as generated using the Unity Test Runner with the Unity Performance Testing Extension) in an html report utilizing graphical visualizations.";
private readonly string learnMore =
"To learn more about the Unity Performance Benchmark Reporter visit the Unity PerformanceBenchmark GitHub wiki at https://github.com/Unity-Technologies/PerformanceBenchmarkReporter/wiki.";
"To learn more about the Unity Performance Benchmark Reporter visit the Unity Performance Benchmark Reporter GitHub wiki at https://github.com/Unity-Technologies/PerformanceBenchmarkReporter/wiki.";
private string sigFigString;
@ -20,7 +21,7 @@ namespace UnityPerformanceBenchmarkReporter
Baseline
}
public void ParseOptions(PerformanceBenchmark performanceBenchmark, string[] args)
public void ParseOptions(PerformanceBenchmark performanceBenchmark, IEnumerable<string> args)
{
var os = GetOptions(performanceBenchmark);
@ -37,7 +38,7 @@ namespace UnityPerformanceBenchmarkReporter
{
try
{
var sigFig = System.Convert.ToUInt32(sigFigString);
var sigFig = Convert.ToUInt32(sigFigString);
performanceBenchmark.AddSigFig(sigFig);
}
catch (Exception)
@ -79,7 +80,7 @@ namespace UnityPerformanceBenchmarkReporter
})
.Add("reportdirpath:", "OPTIONAL - Path to directory where the UnityPerformanceBenchmark report will be written. Default is current working directory.",
performanceBenchmark.AddReportDirPath)
.Add("sigfig:", "OPTIONAL - Specify the number of significant figures to use when collecting and calculating thresholds and failures for non-integer based metrics (from the profiler, Camer.Render CPU time in milliseconds, for example). This value must be an integer >= 0.",
.Add("sigfig:", "OPTIONAL - Specify the number of significant figures to use when collecting and calculating thresholds and failures for non-integer based metrics (from the profiler, Camer.Render CPU time in milliseconds, for example). This value must be an integer >= 0. Default is 3.",
option =>
{
if (option != null)

Просмотреть файл

@ -14,9 +14,9 @@ namespace UnityPerformanceBenchmarkReporter
public HashSet<string> BaselineXmlFilePaths { get; } = new HashSet<string>();
public HashSet<string> BaselineXmlDirectoryPaths { get; } = new HashSet<string>();
public uint SigFig { get; private set; }
public string ReportDirPath { get; set; }
public string ReportDirPath { get; private set; }
public MetadataValidator MetadataValidator = new MetadataValidator();
public readonly MetadataValidator MetadataValidator = new MetadataValidator();
private bool firstResult = true;
private string firstTestRunResultPath;
@ -33,8 +33,9 @@ namespace UnityPerformanceBenchmarkReporter
{
// Default significant figures to use for non-integer metrics if user doesn't specify another value.
// Most values are in milliseconds or a count of something, so using more often creates an artificial baseline
// failure based on insignificant digits
SigFig = 2;
// failure based on insignificant digits equating to a microsecond, or less, time difference. The Unity Profiler only shows
// up to three significant figures for milliseconds as well.
SigFig = 3;
}
public void AddPerformanceTestRunResults(
@ -78,7 +79,7 @@ namespace UnityPerformanceBenchmarkReporter
if (xmlFileNamePaths.Any())
{
List<KeyValuePair<string, PerformanceTestRun>> perfTestRuns = new List<KeyValuePair<string, PerformanceTestRun>>();
var perfTestRuns = new List<KeyValuePair<string, PerformanceTestRun>>();
foreach (var xmlFileNamePath in xmlFileNamePaths)
{
@ -92,7 +93,7 @@ namespace UnityPerformanceBenchmarkReporter
perfTestRuns.Sort((run1, run2) => run1.Value.StartTime.CompareTo(run2.Value.StartTime));
var resultFilesOrderByStartTime = perfTestRuns.ToArray();
for (int i = 0; i < resultFilesOrderByStartTime.Length; i++)
for (var i = 0; i < resultFilesOrderByStartTime.Length; i++)
{
var performanceTestRun = testResultXmlParser.GetPerformanceTestRunFromXml(resultFilesOrderByStartTime[i].Key);

Просмотреть файл

@ -113,7 +113,7 @@ namespace UnityPerformanceBenchmarkReporter
return mergedTestExecutions;
}
double GetAggregatedSampleValue(SampleGroup sampleGroup)
private double GetAggregatedSampleValue(SampleGroup sampleGroup)
{
double aggregatedSampleValue;
switch (sampleGroup.Definition.AggregationType)
@ -139,7 +139,7 @@ namespace UnityPerformanceBenchmarkReporter
return aggregatedSampleValue;
}
MeasurementResult DeterminePerformanceResult(SampleGroupResult sampleGroup, uint sigFig)
private MeasurementResult DeterminePerformanceResult(SampleGroupResult sampleGroup, uint sigFig)
{
var measurementResult = MeasurementResult.Neutral;
var positiveThresholdValue = sampleGroup.BaselineValue + sampleGroup.BaselineValue * sampleGroup.Threshold;

Просмотреть файл

@ -174,17 +174,13 @@ namespace UnityPerformanceBenchmarkReporter.Report
private static void WriteStatMethodButtons(StreamWriter streamWriter)
{
streamWriter.WriteLine("<tr><td>");
streamWriter.WriteLine("<div class=\"buttonheader\">Select statistical method</div>");
streamWriter.WriteLine(
"<div class=\"buttondiv\"><button id=\"MinButton\" class=\"button\">Min</button></div>&nbsp<div class=\"buttondiv\"><button id=\"MaxButton\" class=\"button\">Max</button></div>&nbsp<div class=\"buttondiv\"><button id=\"MedianButton\" class=\"initialbutton\">Median</button></div>&nbsp<div class=\"buttondiv\"><button id=\"AverageButton\" class=\"button\">Average</button></div>");
streamWriter.WriteLine("</td></tr>");
"<tr><td><div class=\"buttonheader\">Select statistical method</div><div class=\"buttondiv\"><button id=\"MinButton\" class=\"button\">Min</button></div>&nbsp<div class=\"buttondiv\"><button id=\"MaxButton\" class=\"button\">Max</button></div>&nbsp<div class=\"buttondiv\"><button id=\"MedianButton\" class=\"initialbutton\">Median</button></div>&nbsp<div class=\"buttondiv\"><button id=\"AverageButton\" class=\"button\">Average</button></div></td></tr>");
}
private void WriteShowFailedTestsCheckbox(StreamWriter streamWriter)
{
streamWriter.WriteLine("<tr><td>");
streamWriter.WriteLine("<div class=\"showedfailedtests\">");
streamWriter.WriteLine("<tr><td><div class=\"showedfailedtests\">");
if (thisHasBenchmarkResults)
{
streamWriter.WriteLine("<label id=\"hidefailed\" class=\"containerLabel\">Show failed tests only");
@ -197,10 +193,7 @@ namespace UnityPerformanceBenchmarkReporter.Report
"<span class=\"tooltiptext\">No failed tests to show because there are no baseline results.</span>");
streamWriter.WriteLine("<input type=\"checkbox\" disabled>");
}
streamWriter.WriteLine("<span class=\"checkmark\"></span>");
streamWriter.WriteLine("</label>");
streamWriter.WriteLine("</div");
streamWriter.WriteLine("</td></tr>");
streamWriter.WriteLine("<span class=\"checkmark\"></span></label></div></td></tr>");
}
private bool TestRunSettingsExist()
@ -216,14 +209,15 @@ namespace UnityPerformanceBenchmarkReporter.Report
private void WriteShowTestConfigButton(StreamWriter rw)
{
if (metadataValidator.MismatchesExist)
{
rw.WriteLine("<div><button id=\"toggleconfig\" class=\"button\" onclick=\"showTestConfiguration()\"><image class=\"warning\" src=\"warning.png\"></img>Show Test Configuration</button><span class=\"configwarning\">Mismatched test configurations present</span></div>");
}
else
{
rw.WriteLine("<button id=\"toggleconfig\" class=\"button\" onclick=\"showTestConfiguration()\">Show Test Configuration<br></button>");
}
rw.WriteLine(
"<div><button id=\"toggleconfig\" class=\"button\" onclick=\"showTestConfiguration()\">{0}Show Test Configuration</button>{1}</div>",
metadataValidator.MismatchesExist
? "<image class=\"warning\" src=\"warning.png\"></img>"
: string.Empty,
metadataValidator.MismatchesExist
? "<span class=\"configwarning\">Mismatched test configurations present</span>"
: string.Empty);
}
private void WriteJavaScript(StreamWriter rw)
@ -496,13 +490,13 @@ namespace UnityPerformanceBenchmarkReporter.Report
foreach (var distinctSampleGroupName in distinctSampleGroupNames)
{
WriteResultForThisSampleGroup(rw, distinctTestName, resultsForThisTest, distinctSampleGroupName, noTestRegressions);
WriteResultForThisSampleGroup(rw, distinctTestName, resultsForThisTest, distinctSampleGroupName);
}
}
private void WriteResultForThisSampleGroup(StreamWriter rw, string distinctTestName,
List<TestResult> resultsForThisTest,
string distinctSampleGroupName, bool noTestRegressions)
string distinctSampleGroupName)
{
if (!SampleGroupHasSamples(resultsForThisTest, distinctSampleGroupName))
{
@ -525,7 +519,7 @@ namespace UnityPerformanceBenchmarkReporter.Report
private bool IsNoTestFailures(List<TestResult> resultsForThisTest)
{
bool noTestFailures = true;
var noTestFailures = true;
foreach (var distinctSampleGroupName2 in distinctSampleGroupNames)
{
if (!SampleGroupHasSamples(resultsForThisTest, distinctSampleGroupName2)) continue;
@ -718,18 +712,25 @@ namespace UnityPerformanceBenchmarkReporter.Report
sb.Append("<table class=\"warningtable\">");
sb.Append("<tr><th>Value</th><th>Result File</th><th>Path</th></tr>");
for (int i = 0; i < resultFiles.Length; i++)
var baselineValue = string.Empty;
for (var i = 0; i < resultFiles.Length; i++)
{
if (i == 0)
{
baselineValue = mismatchedValue.First(kv => kv.Key.Equals(resultFiles[0])).Value;
}
var resultFile = resultFiles[i];
var value = mismatchedValue.Any(kv => kv.Key.Equals(resultFile)) ?
mismatchedValue.First(kv => kv.Key.Equals(resultFile)).Value :
mismatchedValue.First(kv => kv.Key.Equals(resultFiles[0])).Value;
baselineValue;
var pathParts = resultFile.Split('\\');
var path = string.Join('\\', pathParts.Take(pathParts.Length - 1));
sb.Append(string.Format("<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>", value, pathParts[pathParts.Length - 1], path));
sb.Append(string.Format("<tr title={4}><td {0}>{1}</td><td {0}>{2}</td><td {0}>{3}</td></tr>", value.Equals(baselineValue) ? "class=\"targetvalue\"" : string.Empty, value, pathParts[pathParts.Length - 1], path, value.Equals(baselineValue) ? "\"Baseline configuration\"" : "\"Mismatched configuration\""));
}
sb.Append("</table></div>");
@ -756,17 +757,17 @@ namespace UnityPerformanceBenchmarkReporter.Report
private object GetFieldValues<T>(FieldInfo field, T thisObject)
{
return IsIEnumerableFieldType<T>(field) ? ConvertIEnumberableToString(field, thisObject) : field.GetValue(thisObject);
return IsIEnumerableFieldType(field) ? ConvertIEnumberableToString(field, thisObject) : field.GetValue(thisObject);
}
private static bool IsIEnumerableFieldType<T>(FieldInfo field)
private static bool IsIEnumerableFieldType(FieldInfo field)
{
return typeof(IEnumerable).IsAssignableFrom(field.FieldType) && field.FieldType != typeof(string);
}
private string ConvertIEnumberableToString<T>(FieldInfo field, T thisObject)
{
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();
foreach (var enumerable in (IEnumerable) field.GetValue(thisObject))
{
sb.Append(enumerable + ",");

Просмотреть файл

@ -17,6 +17,10 @@ th {
border-bottom-color: lightgray;
}
.targetvalue {
color: black !important;
}
.titletable {
height: 80%;
width: 100%;
@ -99,7 +103,7 @@ th {
div > .configwarning {
visibility: hidden;
width: 120px;
background-color: #F9A625;
background-color: #f28034;
color: white;
text-align: center;
border-radius: 6px;
@ -164,7 +168,7 @@ div:hover > .configwarning {
text-align: left;
font-weight: bold;
font-size: 1.35vh;
background-color: #F9A625;
background-color: #f28034;
color: white;
font-family: 'Arial', 'Helvetica', 'Helvetica Neue', sans-serif;
padding: 5px 5px 5px 10px;
@ -179,7 +183,7 @@ div:hover > .configwarning {
.fieldgroupwarning {
display: inline-block !important;
border: 1px solid #F9A625;
border: 1px solid #f28034;
border-radius: 4px;
margin: 5px;
}
@ -193,7 +197,7 @@ div:hover > .configwarning {
}
.fieldnamewarning {
background-color: #F9A625;
background-color: #f28034;
color: white;
font-weight: bold;
font-size: 1.25vh;
@ -209,7 +213,7 @@ div:hover > .configwarning {
.fieldvaluewarning {
font-size: 1.1vh;
color: #F9A625;
color: #f28034;
}
.warningtable {

Просмотреть файл

@ -113,7 +113,7 @@ namespace UnityPerformanceBenchmarkReporter
private PerformanceTestResult TryDeserializePerformanceTestResultJsonObject(string json)
{
PerformanceTestResult performanceTestResult = null;
PerformanceTestResult performanceTestResult;
try
{
performanceTestResult = JsonConvert.DeserializeObject<PerformanceTestResult>(json);
@ -136,7 +136,7 @@ namespace UnityPerformanceBenchmarkReporter
private PerformanceTestRun TryDeserializePerformanceTestRunJsonObject(string json)
{
PerformanceTestRun performanceTestRun = null;
PerformanceTestRun performanceTestRun;
try
{
performanceTestRun = JsonConvert.DeserializeObject<PerformanceTestRun>(json);

Просмотреть файл

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using UnityPerformanceBenchmarkReporter;
using UnityPerformanceBenchmarkReporter.Entities;
using UnityPerformanceBenchmarkReporter.Report;
namespace UnityPerformanceBenchmarkReporterTests
{

Просмотреть файл

@ -1,39 +0,0 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using UnityPerformanceBenchmarkReporter.Entities;
using UnityPerformanceBenchmarkReporter.Report;
namespace UnityPerformanceBenchmarkReporterTests
{
public class ReportWriterTests
{
private ReportWriter tr;
[SetUp]
public void Setup()
{
}
[Test]
public void WhenResultsAreNull_ReporterWriterThrowsArgNullException()
{
// Arrange
tr = new ReportWriter();
// Act/Assert
Assert.Throws<ArgumentNullException>(() => tr.WriteReport(null));
}
[Test]
public void WhenResultsAreEmpty_ReporterWriterThrowsArgNullException()
{
// Arrange
tr = new ReportWriter();
var results = new List<PerformanceTestRunResult>();
// Act/Assert
Assert.Throws<ArgumentNullException>(() => tr.WriteReport(results));
}
}
}