From e9c6b83d721f3ca9812b9f752ef04727cac58fa4 Mon Sep 17 00:00:00 2001 From: Tom Deseyn Date: Thu, 26 Sep 2024 14:35:36 +0200 Subject: [PATCH 1/2] Add test for source-built bundled NativeAOT. (#113) --- .../Program.cs | 48 ++++++++++++++++++- .../DotNetSdkActions.cs | 11 +++-- .../DotNetSdkHelper.cs | 12 ++++- .../SdkTemplateTest.cs | 10 ++-- .../SdkTemplateTests.cs | 11 +++++ 5 files changed, 80 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.DotNet.ScenarioTests.Common/Program.cs b/src/Microsoft.DotNet.ScenarioTests.Common/Program.cs index a644619a2..13efdfc0a 100644 --- a/src/Microsoft.DotNet.ScenarioTests.Common/Program.cs +++ b/src/Microsoft.DotNet.ScenarioTests.Common/Program.cs @@ -156,7 +156,7 @@ public static int Invoke(string dotnetRoot, discoverer.Find(false, discoverySink, TestFrameworkOptions.ForDiscovery(assemblyConfig)); discoverySink.Finished.WaitOne(); - XunitFilters filters = CreateFilters(noTraits, traits, offlineOnly, platform); + XunitFilters filters = CreateFilters(noTraits, traits, offlineOnly, platform, dotnetRoot, targetRid); var filteredTestCases = discoverySink.TestCases.Where(filters.Filter).ToList(); @@ -217,7 +217,7 @@ private static void SetupTestEnvironment(string dotnetRoot, string testRoot, str } - private static XunitFilters CreateFilters(IList excludedTraits, IList includedTraits, bool offlineOnly, OSPlatform platform) + private static XunitFilters CreateFilters(IList excludedTraits, IList includedTraits, bool offlineOnly, OSPlatform platform, string dotnetRoot, string targetRid) { XunitFilters filters = new XunitFilters(); @@ -234,6 +234,8 @@ private static XunitFilters CreateFilters(IList excludedTraits, IList() {$"{platform}"}); + filters.ExcludedTraits.Add("SkipIfBuild", CreateBuildTraits(dotnetRoot, targetRid)); + Dictionary> includedTraitsMap = ParseTraitKeyValuePairs(includedTraits); foreach (KeyValuePair> kvp in includedTraitsMap) { @@ -243,6 +245,48 @@ private static XunitFilters CreateFilters(IList excludedTraits, IList CreateBuildTraits(string dotnetRoot, string targetRid) + { + List buildTraits = new(); + + // Mono + if (DetermineIsMonoRuntime(dotnetRoot)) + { + buildTraits.Add("Mono"); + } + + // Portable + int archSeparatorPos = targetRid.LastIndexOf('-'); + string ridWithoutArch = targetRid.Substring(0, archSeparatorPos != -1 ? archSeparatorPos : 0); + string[] portableRids = [ "linux", "linux-musl" ]; + if (Array.IndexOf(portableRids, ridWithoutArch) != -1) + { + buildTraits.Add("Portable"); + } + + return buildTraits; + } + + private static bool DetermineIsMonoRuntime(string dotnetRoot) + { + string sharedFrameworkRoot = Path.Combine(dotnetRoot, "shared", "Microsoft.NETCore.App"); + if (!Directory.Exists(sharedFrameworkRoot)) + { + return false; + } + + string? version = Directory.GetDirectories(sharedFrameworkRoot).FirstOrDefault(); + if (version is null) + { + return false; + } + + string sharedFramework = Path.Combine(sharedFrameworkRoot, version); + + // Check the presence of one of the mono header files. + return File.Exists(Path.Combine(sharedFramework, "mono-gc.h")); + } + private static Dictionary> ParseTraitKeyValuePairs(IList excludedTraits) { // Quick hack wo much validation to get args that are passed (notrait, xml) diff --git a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotNetSdkActions.cs b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotNetSdkActions.cs index cd46bc71e..afe933f19 100644 --- a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotNetSdkActions.cs +++ b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotNetSdkActions.cs @@ -14,9 +14,10 @@ public enum DotNetSdkActions Publish = 8, PublishComplex = 16, PublishR2R = 32, - Test = 64, - AddClassLibRef = 128, - FullWorkloadTest = 256, - WorkloadInstall = 512, - WorkloadUninstall = 1024, + PublishAot = 64, + Test = 128, + AddClassLibRef = 256, + FullWorkloadTest = 512, + WorkloadInstall = 1024, + WorkloadUninstall = 2048 } diff --git a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotNetSdkHelper.cs b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotNetSdkHelper.cs index 3cdb4ced3..d815d188e 100644 --- a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotNetSdkHelper.cs +++ b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotNetSdkHelper.cs @@ -17,7 +17,6 @@ internal class DotNetSdkHelper public string? SdkVersion { get; set; } public string DotNetExecutablePath { get => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Path.Combine(DotNetRoot, "dotnet.exe") : Path.Combine(DotNetRoot, "dotnet"); } - private ITestOutputHelper OutputHelper { get; } public DotNetSdkHelper(ITestOutputHelper outputHelper, string dotnetRoot, string? sdkVersion) @@ -105,7 +104,7 @@ public string ExecuteNew(string projectType, string projectName, string projectD return projectDirectory; } - public void ExecutePublish(string projectDirectory, bool? selfContained = null, string? rid = null, bool trimmed = false, bool readyToRun = false, string[]? frameworks = null) + public void ExecutePublish(string projectDirectory, string? rid = null, bool? selfContained = null, bool trimmed = false, bool readyToRun = false, bool? aot = false, string[]? frameworks = null) { string options = string.Empty; string binlogDifferentiator = string.Empty; @@ -134,6 +133,15 @@ public void ExecutePublish(string projectDirectory, bool? selfContained = null, } } + if (aot.HasValue) + { + options += $" /p:PublishAot={aot.Value.ToString().ToLowerInvariant()}"; + if (aot.Value) + { + binlogDifferentiator += "-aot"; + } + } + if (frameworks != null) { foreach (var item in frameworks) diff --git a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTest.cs b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTest.cs index 38f2b5827..8646c9b57 100644 --- a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTest.cs +++ b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTest.cs @@ -86,12 +86,16 @@ internal void Execute(DotNetSdkHelper dotNetHelper, string testRoot, string[]? f if (Commands.HasFlag(DotNetSdkActions.PublishComplex)) { dotNetHelper.ExecutePublish(projectDirectory, selfContained: false); - dotNetHelper.ExecutePublish(projectDirectory, selfContained: true, TargetRid); - dotNetHelper.ExecutePublish(projectDirectory, selfContained: true, $"linux-{TargetArchitecture}"); + dotNetHelper.ExecutePublish(projectDirectory, TargetRid, selfContained: true); + dotNetHelper.ExecutePublish(projectDirectory, $"linux-{TargetArchitecture}", selfContained: true); } if (Commands.HasFlag(DotNetSdkActions.PublishR2R)) { - dotNetHelper.ExecutePublish(projectDirectory, selfContained: true, $"linux-{TargetArchitecture}", trimmed: true, readyToRun: true); + dotNetHelper.ExecutePublish(projectDirectory, $"linux-{TargetArchitecture}", selfContained: true, trimmed: true, readyToRun: true); + } + if (Commands.HasFlag(DotNetSdkActions.PublishAot)) + { + dotNetHelper.ExecutePublish(projectDirectory, TargetRid, aot: true); } if (Commands.HasFlag(DotNetSdkActions.Test)) { diff --git a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTests.cs b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTests.cs index 3ee132ef1..c57a3877f 100644 --- a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTests.cs +++ b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTests.cs @@ -208,6 +208,17 @@ public void VerifyRazorTemplate(DotNetLanguage language) newTest.Execute(_sdkHelper, _scenarioTestInput.TestRoot); } + [Fact] + [Trait("SkipIfBuild", "Portable")] // Portable builds don't bundle an AOT compiler. + [Trait("SkipIfBuild", "Mono")] // Mono builds don't bundle an AOT compiler. + public void VerifyWebTemplatePublishBundledAot() + { + var newTest = new SdkTemplateTest( + nameof(SdkTemplateTests) + "Aot", DotNetLanguage.CSharp, _scenarioTestInput.TargetRid, DotNetSdkTemplate.Web, + DotNetSdkActions.PublishAot); + newTest.Execute(_sdkHelper, _scenarioTestInput.TestRoot); + } + [Fact] [Trait("Category", "Workload")] public void VerifyWorkloadCmd() From c17e53d4105b1893f8a6b69cc80c44cc8910da5d Mon Sep 17 00:00:00 2001 From: Tom Deseyn Date: Thu, 10 Oct 2024 15:02:33 +0200 Subject: [PATCH 2/2] Skip tests that require portable assets on community architectures. (#108) --- .../Program.cs | 13 +++++++++++-- .../ScenarioTestFixture.cs | 2 ++ .../DotnetWorkloadTest.cs | 2 +- .../SdkTemplateTest.cs | 5 ++--- .../SdkTemplateTests.cs | 12 ++++++++++++ 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.DotNet.ScenarioTests.Common/Program.cs b/src/Microsoft.DotNet.ScenarioTests.Common/Program.cs index 13efdfc0a..34ce904aa 100644 --- a/src/Microsoft.DotNet.ScenarioTests.Common/Program.cs +++ b/src/Microsoft.DotNet.ScenarioTests.Common/Program.cs @@ -249,6 +249,10 @@ private static List CreateBuildTraits(string dotnetRoot, string targetRi { List buildTraits = new(); + int archSeparatorPos = targetRid.LastIndexOf('-'); + string ridWithoutArch = targetRid.Substring(0, archSeparatorPos != -1 ? archSeparatorPos : 0); + string arch = targetRid.Substring(archSeparatorPos + 1); + // Mono if (DetermineIsMonoRuntime(dotnetRoot)) { @@ -256,14 +260,19 @@ private static List CreateBuildTraits(string dotnetRoot, string targetRi } // Portable - int archSeparatorPos = targetRid.LastIndexOf('-'); - string ridWithoutArch = targetRid.Substring(0, archSeparatorPos != -1 ? archSeparatorPos : 0); string[] portableRids = [ "linux", "linux-musl" ]; if (Array.IndexOf(portableRids, ridWithoutArch) != -1) { buildTraits.Add("Portable"); } + // CommunityArchitecture + string[] communityArchitectures = [ "s390x", "ppc64le", "loongarch64", "riscv64" ]; + if (Array.IndexOf(communityArchitectures, arch) != -1) + { + buildTraits.Add("CommunityArchitecture"); + } + return buildTraits; } diff --git a/src/Microsoft.DotNet.ScenarioTests.Common/ScenarioTestFixture.cs b/src/Microsoft.DotNet.ScenarioTests.Common/ScenarioTestFixture.cs index 7b51b1e38..32d0d3aae 100644 --- a/src/Microsoft.DotNet.ScenarioTests.Common/ScenarioTestFixture.cs +++ b/src/Microsoft.DotNet.ScenarioTests.Common/ScenarioTestFixture.cs @@ -39,4 +39,6 @@ public ScenarioTestFixture() public string DotNetRoot { get; set; } public string TestRoot { get; set; } public string TargetRid { get; set; } + public string TargetArchitecture { get => TargetRid.Split('-').Last(); } + public string PortableRid { get => $"linux-{TargetArchitecture}"; } } diff --git a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotnetWorkloadTest.cs b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotnetWorkloadTest.cs index 141b70b36..3c35b36bd 100644 --- a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotnetWorkloadTest.cs +++ b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/DotnetWorkloadTest.cs @@ -10,7 +10,7 @@ internal class DotnetWorkloadTest public DotNetLanguage Language { get; } public bool NoHttps { get => TargetRid.Contains("osx"); } public string TargetRid { get; set; } - public string TargetArchitecture { get => TargetRid.Split('-')[1]; } + public string TargetArchitecture { get => TargetRid.Split('-').Last(); } public string ScenarioName { get; } public DotnetWorkloadTest(string scenarioName, string targetRid, DotNetSdkActions commands = DotNetSdkActions.None) diff --git a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTest.cs b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTest.cs index 8646c9b57..37b0c3603 100644 --- a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTest.cs +++ b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTest.cs @@ -10,7 +10,7 @@ public class SdkTemplateTest public DotNetLanguage Language { get; } public bool NoHttps { get => TargetRid.Contains("osx"); } public string TargetRid { get; set; } - public string TargetArchitecture { get => TargetRid.Split('-')[1]; } + public string TargetArchitecture { get => TargetRid.Split('-').Last(); } public string ScenarioName { get; } public DotNetSdkTemplate Template { get; } @@ -87,11 +87,10 @@ internal void Execute(DotNetSdkHelper dotNetHelper, string testRoot, string[]? f { dotNetHelper.ExecutePublish(projectDirectory, selfContained: false); dotNetHelper.ExecutePublish(projectDirectory, TargetRid, selfContained: true); - dotNetHelper.ExecutePublish(projectDirectory, $"linux-{TargetArchitecture}", selfContained: true); } if (Commands.HasFlag(DotNetSdkActions.PublishR2R)) { - dotNetHelper.ExecutePublish(projectDirectory, $"linux-{TargetArchitecture}", selfContained: true, trimmed: true, readyToRun: true); + dotNetHelper.ExecutePublish(projectDirectory, TargetRid, selfContained: true, trimmed: true, readyToRun: true); } if (Commands.HasFlag(DotNetSdkActions.PublishAot)) { diff --git a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTests.cs b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTests.cs index c57a3877f..9553a6861 100644 --- a/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTests.cs +++ b/src/Microsoft.DotNet.ScenarioTests.SdkTemplateTests/SdkTemplateTests.cs @@ -28,6 +28,17 @@ public void VerifyConsoleTemplateComplex(DotNetLanguage language) { var newTest = new SdkTemplateTest( nameof(SdkTemplateTests) + "Complex", language, _scenarioTestInput.TargetRid, DotNetSdkTemplate.Console, + DotNetSdkActions.Build | DotNetSdkActions.Run | DotNetSdkActions.PublishComplex); + newTest.Execute(_sdkHelper, _scenarioTestInput.TestRoot); + } + + [Theory] + [MemberData(nameof(GetLanguages))] + [Trait("SkipIfBuild", "CommunityArchitecture")] // Portable assets are not available for community architectures. + public void VerifyConsoleTemplateComplexPortable(DotNetLanguage language) + { + var newTest = new SdkTemplateTest( + nameof(SdkTemplateTests) + "ComplexPortable", language, _scenarioTestInput.PortableRid, DotNetSdkTemplate.Console, DotNetSdkActions.Build | DotNetSdkActions.Run | DotNetSdkActions.PublishComplex | DotNetSdkActions.PublishR2R); newTest.Execute(_sdkHelper, _scenarioTestInput.TestRoot); } @@ -221,6 +232,7 @@ public void VerifyWebTemplatePublishBundledAot() [Fact] [Trait("Category", "Workload")] + [Trait("SkipIfBuild", "CommunityArchitecture")] // SDK has no workloads that support community architectures. public void VerifyWorkloadCmd() { var newTest = new DotnetWorkloadTest(