Skip to content

Commit

Permalink
Fix race in incremental build tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mhutch committed Jan 25, 2024
1 parent 9b6fc72 commit d6fd26b
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 17 deletions.
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);
}
}
}

0 comments on commit d6fd26b

Please sign in to comment.