Skip to content
This repository has been archived by the owner on Apr 2, 2020. It is now read-only.

Commit

Permalink
Implement a regression test suite for Protobuild
Browse files Browse the repository at this point in the history
  • Loading branch information
hach-que committed Dec 21, 2015
1 parent 329342d commit d9f5bee
Show file tree
Hide file tree
Showing 22 changed files with 581 additions and 21 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,11 @@ Protobuild.FunctionalTests/TestData/PostBuildHookHasHostPlatform/Hook/Resources/
Protobuild.exe.old
Protobuild.FunctionalTests/TestData/**/Info.plist
.pkg
RegressionResults.html
Protobuild.FunctionalTests/PreviousVersions/
Protobuild.FunctionalTests/TestData/ExampleCocos2DXNA/Cocos2DXNA/Cocos2DXNA.Windows.nuspec
Protobuild.FunctionalTests/TestData/ExampleCocos2DXNA/MonoGame/MonoGame.Framework/MonoGame.Framework.Windows.nuspec
Protobuild.FunctionalTests/TestData/ExampleCSTools/CSTools/Tool/Tool.Windows.nuspec
Protobuild.FunctionalTests/TestData/ExampleCSTools/Game/Game.Windows.nuspec
Protobuild.FunctionalTests/TestData/ExampleMonoGame/Game/Game.Windows.nuspec
Protobuild.FunctionalTests/TestData/ExampleMonoGame/MonoGame/MonoGame.Framework/MonoGame.Framework.Windows.nuspec
2 changes: 2 additions & 0 deletions Build/Projects/Protobuild.FunctionalTests.definition
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@
<Compile Include="ProjectSpecificOutputFolderTest.cs" />
<Compile Include="ProtobuildTest.cs" />
<Compile Include="QueryFeaturesTest.cs" />
<Compile Include="Regression\RegressionHtmlSummaryConsumer.cs" />
<Compile Include="Regression\RegressionTestSetProvider.cs" />
<Compile Include="ResyncPreventedWhenSyncIsDisabledTest.cs" />
<Compile Include="ServicesCrossProjectRequireTest.cs" />
<Compile Include="ServicesDefaultForRootTest.cs" />
Expand Down
12 changes: 12 additions & 0 deletions Build/Projects/Protobuild.RegressionTestTool.definition
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Name="Protobuild.RegressionTestTool" Path="Protobuild.RegressionTestTool" Type="Console">
<References>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</References>
<Files>
<Compile Include="Program.cs" />
</Files>
</Project>
11 changes: 9 additions & 2 deletions Protobuild.FunctionalTests/ExampleCSToolsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,16 @@ public ExampleCSToolsTest(IAssert assert) : base(assert)
_assert = assert;
}

public void GenerationIsCorrect()
public void GenerationIsCorrect(string parent, string child)
{
this.SetupTest("ExampleCSTools");
this.SetupTest("ExampleCSTools", parent: parent, child: child);

// Newer versions of Protobuild upgrade this file, but for regression testing we need the old
// format (it's expected that the old format will be used in conjunction with old versions of
// Protobuild, which are the version that we're regression testing with). Copy across
// the old version before the start of every test here.
File.Copy(this.GetPath(@"Build\ModuleOldFormat.xml"), this.GetPath(@"Build\Module.xml"), true);
File.Copy(this.GetPath(@"CSTools\Build\ModuleOldFormat.xml"), this.GetPath(@"CSTools\Build\Module.xml"), true);

this.Generate();

Expand Down
11 changes: 9 additions & 2 deletions Protobuild.FunctionalTests/ExampleCocos2DXNATest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,16 @@ public ExampleCocos2DXNATest(IAssert assert) : base(assert)
_assert = assert;
}

