Skip to content

Commit 0ce3d13

Browse files
CopilotsbomerCopilot
authored
Add NativeAOT + satellite assembly integration test (#53971)
Adds an SDK regression test for dotnet/runtime#127089 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com> Co-authored-by: Sven Boemer <sbomer@gmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 11e05d6 commit 0ce3d13

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,99 @@ private void GetKnownILCompilerPackVersion(TestAsset testAsset, string targetFra
10581058
.Single();
10591059
}
10601060

1061+
[RequiresMSBuildVersionFact("17.0.0.32901")]
1062+
public void NativeAot_app_publishes_with_app_and_package_satellite_assemblies()
1063+
{
1064+
var projectName = "NativeAotAppWithSatellites";
1065+
var testProject = CreateHelloWorldTestProject(ToolsetInfo.CurrentTargetFramework, projectName, true);
1066+
testProject.RecordProperties("NETCoreSdkPortableRuntimeIdentifier");
1067+
testProject.AdditionalProperties["PublishAot"] = "true";
1068+
testProject.AdditionalProperties["SatelliteResourceLanguages"] = "fr;de";
1069+
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
1070+
{
1071+
testProject.AdditionalProperties["StripSymbols"] = "true";
1072+
}
1073+
testProject.PackageReferences.Add(new TestPackageReference("System.Spatial", "5.8.3"));
1074+
1075+
// Override Program.cs to look up French resource strings at runtime
1076+
// from both app-authored and package-provided satellite assemblies
1077+
testProject.SourceFiles[$"{projectName}.cs"] = $@"
1078+
using System;
1079+
using System.Globalization;
1080+
using System.Resources;
1081+
class Test
1082+
{{
1083+
static int Main()
1084+
{{
1085+
// Verify app-authored satellite resources resolve in French
1086+
var appRm = new ResourceManager(""{projectName}.Strings"", typeof(Test).Assembly);
1087+
var appValue = appRm.GetString(""HelloWorld"", CultureInfo.GetCultureInfo(""fr""));
1088+
Console.WriteLine(appValue);
1089+
if (appValue != ""Bonjour"") return 1;
1090+
1091+
// Verify package (System.Spatial) satellite resources resolve in French
1092+
var spatialAsm = typeof(System.Spatial.GeographyPoint).Assembly;
1093+
var pkgRm = new ResourceManager(""System.Spatial"", spatialAsm);
1094+
var pkgValue = pkgRm.GetString(""Validator_SridMismatch"", CultureInfo.GetCultureInfo(""fr""));
1095+
if (string.IsNullOrEmpty(pkgValue)) return 2;
1096+
Console.WriteLine(""PackageSatelliteOK"");
1097+
return 0;
1098+
}}
1099+
}}";
1100+
1101+
// Neutral-culture fallback resource
1102+
testProject.EmbeddedResources["Strings.resx"] = @"<?xml version=""1.0"" encoding=""utf-8""?>
1103+
<root>
1104+
<resheader name=""resmimetype""><value>text/microsoft-resx</value></resheader>
1105+
<resheader name=""version""><value>2.0</value></resheader>
1106+
<resheader name=""reader""><value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader>
1107+
<resheader name=""writer""><value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader>
1108+
<data name=""HelloWorld"" xml:space=""preserve""><value>Hello</value></data>
1109+
</root>";
1110+
1111+
// French satellite resource
1112+
testProject.EmbeddedResources["Strings.fr.resx"] = @"<?xml version=""1.0"" encoding=""utf-8""?>
1113+
<root>
1114+
<resheader name=""resmimetype""><value>text/microsoft-resx</value></resheader>
1115+
<resheader name=""version""><value>2.0</value></resheader>
1116+
<resheader name=""reader""><value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader>
1117+
<resheader name=""writer""><value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader>
1118+
<data name=""HelloWorld"" xml:space=""preserve""><value>Bonjour</value></data>
1119+
</root>";
1120+
1121+
var testAsset = TestAssetsManager.CreateTestProject(testProject);
1122+
var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name));
1123+
publishCommand
1124+
.Execute("/p:UseCurrentRuntimeIdentifier=true", "/p:SelfContained=true")
1125+
.Should().Pass();
1126+
1127+
var buildProperties = testProject.GetPropertyValues(testAsset.TestRoot, ToolsetInfo.CurrentTargetFramework);
1128+
var rid = buildProperties["NETCoreSdkPortableRuntimeIdentifier"];
1129+
var publishDirectory = publishCommand.GetOutputDirectory(targetFramework: ToolsetInfo.CurrentTargetFramework, runtimeIdentifier: rid).FullName;
1130+
1131+
// NativeAOT embeds satellite assemblies into the native binary, so they
1132+
// should NOT appear as separate files in the publish directory (dotnet/runtime#124191).
1133+
File.Exists(Path.Combine(publishDirectory, "fr", $"{projectName}.resources.dll")).Should().BeFalse("fr app satellite should be embedded, not published separately");
1134+
File.Exists(Path.Combine(publishDirectory, "fr", "System.Spatial.resources.dll")).Should().BeFalse("fr package satellite should be embedded, not published separately");
1135+
File.Exists(Path.Combine(publishDirectory, "de", "System.Spatial.resources.dll")).Should().BeFalse("de package satellite should be embedded, not published separately");
1136+
1137+
// Satellite for a non-selected culture (ja) should be absent
1138+
File.Exists(Path.Combine(publishDirectory, "ja", "System.Spatial.resources.dll")).Should().BeFalse("ja System.Spatial satellite should be filtered out");
1139+
1140+
// Published output should be a native image
1141+
var publishedExe = Path.Combine(publishDirectory, $"{projectName}{Constants.ExeSuffix}");
1142+
File.Exists(publishedExe).Should().BeTrue();
1143+
IsNativeImage(publishedExe).Should().BeTrue();
1144+
1145+
// Running the native image should resolve French resources correctly
1146+
// from both app-authored and package-provided satellites
1147+
new RunExeCommand(Log, publishedExe)
1148+
.Execute()
1149+
.Should().Pass()
1150+
.And.HaveStdOutContaining("Bonjour")
1151+
.And.HaveStdOutContaining("PackageSatelliteOK");
1152+
}
1153+
10611154
private void CheckIlcVersions(TestAsset testAsset, string targetFramework, string rid, string expectedVersion, bool useRuntimePackLayout)
10621155
{
10631156
// Compiler version matches expected version

0 commit comments

Comments
 (0)