Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix race in incremental build tests #178

Merged
merged 1 commit into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions Mono.TextTemplating.Build.Tests/MSBuildExecutionTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.IO;
using System.Linq;

using Xunit;

namespace Mono.TextTemplating.Tests
Expand Down Expand Up @@ -154,23 +151,22 @@ void AssertNoopBuild ()
AssertNoopBuild ();

// check touching a template causes rebuild of that file only
File.SetLastWriteTime (fooTemplate, DateTime.Now);
WriteTimeTracker.SetWriteTimeNewerThan (barWriteTime, barTemplate);
ExecuteAndValidate ();
fooWriteTime.AssertChanged ();
barWriteTime.AssertSame ();
fooWriteTime.AssertSame ();
barWriteTime.AssertChanged ();

AssertNoopBuild ();

// check touching the include causes rebuild of the file that uses it
File.SetLastWriteTime (includeFile, DateTime.Now);
WriteTimeTracker.SetWriteTimeNewerThan (fooWriteTime, includeFile);
ExecuteAndValidate ();
fooWriteTime.AssertChanged ();
barWriteTime.AssertSame ();

AssertNoopBuild ();

// check changing a parameter causes rebuild of both files
File.SetLastWriteTime (includeFile, DateTime.Now);
project.Project.GetItems ("T4Argument").Single (i => i.UnevaluatedInclude == "Year").SetMetadataValue ("Value", "2021");
ExecuteAndValidate ();
fooGenerated.AssertTextStartsWith ("Helper says Hello 2021!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<None Include="TestCases\**\*.*" />
<Compile Include="..\Mono.TextTemplating.Tests\Platform.cs" />
<Compile Include="..\Mono.TextTemplating.Tests\TestDataPath.cs" />
<Compile Include="..\Mono.TextTemplating.Tests\WriteTimeTracker.cs" />
</ItemGroup>

</Project>
9 changes: 0 additions & 9 deletions Mono.TextTemplating.Tests/TestDataPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,6 @@ public DateTime AssertWriteTimeNewerThan (DateTime previousWriteTime)
}
}

sealed class WriteTimeTracker
{
readonly TestDataPath file;
DateTime lastWriteTime;
public WriteTimeTracker (TestDataPath file) => lastWriteTime = (this.file = file).GetLastWriteTime ();
public void AssertChanged () => lastWriteTime = file.AssertWriteTimeNewerThan (lastWriteTime);
public void AssertSame () => file.AssertWriteTimeEquals (lastWriteTime);
}

static class StringNormalizationExtensions
{
public static string NormalizeNewlines (this string s, string newLine = "\n") => s.Replace ("\r\n", "\n").Replace ("\n", newLine);
Expand Down
65 changes: 65 additions & 0 deletions Mono.TextTemplating.Tests/WriteTimeTracker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;

namespace Mono.TextTemplating.Tests;

sealed class WriteTimeTracker
{
readonly TestDataPath file;
DateTime lastWriteTime;
public WriteTimeTracker (TestDataPath file) => lastWriteTime = (this.file = file).GetLastWriteTime ();
public void AssertChanged () => lastWriteTime = file.AssertWriteTimeNewerThan (lastWriteTime);
public void AssertSame () => file.AssertWriteTimeEquals (lastWriteTime);

public DateTime WaitUntilLaterNow () => LaterNowThan (lastWriteTime);

static DateTime GetNewestWriteTime (IEnumerable<WriteTimeTracker> trackers)
{
DateTime newest = DateTime.MinValue;
foreach (var tracker in trackers) {
if (newest < tracker.lastWriteTime) {
newest = tracker.lastWriteTime;
}
}
return newest;
}

public static void SetWriteTimeNewerThan (IEnumerable<WriteTimeTracker> trackers, string filePath)
=> SetWriteTimeNewerThan (GetNewestWriteTime (trackers), filePath);

public static void SetWriteTimeNewerThan (WriteTimeTracker tracker, string filePath)
=> SetWriteTimeNewerThan (tracker.lastWriteTime, filePath);

public static void SetWriteTimeNewerThan (IEnumerable<WriteTimeTracker> trackers, params string[] filePaths)
=> SetWriteTimeNewerThan (GetNewestWriteTime (trackers), filePaths);

public static void SetWriteTimeNewerThan (WriteTimeTracker tracker, params string[] filePaths)
=> SetWriteTimeNewerThan (tracker.lastWriteTime, filePaths);

/// <summary>
/// Waits until `DateTime.Now` is newer than `time`, then return this newer value.
/// </summary>
static DateTime LaterNowThan (DateTime time)
{
DateTime now;
while ((now = DateTime.Now) <= time) {
Thread.Sleep (10);
}
return now;
}

static void SetWriteTimeNewerThan (DateTime time, string filePath) => File.SetLastWriteTime (filePath, LaterNowThan (time));

static void SetWriteTimeNewerThan (DateTime time, params string[] filePaths)
{
var now = LaterNowThan (time);
foreach (var file in filePaths) {
File.SetLastWriteTime (file, now);
}
}
}
Loading