Skip to content
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
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<PackageVersion Include="System.Threading.Channels" Version="$(SystemThreadingChannelsVersion)" />
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="$(SystemThreadingTasksDataflowVersion)" />
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="$(SystemThreadingTasksExtensionsVersion)" />
<PackageVersion Include="System.ValueTuple" Version="$(SystemValueTupleVersion)" />
<PackageVersion Include="xunit.console" Version="$(XUnitVersion)" />
<PackageVersion Include="Microsoft.VisualStudio.Telemetry" Version="$(MicrosoftVisualStudioTelemetryVersion)" />
<!-- Microsoft.VisualStudio.SolutionPersistence is maintained in eng/dependabot/Packages.props -->
Expand Down
34 changes: 17 additions & 17 deletions eng/Version.Details.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ This file should be imported by eng/Versions.props
<Project>
<PropertyGroup>
<!-- dotnet/runtime dependencies -->
<SystemCodeDomPackageVersion>9.0.11</SystemCodeDomPackageVersion>
<SystemCollectionsImmutablePackageVersion>9.0.11</SystemCollectionsImmutablePackageVersion>
<SystemConfigurationConfigurationManagerPackageVersion>9.0.11</SystemConfigurationConfigurationManagerPackageVersion>
<SystemDiagnosticsDiagnosticSourcePackageVersion>9.0.11</SystemDiagnosticsDiagnosticSourcePackageVersion>
<SystemDiagnosticsEventLogPackageVersion>9.0.11</SystemDiagnosticsEventLogPackageVersion>
<SystemFormatsAsn1PackageVersion>9.0.11</SystemFormatsAsn1PackageVersion>
<SystemFormatsNrbfPackageVersion>9.0.11</SystemFormatsNrbfPackageVersion>
<SystemReflectionMetadataPackageVersion>9.0.11</SystemReflectionMetadataPackageVersion>
<SystemReflectionMetadataLoadContextPackageVersion>9.0.11</SystemReflectionMetadataLoadContextPackageVersion>
<SystemResourcesExtensionsPackageVersion>9.0.11</SystemResourcesExtensionsPackageVersion>
<SystemSecurityCryptographyPkcsPackageVersion>9.0.11</SystemSecurityCryptographyPkcsPackageVersion>
<SystemSecurityCryptographyProtectedDataPackageVersion>9.0.11</SystemSecurityCryptographyProtectedDataPackageVersion>
<SystemSecurityCryptographyXmlPackageVersion>9.0.11</SystemSecurityCryptographyXmlPackageVersion>
<SystemTextEncodingCodePagesPackageVersion>9.0.11</SystemTextEncodingCodePagesPackageVersion>
<SystemTextJsonPackageVersion>9.0.11</SystemTextJsonPackageVersion>
<SystemThreadingChannelsPackageVersion>9.0.11</SystemThreadingChannelsPackageVersion>
<SystemThreadingTasksDataflowPackageVersion>9.0.11</SystemThreadingTasksDataflowPackageVersion>
<SystemCodeDomPackageVersion>10.0.1</SystemCodeDomPackageVersion>
<SystemCollectionsImmutablePackageVersion>10.0.1</SystemCollectionsImmutablePackageVersion>
<SystemConfigurationConfigurationManagerPackageVersion>10.0.1</SystemConfigurationConfigurationManagerPackageVersion>
<SystemDiagnosticsDiagnosticSourcePackageVersion>10.0.1</SystemDiagnosticsDiagnosticSourcePackageVersion>
<SystemDiagnosticsEventLogPackageVersion>10.0.1</SystemDiagnosticsEventLogPackageVersion>
<SystemFormatsAsn1PackageVersion>10.0.1</SystemFormatsAsn1PackageVersion>
<SystemFormatsNrbfPackageVersion>10.0.1</SystemFormatsNrbfPackageVersion>
<SystemReflectionMetadataPackageVersion>10.0.1</SystemReflectionMetadataPackageVersion>
<SystemReflectionMetadataLoadContextPackageVersion>10.0.1</SystemReflectionMetadataLoadContextPackageVersion>
<SystemResourcesExtensionsPackageVersion>10.0.1</SystemResourcesExtensionsPackageVersion>
<SystemSecurityCryptographyPkcsPackageVersion>10.0.1</SystemSecurityCryptographyPkcsPackageVersion>
<SystemSecurityCryptographyProtectedDataPackageVersion>10.0.1</SystemSecurityCryptographyProtectedDataPackageVersion>
<SystemSecurityCryptographyXmlPackageVersion>10.0.1</SystemSecurityCryptographyXmlPackageVersion>
<SystemTextEncodingCodePagesPackageVersion>10.0.1</SystemTextEncodingCodePagesPackageVersion>
<SystemTextJsonPackageVersion>10.0.1</SystemTextJsonPackageVersion>
<SystemThreadingChannelsPackageVersion>10.0.1</SystemThreadingChannelsPackageVersion>
<SystemThreadingTasksDataflowPackageVersion>10.0.1</SystemThreadingTasksDataflowPackageVersion>
<!-- dotnet/arcade dependencies -->
<MicrosoftDotNetArcadeSdkPackageVersion>10.0.0-beta.26062.3</MicrosoftDotNetArcadeSdkPackageVersion>
<MicrosoftDotNetXUnitExtensionsPackageVersion>10.0.0-beta.26062.3</MicrosoftDotNetXUnitExtensionsPackageVersion>
Expand Down
34 changes: 17 additions & 17 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,103 +3,103 @@
<Source Uri="https://github.com/dotnet/dotnet" Mapping="msbuild" Sha="887f3d5a26e1001ee2777afde10cadcacb8cc735" BarId="297286" />
<ProductDependencies>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.CodeDom" Version="9.0.11">
<Dependency Name="System.CodeDom" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Collections.Immutable" Version="9.0.11">
<Dependency Name="System.Collections.Immutable" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Configuration.ConfigurationManager" Version="9.0.11">
<Dependency Name="System.Configuration.ConfigurationManager" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Diagnostics.DiagnosticSource" Version="9.0.11">
<Dependency Name="System.Diagnostics.DiagnosticSource" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Diagnostics.EventLog" Version="9.0.11">
<Dependency Name="System.Diagnostics.EventLog" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Formats.Asn1" Version="9.0.11">
<Dependency Name="System.Formats.Asn1" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Formats.Nrbf" Version="9.0.11">
<Dependency Name="System.Formats.Nrbf" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Reflection.Metadata" Version="9.0.11">
<Dependency Name="System.Reflection.Metadata" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Reflection.MetadataLoadContext" Version="9.0.11">
<Dependency Name="System.Reflection.MetadataLoadContext" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Resources.Extensions" Version="9.0.11">
<Dependency Name="System.Resources.Extensions" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Security.Cryptography.ProtectedData" Version="9.0.11">
<Dependency Name="System.Security.Cryptography.ProtectedData" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Security.Cryptography.Pkcs" Version="9.0.11">
<Dependency Name="System.Security.Cryptography.Pkcs" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Security.Cryptography.Xml" Version="9.0.11">
<Dependency Name="System.Security.Cryptography.Xml" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Text.Encoding.CodePages" Version="9.0.11">
<Dependency Name="System.Text.Encoding.CodePages" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Text.Json" Version="9.0.11">
<Dependency Name="System.Text.Json" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Threading.Channels" Version="9.0.11">
<Dependency Name="System.Threading.Channels" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the live version of the package to be used by source-build. -->
<Dependency Name="System.Threading.Tasks.Dataflow" Version="9.0.11">
<Dependency Name="System.Threading.Tasks.Dataflow" Version="10.0.1">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>
</Sha>
Expand Down
9 changes: 5 additions & 4 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@
However, we can update, binding-redirect to, and distribute the newest version (that matches the VS-referenced versions) in order to get the benefits of updating.
See uses of $(UseFrozenMaintenancePackageVersions) for details.
-->
<SystemMemoryVersion>4.6.0</SystemMemoryVersion>
<SystemRuntimeCompilerServicesUnsafeVersion>6.1.0</SystemRuntimeCompilerServicesUnsafeVersion>
<SystemThreadingTasksExtensionsVersion>4.6.0</SystemThreadingTasksExtensionsVersion>
<SystemMemoryVersion>4.6.3</SystemMemoryVersion>
<SystemRuntimeCompilerServicesUnsafeVersion>6.1.2</SystemRuntimeCompilerServicesUnsafeVersion>
<SystemThreadingTasksExtensionsVersion>4.6.3</SystemThreadingTasksExtensionsVersion>
<SystemValueTupleVersion>4.6.1</SystemValueTupleVersion>
</PropertyGroup>

