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

[browser] Fix fingerprinting of relinked dotnet.js - follow up #87051

Merged
merged 9 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -187,18 +187,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>
maraf marked this conversation as resolved.
Show resolved Hide resolved

<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 @@ -209,7 +213,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 @@ -352,7 +356,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 @@ -366,14 +370,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 @@ -383,7 +379,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 @@ -824,7 +826,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 @@ -856,12 +858,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 @@ -1290,7 +1301,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