Skip to content

Commit 3435d2e

Browse files
committed
Add github actions, fix on Windows
1 parent 745abed commit 3435d2e

4 files changed

Lines changed: 96 additions & 13 deletions

File tree

.github/workflows/main.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Github Actions
2+
on: ["push"]
3+
env:
4+
DOTNET_NOLOGO: 1
5+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
6+
DOTNET_CLI_TELEMETRY_OPTOUT: 1
7+
8+
jobs:
9+
dotnet-unit-tests:
10+
name: .NET unit tests
11+
runs-on: ${{ matrix.os }}
12+
timeout-minutes: 20
13+
strategy:
14+
fail-fast: false # don't kill tests when one environment fails
15+
matrix:
16+
os: [ubuntu-latest, windows-2022, macOS-latest]
17+
steps:
18+
- uses: actions/checkout@v2
19+
# .NET
20+
- uses: actions/setup-dotnet@v1
21+
with:
22+
dotnet-version: |
23+
6.0.100
24+
- if: ${{ runner.os == 'Windows' }}
25+
uses: microsoft/setup-msbuild@v1.1
26+
- run: dotnet build src /WarnAsError
27+
- run: dotnet build exampleTest
28+
- run: dotnet test
29+
--logger "GitHubActions;report-warnings=true"
30+
--configuration Debug
31+
-p:WarningLevel=0
32+
exampleTest
33+
shell: bash
34+
- run: dotnet test
35+
--logger "GitHubActions;report-warnings=true"
36+
--configuration Release
37+
-p:WarningLevel=0
38+
exampleTest
39+
shell: bash

exampleTest/CheckTestOutput.Example.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
1313
<PackageReference Include="xunit" Version="2.4.0" />
1414
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
15+
<PackageReference Include="GitHubActionsTestLogger" Version="2.0.0" PrivateAssets="all" />
1516
</ItemGroup>
1617

1718
<ItemGroup>

exampleTest/testoutputs/SomeTest.ShortTable.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@ ID Age Something Title PolymorphicSomething
88

99
3 20 "I don't know"
1010
4 20 ...
11-

src/OutputChecker.cs

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
using System;
2+
using System.Collections.Concurrent;
23
using System.Collections.Generic;
34
using System.ComponentModel;
45
using System.Diagnostics;
56
using System.IO;
67
using System.Linq;
8+
using System.Runtime.InteropServices;
79
using System.Text.RegularExpressions;
10+
using System.Threading.Tasks;
811

