diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets
index 8ce39e4370b2..0e991e2df7f9 100644
--- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets
+++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets
@@ -103,7 +103,7 @@ Copyright (c) .NET Foundation. All rights reserved.
- false
true
@@ -1292,30 +1295,35 @@ Copyright (c) .NET Foundation. All rights reserved.
false
-
-
- false
-
-
-
-
- false
-
-
-
<_UseAttributeForTargetFrameworkInfoPropertyNames Condition="$([MSBuild]::VersionGreaterThanOrEquals($(MSBuildVersion), '17.0'))">true
+
+
+
+
+ <_IsVSTestTestProject Condition="'$(IsTestProject)' == 'true' and '$(IsTestingPlatformApplication)' != 'true'">true
+ <_IsVSTestTestProject Condition="'$(_IsVSTestTestProject)' == ''">false
+
+
+ false
+
+
+ false
+
+
+
+ DependsOnTargets="_CalculateIsVSTestTestProject"
+ AfterTargets="_GetProjectReferenceTargetFrameworkProperties">
+
+ true
+
+
+ """);
+ }
+
+ var result = new BuildCommand(Log, mtpProjectDirectory).Execute();
+ result.Should().Fail().And.HaveStdOutContaining("NETSDK1151");
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void MTPNonSelfContainedExecutableCannotBeReferencedBySelfContained(bool setIsTestingPlatformApplicationEarly)
+ {
+ // The setup of this test is as follows:
+ // ConsoleApp is a self-contained executable project, which references a non-self-contained MTP executable test project.
+ // Building ConsoleApp should fail because it references a non-self-contained MTP executable project.
+ // A non self-contained executable cannot be referenced by a self-contained executable.
+ var testConsoleProjectSelfContained = new TestProject("ConsoleApp")
+ {
+ IsExe = true,
+ TargetFrameworks = ToolsetInfo.CurrentTargetFramework,
+ SelfContained = "true",
+ };
+
+ var mtpNotSelfContained = new TestProject("MTPTestProject")
+ {
+ TargetFrameworks = ToolsetInfo.CurrentTargetFramework,
+ IsExe = true,
+ };
+
+ mtpNotSelfContained.AdditionalProperties["IsTestProject"] = "true";
+
+ if (setIsTestingPlatformApplicationEarly)
+ {
+ mtpNotSelfContained.AdditionalProperties["IsTestingPlatformApplication"] = "true";
+ }
+
+ testConsoleProjectSelfContained.ReferencedProjects.Add(mtpNotSelfContained);
+
+ var testAssetSelfContained = _testAssetsManager.CreateTestProject(testConsoleProjectSelfContained);
+
+ if (!setIsTestingPlatformApplicationEarly)
+ {
+ File.WriteAllText(Path.Combine(testAssetSelfContained.TestRoot, mtpNotSelfContained.Name, "Directory.Build.targets"), """
+
+
+ true
+
+
+ """);
+ }
+
+ var consoleAppDirectory = Path.Combine(testAssetSelfContained.Path, testConsoleProjectSelfContained.Name);
+
+ var result = new BuildCommand(Log, consoleAppDirectory).Execute();
+ result.Should().HaveStdOutContaining("NETSDK1150").And.ExitWith(1);
+ }
+
[RequiresMSBuildVersionTheory("17.0.0.32901")]
- [InlineData("xunit")]
- [InlineData("mstest")]
- public void ExeProjectCanReferenceTestProject(string testTemplateName)
+ [CombinatorialData]
+ public void ExeProjectCanReferenceTestProject(
+ [CombinatorialValues("xunit", "mstest")] string testTemplateName,
+ bool setSelfContainedProperty,
+ bool buildWithSelfContainedFromCommandLine)
{
var testConsoleProject = new TestProject("ConsoleApp")
{
@@ -371,6 +478,11 @@ public void ExeProjectCanReferenceTestProject(string testTemplateName)
RuntimeIdentifier = EnvironmentInfo.GetCompatibleRid()
};
+ if (setSelfContainedProperty)
+ {
+ testConsoleProject.SelfContained = "true";
+ }
+
var testAsset = _testAssetsManager.CreateTestProject(testConsoleProject, identifier: testTemplateName);
var testProjectDirectory = Path.Combine(testAsset.TestRoot, "TestProject");
@@ -391,7 +503,47 @@ public void ExeProjectCanReferenceTestProject(string testTemplateName)
.Should()
.Pass();
- new BuildCommand(Log, consoleProjectDirectory)
+ new BuildCommand(testAsset)
+ .WithWorkingDirectory(consoleProjectDirectory)
+ .Execute(buildWithSelfContainedFromCommandLine ? ["-p:SelfContained=true"] : Array.Empty())
+ .Should()
+ .Pass();
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void MTPCanBeBuiltAsSelfContained(bool setIsTestingPlatformApplicationEarly)
+ {
+ var mtpSelfContained = new TestProject("MTPTestProject")
+ {
+ TargetFrameworks = ToolsetInfo.CurrentTargetFramework,
+ IsExe = true,
+ SelfContained = "true",
+ };
+
+ mtpSelfContained.AdditionalProperties["IsTestProject"] = "true";
+
+ if (setIsTestingPlatformApplicationEarly)
+ {
+ mtpSelfContained.AdditionalProperties["IsTestingPlatformApplication"] = "true";
+ }
+
+ var testAssetMTP = _testAssetsManager.CreateTestProject(mtpSelfContained);
+
+ var mtpProjectDirectory = Path.Combine(testAssetMTP.Path, mtpSelfContained.Name);
+
+ if (!setIsTestingPlatformApplicationEarly)
+ {
+ File.WriteAllText(Path.Combine(mtpProjectDirectory, "Directory.Build.targets"), """
+
+
+ true
+
+
+ """);
+ }
+
+ new BuildCommand(Log, mtpProjectDirectory)
.Execute()
.Should()
.Pass();
diff --git a/test/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs b/test/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs
index 9a1653b3e635..b2260f81205c 100644
--- a/test/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs
+++ b/test/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs
@@ -34,7 +34,6 @@ public TestProject([CallerMemberName] string? name = null)
///
public bool IsWinExe { get; set; }
-
public string? ProjectSdk { get; set; }
///