Skip to content

Commit

Permalink
[browser] Fix fingerprinting of relinked dotnet.js - follow up (dotne…
Browse files Browse the repository at this point in the history
…t#87051)

Address comments from dotnet#86048
  • Loading branch information
maraf authored Jun 8, 2023
1 parent 2835110 commit 5ebb520
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -191,18 +191,22 @@ Copyright (c) .NET Foundation. All rights reserved.

<Target Name="ResolveWasmOutputs" DependsOnTargets="_ResolveWasmOutputs" />

<Target Name="_ResolveWasmOutputs" DependsOnTargets="ResolveReferences;PrepareResourceNames;ComputeIntermediateSatelliteAssemblies;_ResolveWasmConfiguration;_WasmNativeForBuild">
<Target Name="_GetWasmRuntimePackVersion">
<PropertyGroup>
<_WasmRuntimePackVersion>%(ResolvedRuntimePack.NuGetPackageVersion)</_WasmRuntimePackVersion>
</PropertyGroup>

<Error Code="WASM0005" Message="Unnable to resolve WebAssembly runtime pack version" Condition="'$(_WasmRuntimePackVersion)' == ''" />
</Target>

<Target Name="_ResolveWasmOutputs" DependsOnTargets="ResolveReferences;PrepareResourceNames;ComputeIntermediateSatelliteAssemblies;_ResolveWasmConfiguration;_WasmNativeForBuild;_GetWasmRuntimePackVersion">
<ItemGroup>
<_WasmConfigFileCandidates Include="@(StaticWebAsset)" Condition="'%(SourceType)' == 'Discovered'" />
<_DotNetJsItem Include="@(ReferenceCopyLocalPaths)" Condition="('%(FileName)' == 'dotnet' or '%(FileName)' == 'dotnet.native') and '%(Extension)' == '.js'" />

<!-- Remove dotnet.js/wasm from runtime pack, in favor of the relinked ones in @(WasmNativeAsset) -->
<ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)"
Condition="@(WasmNativeAsset->Count()) > 0 and ( '%(FileName)' == 'dotnet' or '%(FileName)' == 'dotnet.native' ) and ('%(Extension)' == '.wasm' or '%(Extension)' == '.js')" />
</ItemGroup>
<PropertyGroup>
<_DotNetJsBuildVersion>%(_DotNetJsItem.NuGetPackageVersion)</_DotNetJsBuildVersion>
</PropertyGroup>

<ComputeWasmBuildAssets
Candidates="@(ReferenceCopyLocalPaths->Distinct());@(WasmNativeAsset)"
Expand All @@ -213,7 +217,7 @@ Copyright (c) .NET Foundation. All rights reserved.
ProjectSatelliteAssemblies="@(IntermediateSatelliteAssembliesWithTargetPath)"
TimeZoneSupport="$(_BlazorEnableTimeZoneSupport)"
InvariantGlobalization="$(_WasmInvariantGlobalization)"
DotNetJsVersion="$(_DotNetJsBuildVersion)"
DotNetJsVersion="$(_WasmRuntimePackVersion)"
CopySymbols="$(_WasmCopyOutputSymbolsToOutputDirectory)"
OutputPath="$(OutputPath)"
FingerprintDotNetJs="$(WasmFingerprintDotnetJs)"
Expand Down Expand Up @@ -357,7 +361,7 @@ Copyright (c) .NET Foundation. All rights reserved.
BeforeTargets="PrepareForPublish" />

<!-- Wasm's Nested publish is run just to build the native bits. We don't need to run blazor targets for that -->
<Target Name="ProcessPublishFilesForWasm" DependsOnTargets="_ResolveWasmConfiguration;LoadStaticWebAssetsBuildManifest" AfterTargets="ILLink" Condition="'$(WasmBuildingForNestedPublish)' != 'true'">
<Target Name="ProcessPublishFilesForWasm" DependsOnTargets="_ResolveWasmConfiguration;LoadStaticWebAssetsBuildManifest;_GetWasmRuntimePackVersion" AfterTargets="ILLink" Condition="'$(WasmBuildingForNestedPublish)' != 'true'">
<!-- The list of static web assets already contains all the assets from the build. We want to correct certain assets that might
have changed as part of the publish process. We are going to do so as follows:
* We will update Blazor runtime asset dlls if we are running PublishTrimmed
Expand All @@ -371,14 +375,6 @@ Copyright (c) .NET Foundation. All rights reserved.
Condition="'%(StaticWebAsset.AssetTraitName)' == 'WasmResource' or '%(StaticWebAsset.AssetTraitName)' == 'Culture' or '%(AssetRole)' == 'Alternative'" />
</ItemGroup>

<ItemGroup>
<_DotNetJsItem Include="@(ResolvedFileToPublish)" Condition="'%(ResolvedFileToPublish.DestinationSubPath)' == 'dotnet.js' AND '%(ResolvedFileToPublish.AssetType)' == 'native'" />
</ItemGroup>

