diff --git a/src/installer/tests/AppHost.Bundle.Tests/AppLaunch.cs b/src/installer/tests/AppHost.Bundle.Tests/AppLaunch.cs index c1ccb708ad6719..67179e1577a625 100644 --- a/src/installer/tests/AppHost.Bundle.Tests/AppLaunch.cs +++ b/src/installer/tests/AppHost.Bundle.Tests/AppLaunch.cs @@ -82,6 +82,34 @@ private void RunApp(bool selfContained) } } + [Fact] + private void NonAsciiCharacterSelfContainedApp() + { + // Bundle to a single-file + bool selfContained = true; + string singleFile = sharedTestState.SpecialCharacterSelfContainedApp.Bundle(); + + // Run the bundled app + RunTheApp(singleFile, selfContained); + + if (OperatingSystem.IsMacOS()) + { + string fatApp = MakeUniversalBinary(singleFile, RuntimeInformation.OSArchitecture); + + // Run the fat app + RunTheApp(fatApp, selfContained); + } + + if (OperatingSystem.IsWindows()) + { + // StandaloneApp sets FileVersion to NETCoreApp version. On Windows, this should be copied to singlefilehost resources. + string expectedVersion = TestContext.MicrosoftNETCoreAppVersion.Contains('-') + ? TestContext.MicrosoftNETCoreAppVersion[..TestContext.MicrosoftNETCoreAppVersion.IndexOf('-')] + : TestContext.MicrosoftNETCoreAppVersion; + Assert.Equal(expectedVersion, System.Diagnostics.FileVersionInfo.GetVersionInfo(singleFile).FileVersion); + } + } + [ConditionalTheory(typeof(Binaries.CetCompat), nameof(Binaries.CetCompat.IsSupported))] [InlineData(true)] [InlineData(false)] @@ -186,17 +214,20 @@ public class SharedTestState : IDisposable { public SingleFileTestApp FrameworkDependentApp { get; } public SingleFileTestApp SelfContainedApp { get; } + public SingleFileTestApp SpecialCharacterSelfContainedApp { get; } public SharedTestState() { FrameworkDependentApp = SingleFileTestApp.CreateFrameworkDependent("HelloWorld"); SelfContainedApp = SingleFileTestApp.CreateSelfContained("HelloWorld"); + SpecialCharacterSelfContainedApp = SingleFileTestApp.CreateSelfContained("HelloWorld_中文"); } public void Dispose() { FrameworkDependentApp.Dispose(); SelfContainedApp.Dispose(); + SpecialCharacterSelfContainedApp.Dispose(); } } } diff --git "a/src/installer/tests/Assets/Projects/HelloWorld/HelloWorld_\344\270\255\346\226\207.csproj" "b/src/installer/tests/Assets/Projects/HelloWorld/HelloWorld_\344\270\255\346\226\207.csproj" new file mode 100644 index 00000000000000..a600aa229c5ec8 --- /dev/null +++ "b/src/installer/tests/Assets/Projects/HelloWorld/HelloWorld_\344\270\255\346\226\207.csproj" @@ -0,0 +1,19 @@ + + + + $(NetCoreAppCurrent) + Exe + + + + + + $(ProductVersion) + + + + + + + + diff --git a/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs b/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs index 7cce3c76fdd8bb..44cfdfd95358cf 100644 --- a/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs +++ b/src/installer/tests/Microsoft.NET.HostModel.Tests/Bundle/BundlerConsistencyTests.cs @@ -116,6 +116,29 @@ public void DuplicateBundleRelativePath_Fails() .And.Contain(sharedTestState.App.AppDll); } + [Fact] + public void FilesWithNonAsciiCharsCanBundle() + { + string appPath = sharedTestState.NonAsciiApp.AppDll; + string systemLibPath = sharedTestState.SystemDll; + + // File specification with non-ASCII characters in the relative paths + var fileSpecs = new FileSpec[] + { + new FileSpec(Binaries.AppHost.FilePath, BundlerHostName), + new FileSpec(appPath, "中文/app.dll"), + new FileSpec(appPath, "rel/中文.dll"), + new FileSpec(systemLibPath, "中文") + }; + + Bundler bundler = CreateBundlerInstance(); + var bundlePath = bundler.GenerateBundle(fileSpecs); + + bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("中文/app.dll")).Single().Type.Should().Be(FileType.Assembly); + bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("rel/中文.dll")).Single().Type.Should().Be(FileType.Assembly); + bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("中文")).Single().Type.Should().Be(FileType.Assembly); + } + [Fact] public void CaseSensitiveBundleRelativePath() { @@ -366,11 +389,13 @@ public class SharedTestState : IDisposable { public const string AppName = "HelloWorld"; public TestApp App { get; } + public TestApp NonAsciiApp { get; } public string SystemDll { get; } public SharedTestState() { App = TestApp.CreateFromBuiltAssets(AppName); + NonAsciiApp = TestApp.CreateFromBuiltAssets("HelloWorld_中文"); SystemDll = Path.Combine(TestContext.BuiltDotNet.GreatestVersionSharedFxPath, "System.dll"); } @@ -378,6 +403,7 @@ public SharedTestState() public void Dispose() { App.Dispose(); + NonAsciiApp.Dispose(); } } }