Skip to content

Commit 62ef282

Browse files
test cleanup
1 parent 349b797 commit 62ef282

1 file changed

Lines changed: 51 additions & 49 deletions

File tree

src/Build.UnitTests/TaskHostFactoryLifecycle_E2E_Tests.cs

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@ namespace Microsoft.Build.Engine.UnitTests
2222
/// </summary>
2323
public class TaskHostFactoryLifecycle_E2E_Tests
2424
{
25-
private static string AssemblyLocation { get; } = Path.Combine(Path.GetDirectoryName(typeof(TaskHostFactoryLifecycle_E2E_Tests).Assembly.Location) ?? System.AppContext.BaseDirectory);
25+
private static string AssemblyLocation { get; } = Path.Combine(Path.GetDirectoryName(typeof(TaskHostFactoryLifecycle_E2E_Tests).Assembly.Location) ?? AppContext.BaseDirectory);
2626

2727
private static string TestAssetsRootPath { get; } = Path.Combine(AssemblyLocation, "TestAssets", "TaskHostLifecycle");
2828

29+
private const string TaskHostFactory = "TaskHostFactory";
30+
private const string AssemblyTaskFactory = "AssemblyTaskFactory";
31+
private const string CurrentRuntime = "CurrentRuntime";
32+
private const string NetRuntime = "NET";
33+
2934
private readonly ITestOutputHelper _output;
3035

3136
public TaskHostFactoryLifecycle_E2E_Tests(ITestOutputHelper output)
@@ -46,74 +51,71 @@ public TaskHostFactoryLifecycle_E2E_Tests(ITestOutputHelper output)
4651
/// <param name="taskFactoryToUse">The task factory to use (TaskHostFactory or AssemblyTaskFactory)</param>
4752
[Theory]
4853
#if NET
49-
[InlineData("CurrentRuntime", "AssemblyTaskFactory")] // Match + No Explicit → in-proc
50-
[InlineData("CurrentRuntime", "TaskHostFactory")] // Match + Explicit → short-lived out-of-proc
54+
[InlineData(CurrentRuntime, AssemblyTaskFactory)] // Match + No Explicit → in-proc
55+
[InlineData(CurrentRuntime, TaskHostFactory)] // Match + Explicit → short-lived out-of-proc
5156
#endif
52-
[InlineData("NET", "AssemblyTaskFactory")] // No Match + No Explicit → long-lived sidecar out-of-proc
53-
[InlineData("NET", "TaskHostFactory")] // No Match + Explicit → short-lived out-of-proc
57+
[InlineData(NetRuntime, AssemblyTaskFactory)] // No Match + No Explicit → long-lived sidecar out-of-proc
58+
[InlineData(NetRuntime, TaskHostFactory)] // No Match + Explicit → short-lived out-of-proc
5459
public void TaskHostLifecycle_ValidatesAllScenarios(
5560
string runtimeToUse,
5661
string taskFactoryToUse)
5762
{
58-
bool? expectedNodeReuse;
63+
bool? expectedNodeReuse = DetermineExpectedNodeReuse(runtimeToUse, taskFactoryToUse);
5964

60-
// TaskHostFactory is always short lived and out-of-proc
61-
if (taskFactoryToUse == "TaskHostFactory")
62-
{
63-
expectedNodeReuse = false;
64-
}
65-
// AssemblyTaskFactory behavior depends on runtime
66-
else if (taskFactoryToUse == "AssemblyTaskFactory")
67-
{
68-
if (runtimeToUse == "CurrentRuntime")
69-
{
70-
// in-proc
71-
expectedNodeReuse = null;
72-
}
73-
else if (runtimeToUse == "NET")
74-
{
75-
// When running on .NET Framework: out-of-proc, otherwise on .NET in-proc.
76-
expectedNodeReuse = RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework", StringComparison.OrdinalIgnoreCase) ? true : null;
77-
}
78-
else
79-
{
80-
throw new ArgumentOutOfRangeException(nameof(runtimeToUse), "Unknown runtime to use: " + runtimeToUse);
81-
}
82-
}
83-
else
65+
using TestEnvironment env = TestEnvironment.Create(_output);
66+
67+
string buildOutput = ExecuteBuildWithTaskHost(runtimeToUse, taskFactoryToUse);
68+
69+
ValidateTaskHostBehavior(buildOutput, expectedNodeReuse);
70+
}
71+
72+
private static bool? DetermineExpectedNodeReuse(string runtimeToUse, string taskFactoryToUse)
73+
=> (taskFactoryToUse, runtimeToUse) switch
8474
{
85-
throw new ArgumentOutOfRangeException(nameof(taskFactoryToUse), "Unknown task factory to use: " + taskFactoryToUse);
86-
}
75+
// TaskHostFactory is always short-lived and out-of-proc (nodereuse:False)
76+
(TaskHostFactory, _) => false,
8777

88-
using TestEnvironment env = TestEnvironment.Create(_output);
78+
// AssemblyTaskFactory with CurrentRuntime runs in-proc
79+
(AssemblyTaskFactory, CurrentRuntime) => null,
80+
81+
// AssemblyTaskFactory with NET runtime:
82+
// - On .NET Framework host: out-of-proc with long-lived sidecar (nodereuse:True)
83+
// - On .NET host: in-proc
84+
(AssemblyTaskFactory, NetRuntime) =>
85+
#if NET
86+
null, // On .NET host: in-proc execution
87+
#else
88+
true, // On .NET Framework host: out-of-proc with long-lived sidecar
89+
#endif
90+
_ => throw new ArgumentException($"Unknown combination: runtime={runtimeToUse}, factory={taskFactoryToUse}")
91+
};
92+
93+
private string ExecuteBuildWithTaskHost(string runtimeToUse, string taskFactoryToUse)
94+
{
8995
string testProjectPath = Path.Combine(TestAssetsRootPath, "TaskHostLifecycleTestApp.csproj");
9096

91-
string testTaskOutput = RunnerUtilities.ExecBootstrapedMSBuild(
92-
$"{testProjectPath} -v:n -restore /p:RuntimeToUse={runtimeToUse} /p:TaskFactoryToUse={taskFactoryToUse}",
93-
out bool successTestTask,
97+
string output = RunnerUtilities.ExecBootstrapedMSBuild(
98+
$"{testProjectPath} -v:n -restore /p:RuntimeToUse={runtimeToUse} /p:TaskFactoryToUse={taskFactoryToUse}",
99+
out bool success,
94100
outputHelper: _output);
95101

96-
successTestTask.ShouldBeTrue();
102+
success.ShouldBeTrue("Build should succeed");
97103

98-
// Verify execution mode (out-of-proc vs in-proc) and node reuse behavior
104+
return output;
105+
}
106+
107+
private static void ValidateTaskHostBehavior(string buildOutput, bool? expectedNodeReuse)
108+
{
99109
if (expectedNodeReuse.HasValue)
100110
{
101-
// For out-of-proc scenarios, validate the task runs in a separate process
102-
// by checking for the presence of command-line arguments that indicate task host execution
103-
testTaskOutput.ShouldContain("/nodemode:",
104-
customMessage: "Task should run out-of-proc and have /nodemode: in its command-line arguments");
111+
buildOutput.ShouldContain("/nodemode:", customMessage: "Task should run out-of-proc and have /nodemode: in its command-line arguments");
105112

106-
// Validate the nodereuse flag in the task's command-line arguments
107113
string expectedFlag = expectedNodeReuse.Value ? "/nodereuse:True" : "/nodereuse:False";
108-
testTaskOutput.ShouldContain(expectedFlag,
109-
customMessage: $"Task should have {expectedFlag} in its command-line arguments");
114+
buildOutput.ShouldContain(expectedFlag, customMessage: $"Task should have {expectedFlag} in its command-line arguments");
110115
}
111116
else
112117
{
113-
// For in-proc scenarios, validate the task does NOT run in a task host
114-
// by ensuring task host specific command-line flags are not present
115-
testTaskOutput.ShouldNotContain("/nodemode:",
116-
customMessage: "Task should run in-proc and not have task host command-line arguments like /nodemode:");
118+
buildOutput.ShouldNotContain("/nodemode:", customMessage: "Task should run in-proc and not have task host command-line arguments like /nodemode:");
117119
}
118120
}
119121
}

0 commit comments

Comments
 (0)