Skip to content

Commit 00df9f8

Browse files
committed
Add end-to-end tests for stamp-based cache hits
Fix dev mode to pass the entry file directly to dotnet run instead of the publish-only --ucr flag.
1 parent 82304ba commit 00df9f8

3 files changed

Lines changed: 166 additions & 2 deletions

File tree

plans/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ executor needs no context beyond the plan file itself.
1010
| # | Plan | Priority | Effort | Depends on | Status |
1111
|---|------|----------|--------|------------|--------|
1212
| 001 | [Harden background cache cleanup](001-harden-cache-cleanup.md) | P1 | S || DONE |
13-
| 002 | [End-to-end cache behavior tests](002-e2e-cache-tests.md) | P1 | M || TODO |
13+
| 002 | [End-to-end cache behavior tests](002-e2e-cache-tests.md) | P1 | M || DONE |
1414
| 003 | [`go clean --all`](003-clean-all.md) | P2 | S | 001 | TODO |
1515
| 004 | [Readme: cache and cleaning docs](004-readme-cache-docs.md) | P2 | S | 003 | TODO |
1616

src/Tests/EndToEndTests.cs

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
using System.Diagnostics;
2+
using Devlooped;
3+
4+
namespace Tests;
5+
6+
public class EndToEndTests
7+
{
8+
[Fact]
9+
public void Dev_second_run_hits_cache_and_edit_invalidates()
10+
{
11+
var marker = "e2e-" + Guid.NewGuid().ToString("N");
12+
var app = CreateApp(marker);
13+
14+
try
15+
{
16+
var (exit1, output1) = RunGo("dev", app);
17+
Assert.Equal(0, exit1);
18+
Assert.Contains(marker, output1);
19+
20+
var stamp = FindStamp(app);
21+
Assert.True(File.Exists(stamp));
22+
var stampContent = File.ReadAllText(stamp);
23+
var stampWriteTime = File.GetLastWriteTimeUtc(stamp);
24+
25+
var (exit2, output2) = RunGo("dev", app);
26+
Assert.Equal(0, exit2);
27+
Assert.Contains(marker, output2);
28+
Assert.Equal(stampContent, File.ReadAllText(stamp));
29+
Assert.Equal(stampWriteTime, File.GetLastWriteTimeUtc(stamp));
30+
31+
var marker2 = "e2e-" + Guid.NewGuid().ToString("N");
32+
File.WriteAllText(app, $"""
33+
#:property TargetFramework=net10.0
34+
35+
Console.WriteLine("{marker2}");
36+
""");
37+
File.SetLastWriteTimeUtc(app, DateTime.UtcNow.AddSeconds(2));
38+
39+
var (exit3, output3) = RunGo("dev", app);
40+
Assert.Equal(0, exit3);
41+
Assert.Contains(marker2, output3);
42+
Assert.DoesNotContain(marker, output3);
43+
Assert.NotEqual(stampContent, File.ReadAllText(stamp));
44+
}
45+
finally
46+
{
47+
CleanApp(app);
48+
}
49+
}
50+
51+
[Fact]
52+
public void Publish_r2r_second_run_hits_cache()
53+
{
54+
var marker = "e2e-" + Guid.NewGuid().ToString("N");
55+
var app = CreateApp(marker);
56+
57+
try
58+
{
59+
var (exit1, output1) = RunGo(app, "--r2r");
60+
Assert.Equal(0, exit1);
61+
Assert.Contains(marker, output1);
62+
63+
var stamp = FindStamp(app);
64+
var stampContent = File.ReadAllText(stamp);
65+
Assert.Contains("app=", stampContent);
66+
Assert.Contains("mode=r2r", stampContent);
67+
var stampWriteTime = File.GetLastWriteTimeUtc(stamp);
68+
69+
var (exit2, output2) = RunGo(app, "--r2r");
70+
Assert.Equal(0, exit2);
71+
Assert.Contains(marker, output2);
72+
Assert.Equal(stampContent, File.ReadAllText(stamp));
73+
Assert.Equal(stampWriteTime, File.GetLastWriteTimeUtc(stamp));
74+
}
75+
finally
76+
{
77+
CleanApp(app);
78+
}
79+
}
80+
81+
static string CreateApp(string marker)
82+
{
83+
var dir = CreateTempDir();
84+
var app = Path.Combine(dir, "app.cs");
85+
File.WriteAllText(app, $"""
86+
#:property TargetFramework=net10.0
87+
88+
Console.WriteLine("{marker}");
89+
""");
90+
return app;
91+
}
92+
93+
static string GetTempRoot()
94+
{
95+
var directory = OperatingSystem.IsWindows()
96+
? Path.GetTempPath()
97+
: Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
98+
return Path.Join(directory, "dotnet", "go");
99+
}
100+
101+
static string FindStamp(string appFile)
102+
{
103+
var normalizedInput = $"input={appFile.Replace('\\', '/')}";
104+
var prefix = Path.GetFileNameWithoutExtension(appFile) + "-";
105+
var matches = Directory.GetDirectories(GetTempRoot(), prefix + "*")
106+
.Where(dir => File.Exists(Path.Combine(dir, "go.stamp")))
107+
.Where(dir => File.ReadAllText(Path.Combine(dir, "go.stamp")).Contains(normalizedInput))
108+
.ToArray();
109+
110+
Assert.Single(matches);
111+
return Path.Combine(matches[0], "go.stamp");
112+
}
113+
114+
static (int ExitCode, string Output) RunGo(params string[] args)
115+
{
116+
var startInfo = new ProcessStartInfo
117+
{
118+
FileName = DotnetMuxer.Path!.FullName,
119+
RedirectStandardOutput = true,
120+
RedirectStandardError = true,
121+
UseShellExecute = false,
122+
};
123+
startInfo.Environment["NO_COLOR"] = "true";
124+
startInfo.ArgumentList.Add(Path.Combine(AppContext.BaseDirectory, "go.dll"));
125+
foreach (var arg in args)
126+
startInfo.ArgumentList.Add(arg);
127+
128+
using var process = Process.Start(startInfo)!;
129+
var stdout = process.StandardOutput.ReadToEndAsync();
130+
var stderr = process.StandardError.ReadToEndAsync();
131+
process.WaitForExit();
132+
Task.WaitAll(stdout, stderr);
133+
134+
return (process.ExitCode, stdout.Result + stderr.Result);
135+
}
136+
137+
static void CleanApp(string appFile)
138+
{
139+
try
140+
{
141+
RunGo("clean", appFile);
142+
}
143+
catch
144+
{
145+
}
146+
147+
try
148+
{
149+
var dir = Path.GetDirectoryName(appFile);
150+
if (dir is not null && Directory.Exists(dir))
151+
Directory.Delete(dir, recursive: true);
152+
}
153+
catch
154+
{
155+
}
156+
}
157+
158+
static string CreateTempDir()
159+
{
160+
var dir = Path.Combine(Path.GetTempPath(), "go-tests-" + Guid.NewGuid().ToString("N"));
161+
Directory.CreateDirectory(dir);
162+
return dir;
163+
}
164+
}

src/go/ProcessRunner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static Task<int> DotnetRunAsync(string dotnet, string cs, string config,
2020
{
2121
var environment = CreateGoEnvironment(config, targets);
2222

23-
var arguments = new List<string> { "run", "--ucr", cs };
23+
var arguments = new List<string> { "run", cs };
2424
if (dotnetArgs is not null)
2525
arguments.AddRange(dotnetArgs);
2626

0 commit comments

Comments
 (0)