<PropertyGroup>
<_DotNetJsVersion>%(_DotNetJsItem.NuGetPackageVersion)</_DotNetJsVersion>
</PropertyGroup>

<ComputeWasmPublishAssets
ResolvedFilesToPublish="@(ResolvedFileToPublish)"
CustomIcuCandidate="$(_BlazorIcuDataFileName)"
Expand All @@ -388,7 +384,7 @@ Copyright (c) .NET Foundation. All rights reserved.
InvariantGlobalization="$(_WasmInvariantGlobalization)"
CopySymbols="$(CopyOutputSymbolsToPublishDirectory)"
ExistingAssets="@(_WasmPublishPrefilteredAssets)"
DotNetJsVersion="$(_DotNetJsVersion)"
DotNetJsVersion="$(_WasmRuntimePackVersion)"
FingerprintDotNetJs="$(WasmFingerprintDotnetJs)"
EnableThreads="$(_WasmEnableThreads)"
IsWebCilEnabled="$(_WasmEnableWebcil)"
Expand Down
37 changes: 22 additions & 15 deletions src/mono/wasm/Wasm.Build.Tests/Blazor/BuildPublishTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// 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 System.Linq;
using System.Text.Json;
Expand Down Expand Up @@ -65,15 +66,21 @@ public void DefaultTemplate_NoAOT_WithWorkload(string config)
}

[Theory]
[InlineData("Debug")]
[InlineData("Release")]
public void DefaultTemplate_BuildNative_WithWorkload(string config)
[InlineData("Debug", false)]
[InlineData("Release", false)]
[InlineData("Debug", true)]
[InlineData("Release", true)]
public void DefaultTemplate_CheckFingerprinting(string config, bool expectFingerprintOnDotnetJs)
{
string id = $"blz_buildandbuildnative_{config}_{Path.GetRandomFileName()}";
string id = $"blz_checkfingerprinting_{config}_{Path.GetRandomFileName()}";

CreateBlazorWasmTemplateProject(id);

BlazorBuild(new BlazorBuildOptions(id, config, NativeFilesType.Relinked), "/p:WasmBuildNative=true");
var options = new BlazorBuildOptions(id, config, NativeFilesType.Relinked, ExpectRelinkDirWhenPublishing: true, ExpectFingerprintOnDotnetJs: expectFingerprintOnDotnetJs);
var finterprintingArg = expectFingerprintOnDotnetJs ? "/p:WasmFingerprintDotnetJs=true" : string.Empty;

BlazorBuild(options, "/p:WasmBuildNative=true", finterprintingArg);
BlazorPublish(options, "/p:WasmBuildNative=true", finterprintingArg);
}

// Disabling for now - publish folder can have more than one dotnet*hash*js, and not sure
Expand All @@ -83,18 +90,18 @@ public void DefaultTemplate_BuildNative_WithWorkload(string config)
//[InlineData("Release")]
//public void DefaultTemplate_AOT_OnlyWithPublishCommandLine_Then_PublishNoAOT(string config)
//{
//string id = $"blz_aot_pub_{config}";
//CreateBlazorWasmTemplateProject(id);
//string id = $"blz_aot_pub_{config}";
//CreateBlazorWasmTemplateProject(id);

//// No relinking, no AOT
//BlazorBuild(new BlazorBuildOptions(id, config, NativeFilesType.FromRuntimePack);
//// No relinking, no AOT
//BlazorBuild(new BlazorBuildOptions(id, config, NativeFilesType.FromRuntimePack);

//// AOT=true only for the publish command line, similar to what
//// would happen when setting it in Publish dialog for VS
//BlazorPublish(new BlazorBuildOptions(id, config, expectedFileType: NativeFilesType.AOT, "-p:RunAOTCompilation=true");
//// AOT=true only for the publish command line, similar to what
//// would happen when setting it in Publish dialog for VS
//BlazorPublish(new BlazorBuildOptions(id, config, expectedFileType: NativeFilesType.AOT, "-p:RunAOTCompilation=true");

//// publish again, no AOT
//BlazorPublish(new BlazorBuildOptions(id, config, NativeFilesType.Relinked);
//// publish again, no AOT
//BlazorPublish(new BlazorBuildOptions(id, config, NativeFilesType.Relinked);
//}

