Skip to content
Closed
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
84 changes: 84 additions & 0 deletions src/Build.UnitTests/NetTaskHost_E2E_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,89 @@ public void NetTaskWithImplicitHostParamsTest()
// Output from the task where neither TaskHost nor Runtime were specified
testTaskOutput.ShouldContain("Found item: Banana");
}

[WindowsFullFrameworkOnlyFact]
public void NetTaskHost_WithNetCoreSdkRootSet_UsesNetCoreSdkRootDirectly()
{
using TestEnvironment env = TestEnvironment.Create(_output);
var dotnetPath = env.GetEnvironmentVariable("DOTNET_ROOT");

string testProjectPath = Path.Combine(TestAssetsRootPath, "ExampleNetTask", "TestNetCoreSdkRootDirect", "TestNetCoreSdkRootDirect.csproj");

string testTaskOutput = RunnerUtilities.ExecBootstrapedMSBuild($"{testProjectPath} -restore -v:n", out bool successTestTask);

if (!successTestTask)
{
_output.WriteLine(testTaskOutput);
}

successTestTask.ShouldBeTrue();
// Verify the task ran successfully with NetCoreSdkRoot property set
testTaskOutput.ShouldContain($"The task is executed in process: dotnet");
testTaskOutput.ShouldContain($"Process path: {dotnetPath}", customMessage: testTaskOutput);
testTaskOutput.ShouldContain("NetCoreSdkRoot test:");
}

[WindowsFullFrameworkOnlyFact]
public void NetTaskHost_WithRuntimeIdentifierGraphPath_FallsBackToRIDGraph()
{
using TestEnvironment env = TestEnvironment.Create(_output);
var dotnetPath = env.GetEnvironmentVariable("DOTNET_ROOT");

string testProjectPath = Path.Combine(TestAssetsRootPath, "ExampleNetTask", "TestRIDGraphFallback", "TestRIDGraphFallback.csproj");

string testTaskOutput = RunnerUtilities.ExecBootstrapedMSBuild($"{testProjectPath} -restore -v:n", out bool successTestTask);

if (!successTestTask)
{
_output.WriteLine(testTaskOutput);
}

successTestTask.ShouldBeTrue();
// Verify the task ran successfully with fallback to RuntimeIdentifierGraphPath
testTaskOutput.ShouldContain($"The task is executed in process: dotnet");
testTaskOutput.ShouldContain($"Process path: {dotnetPath}", customMessage: testTaskOutput);
testTaskOutput.ShouldContain("RIDGraphFallback test");
}

[WindowsFullFrameworkOnlyFact]
public void NetTaskHost_WithNoSDKProperties_StillSucceeds()
{
using TestEnvironment env = TestEnvironment.Create(_output);

string testProjectPath = Path.Combine(TestAssetsRootPath, "ExampleNetTask", "TestNoSDKProperties", "TestNoSDKProperties.csproj");

string testTaskOutput = RunnerUtilities.ExecBootstrapedMSBuild($"{testProjectPath} -restore -v:n", out bool successTestTask);

if (!successTestTask)
{
_output.WriteLine(testTaskOutput);
}

// The task should still succeed even without SDK properties
// This tests the scenario where the fallback returns original parameters
successTestTask.ShouldBeTrue();
testTaskOutput.ShouldContain("NoSDKProperties test completed");
}