<PropertyGroup>
Expand Down Expand Up @@ -80,7 +81,7 @@
</PropertyGroup>

<PropertyGroup>
<BootstrapSdkVersion>10.0.100</BootstrapSdkVersion>
<BootstrapSdkVersion>10.0.101</BootstrapSdkVersion>
</PropertyGroup>

<Target Name="OverrideArcadeFileVersion" AfterTargets="_InitializeAssemblyVersion">
Expand Down
100 changes: 51 additions & 49 deletions src/Build.UnitTests/TaskHostFactoryLifecycle_E2E_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ namespace Microsoft.Build.Engine.UnitTests
/// </summary>
public class TaskHostFactoryLifecycle_E2E_Tests
{
private static string AssemblyLocation { get; } = Path.Combine(Path.GetDirectoryName(typeof(TaskHostFactoryLifecycle_E2E_Tests).Assembly.Location) ?? System.AppContext.BaseDirectory);
private static string AssemblyLocation { get; } = Path.Combine(Path.GetDirectoryName(typeof(TaskHostFactoryLifecycle_E2E_Tests).Assembly.Location) ?? AppContext.BaseDirectory);

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

private const string TaskHostFactory = "TaskHostFactory";
private const string AssemblyTaskFactory = "AssemblyTaskFactory";
private const string CurrentRuntime = "CurrentRuntime";
private const string NetRuntime = "NET";

private readonly ITestOutputHelper _output;

public TaskHostFactoryLifecycle_E2E_Tests(ITestOutputHelper output)
Expand All @@ -46,74 +51,71 @@ public TaskHostFactoryLifecycle_E2E_Tests(ITestOutputHelper output)
/// <param name="taskFactoryToUse">The task factory to use (TaskHostFactory or AssemblyTaskFactory)</param>
[Theory]
#if NET
[InlineData("CurrentRuntime", "AssemblyTaskFactory")] // Match + No Explicit → in-proc
[InlineData("CurrentRuntime", "TaskHostFactory")] // Match + Explicit → short-lived out-of-proc
[InlineData(CurrentRuntime, AssemblyTaskFactory)] // Match + No Explicit → in-proc
[InlineData(CurrentRuntime, TaskHostFactory)] // Match + Explicit → short-lived out-of-proc
#endif
[InlineData("NET", "AssemblyTaskFactory")] // No Match + No Explicit → long-lived sidecar out-of-proc
[InlineData("NET", "TaskHostFactory")] // No Match + Explicit → short-lived out-of-proc
[InlineData(NetRuntime, AssemblyTaskFactory)] // No Match + No Explicit → long-lived sidecar out-of-proc
[InlineData(NetRuntime, TaskHostFactory)] // No Match + Explicit → short-lived out-of-proc
public void TaskHostLifecycle_ValidatesAllScenarios(
string runtimeToUse,
string taskFactoryToUse)
{
bool? expectedNodeReuse;
bool? expectedNodeReuse = DetermineExpectedNodeReuse(runtimeToUse, taskFactoryToUse);

// TaskHostFactory is always short lived and out-of-proc
if (taskFactoryToUse == "TaskHostFactory")
{
expectedNodeReuse = false;
}
// AssemblyTaskFactory behavior depends on runtime
else if (taskFactoryToUse == "AssemblyTaskFactory")
{
if (runtimeToUse == "CurrentRuntime")
{
// in-proc
expectedNodeReuse = null;
}
else if (runtimeToUse == "NET")
{
// When running on .NET Framework: out-of-proc, otherwise on .NET in-proc.
expectedNodeReuse = RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework", StringComparison.OrdinalIgnoreCase) ? true : null;
}
else
{
throw new ArgumentOutOfRangeException(nameof(runtimeToUse), "Unknown runtime to use: " + runtimeToUse);
}
}
else
using TestEnvironment env = TestEnvironment.Create(_output);

string buildOutput = ExecuteBuildWithTaskHost(runtimeToUse, taskFactoryToUse);

ValidateTaskHostBehavior(buildOutput, expectedNodeReuse);
}

private static bool? DetermineExpectedNodeReuse(string runtimeToUse, string taskFactoryToUse)
=> (taskFactoryToUse, runtimeToUse) switch
{
throw new ArgumentOutOfRangeException(nameof(taskFactoryToUse), "Unknown task factory to use: " + taskFactoryToUse);
}
// TaskHostFactory is always short-lived and out-of-proc (nodereuse:False)
(TaskHostFactory, _) => false,

using TestEnvironment env = TestEnvironment.Create(_output);
// AssemblyTaskFactory with CurrentRuntime runs in-proc
(AssemblyTaskFactory, CurrentRuntime) => null,

// AssemblyTaskFactory with NET runtime:
// - On .NET Framework host: out-of-proc with long-lived sidecar (nodereuse:True)
// - On .NET host: in-proc
(AssemblyTaskFactory, NetRuntime) =>
#if NET
null, // On .NET host: in-proc execution
#else
true, // On .NET Framework host: out-of-proc with long-lived sidecar
#endif
_ => throw new ArgumentException($"Unknown combination: runtime={runtimeToUse}, factory={taskFactoryToUse}")
};