[Theory]
Expand Down Expand Up @@ -212,7 +219,7 @@ public void BugRegression_60479_WithRazorClassLib()
string razorClassLibraryFileName = UseWebcil ? $"RazorClassLibrary{WebcilInWasmExtension}" : "RazorClassLibrary.dll";
AddItemsPropertiesToProject(wasmProjectFile, extraItems: @$"
<ProjectReference Include=""..\\RazorClassLibrary\\RazorClassLibrary.csproj"" />
<BlazorWebAssemblyLazyLoad Include=""{ razorClassLibraryFileName }"" />
<BlazorWebAssemblyLazyLoad Include=""{razorClassLibraryFileName}"" />
");

_projectDir = wasmProjectDir;
Expand Down
30 changes: 21 additions & 9 deletions src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,8 @@ public string CreateBlazorWasmTemplateProject(string id)
AssertBlazorBundle(options.Config,
isPublish: false,
dotnetWasmFromRuntimePack: options.ExpectedFileType == NativeFilesType.FromRuntimePack,
targetFramework: options.TargetFramework);
targetFramework: options.TargetFramework,
expectFingerprintOnDotnetJs: options.ExpectFingerprintOnDotnetJs);

return res;
}
Expand All @@ -565,7 +566,8 @@ public string CreateBlazorWasmTemplateProject(string id)
AssertBlazorBundle(options.Config,
isPublish: true,
dotnetWasmFromRuntimePack: options.ExpectedFileType == NativeFilesType.FromRuntimePack,
targetFramework: options.TargetFramework);
targetFramework: options.TargetFramework,
expectFingerprintOnDotnetJs: options.ExpectFingerprintOnDotnetJs);

if (options.ExpectedFileType == NativeFilesType.AOT)
{
Expand All @@ -581,7 +583,7 @@ public string CreateBlazorWasmTemplateProject(string id)
string objBuildDir = Path.Combine(_projectDir!, "obj", options.Config, options.TargetFramework, "wasm", "for-build");
// Check that we linked only for publish
if (options.ExpectRelinkDirWhenPublishing)
Assert.True(Directory.Exists(objBuildDir), $"Could not find expected {objBuildDir}, which gets created when relinking during Build. This is liokely a test authoring error");
Assert.True(Directory.Exists(objBuildDir), $"Could not find expected {objBuildDir}, which gets created when relinking during Build. This is likely a test authoring error");
else
Assert.False(Directory.Exists(objBuildDir), $"Found unexpected {objBuildDir}, which gets created when relinking during Build");

Expand Down Expand Up @@ -829,7 +831,7 @@ protected static void AssertFile(string file0, string file1, string? label = nul
return result;
}

protected void AssertBlazorBundle(string config, bool isPublish, bool dotnetWasmFromRuntimePack, string targetFramework = DefaultTargetFrameworkForBlazor, string? binFrameworkDir = null, bool expectFingerprinting = false)
protected void AssertBlazorBundle(string config, bool isPublish, bool dotnetWasmFromRuntimePack, string targetFramework = DefaultTargetFrameworkForBlazor, string? binFrameworkDir = null, bool expectFingerprintOnDotnetJs = false)
{
binFrameworkDir ??= FindBlazorBinFrameworkDir(config, isPublish, targetFramework);

Expand Down Expand Up @@ -861,12 +863,21 @@ void AssertFileExists(string fileName)
Assert.True(File.Exists(absolutePath), $"Expected to find '{absolutePath}'");
}

string versionHashRegex = @"\d.0.\d?(-[a-z]+(\.\d\.\d+\.\d)?)?\.([a-zA-Z0-9])+";
string versionHashRegex = @"\.(?<version>.+)\.(?<hash>[a-zA-Z0-9]+)\.";

Assert.Collection(
dotnetJsEntries.OrderBy(f => f),
item => { Assert.Equal(expectFingerprinting ? $"dotnet\\.{versionHashRegex}\\.js" : "dotnet.js", item); AssertFileExists(item); },
item => { Assert.Matches($"dotnet\\.native\\.{versionHashRegex}\\.js", item); AssertFileExists(item); },
item => { Assert.Matches($"dotnet\\.runtime\\.{versionHashRegex}\\.js", item); AssertFileExists(item); }
item =>
{
if (expectFingerprintOnDotnetJs)
Assert.Matches($"dotnet{versionHashRegex}js", item);
else
Assert.Equal("dotnet.js", item);

AssertFileExists(item);
},
item => { Assert.Matches($"dotnet\\.native{versionHashRegex}js", item); AssertFileExists(item); },
item => { Assert.Matches($"dotnet\\.runtime{versionHashRegex}js", item); AssertFileExists(item); }
);
}
}
Expand Down Expand Up @@ -1295,7 +1306,8 @@ public record BlazorBuildOptions
NativeFilesType ExpectedFileType,
string TargetFramework = BuildTestBase.DefaultTargetFrameworkForBlazor,
bool WarnAsError = true,
bool ExpectRelinkDirWhenPublishing = false
bool ExpectRelinkDirWhenPublishing = false,
bool ExpectFingerprintOnDotnetJs = false
);

public enum GlobalizationMode
Expand Down

0 comments on commit 5ebb520

Please sign in to comment.