[WindowsFullFrameworkOnlyFact]
public void NetTaskHost_WithRIDGraphPathAtRoot_HandlesEdgeCase()
{
using TestEnvironment env = TestEnvironment.Create(_output);

string testProjectPath = Path.Combine(TestAssetsRootPath, "ExampleNetTask", "TestRIDGraphEdgeCase", "TestRIDGraphEdgeCase.csproj");

string testTaskOutput = RunnerUtilities.ExecBootstrapedMSBuild($"{testProjectPath} -restore -v:n", out bool successTestTask);

if (!successTestTask)
{
_output.WriteLine(testTaskOutput);
}

// The task should succeed even with edge case RID graph path
// This tests that Path.GetDirectoryName returning null or empty is handled correctly
successTestTask.ShouldBeTrue();
testTaskOutput.ShouldContain("RIDGraphEdgeCase test");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<!-- Explicitly set NetCoreSdkRoot to verify it's used directly -->
<NetCoreSdkRoot>$(MSBuildSDKsPath)\..</NetCoreSdkRoot>
</PropertyGroup>

<PropertyGroup>
<TestProjectFolder>$([System.IO.Path]::GetFullPath('$([System.IO.Path]::Combine('$(AssemblyLocation)', '..'))'))</TestProjectFolder>
<ExampleTaskPath>$([System.IO.Path]::Combine('$(TestProjectFolder)', '$(TargetFramework)', 'ExampleTask.dll'))</ExampleTaskPath>
</PropertyGroup>

<UsingTask
TaskName="ExampleTask"
AssemblyFile="$(ExampleTaskPath)"
TaskFactory="TaskHostFactory"
Runtime="NET"/>

<Target Name="TestTask" BeforeTargets="Build">
<ExampleTask />
<Message Text="NetCoreSdkRoot test: $(NetCoreSdkRoot)" Importance="high" />
</Target>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"sdk": {
// This global.json is needed to prevent builds running in tests using the bootstrap layout from walking
// up the repo tree and resolving our sdk.paths, instead of the bootstrap layout's SDK.
// See https://github.com/dotnet/runtime/issues/118488 for details.
"allowPrerelease": true,
"rollForward": "latestMajor"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<!-- Explicitly clear both properties to test behavior when both are missing -->
<NetCoreSdkRoot></NetCoreSdkRoot>
<RuntimeIdentifierGraphPath></RuntimeIdentifierGraphPath>
</PropertyGroup>

<PropertyGroup>
<TestProjectFolder>$([System.IO.Path]::GetFullPath('$([System.IO.Path]::Combine('$(AssemblyLocation)', '..'))'))</TestProjectFolder>
<ExampleTaskPath>$([System.IO.Path]::Combine('$(TestProjectFolder)', '$(TargetFramework)', 'ExampleTask.dll'))</ExampleTaskPath>
</PropertyGroup>

<UsingTask
TaskName="ExampleTask"
AssemblyFile="$(ExampleTaskPath)"
TaskFactory="TaskHostFactory"
Runtime="NET"/>

<Target Name="TestTask" BeforeTargets="Build">
<ExampleTask />
<Message Text="NoSDKProperties test completed" Importance="high" />
</Target>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"sdk": {
// This global.json is needed to prevent builds running in tests using the bootstrap layout from walking
// up the repo tree and resolving our sdk.paths, instead of the bootstrap layout's SDK.
// See https://github.com/dotnet/runtime/issues/118488 for details.
"allowPrerelease": true,
"rollForward": "latestMajor"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<!-- Explicitly clear NetCoreSdkRoot to test fallback -->
<NetCoreSdkRoot></NetCoreSdkRoot>
<!-- Set RuntimeIdentifierGraphPath to a file in a near-root directory to test edge case -->
<RuntimeIdentifierGraphPath Condition="$([MSBuild]::IsOSPlatform('Windows'))">\runtime.json</RuntimeIdentifierGraphPath>
<RuntimeIdentifierGraphPath Condition="!$([MSBuild]::IsOSPlatform('Windows'))">/runtime.json</RuntimeIdentifierGraphPath>
</PropertyGroup>

<PropertyGroup>
<TestProjectFolder>$([System.IO.Path]::GetFullPath('$([System.IO.Path]::Combine('$(AssemblyLocation)', '..'))'))</TestProjectFolder>
<ExampleTaskPath>$([System.IO.Path]::Combine('$(TestProjectFolder)', '$(TargetFramework)', 'ExampleTask.dll'))</ExampleTaskPath>
</PropertyGroup>

<UsingTask
TaskName="ExampleTask"
AssemblyFile="$(ExampleTaskPath)"
TaskFactory="TaskHostFactory"
Runtime="NET"/>

<Target Name="TestTask" BeforeTargets="Build">
<ExampleTask />
<Message Text="RIDGraphEdgeCase test - RIDGraphPath: $(RuntimeIdentifierGraphPath)" Importance="high" />
</Target>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"sdk": {
// This global.json is needed to prevent builds running in tests using the bootstrap layout from walking
// up the repo tree and resolving our sdk.paths, instead of the bootstrap layout's SDK.
// See https://github.com/dotnet/runtime/issues/118488 for details.
"allowPrerelease": true,
"rollForward": "latestMajor"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<!-- Explicitly clear NetCoreSdkRoot to test fallback to RuntimeIdentifierGraphPath -->
<NetCoreSdkRoot></NetCoreSdkRoot>
<!-- Set RuntimeIdentifierGraphPath to simulate .NET 10 and earlier behavior -->
<RuntimeIdentifierGraphPath>$(MSBuildSDKsPath)\..\runtime.json</RuntimeIdentifierGraphPath>
</PropertyGroup>

<PropertyGroup>
<TestProjectFolder>$([System.IO.Path]::GetFullPath('$([System.IO.Path]::Combine('$(AssemblyLocation)', '..'))'))</TestProjectFolder>
<ExampleTaskPath>$([System.IO.Path]::Combine('$(TestProjectFolder)', '$(TargetFramework)', 'ExampleTask.dll'))</ExampleTaskPath>
</PropertyGroup>

<UsingTask
TaskName="ExampleTask"
AssemblyFile="$(ExampleTaskPath)"
TaskFactory="TaskHostFactory"
Runtime="NET"/>

<Target Name="TestTask" BeforeTargets="Build">
<ExampleTask />
<Message Text="RIDGraphFallback test - RIDGraphPath: $(RuntimeIdentifierGraphPath)" Importance="high" />
</Target>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"sdk": {
// This global.json is needed to prevent builds running in tests using the bootstrap layout from walking
// up the repo tree and resolving our sdk.paths, instead of the bootstrap layout's SDK.
// See https://github.com/dotnet/runtime/issues/118488 for details.
"allowPrerelease": true,
"rollForward": "latestMajor"
}
}
Loading