Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Blazor] Add basic ICU tests #89771

Merged
merged 22 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eng/testing/scenarios/BuildWasmAppsJobsList.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Wasm.Build.Tests.Blazor.MiscTests2
Wasm.Build.Tests.Blazor.MiscTests3
Wasm.Build.Tests.Blazor.NativeTests
Wasm.Build.Tests.Blazor.NoopNativeRebuildTest
Wasm.Build.Tests.Blazor.IcuTests
Wasm.Build.Tests.BuildPublishTests
Wasm.Build.Tests.ConfigSrcTests
Wasm.Build.Tests.HybridGlobalizationTests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,17 @@ Copyright (c) .NET Foundation. All rights reserved.
<Target Name="_ResolveGlobalizationConfiguration">
<Error Condition="'$(BlazorIcuDataFileName)' != '' AND !$([System.IO.Path]::GetFileName('$(BlazorIcuDataFileName)').StartsWith('icudt'))" Text="File name in %24(BlazorIcuDataFileName) has to start with 'icudt'." />
<Warning Condition="'$(InvariantGlobalization)' == 'true' AND '$(BlazorWebAssemblyLoadAllGlobalizationData)' == 'true'" Text="%24(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when %24(InvariantGlobalization) is set to true." />
<Warning Condition="'$(HybridGlobalization)' == 'true' AND '$(BlazorWebAssemblyLoadAllGlobalizationData)' == 'true'" Text="%24(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when %24(HybridGlobalization) is set to true." />
<Warning Condition="'$(InvariantGlobalization)' == 'true' AND '$(BlazorIcuDataFileName)' != ''" Text="%24(BlazorIcuDataFileName) has no effect when %24(InvariantGlobalization) is set to true." />
<Warning Condition="'$(BlazorWebAssemblyLoadAllGlobalizationData)' == 'true' AND '$(BlazorIcuDataFileName)' != ''" Text="%24(BlazorIcuDataFileName) has no effect when %24(BlazorWebAssemblyLoadAllGlobalizationData) is set to true." />
<Warning Condition="'$(InvariantGlobalization)' == 'true' AND '$(HybridGlobalization)' == 'true'" Text="%24(HybridGlobalization) has no effect when %24(InvariantGlobalization) is set to true." />
<Warning Condition="'$(BlazorIcuDataFileName)' != '' AND '$(HybridGlobalization)' == 'true'" Text="%24(HybridGlobalization) has no effect when %24(BlazorIcuDataFileName) is set." />
<PropertyGroup>
<HybridGlobalization Condition="'$(BlazorIcuDataFileName)' != ''">false</HybridGlobalization>
<_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(InvariantGlobalization)' != 'true'">$(BlazorWebAssemblyLoadAllGlobalizationData)</_BlazorWebAssemblyLoadAllGlobalizationData>
<_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(InvariantGlobalization)' != 'true' AND '$(HybridGlobalization)' != 'true'">$(BlazorWebAssemblyLoadAllGlobalizationData)</_BlazorWebAssemblyLoadAllGlobalizationData>
<_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(_BlazorWebAssemblyLoadAllGlobalizationData)' == ''">false</_BlazorWebAssemblyLoadAllGlobalizationData>
<_IsHybridGlobalization Condition="'$(InvariantGlobalization)' != 'true' AND '$(HybridGlobalization)' == 'true'"></_IsHybridGlobalization>
<_IsHybridGlobalization>$(HybridGlobalization)</_IsHybridGlobalization>
<_IsHybridGlobalization Condition="'$(InvariantGlobalization)' == 'true' OR '$(HybridGlobalization)' == ''">false</_IsHybridGlobalization>
<_BlazorIcuDataFileName Condition="'$(InvariantGlobalization)' != 'true' AND '$(BlazorWebAssemblyLoadAllGlobalizationData)' != 'true' AND '$(HybridGlobalization)' != 'true'">$(BlazorIcuDataFileName)</_BlazorIcuDataFileName>
<_LoadCustomIcuData>false</_LoadCustomIcuData>
<_LoadCustomIcuData Condition="'$(_BlazorIcuDataFileName)' != ''">true</_LoadCustomIcuData>
Expand Down Expand Up @@ -240,6 +242,8 @@ Copyright (c) .NET Foundation. All rights reserved.
ProjectSatelliteAssemblies="@(IntermediateSatelliteAssembliesWithTargetPath)"
TimeZoneSupport="$(_BlazorEnableTimeZoneSupport)"
InvariantGlobalization="$(_WasmInvariantGlobalization)"
HybridGlobalization="$(_IsHybridGlobalization)"
LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)"
DotNetJsVersion="$(_WasmRuntimePackVersion)"
CopySymbols="$(_WasmCopyOutputSymbolsToOutputDirectory)"
OutputPath="$(OutputPath)"
Expand Down Expand Up @@ -366,7 +370,7 @@ Copyright (c) .NET Foundation. All rights reserved.
InvariantGlobalization="$(InvariantGlobalization)"
LoadCustomIcuData="$(_LoadCustomIcuData)"
IsHybridGlobalization="$(_IsHybridGlobalization)"
LoadAllICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)"
LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)"
StartupMemoryCache="$(_BlazorWebAssemblyStartupMemoryCache)"
Jiterpreter="$(_BlazorWebAssemblyJiterpreter)"
RuntimeOptions="$(_BlazorWebAssemblyRuntimeOptions)"
Expand Down Expand Up @@ -414,6 +418,8 @@ Copyright (c) .NET Foundation. All rights reserved.
PublishPath="$(PublishDir)"
WasmAotAssets="@(WasmNativeAsset)"
InvariantGlobalization="$(_WasmInvariantGlobalization)"
HybridGlobalization="$(_IsHybridGlobalization)"
LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)"
CopySymbols="$(CopyOutputSymbolsToPublishDirectory)"
ExistingAssets="@(_WasmPublishPrefilteredAssets)"
DotNetJsVersion="$(_WasmRuntimePackVersion)"
Expand Down Expand Up @@ -557,7 +563,7 @@ Copyright (c) .NET Foundation. All rights reserved.
InvariantGlobalization="$(InvariantGlobalization)"
LoadCustomIcuData="$(_LoadCustomIcuData)"
IsHybridGlobalization="$(_IsHybridGlobalization)"
LoadAllICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)"
LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)"
StartupMemoryCache="$(_BlazorWebAssemblyStartupMemoryCache)"
Jiterpreter="$(_BlazorWebAssemblyJiterpreter)"
RuntimeOptions="$(_BlazorWebAssemblyRuntimeOptions)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ public record BlazorBuildOptions
bool WarnAsError = true,
bool ExpectRelinkDirWhenPublishing = false,
bool ExpectFingerprintOnDotnetJs = false,
RuntimeVariant RuntimeType = RuntimeVariant.SingleThreaded
RuntimeVariant RuntimeType = RuntimeVariant.SingleThreaded,
GlobalizationMode GlobalizationMode = GlobalizationMode.Sharded,
string PredefinedIcudt = ""
);
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ public void AssertBundle(BlazorBuildOptions options)
IsPublish: options.IsPublish,
TargetFramework: options.TargetFramework,
BinFrameworkDir: FindBinFrameworkDir(options.Config, options.IsPublish, options.TargetFramework),
GlobalizationMode: GlobalizationMode.Sharded,
PredefinedIcudt: null,
GlobalizationMode: options.GlobalizationMode,
PredefinedIcudt: options.PredefinedIcudt,
ExpectFingerprintOnDotnetJs: options.ExpectFingerprintOnDotnetJs,
ExpectedFileType: options.ExpectedFileType,
RuntimeType: options.RuntimeType,
AssertIcuAssets: false, // FIXME: this is broken right now
AssertIcuAssets: true,
AssertSymbolsFile: false // FIXME: not supported yet
));
}
134 changes: 134 additions & 0 deletions src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.IO;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;
using System.Collections.Generic;
using System.Threading.Tasks;

