From 57b5a97d2df7eb924701d3419e1ce17eeb5a11a3 Mon Sep 17 00:00:00 2001 From: Tanay Parikh Date: Thu, 10 Nov 2022 09:44:30 -0800 Subject: [PATCH] [release/6.0.1xx] Backport Add Blazor SWA Baseline Mismatched Assets Logging (#28894) * Add Blazor SWA Baseline Mismatched Assets Logging (#27542) * Add Blazor AssetDifferencesDetails * Update AspNetSdkBaselineTest.cs For https://github.com/dotnet/sdk/issues/27346 * Spacing * Create blazor-swa-baseline-generation.md * PR Feedback * Remove instructions add script reference * Property level comparison * Added instructions * Update AspNetSdkBaselineTest.cs * Update AspNetSdkBaselineTest.cs (cherry picked from commit bacc17c6f704a4a21d754e0299663b52fa7f72e6) * Create update-test-baselines.ps1 --- src/RazorSdk/update-test-baselines.ps1 | 6 + .../AspNetSdkBaselineTest.cs | 149 +++++++++++++++++- 2 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 src/RazorSdk/update-test-baselines.ps1 diff --git a/src/RazorSdk/update-test-baselines.ps1 b/src/RazorSdk/update-test-baselines.ps1 new file mode 100644 index 000000000000..38c7e9553632 --- /dev/null +++ b/src/RazorSdk/update-test-baselines.ps1 @@ -0,0 +1,6 @@ +$RepoRoot= Resolve-Path "$PSScriptRoot/../.." + +$TestProjects = "Microsoft.NET.Sdk.Razor.Tests", "Microsoft.NET.Sdk.BlazorWebAssembly.Tests" | + ForEach-Object { Join-Path -Path "$RepoRoot/src/Tests/" -ChildPath $_ }; + +$TestProjects | ForEach-Object { dotnet test --no-build -l "console;verbosity=normal" $_ -e ASPNETCORE_TEST_BASELINES=true --filter AspNetCore=BaselineTest } diff --git a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/AspNetSdkBaselineTest.cs b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/AspNetSdkBaselineTest.cs index 4fcddc09d826..f43982291904 100644 --- a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/AspNetSdkBaselineTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/AspNetSdkBaselineTest.cs @@ -21,6 +21,18 @@ namespace Microsoft.NET.Sdk.Razor.Tests public class AspNetSdkBaselineTest : AspNetSdkTest { private static readonly JsonSerializerOptions BaselineSerializationOptions = new() { WriteIndented = true }; + private static readonly string BaselineGenerationInstructions = + @"If the difference in baselines is expected, please re-generate the baselines. +Note, baseline generation must be done on a Windows device. +Start by ensuring you're dogfooding the SDK from the current branch (dotnet --version should be '*.0.0-dev'). + If you're not on the dogfood sdk, from the root of the repository run: + 1. dotnet clean + 2. .\restore.cmd + 3. .\build.cmd + 4. .\eng\dogfood.cmd + +Then, using the dogfood SDK run the .\src\RazorSdk\update-test-baselines.ps1 script."; + protected static readonly string DotNetJSHashRegexPattern = "\\.[a-z0-9]{10}\\.js"; protected static readonly string DotNetJSHashTemplate = ".[[hash]].js"; @@ -352,12 +364,144 @@ internal void AssertManifest( manifest.BasePath.Should().Be(expected.BasePath); manifest.Mode.Should().Be(expected.Mode); manifest.ManifestType.Should().Be(expected.ManifestType); + manifest.ReferencedProjectsConfiguration.OrderBy(cm => cm.Identity) .Should() .BeEquivalentTo(expected.ReferencedProjectsConfiguration.OrderBy(cm => cm.Identity)); manifest.DiscoveryPatterns.OrderBy(dp => dp.Name).ShouldBeEquivalentTo(expected.DiscoveryPatterns.OrderBy(dp => dp.Name)); - manifest.Assets.OrderBy(a => a.BasePath).ThenBy(a => a.RelativePath).ThenBy(a => a.AssetKind) - .ShouldBeEquivalentTo(expected.Assets.OrderBy(a => a.BasePath).ThenBy(a => a.RelativePath).ThenBy(a => a.AssetKind)); + + var manifestAssets = manifest.Assets.OrderBy(a => a.BasePath).ThenBy(a => a.RelativePath).ThenBy(a => a.AssetKind); + var expectedAssets = expected.Assets.OrderBy(a => a.BasePath).ThenBy(a => a.RelativePath).ThenBy(a => a.AssetKind); + + // If there's a mismatch in the number of assets, just print the strict difference in the asset `Identity` + if (manifestAssets.Count() != expectedAssets.Count()) + { + ThrowAssetCountMismatchError(manifestAssets, expectedAssets); + } + + // Otherwise, do a property level comparison of all assets + var manifestAssetsEnumerator = manifestAssets.GetEnumerator(); + var expectedAssetsEnumerator = expectedAssets.GetEnumerator(); + + var differences = new List(); + + do + { + var manifestAsset = manifestAssetsEnumerator.Current; + var expectedAsset = expectedAssetsEnumerator.Current; + + if (manifestAsset is null && expectedAsset is null) + { + continue; + } + + var assetDifferences = new List(); + + if (manifestAsset.Identity != expectedAsset.Identity) + { + assetDifferences.Add($"Expected manifest Identity of {expectedAsset.Identity} but found {manifestAsset.Identity}."); + } + if (manifestAsset.SourceType != expectedAsset.SourceType) + { + assetDifferences.Add($"Expected manifest SourceType of {expectedAsset.SourceType} but found {manifestAsset.SourceType}."); + } + if (manifestAsset.SourceId != expectedAsset.SourceId) + { + assetDifferences.Add($"Expected manifest SourceId of {expectedAsset.SourceId} but found {manifestAsset.SourceId}."); + } + if (manifestAsset.ContentRoot != expectedAsset.ContentRoot) + { + assetDifferences.Add($"Expected manifest ContentRoot of {expectedAsset.ContentRoot} but found {manifestAsset.ContentRoot}."); + } + if (manifestAsset.BasePath != expectedAsset.BasePath) + { + assetDifferences.Add($"Expected manifest BasePath of {expectedAsset.BasePath} but found {manifestAsset.BasePath}."); + } + if (manifestAsset.RelativePath != expectedAsset.RelativePath) + { + assetDifferences.Add($"Expected manifest RelativePath of {expectedAsset.RelativePath} but found {manifestAsset.RelativePath}."); + } + if (manifestAsset.AssetKind != expectedAsset.AssetKind) + { + assetDifferences.Add($"Expected manifest AssetKind of {expectedAsset.AssetKind} but found {manifestAsset.AssetKind}."); + } + if (manifestAsset.AssetMode != expectedAsset.AssetMode) + { + assetDifferences.Add($"Expected manifest AssetMode of {expectedAsset.AssetMode} but found {manifestAsset.AssetMode}."); + } + if (manifestAsset.AssetRole != expectedAsset.AssetRole) + { + assetDifferences.Add($"Expected manifest AssetRole of {expectedAsset.AssetRole} but found {manifestAsset.AssetRole}."); + } + if (manifestAsset.RelatedAsset != expectedAsset.RelatedAsset) + { + assetDifferences.Add($"Expected manifest RelatedAsset of {expectedAsset.RelatedAsset} but found {manifestAsset.RelatedAsset}."); + } + if (manifestAsset.AssetTraitName != expectedAsset.AssetTraitName) + { + assetDifferences.Add($"Expected manifest AssetTraitName of {expectedAsset.AssetTraitName} but found {manifestAsset.AssetTraitName}."); + } + if (manifestAsset.AssetTraitValue != expectedAsset.AssetTraitValue) + { + assetDifferences.Add($"Expected manifest AssetTraitValue of {expectedAsset.AssetTraitValue} but found {manifestAsset.AssetTraitValue}."); + } + if (manifestAsset.CopyToOutputDirectory != expectedAsset.CopyToOutputDirectory) + { + assetDifferences.Add($"Expected manifest CopyToOutputDirectory of {expectedAsset.CopyToOutputDirectory} but found {manifestAsset.CopyToOutputDirectory}."); + } + if (manifestAsset.CopyToPublishDirectory != expectedAsset.CopyToPublishDirectory) + { + assetDifferences.Add($"Expected manifest CopyToPublishDirectory of {expectedAsset.CopyToPublishDirectory} but found {manifestAsset.CopyToPublishDirectory}."); + } + if (manifestAsset.OriginalItemSpec != expectedAsset.OriginalItemSpec) + { + assetDifferences.Add($"Expected manifest OriginalItemSpec of {expectedAsset.OriginalItemSpec} but found {manifestAsset.OriginalItemSpec}."); + } + + if (assetDifferences.Any()) + { + differences.Add(@$" +================================================== + +For {expectedAsset.Identity}: + +{string.Join(Environment.NewLine, assetDifferences)} + +=================================================="); + } + + } while (manifestAssetsEnumerator.MoveNext() && expectedAssetsEnumerator.MoveNext()); + + differences.Should().BeEmpty( + @$" the generated manifest should match the expected baseline. + +{BaselineGenerationInstructions} + +"); + + static void ThrowAssetCountMismatchError(IEnumerable manifestAssets, IEnumerable expectedAssets) + { + var missingAssets = expectedAssets.Except(manifestAssets); + var unexpectedAssets = manifestAssets.Except(expectedAssets); + + var differences = new List(); + + if (missingAssets.Any()) + { + differences.Add($@"The following expected assets weren't found in the manifest: + {string.Join($"{Environment.NewLine}\t", missingAssets.Select(a => a.Identity))}"); + } + + if (unexpectedAssets.Any()) + { + differences.Add($@"The following additional unexpected assets were found in the manifest: + {string.Join($"{Environment.NewLine}\t", unexpectedAssets.Select(a => a.Identity))}"); + } + + throw new Exception($@"{string.Join(Environment.NewLine, differences)} + +{BaselineGenerationInstructions}"); + } } else { @@ -528,3 +672,4 @@ string TemplatizeRestorePath(string restorePath, string property) } } } +