Skip to content
Merged
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
41 changes: 29 additions & 12 deletions src/MSBuild.UnitTests/MSBuildServer_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@ public class MSBuildServer_Tests : IDisposable
<Message Text=""Server ID is $(PID)"" Importance=""High"" />
</Target>
</Project>";
private static string sleepingTaskContents = @$"
private static string sleepingTaskContentsFormat = @$"
<Project>
<UsingTask TaskName=""SleepingTask"" AssemblyFile=""{Assembly.GetExecutingAssembly().Location}"" />
<Target Name='Sleep'>
<!-- create a marker file that represents the build is started. -->
<WriteLinesToFile File=""{{0}}"" />
<SleepingTask SleepTime=""100000"" />
</Target>
</Project>";
Expand Down Expand Up @@ -106,22 +108,23 @@ public void MSBuildServerTest()
pidOfServerProcess.ShouldBe(ParseNumber(output, "Server ID is "), "Node used by both the first and second build should be the same.");

// Prep to kill the long-lived task we're about to start.
Task t = Task.Run(() =>
TransientTestFile markerFile = _env.ExpectFile();
string? dir = Path.GetDirectoryName(markerFile.Path);
using var watcher = new System.IO.FileSystemWatcher(dir!);
watcher.Created += (o, e) =>
{
// Wait for the long-lived task to start
// If this test seems to fail randomly, increase this time.
Thread.Sleep(1000);

_output.WriteLine($"The marker file {markerFile.Path} was created. The build task has been started. Ready to kill the server.");
// Kill the server
Process.GetProcessById(pidOfServerProcess).KillTree(1000);
});
_output.WriteLine($"The old server was killed.");
};
watcher.Filter = Path.GetFileName(markerFile.Path);
watcher.EnableRaisingEvents = true;

// Start long-lived task execution
TransientTestFile sleepProject = _env.CreateFile("napProject.proj", sleepingTaskContents);
TransientTestFile sleepProject = _env.CreateFile("napProject.proj", string.Format(sleepingTaskContentsFormat, markerFile.Path));
RunnerUtilities.ExecMSBuild(BuildEnvironmentHelper.Instance.CurrentMSBuildExePath, sleepProject.Path, out _);

t.Wait();

// Ensure that a new build can still succeed and that its server node is different.
output = RunnerUtilities.ExecMSBuild(BuildEnvironmentHelper.Instance.CurrentMSBuildExePath, project.Path, out success, false, _output);

Expand Down Expand Up @@ -176,7 +179,9 @@ public void BuildsWhileBuildIsRunningOnServer()
{
_env.SetEnvironmentVariable("MSBUILDUSESERVER", "1");
TransientTestFile project = _env.CreateFile("testProject.proj", printPidContents);
TransientTestFile sleepProject = _env.CreateFile("napProject.proj", sleepingTaskContents);

TransientTestFile markerFile = _env.ExpectFile();
TransientTestFile sleepProject = _env.CreateFile("napProject.proj", string.Format(sleepingTaskContentsFormat, markerFile.Path));

int pidOfServerProcess;
Task t;
Expand All @@ -185,13 +190,25 @@ public void BuildsWhileBuildIsRunningOnServer()
pidOfServerProcess = ParseNumber(output, "Server ID is ");
_env.WithTransientProcess(pidOfServerProcess);

string? dir = Path.GetDirectoryName(markerFile.Path);
using var watcher = new System.IO.FileSystemWatcher(dir!);
ManualResetEvent mre = new ManualResetEvent(false);
watcher.Created += (o, e) =>
{
_output.WriteLine($"The marker file {markerFile.Path} was created. The build task has been started.");
mre.Set();
};
watcher.Filter = Path.GetFileName(markerFile.Path);
watcher.EnableRaisingEvents = true;
t = Task.Run(() =>
{
RunnerUtilities.ExecMSBuild(BuildEnvironmentHelper.Instance.CurrentMSBuildExePath, sleepProject.Path, out _, false, _output);
});

// The server will soon be in use; make sure we don't try to use it before that happens.
Thread.Sleep(1000);
_output.WriteLine("Waiting for the server to be in use.");
mre.WaitOne();
_output.WriteLine("It's OK to go ahead.");

Environment.SetEnvironmentVariable("MSBUILDUSESERVER", "0");

Expand Down