diff --git a/test/Microsoft.NET.Build.Tests/RoslynBuildTaskTests.cs b/test/Microsoft.NET.Build.Tests/RoslynBuildTaskTests.cs index ba14cd54eebc..b4d40e228218 100644 --- a/test/Microsoft.NET.Build.Tests/RoslynBuildTaskTests.cs +++ b/test/Microsoft.NET.Build.Tests/RoslynBuildTaskTests.cs @@ -3,6 +3,7 @@ using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.Versioning; using Basic.CompilerLog.Util; using Microsoft.Build.Logging.StructuredLogger; using Microsoft.CodeAnalysis; @@ -11,6 +12,9 @@ namespace Microsoft.NET.Build.Tests; public sealed class RoslynBuildTaskTests(ITestOutputHelper log) : SdkTest(log) { + private const string CoreTargetFrameworkName = ".NETCoreApp"; + private const string FxTargetFrameworkName = ".NETFramework"; + private static string CompilerFileNameWithoutExtension(Language language) => language switch { Language.CSharp => "csc", @@ -27,7 +31,7 @@ public void FullMSBuild_SdkStyle(bool useSharedCompilation, Language language) { var testAsset = CreateProject(useSharedCompilation, language); var buildCommand = BuildAndRunUsingMSBuild(testAsset); - VerifyCompiler(buildCommand, CoreCompilerFileName(language), useSharedCompilation); + VerifyCompiler(buildCommand, CoreCompilerFileName(language), CoreTargetFrameworkName, useSharedCompilation); } [FullMSBuildOnlyTheory, CombinatorialData] @@ -38,7 +42,7 @@ public void FullMSBuild_SdkStyle_OptOut(bool useSharedCompilation, Language lang doc.Root!.Element("PropertyGroup")!.Add(new XElement("RoslynCompilerType", "Framework")); }); var buildCommand = BuildAndRunUsingMSBuild(testAsset); - VerifyCompiler(buildCommand, FxCompilerFileName(language), useSharedCompilation); + VerifyCompiler(buildCommand, FxCompilerFileName(language), FxTargetFrameworkName, useSharedCompilation); } [FullMSBuildOnlyTheory, CombinatorialData] @@ -50,15 +54,19 @@ public void FullMSBuild_NonSdkStyle(bool useSharedCompilation, Language language project.TargetFrameworkVersion = "v4.7.2"; }); var buildCommand = BuildAndRunUsingMSBuild(testAsset); - VerifyCompiler(buildCommand, FxCompilerFileName(language), useSharedCompilation); + VerifyCompiler(buildCommand, FxCompilerFileName(language), FxTargetFrameworkName, useSharedCompilation); } [FullMSBuildOnlyTheory, CombinatorialData] - public void FullMSBuild_SdkStyle_ToolsetPackage(bool useSharedCompilation, Language language) + public void FullMSBuild_SdkStyle_ToolsetPackage(bool useSharedCompilation, Language language, bool useFrameworkCompiler) { var testAsset = CreateProject(useSharedCompilation, language, AddCompilersToolsetPackage); - var buildCommand = BuildAndRunUsingMSBuild(testAsset); - VerifyCompiler(buildCommand, FxCompilerFileName(language), useSharedCompilation, toolsetPackage: true); + ReadOnlySpan args = useFrameworkCompiler ? ["-p:RoslynCompilerType=Framework"] : []; + var buildCommand = BuildAndRunUsingMSBuild(testAsset, args); + VerifyCompiler(buildCommand, + useFrameworkCompiler ? FxCompilerFileName(language) : CoreCompilerFileName(language), + useFrameworkCompiler ? FxTargetFrameworkName : CoreTargetFrameworkName, + useSharedCompilation, toolsetPackage: true); } [Theory, CombinatorialData] @@ -66,7 +74,7 @@ public void DotNet(bool useSharedCompilation, Language language) { var testAsset = CreateProject(useSharedCompilation, language); var buildCommand = BuildAndRunUsingDotNet(testAsset); - VerifyCompiler(buildCommand, CoreCompilerFileName(language), useSharedCompilation); + VerifyCompiler(buildCommand, CoreCompilerFileName(language), CoreTargetFrameworkName, useSharedCompilation); } // https://github.com/dotnet/sdk/issues/49665 @@ -75,7 +83,7 @@ public void DotNet_ToolsetPackage(bool useSharedCompilation, Language language) { var testAsset = CreateProject(useSharedCompilation, language, AddCompilersToolsetPackage); var buildCommand = BuildAndRunUsingDotNet(testAsset); - VerifyCompiler(buildCommand, CoreCompilerFileName(language), useSharedCompilation, toolsetPackage: true); + VerifyCompiler(buildCommand, CoreCompilerFileName(language), CoreTargetFrameworkName, useSharedCompilation, toolsetPackage: true); } private TestAsset CreateProject(bool useSharedCompilation, Language language, Action? configure = null, [CallerMemberName] string callingMethod = "") @@ -129,21 +137,21 @@ private static void AddCompilersToolsetPackage(TestProject project) project.PackageReferences.Add(new TestPackageReference("Microsoft.Net.Compilers.Toolset", roslynVersion)); } - private TestCommand BuildAndRunUsingMSBuild(TestAsset testAsset) + private TestCommand BuildAndRunUsingMSBuild(TestAsset testAsset, params ReadOnlySpan args) { var buildCommand = new MSBuildCommand(testAsset, "Build"); buildCommand.WithWorkingDirectory(testAsset.Path) - .Execute("-bl").Should().Pass(); + .Execute(["-bl", .. args]).Should().Pass(); Run(buildCommand.GetOutputDirectory().File(testAsset.TestProject!.GetOutputFileName())); return buildCommand; } - private TestCommand BuildAndRunUsingDotNet(TestAsset testAsset) + private TestCommand BuildAndRunUsingDotNet(TestAsset testAsset, params ReadOnlySpan args) { var buildCommand = new DotnetBuildCommand(testAsset); - buildCommand.Execute("-bl").Should().Pass(); + buildCommand.Execute(["-bl", .. args]).Should().Pass(); Run(buildCommand.GetOutputDirectory().File(testAsset.TestProject!.GetOutputFileName())); @@ -157,7 +165,7 @@ private void Run(FileInfo outputFile) .And.HaveStdOut("42"); } - private static void VerifyCompiler(TestCommand buildCommand, string compilerFileName, bool usedCompilerServer, bool toolsetPackage = false) + private static void VerifyCompiler(TestCommand buildCommand, string compilerFileName, string targetFrameworkName, bool usedCompilerServer, bool toolsetPackage = false) { var binaryLogPath = Path.Join(buildCommand.WorkingDirectory, "msbuild.binlog"); using (var reader = BinaryLogReader.Create(binaryLogPath)) @@ -174,16 +182,31 @@ private static void VerifyCompiler(TestCommand buildCommand, string compilerFile { call.CompilerFilePath.Should().NotContain(toolsetPackageName); } + + GetTargetFramework(call.CompilerFilePath).Should().StartWith($"{targetFrameworkName},"); } // Verify compiler server message. - var compilerServerMesssages = BinaryLog.ReadBuild(binaryLogPath).FindChildrenRecursive( + var compilerServerMessages = BinaryLog.ReadBuild(binaryLogPath).FindChildrenRecursive( static message => message.Text.StartsWith("CompilerServer:", StringComparison.Ordinal)); - compilerServerMesssages.Should().ContainSingle().Which.Text.Should().StartWith(usedCompilerServer + compilerServerMessages.Should().ContainSingle().Which.Text.Should().StartWith(usedCompilerServer ? "CompilerServer: server - server processed compilation - " : "CompilerServer: tool - using command line tool by design"); } + private static string? GetTargetFramework(string dllPath) + { + var tpa = ((string?)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES"))?.Split(Path.PathSeparator) ?? []; + var resolver = new PathAssemblyResolver([.. tpa, dllPath]); + using var mlc = new MetadataLoadContext(resolver); + var asm = mlc.LoadFromAssemblyPath(dllPath); + var attrFullName = typeof(TargetFrameworkAttribute).FullName; + return asm.GetCustomAttributesData() + .Where(a => a.AttributeType.FullName == attrFullName) + .Select(a => a.ConstructorArguments[0].Value) + .FirstOrDefault() as string; + } + public enum Language { CSharp,