private string ExecuteBuildWithTaskHost(string runtimeToUse, string taskFactoryToUse)
{
string testProjectPath = Path.Combine(TestAssetsRootPath, "TaskHostLifecycleTestApp.csproj");

string testTaskOutput = RunnerUtilities.ExecBootstrapedMSBuild(
$"{testProjectPath} -v:n -restore /p:RuntimeToUse={runtimeToUse} /p:TaskFactoryToUse={taskFactoryToUse}",
out bool successTestTask,
string output = RunnerUtilities.ExecBootstrapedMSBuild(
$"{testProjectPath} -v:n -restore /p:RuntimeToUse={runtimeToUse} /p:TaskFactoryToUse={taskFactoryToUse}",
out bool success,
outputHelper: _output);

successTestTask.ShouldBeTrue();
success.ShouldBeTrue("Build should succeed");

// Verify execution mode (out-of-proc vs in-proc) and node reuse behavior
return output;
}

private static void ValidateTaskHostBehavior(string buildOutput, bool? expectedNodeReuse)
{
if (expectedNodeReuse.HasValue)
{
// For out-of-proc scenarios, validate the task runs in a separate process
// by checking for the presence of command-line arguments that indicate task host execution
testTaskOutput.ShouldContain("/nodemode:",
customMessage: "Task should run out-of-proc and have /nodemode: in its command-line arguments");
buildOutput.ShouldContain("/nodemode:", customMessage: "Task should run out-of-proc and have /nodemode: in its command-line arguments");

// Validate the nodereuse flag in the task's command-line arguments
string expectedFlag = expectedNodeReuse.Value ? "/nodereuse:True" : "/nodereuse:False";
testTaskOutput.ShouldContain(expectedFlag,
customMessage: $"Task should have {expectedFlag} in its command-line arguments");
buildOutput.ShouldContain(expectedFlag, customMessage: $"Task should have {expectedFlag} in its command-line arguments");
}
else
{
// For in-proc scenarios, validate the task does NOT run in a task host
// by ensuring task host specific command-line flags are not present
testTaskOutput.ShouldNotContain("/nodemode:",
customMessage: "Task should run in-proc and not have task host command-line arguments like /nodemode:");
buildOutput.ShouldNotContain("/nodemode:", customMessage: "Task should run in-proc and not have task host command-line arguments like /nodemode:");
}
}
}
Expand Down
Loading
Loading