912
namespace CheckTestOutput
1013
{
@@ -42,7 +45,7 @@ public OutputChecker(
4245
this.CheckDirectory = Path.Combine(Path.GetDirectoryName(calledFrom), directory);
4346
}
4447

45-
DoesGitWork = new Lazy<bool>(() => {
48+
DoesGitWork = doesGitWorkCache.GetOrAdd(directory, new Lazy<bool>(() => {
4649
try
4750
{
4851
var path = RunGitCommand("rev-parse", "--show-toplevel");
@@ -64,10 +67,12 @@ public OutputChecker(
6467
Console.WriteLine("Error: " + e);
6568
return false;
6669
}
67-
});
70+
}));
6871

6972
}
7073

74+
private static ConcurrentDictionary<string, Lazy<bool>> doesGitWorkCache = new();
75+
7176
public string CheckDirectory { get; }
7277
private string[] _nonDeterminismSanitizers;
7378
/// <summary> List of regular expressions that are replaced by a sequential id for the purpose of the check. The sanitization preserves equality over the checked string (equal strings are replaced by equal id, different strings by different ids) </summary>
@@ -80,31 +85,51 @@ public OutputChecker(
8085

8186
private string[] RunGitCommand(params string[] args)
8287
{
88+
#if DEBUG
89+
Console.WriteLine("Running git command: " + string.Join(" ", args));
90+
#endif
8391
// run `git ...args` in CheckDirectory working directory with 3 second timeout
8492
var procInfo = new ProcessStartInfo("git")
8593
{
8694
WorkingDirectory = CheckDirectory,
8795
UseShellExecute = false,
8896
RedirectStandardOutput = true,
8997
RedirectStandardError = true,
98+
RedirectStandardInput = true,
9099
CreateNoWindow = true,
91100
StandardOutputEncoding = System.Text.Encoding.UTF8,
92101
StandardErrorEncoding = System.Text.Encoding.UTF8,
93102
};
94103
foreach (var a in args)
95104
procInfo.ArgumentList.Add(a);
96105

106+
97107
var proc = Process.Start(procInfo);
98-
if (!proc.WaitForExit(3000))
108+
109+
var outputLines = new List<string>();
110+
var outputReaderTask = Task.Run(() => {
111+
string line = null;
112+
while ((line = proc.StandardOutput.ReadLine()) != null)
113+
{
114+
if (line.Length > 0)
115+
outputLines.Add(line);
116+
}
117+
});
118+
119+
// Literally, a Raspberry PI with a shitty SD card has faster IO than Azure Windows VM
120+
var timeout = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 15_000 : 3_000;
121+
if (!proc.WaitForExit(timeout))
99122
{
100123
proc.Kill();
101-
throw new Exception("Git command timed out");
124+
throw new Exception($"`git {string.Join(" ", args)}` command timed out");
102125
}
103126

104127
if (proc.ExitCode != 0)
105-
throw new Exception("Git command failed: " + proc.StandardError.ReadToEnd());
106-
107-
return proc.StandardOutput.ReadToEnd().Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
128+
throw new Exception($"`git {string.Join(" ", args)}` command failed: " + proc.StandardError.ReadToEnd());
129+
130+
outputReaderTask.Wait();
131+
132+
return outputLines.ToArray();
108133
}
109134

110135
static string[] ReadAllLines(StreamReader reader)
@@ -143,6 +168,13 @@ private bool IsModified(string file)
143168
return !gitOut.All(string.IsNullOrEmpty);
144169
}
145170

171+
private bool IsNewFile(string file)
172+
{
173+
var gitOut = RunGitCommand("ls-files", "--other", file);
174+
// if it outputs back the filename, it is other (untracked)
175+
return !gitOut.All(string.IsNullOrEmpty);
176+
}
177+
146178
/// <summary> Applies the <see cref="NonDeterminismSanitizers" /> to the string. </summary>
147179
public string SanitizeString(string outputString)
148180
{
@@ -163,21 +195,22 @@ public string SanitizeString(string outputString)
163195

164196
internal void CheckOutputCore(string outputString, string checkName, string method, string fileExtension = "txt")
165197
{
198+
outputString = outputString.Replace("\r\n", "\n").TrimEnd('\n');
166199
outputString = SanitizeString(outputString);
167200

168201
Directory.CreateDirectory(CheckDirectory);
169202

170203
var filename = Path.Combine(CheckDirectory, (checkName == null ? method : $"{method}-{checkName}") + "." + fileExtension);
171204

172-
173-
if (GetOldContent(filename) == outputString.Replace("\r", ""))
205+
if (GetOldContent(filename) == outputString)
174206
{
175207
// fine! Just check that the file is not changed - if it is changed or deleted, we rewrite
176208
if (IsModified(filename))
177209
{
178210
using (var t = File.CreateText(filename))
179211
{
180-
t.WriteLine(outputString);
212+
t.Write(outputString);
213+
t.Write("\n");
181214
}
182215
}
183216
return;
@@ -187,14 +220,25 @@ internal void CheckOutputCore(string outputString, string checkName, string meth
187220
{
188221
using (var t = File.CreateText(filename))
189222
{
190-
t.WriteLine(outputString);
223+
t.Write(outputString);
224+
t.Write("\n");
191225
}
192226

193227
if (IsModified(filename))
194228
{
229+
if (IsNewFile(filename))
230+
{
231+
throw new Exception($"{Path.GetFileName(filename)} is not explicitly accepted - the file is untracked in git. To let this test pass, view the file and stage it. Confused? See https://github.com/exyi/CheckTestOutput/blob/master/trouble.md#untracked-file\n");
232+
}
233+
234+
195235
var diff = RunGitCommand("diff", filename);
196236
if (diff.All(string.IsNullOrEmpty))
197-
throw new Exception($"{Path.GetFileName(filename)} is not explicitly accepted - the file is untracked in git. To let this test pass, view the file and stage it. Confused? See https://github.com/exyi/CheckTestOutput/blob/master/trouble.md#untracked-file\n");
237+
{
238+
// I guess fine from our perspective, but it's weird...
239+
Console.WriteLine($"CheckTestOutput warning: {Path.GetFileName(filename)} is modified, but the diff is empty.");
240+
return;
241+
}
198242
throw new Exception(
199243
$"{Path.GetFileName(filename)} has changed, the actual output differs from the previous accepted output:\n\n" +
200244
string.Join("\n", diff) + "\n\n" +

0 commit comments

Comments
 (0)