public void GenerationIsCorrect()
public void GenerationIsCorrect(string parent, string child)
{
this.SetupTest("ExampleCocos2DXNA");
this.SetupTest("ExampleCocos2DXNA", parent: parent, child: child);

// Newer versions of Protobuild upgrade this file, but for regression testing we need the old
// format (it's expected that the old format will be used in conjunction with old versions of
// Protobuild, which are the version that we're regression testing with). Copy across
// the old version before the start of every test here.
File.Copy(this.GetPath(@"Build\ModuleOldFormat.xml"), this.GetPath(@"Build\Module.xml"), true);
File.Copy(this.GetPath(@"MonoGame\Build\ModuleOldFormat.xml"), this.GetPath(@"MonoGame\Build\Module.xml"), true);

this.Generate("Windows");

Expand Down
13 changes: 10 additions & 3 deletions Protobuild.FunctionalTests/ExampleMonoGameTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ public ExampleMonoGameTest(IAssert assert) : base(assert)
{
_assert = assert;
}

public void GenerationIsCorrect()
public void GenerationIsCorrect(string parent, string child)
{
this.SetupTest("ExampleMonoGame");
this.SetupTest("ExampleMonoGame", parent: parent, child: child);

// Newer versions of Protobuild upgrade this file, but for regression testing we need the old
// format (it's expected that the old format will be used in conjunction with old versions of
// Protobuild, which are the version that we're regression testing with). Copy across
// the old version before the start of every test here.
File.Copy(this.GetPath(@"Build\ModuleOldFormat.xml"), this.GetPath(@"Build\Module.xml"), true);
File.Copy(this.GetPath(@"MonoGame\Build\ModuleOldFormat.xml"), this.GetPath(@"MonoGame\Build\Module.xml"), true);

this.Generate("Windows");

Expand Down
17 changes: 12 additions & 5 deletions Protobuild.FunctionalTests/ProtobuildTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ protected ProtobuildTest(IAssert assert)
_assert = assert;
}

protected void SetupTest(string name, bool isPackTest = false)
protected void SetupTest(string name, bool isPackTest = false, string parent = null, string child = null)
{
// This is used to ensure Protobuild.exe is referenced.
_protobuildName = typeof(Protobuild.Bootstrap.Program).FullName;
Expand All @@ -40,7 +40,7 @@ protected void SetupTest(string name, bool isPackTest = false)

this.m_TestLocation = dataLocation;

this.DeployProtobuildToTestFolder(dataLocation, protobuildLocation, isPackTest);
this.DeployProtobuildToTestFolder(dataLocation, protobuildLocation, isPackTest, parent, child);
}

private void PurgeSolutionsAndProjects(string dataLocation)
Expand All @@ -63,17 +63,24 @@ private void PurgeSolutionsAndProjects(string dataLocation)
}
}