#nullable enable

namespace Wasm.Build.Tests.Blazor;

// these tests only check if correct ICU files got copied
public class IcuTests : BlazorWasmTestBase
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
{
public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
: base(output, buildContext) {}

[Theory]
[InlineData("Debug", false)]
[InlineData("Debug", true)]
[InlineData("Debug", null)]
[InlineData("Release", false)]
[InlineData("Release", true)]
[InlineData("Release", null)]
public async Task HybridWithInvariant(string config, bool? invariant)
{
string id = $"blz_hybrid_{config}_{GetRandomId()}";
string projectFile = CreateBlazorWasmTemplateProject(id);
string extraProperties = "<HybridGlobalization>true</HybridGlobalization>";
if (invariant != null)
extraProperties += $"<InvariantGlobalization>{invariant}</InvariantGlobalization>";
AddItemsPropertiesToProject(projectFile, extraProperties: extraProperties);

(CommandResult res, string logPath) = BlazorBuild(
new BlazorBuildOptions(
id,
config,
WarnAsError: false,
radical marked this conversation as resolved.
Show resolved Hide resolved
GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid,
ExpectedFileType: invariant == true ? NativeFilesType.Relinked : NativeFilesType.FromRuntimePack
));

string warning = "$(HybridGlobalization) has no effect when $(InvariantGlobalization) is set to true.";
if (invariant == true)
{
Assert.Contains(warning, res.Output);
}
else
{
Assert.DoesNotContain(warning, res.Output);
}

await BlazorRunForBuildWithDotnetRun(new BlazorRunOptions() { Config = config });
}

[Theory]
[InlineData("Debug", false)]
[InlineData("Debug", true)]
[InlineData("Debug", null)]
[InlineData("Release", false)]
[InlineData("Release", true)]
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
[InlineData("Release", null)]
public async Task HybridWithFullIcuFromRuntimePack(string config, bool? fullIcu)
{
string id = $"blz_hybrid_{config}_{GetRandomId()}";
string projectFile = CreateBlazorWasmTemplateProject(id);
string extraProperties = "<HybridGlobalization>true</HybridGlobalization>";
if (fullIcu != null)
extraProperties += $"<BlazorWebAssemblyLoadAllGlobalizationData>{fullIcu}</BlazorWebAssemblyLoadAllGlobalizationData>";
AddItemsPropertiesToProject(projectFile, extraProperties: extraProperties);

(CommandResult res, string logPath) = BlazorBuild(
new BlazorBuildOptions(
id,
config,
WarnAsError: false,
GlobalizationMode: GlobalizationMode.Hybrid
));

string warning = "$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(HybridGlobalization) is set to true.";
if (fullIcu == true)
{
Assert.Contains(warning, res.Output);
}
else
{
Assert.DoesNotContain(warning, res.Output);
}

await BlazorRunForBuildWithDotnetRun(new BlazorRunOptions() { Config = config });
}

[Theory]
[InlineData("Debug", false)]
[InlineData("Debug", true)]
[InlineData("Debug", null)]
[InlineData("Release", false)]
[InlineData("Release", true)]
[InlineData("Release", null)]
public async Task FullIcuFromRuntimePackWithInvariant(string config, bool? invariant)
{
string id = $"blz_hybrid_{config}_{GetRandomId()}";
string projectFile = CreateBlazorWasmTemplateProject(id);
string extraProperties = "<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>";
if (invariant != null)
extraProperties += $"<InvariantGlobalization>{invariant}</InvariantGlobalization>";
AddItemsPropertiesToProject(projectFile, extraProperties: extraProperties);

(CommandResult res, string logPath) = BlazorBuild(
new BlazorBuildOptions(
id,
config,
WarnAsError: false,
GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu,
ExpectedFileType: invariant == true ? NativeFilesType.Relinked : NativeFilesType.FromRuntimePack
));

string warning = "$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(InvariantGlobalization) is set to true.";
if (invariant == true)
{
Assert.Contains(warning, res.Output);
}
else
{
Assert.DoesNotContain(warning, res.Output);
}

await BlazorRunForBuildWithDotnetRun(new BlazorRunOptions() { Config = config });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public enum GlobalizationMode
Sharded, // chosen based on locale
Invariant, // no icu
FullIcu, // full icu data: icudt.dat is loaded
PredefinedIcu, // user set WasmIcuDataFileName value and we are loading that file
PredefinedIcu, // user set WasmIcuDataFileName/BlazorIcuDataFileName value and we are loading that file
Hybrid // reduced icu, missing data is provided by platform-native functions (web api for wasm)
};
5 changes: 4 additions & 1 deletion src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ public IReadOnlyDictionary<string, DotNetFileName> AssertBasicBundle(AssertBundl
// icu
if (assertOptions.AssertIcuAssets)
{
_testOutput.WriteLine("Skipping asserting icu assets");
AssertIcuAssets(assertOptions);
}
else
{
_testOutput.WriteLine("Skipping asserting icu assets");
}

// symbols
if (assertOptions.AssertSymbolsFile)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,19 @@ public class AssetsComputingHelper
"dotnet.runtime"
};

private static readonly string[] icuShardsFromRuntimePack = new[]
{
"icudt_EFIGS",
"icudt_CJK",
"icudt_no_CJK"
};

public static bool ShouldFilterCandidate(
ITaskItem candidate,
bool timezoneSupport,
bool invariantGlobalization,
bool hybridGlobalization,
bool loadFullICUData,
bool copySymbols,
string customIcuCandidateFilename,
bool enableThreads,
Expand All @@ -53,7 +62,10 @@ public static bool ShouldFilterCandidate(
".props" when fromMonoPackage => "extension is .props is not supported.",
".blat" when !timezoneSupport => "timezone support is not enabled.",
".dat" when invariantGlobalization && fileName.StartsWith("icudt") => "invariant globalization is enabled",
".dat" when loadFullICUData && fileName != "icudt" => "full ICU data is enabled",
".dat" when hybridGlobalization && fileName != "icudt_hybrid" => "hybrid globalization is enabled",
".dat" when !string.IsNullOrEmpty(customIcuCandidateFilename) && fileName != customIcuCandidateFilename => "custom icu file will be used instead of icu from the runtime pack",
".dat" when IsDefaultIcuMode() && !(icuShardsFromRuntimePack.Any(f => f == fileName)) => "automatic icu shard selection, based on application culture, is enabled",
".json" when fromMonoPackage && (fileName == "emcc-props" || fileName == "package") => $"{fileName}{extension} is not used by Blazor",
".ts" when fromMonoPackage && fileName == "dotnet.d" => "dotnet type definition is not used by Blazor",
".map" when !emitSourceMap && fromMonoPackage && (fileName == "dotnet.js" || fileName == "dotnet.runtime.js") => "source map file is not published",
Expand All @@ -65,6 +77,12 @@ public static bool ShouldFilterCandidate(
};

return reason != null;

bool IsDefaultIcuMode() =>
!invariantGlobalization &&
!loadFullICUData &&
!hybridGlobalization &&
string.IsNullOrEmpty(customIcuCandidateFilename);
}

private static bool IsFromMonoPackage(ITaskItem candidate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ public class ComputeWasmBuildAssets : Task
[Required]
public bool InvariantGlobalization { get; set; }

[Required]
public bool HybridGlobalization { get; set; }

[Required]
public bool LoadFullICUData { get; set; }

[Required]
public bool CopySymbols { get; set; }

Expand Down Expand Up @@ -86,7 +92,7 @@ public override bool Execute()
for (int i = 0; i < Candidates.Length; i++)
{
var candidate = Candidates[i];
if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason))
if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, HybridGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason))
{
Log.LogMessage(MessageImportance.Low, "Skipping asset '{0}' because '{1}'", candidate.ItemSpec, reason);
filesToRemove.Add(candidate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ public class ComputeWasmPublishAssets : Task
[Required]
public bool InvariantGlobalization { get; set; }

[Required]
public bool HybridGlobalization { get; set; }

[Required]
public bool LoadFullICUData { get; set; }

[Required]
public bool CopySymbols { get; set; }

Expand Down Expand Up @@ -577,7 +583,7 @@ private void GroupResolvedFilesToPublish(
foreach (var candidate in resolvedFilesToPublish)
{
#pragma warning disable CA1864 // Prefer the 'IDictionary.TryAdd(TKey, TValue)' method. Dictionary.TryAdd() not available in .Net framework.
if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason))
if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, HybridGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason))
{
Log.LogMessage(MessageImportance.Low, "Skipping asset '{0}' because '{1}'", candidate.ItemSpec, reason);
if (!resolvedFilesToPublishToRemove.ContainsKey(candidate.ItemSpec))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class GenerateWasmBootJson : Task
[Required]
public bool CacheBootResources { get; set; }

public bool LoadAllICUData { get; set; }
public bool LoadFullICUData { get; set; }

public bool IsHybridGlobalization { get; set; }

Expand Down Expand Up @@ -386,7 +386,7 @@ private GlobalizationMode GetGlobalizationMode()
return GlobalizationMode.Invariant;
else if (IsHybridGlobalization)
return GlobalizationMode.Hybrid;
else if (LoadAllICUData)
else if (LoadFullICUData)
return GlobalizationMode.All;
else if (LoadCustomIcuData)
return GlobalizationMode.Custom;
Expand Down
Loading