private void DeployProtobuildToTestFolder(string dataLocation, string protobuildLocation, bool isPackTest)
private void DeployProtobuildToTestFolder(string dataLocation, string protobuildLocation, bool isPackTest, string parent, string child)
{
File.Copy(protobuildLocation, Path.Combine(dataLocation, "Protobuild.exe"), true);
if (parent == null)
{
File.Copy(protobuildLocation, Path.Combine(dataLocation, "Protobuild.exe"), true);
}
else
{
File.Copy(parent, Path.Combine(dataLocation, "Protobuild.exe"), true);
}

if (!isPackTest)
{
foreach (var dir in new DirectoryInfo(dataLocation).GetDirectories())
{
if (dir.GetDirectories().Any(x => x.Name == "Build"))
{
this.DeployProtobuildToTestFolder(dir.FullName, protobuildLocation, isPackTest);
this.DeployProtobuildToTestFolder(dir.FullName, protobuildLocation, false, child, child);
}
}
}
Expand Down
189 changes: 189 additions & 0 deletions Protobuild.FunctionalTests/Regression/RegressionHtmlSummaryConsumer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Prototest.Library.Version11;

namespace Protobuild.FunctionalTests.Regression
{
public class RegressionHtmlSummaryConsumer : ITestSummaryConsumer
{
public void HandleResults(List<TestResult> results)
{
var resultsBySet = results.GroupBy(x => x.Set).Where(g => g.Key.Name.StartsWith("regression-")).ToList();

if (resultsBySet.Count == 0)
{
return;
}

var columns = resultsBySet.First().Select(x => x.Entry.TestClass).ToArray();

Func<string, string> nameTranslate = x =>
{
switch (x)
{
case "ExampleMonoGameTest":
return "MG";
case "ExampleCSToolsTest":
return "CS";
case "ExampleCocos2DXNATest":
return "CO";
default:
return string.Empty;
}
};

var content = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
<link rel=""stylesheet"" href=""https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"" integrity=""sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"" crossorigin=""anonymous"">
<link rel=""stylesheet"" href=""https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"">
<style type=""text/css"">
#container { max-width: 800px; margin: auto; }
.mcol { text-align: center; width:0px; width: 47px; padding-left: 0px; padding-right: 0px; }
.timestamp { width: 160px; }
.commit { width: 100px; }
</style>
</head>
<body>
<div id=""container"">
<h1>Protobuild Regression Test Suite</h1>
<p>
Legend:
</p>
<ul>
<li><strong>MG</strong>: Test a structure similar to the <a href=""https://github.com/mono/MonoGame"">MonoGame</a> repository</li>
<li><strong>CS</strong>: Test a structure similar to the <a href=""https://github.com/hach-que/cstools"">C# Tools</a> repository</li>
<li><strong>CO</strong>: Test a structure similar to the <a href=""https://github.com/Cocos2DXNA/cocos2d-xna"">Cocos2D XNA</a> repository</li>
<li><i class='fa fa-check-circle' style='color: #090;'></i>: Test Passed</li>
<li><i class='fa fa-dot-circle-o' style='color: #F90;'></i>: Expected Failure (not compatible in this scenario)</li>
<li><i class='fa fa-times-circle' style='color: #F00;'></i>: Test Failed</li>
</ul>
<table class=""table""><tr><th colspan=""3"">Regression Set</th>";
content += "<th colspan=\"" + columns.Length + @""" width=""0"" style=""text-align: center;padding-left:0px; padding-right:0px;"">Latest as Child</th>";
content += "<th colspan=\"" + columns.Length + @""" width=""0"" style=""text-align: center;padding-left:0px; padding-right:0px;"">Latest as Parent</th>";
content += "</tr><tr>";
content += "<th colspan=\"3\">&nbsp;</th>";
foreach (var column in columns)
{
content += "<th class=\"mcol\">" + nameTranslate(column.Name) + "</th>";
}
foreach (var column in columns)
{
content += "<th class=\"mcol\">" + nameTranslate(column.Name) + "</th>";
}
content += "</tr>";

var resultsByCommitHash = resultsBySet.GroupBy(x => x.Key.Name.Split('-')[3]).ToList();

var directoryInfo = new FileInfo(typeof(RegressionTestSetProvider).Assembly.Location).Directory?.Parent?.Parent?.Parent?.Parent;

foreach (var set in resultsByCommitHash.OrderByDescending(x => x.First().Key.Name))
{
content += "<tr>";
var sp = set.First().Key.Name.Split('-');
if (sp[3] == "latest")
{
content += "<td class=\"timestamp\"></td>";
}
else
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime();
var c = epoch.AddSeconds(int.Parse(sp[2]));
content += "<td class=\"timestamp\">" + c.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss") + "</td>";
}

if (set.Key == "latest")
{
content += "<td class=\"commit\">" + set.Key + "</td>";
content += "<td class=\"message\"></td>";
}
else
{
content += "<td class=\"commit\"><a href=\"\">" + set.Key.Substring(0, 9) + "</td>";
var message = string.Empty;

if (directoryInfo != null)
{
var messageFile =
new FileInfo(Path.Combine(directoryInfo.FullName, "PreviousVersions", set.Key.Split('.').First() + ".txt"));
if (messageFile.Exists)
{
using (var reader = new StreamReader(messageFile.FullName))
{
message = reader.ReadToEnd().Trim();
}
}
}

content += "<td class=\"message\">" + SecurityElement.Escape(message) + "</td>";
}

var parent = set.FirstOrDefault(x => x.Key.Name.Contains("parent") || x.Key.Name.Contains("latest"));

if (parent != null)
{
var passSet = parent.ToDictionary(k => k.Entry.TestClass, v => v);
foreach (var column in columns)
{
if (passSet[column].Passed)
{
content += "<td class=\"mcol\"><i class='fa fa-check-circle' style='color: #090;'></i></td>";
}
else if (passSet[column].Entry.AllowFail)
{
content += "<td class=\"mcol\"><i class='fa fa-dot-circle-o' style='color: #F90;'></i></td>";
}
else
{
content += "<td class=\"mcol\"><i class='fa fa-times-circle' style='color: #F00;'></i></td>";
}
}
}

var child = set.FirstOrDefault(x => x.Key.Name.Contains("child") || x.Key.Name.Contains("latest"));

if (child != null)
{
var passSet = child.ToDictionary(k => k.Entry.TestClass, v => v);
foreach (var column in columns)
{
if (passSet[column].Passed)
{
content += "<td class=\"mcol\"><i class='fa fa-check-circle' style='color: #090;'></i></td>";
}
else if (passSet[column].Entry.AllowFail)
{
content += "<td class=\"mcol\"><i class='fa fa-dot-circle-o' style='color: #F90;'></i></td>";
}
else
{
content += "<td class=\"mcol\"><i class='fa fa-times-circle' style='color: #F00;'></i></td>";
}
}
}

content += "</tr>";
}

content += "</table></div></body></html>";

using (var writer = new StreamWriter("RegressionResults.html"))
{
writer.Write(content);
}

Console.WriteLine();
Console.WriteLine();
Console.WriteLine(content);
Console.WriteLine();
Console.WriteLine();
}
}
}
Loading

0 comments on commit d9f5bee

Please sign in to comment.