diff --git a/eng/testing/scenarios/BuildWasmAppsJobsList.txt b/eng/testing/scenarios/BuildWasmAppsJobsList.txt
index e16c74fe4f0750..9bb06b872bb6c9 100644
--- a/eng/testing/scenarios/BuildWasmAppsJobsList.txt
+++ b/eng/testing/scenarios/BuildWasmAppsJobsList.txt
@@ -43,3 +43,5 @@ Wasm.Build.Tests.WasmTemplateTests
Wasm.Build.Tests.WorkloadTests
Wasm.Build.Tests.TestAppScenarios.ModuleConfigTests
Wasm.Build.Tests.MT.Blazor.SimpleMultiThreadedTests
+Wasm.Build.Tests.TestAppScenarios.WasmSdkDebugLevelTests
+Wasm.Build.Tests.TestAppScenarios.WasmAppBuilderDebugLevelTests
diff --git a/eng/testing/tests.wasm.targets b/eng/testing/tests.wasm.targets
index 4dc6b71005449b..9e0fdaf3289e6f 100644
--- a/eng/testing/tests.wasm.targets
+++ b/eng/testing/tests.wasm.targets
@@ -15,10 +15,7 @@
But we do want to set it for Configuration=Debug .
-->
-1
-
- reset-to-zero
+ 0
full
true
diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
index 324f36cad7957f..b13b13a02bcffc 100644
--- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
+++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
@@ -212,9 +212,6 @@ Copyright (c) .NET Foundation. All rights reserved.
<_BlazorWebAssemblyStartupMemoryCache>$(BlazorWebAssemblyStartupMemoryCache)
<_BlazorWebAssemblyJiterpreter>$(BlazorWebAssemblyJiterpreter)
<_BlazorWebAssemblyRuntimeOptions>$(BlazorWebAssemblyRuntimeOptions)
- <_WasmDebugLevel>$(WasmDebugLevel)
- <_WasmDebugLevel Condition="'$(_WasmDebugLevel)' == ''">0
- <_WasmDebugLevel Condition="'$(_WasmDebugLevel)' == '0' and ('$(DebuggerSupport)' == 'true' or '$(Configuration)' == 'Debug')">-1
$(OutputPath)$(PublishDirName)\
@@ -373,7 +370,7 @@ Copyright (c) .NET Foundation. All rights reserved.
AssemblyPath="@(IntermediateAssembly)"
Resources="@(_WasmOutputWithHash)"
DebugBuild="true"
- DebugLevel="$(_WasmDebugLevel)"
+ DebugLevel="$(WasmDebugLevel)"
LinkerEnabled="false"
CacheBootResources="$(BlazorCacheBootResources)"
OutputPath="$(_WasmBuildBootJsonPath)"
@@ -389,7 +386,8 @@ Copyright (c) .NET Foundation. All rights reserved.
Extensions="@(WasmBootConfigExtension)"
TargetFrameworkVersion="$(TargetFrameworkVersion)"
ModuleAfterConfigLoaded="@(WasmModuleAfterConfigLoaded)"
- ModuleAfterRuntimeReady="@(WasmModuleAfterRuntimeReady)" />
+ ModuleAfterRuntimeReady="@(WasmModuleAfterRuntimeReady)"
+ IsPublish="false" />
@@ -566,7 +564,7 @@ Copyright (c) .NET Foundation. All rights reserved.
AssemblyPath="@(IntermediateAssembly)"
Resources="@(_WasmPublishBootResourceWithHash)"
DebugBuild="false"
- DebugLevel="$(_WasmDebugLevel)"
+ DebugLevel="$(WasmDebugLevel)"
LinkerEnabled="$(PublishTrimmed)"
CacheBootResources="$(BlazorCacheBootResources)"
OutputPath="$(IntermediateOutputPath)blazor.publish.boot.json"
@@ -582,7 +580,8 @@ Copyright (c) .NET Foundation. All rights reserved.
Extensions="@(WasmBootConfigExtension)"
TargetFrameworkVersion="$(TargetFrameworkVersion)"
ModuleAfterConfigLoaded="@(WasmModuleAfterConfigLoaded)"
- ModuleAfterRuntimeReady="@(WasmModuleAfterRuntimeReady)" />
+ ModuleAfterRuntimeReady="@(WasmModuleAfterRuntimeReady)"
+ IsPublish="true" />
diff --git a/src/mono/wasi/build/WasiApp.targets b/src/mono/wasi/build/WasiApp.targets
index 099ba8c3ebea27..c403cd718f55c6 100644
--- a/src/mono/wasi/build/WasiApp.targets
+++ b/src/mono/wasi/build/WasiApp.targets
@@ -368,6 +368,11 @@
+
+ <_WasmOutputSymbolsToAppBundle Condition="'$(CopyOutputSymbolsToPublishDirectory)' == 'true' and '$(_IsPublishing)' == 'true'">true
+ <_WasmOutputSymbolsToAppBundle Condition="'$(_WasmOutputSymbolsToAppBundle)' == ''">false
+
+
diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs
index 1d13051dd7344e..dbf0e848f75135 100644
--- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs
@@ -75,6 +75,10 @@ public string CreateBlazorWasmTemplateProject(string id)
if (options.ExpectSuccess && options.AssertAppBundle)
{
+ // Because we do relink in Release publish by default
+ if (options.Config == "Release")
+ options = options with { ExpectedFileType = NativeFilesType.Relinked };
+
AssertBundle(res.Output, options with { IsPublish = true });
}
diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppSettingsTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppSettingsTests.cs
index 96f2c4ebd6a1bf..5d028cc238909a 100644
--- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppSettingsTests.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppSettingsTests.cs
@@ -28,7 +28,7 @@ public async Task LoadAppSettingsBasedOnApplicationEnvironment(string applicatio
CopyTestAsset("WasmBasicTestApp", "AppSettingsTests");
PublishProject("Debug");
- var result = await RunSdkStyleApp(new(
+ var result = await RunSdkStyleAppForPublish(new(
Configuration: "Debug",
TestScenario: "AppSettingsTest",
BrowserQueryString: new Dictionary { ["applicationEnvironment"] = applicationEnvironment }
diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs
index dc6fb9b490e7f3..3b3baf581c185a 100644
--- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs
@@ -36,15 +36,15 @@ protected void CopyTestAsset(string assetName, string generatedProjectNamePrefix
_projectDir = Path.Combine(_projectDir!, "App");
}
- protected void BuildProject(string configuration)
+ protected void BuildProject(string configuration, bool assertAppBundle = true, params string[] extraArgs)
{
- (CommandResult result, _) = BlazorBuild(new BlazorBuildOptions(Id, configuration));
+ (CommandResult result, _) = BlazorBuild(new BlazorBuildOptions(Id, configuration, AssertAppBundle: assertAppBundle), extraArgs);
result.EnsureSuccessful();
}
- protected void PublishProject(string configuration)
+ protected void PublishProject(string configuration, bool assertAppBundle = true, params string[] extraArgs)
{
- (CommandResult result, _) = BlazorPublish(new BlazorBuildOptions(Id, configuration));
+ (CommandResult result, _) = BlazorPublish(new BlazorBuildOptions(Id, configuration, AssertAppBundle: assertAppBundle), extraArgs);
result.EnsureSuccessful();
}
@@ -52,7 +52,13 @@ protected void PublishProject(string configuration)
.WithWorkingDirectory(_projectDir!)
.WithEnvironmentVariable("NUGET_PACKAGES", _nugetPackagesDir);
- protected async Task RunSdkStyleApp(RunOptions options)
+ protected Task RunSdkStyleAppForBuild(RunOptions options)
+ => RunSdkStyleApp(options, BlazorRunHost.DotnetRun);
+
+ protected Task RunSdkStyleAppForPublish(RunOptions options)
+ => RunSdkStyleApp(options, BlazorRunHost.WebServer);
+
+ private async Task RunSdkStyleApp(RunOptions options, BlazorRunHost host = BlazorRunHost.DotnetRun)
{
string queryString = "?test=" + options.TestScenario;
if (options.BrowserQueryString != null)
@@ -67,9 +73,10 @@ protected async Task RunSdkStyleApp(RunOptions options)
CheckCounter: false,
Config: options.Configuration,
OnConsoleMessage: OnConsoleMessage,
- QueryString: queryString);
+ QueryString: queryString,
+ Host: host);
- await BlazorRunForBuildWithDotnetRun(blazorRunOptions);
+ await BlazorRunTest(blazorRunOptions);
void OnConsoleMessage(IConsoleMessage msg)
{
diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DebugLevelTestsBase.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DebugLevelTestsBase.cs
new file mode 100644
index 00000000000000..219b8b2ed6714d
--- /dev/null
+++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DebugLevelTestsBase.cs
@@ -0,0 +1,86 @@
+// 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.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Xunit;
+using Xunit.Abstractions;
+
+#nullable enable
+
+namespace Wasm.Build.Tests.TestAppScenarios;
+
+public abstract class DebugLevelTestsBase : AppTestBase
+{
+ public DebugLevelTestsBase(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
+ : base(output, buildContext)
+ {
+ }
+
+ protected void AssertDebugLevel(RunResult result, int value)
+ {
+ Assert.Collection(
+ result.TestOutput,
+ m => Assert.Equal($"WasmDebugLevel: {value}", m)
+ );
+ }
+
+ protected abstract void SetupProject(string projectId);
+ protected abstract Task RunForBuild(string configuration);
+ protected abstract Task RunForPublish(string configuration);
+
+ [Theory]
+ [InlineData("Debug")]
+ [InlineData("Release")]
+ public async Task BuildWithDefaultLevel(string configuration)
+ {
+ SetupProject($"DebugLevelTests_BuildWithDefaultLevel_{configuration}");
+ BuildProject(configuration, assertAppBundle: false);
+
+ var result = await RunForBuild(configuration);
+ AssertDebugLevel(result, -1);
+ }
+
+ [Theory]
+ [InlineData("Debug", 1)]
+ [InlineData("Release", 1)]
+ [InlineData("Debug", 0)]
+ [InlineData("Release", 0)]
+ public async Task BuildWithExplicitValue(string configuration, int debugLevel)
+ {
+ SetupProject($"DebugLevelTests_BuildWithExplicitValue_{configuration}");
+ BuildProject(configuration, assertAppBundle: false, extraArgs: $"-p:WasmDebugLevel={debugLevel}");
+
+ var result = await RunForBuild(configuration);
+ AssertDebugLevel(result, debugLevel);
+ }
+
+ [Theory]
+ [InlineData("Debug")]
+ [InlineData("Release")]
+ public async Task PublishWithDefaultLevel(string configuration)
+ {
+ SetupProject($"DebugLevelTests_PublishWithDefaultLevel_{configuration}");
+ PublishProject(configuration, assertAppBundle: false);
+
+ var result = await RunForPublish(configuration);
+ AssertDebugLevel(result, 0);
+ }
+
+ [Theory]
+ [InlineData("Debug", 1)]
+ [InlineData("Release", 1)]
+ [InlineData("Debug", -1)]
+ [InlineData("Release", -1)]
+ public async Task PublishWithExplicitValue(string configuration, int debugLevel)
+ {
+ SetupProject($"DebugLevelTests_PublishWithExplicitValue_{configuration}");
+ PublishProject(configuration, assertAppBundle: false, extraArgs: $"-p:WasmDebugLevel={debugLevel}");
+
+ var result = await RunForPublish(configuration);
+ AssertDebugLevel(result, debugLevel);
+ }
+}
\ No newline at end of file
diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs
index 8f37a47e18860a..cf16a0536a38da 100644
--- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs
@@ -26,7 +26,7 @@ public async Task LoadLazyAssemblyBeforeItIsNeeded()
CopyTestAsset("WasmBasicTestApp", "LazyLoadingTests");
PublishProject("Debug");
- var result = await RunSdkStyleApp(new(Configuration: "Debug", TestScenario: "LazyLoadingTest"));
+ var result = await RunSdkStyleAppForPublish(new(Configuration: "Debug", TestScenario: "LazyLoadingTest"));
Assert.True(result.TestOutput.Any(m => m.Contains("FirstName")), "The lazy loading test didn't emit expected message with JSON");
}
@@ -36,7 +36,7 @@ public async Task FailOnMissingLazyAssembly()
CopyTestAsset("WasmBasicTestApp", "LazyLoadingTests");
PublishProject("Debug");
- var result = await RunSdkStyleApp(new(
+ var result = await RunSdkStyleAppForPublish(new(
Configuration: "Debug",
TestScenario: "LazyLoadingTest",
BrowserQueryString: new Dictionary { ["loadRequiredAssembly"] = "false" },
diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LibraryInitializerTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LibraryInitializerTests.cs
index 6f68a96ad1d61a..e985ad23d89a0b 100644
--- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LibraryInitializerTests.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LibraryInitializerTests.cs
@@ -29,7 +29,7 @@ public async Task LoadLibraryInitializer()
CopyTestAsset("WasmBasicTestApp", "LibraryInitializerTests_LoadLibraryInitializer");
PublishProject("Debug");
- var result = await RunSdkStyleApp(new(Configuration: "Debug", TestScenario: "LibraryInitializerTest"));
+ var result = await RunSdkStyleAppForPublish(new(Configuration: "Debug", TestScenario: "LibraryInitializerTest"));
Assert.Collection(
result.TestOutput,
m => Assert.Equal("LIBRARY_INITIALIZER_TEST = 1", m)
@@ -42,7 +42,7 @@ public async Task AbortStartupOnError()
CopyTestAsset("WasmBasicTestApp", "LibraryInitializerTests_AbortStartupOnError");
PublishProject("Debug");
- var result = await RunSdkStyleApp(new(
+ var result = await RunSdkStyleAppForPublish(new(
Configuration: "Debug",
TestScenario: "LibraryInitializerTest",
BrowserQueryString: new Dictionary { ["throwError"] = "true" },
diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs
index 1b8c43ecea77b0..bc2b5631d2373f 100644
--- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs
@@ -28,7 +28,7 @@ public async Task DownloadProgressFinishes(bool failAssemblyDownload)
CopyTestAsset("WasmBasicTestApp", $"ModuleConfigTests_DownloadProgressFinishes_{failAssemblyDownload}");
PublishProject("Debug");
- var result = await RunSdkStyleApp(new(
+ var result = await RunSdkStyleAppForPublish(new(
Configuration: "Debug",
TestScenario: "DownloadResourceProgressTest",
BrowserQueryString: new Dictionary { ["failAssemblyDownload"] = failAssemblyDownload.ToString().ToLowerInvariant() }
@@ -54,24 +54,4 @@ public async Task DownloadProgressFinishes(bool failAssemblyDownload)
: "The download progress test did emit unexpected message about failing download"
);
}
-
- [Fact]
- public async Task OutErrOverrideWorks()
- {
- CopyTestAsset("WasmBasicTestApp", $"ModuleConfigTests_OutErrOverrideWorks");
- PublishProject("Debug");
-
- var result = await RunSdkStyleApp(new(
- Configuration: "Debug",
- TestScenario: "OutErrOverrideWorks"
- ));
- Assert.True(
- result.ConsoleOutput.Any(m => m.Contains("Emscripten out override works!")),
- "Emscripten out override doesn't work"
- );
- Assert.True(
- result.ConsoleOutput.Any(m => m.Contains("Emscripten err override works!")),
- "Emscripten err override doesn't work"
- );
- }
}
diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs
index 31dcb65582869e..2088e1522ad73b 100644
--- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs
@@ -29,7 +29,7 @@ public async Task LoadSatelliteAssembly()
CopyTestAsset("WasmBasicTestApp", "SatelliteLoadingTests");
BuildProject("Debug");
- var result = await RunSdkStyleApp(new(Configuration: "Debug", TestScenario: "SatelliteAssembliesTest"));
+ var result = await RunSdkStyleAppForBuild(new(Configuration: "Debug", TestScenario: "SatelliteAssembliesTest"));
Assert.Collection(
result.TestOutput,
m => Assert.Equal("default: hello", m),
diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/WasmAppBuilderDebugLevelTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/WasmAppBuilderDebugLevelTests.cs
new file mode 100644
index 00000000000000..60fb3d86f7d0ea
--- /dev/null
+++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/WasmAppBuilderDebugLevelTests.cs
@@ -0,0 +1,69 @@
+// 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.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Xunit;
+using Xunit.Abstractions;
+
+#nullable enable
+
+namespace Wasm.Build.Tests.TestAppScenarios;
+
+public class WasmAppBuilderDebugLevelTests : DebugLevelTestsBase
+{
+ public WasmAppBuilderDebugLevelTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
+ : base(output, buildContext)
+ {
+ }
+
+ protected override void SetupProject(string projectId)
+ {
+ Id = $"{projectId}_{GetRandomId()}";
+ string projectfile = CreateWasmTemplateProject(Id, "wasmconsole", extraArgs: "-f net8.0");
+ string projectDir = Path.GetDirectoryName(projectfile)!;
+ string mainJs = Path.Combine(projectDir, "main.mjs");
+ string mainJsContent = File.ReadAllText(mainJs);
+ mainJsContent = mainJsContent
+ .Replace("await dotnet.run()", "console.log('TestOutput -> WasmDebugLevel: ' + config.debugLevel); exit(0)");
+ File.WriteAllText(mainJs, mainJsContent);
+ }
+
+ protected override Task RunForBuild(string configuration)
+ {
+ CommandResult res = new RunCommand(s_buildEnv, _testOutput)
+ .WithWorkingDirectory(_projectDir!)
+ .ExecuteWithCapturedOutput($"run --no-silent --no-build -c {configuration}");
+
+ return Task.FromResult(ProcessRunOutput(res));
+ }
+
+ private RunResult ProcessRunOutput(CommandResult res)
+ {
+ var output = res.Output.Split(Environment.NewLine);
+ _testOutput.WriteLine($"DEBUG: parsed lines '{String.Join(", ", output)}'");
+
+ var prefix = "[] TestOutput -> ";
+ var testOutput = output
+ .Where(l => l.StartsWith(prefix))
+ .Select(l => l.Substring(prefix.Length))
+ .ToArray();
+
+ _testOutput.WriteLine($"DEBUG: testOutput '{String.Join(", ", testOutput)}'");
+ return new RunResult(res.ExitCode, testOutput, output);
+ }
+
+ protected override Task RunForPublish(string configuration)
+ {
+ // WasmAppBuilder does publish to the same folder as build (it overrides the output),
+ // and thus using dotnet run work correctly for publish as well.
+ CommandResult res = new RunCommand(s_buildEnv, _testOutput)
+ .WithWorkingDirectory(_projectDir!)
+ .ExecuteWithCapturedOutput($"run --no-silent --no-build -c {configuration}");
+
+ return Task.FromResult(ProcessRunOutput(res));
+ }
+}
diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/WasmSdkDebugLevelTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/WasmSdkDebugLevelTests.cs
new file mode 100644
index 00000000000000..f88bb3c7239c99
--- /dev/null
+++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/WasmSdkDebugLevelTests.cs
@@ -0,0 +1,46 @@
+// 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.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Xunit;
+using Xunit.Abstractions;
+
+#nullable enable
+
+namespace Wasm.Build.Tests.TestAppScenarios;
+
+public class WasmSdkDebugLevelTests : DebugLevelTestsBase
+{
+ public WasmSdkDebugLevelTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
+ : base(output, buildContext)
+ {
+ }
+
+ protected override void SetupProject(string projectId) => CopyTestAsset("WasmBasicTestApp", projectId);
+
+ protected override Task RunForBuild(string configuration) => RunSdkStyleAppForBuild(new(
+ Configuration: configuration,
+ TestScenario: "DebugLevelTest"
+ ));
+
+ protected override Task RunForPublish(string configuration) => RunSdkStyleAppForPublish(new(
+ Configuration: configuration,
+ TestScenario: "DebugLevelTest"
+ ));
+
+ [Theory]
+ [InlineData("Debug")]
+ [InlineData("Release")]
+ public async Task PublishWithDefaultLevelAndPdbs(string configuration)
+ {
+ SetupProject($"DebugLevelTests_PublishWithDefaultLevelAndPdbs_{configuration}");
+ PublishProject(configuration, extraArgs: $"-p:CopyOutputSymbolsToPublishDirectory=true");
+
+ var result = await RunForPublish(configuration);
+ AssertDebugLevel(result, -1);
+ }
+}
diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs
index a7ae3fba70ed30..1cc70d823ef14e 100644
--- a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs
@@ -21,7 +21,7 @@ protected WasmTemplateTestBase(ITestOutputHelper output, SharedBuildPerTestClass
_provider.BundleDirName = "AppBundle";
}
- public string CreateWasmTemplateProject(string id, string template = "wasmbrowser", string extraArgs = "", bool runAnalyzers = true)
+ public string CreateWasmTemplateProject(string id, string template = "wasmbrowser", string extraArgs = "", bool runAnalyzers = true, string? extraProperties = null)
{
InitPaths(id);
InitProjectDir(_projectDir, addNuGetSourceForLocalPackages: true);
@@ -42,7 +42,9 @@ public string CreateWasmTemplateProject(string id, string template = "wasmbrowse
.EnsureSuccessful();
string projectfile = Path.Combine(_projectDir!, $"{id}.csproj");
- string extraProperties = string.Empty;
+ if (extraProperties == null)
+ extraProperties = string.Empty;
+
extraProperties += "true";
if (runAnalyzers)
extraProperties += "true";
diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets
index a640a128b25044..bc92659fa3479b 100644
--- a/src/mono/wasm/build/WasmApp.targets
+++ b/src/mono/wasm/build/WasmApp.targets
@@ -142,9 +142,6 @@
false
-
- -1
-
true
.wasm
@@ -210,7 +207,7 @@
+ Properties="_WasmInNestedPublish_UniqueProperty_XYZ=true;;WasmBuildingForNestedPublish=true;DeployOnBuild=;_IsPublishing=;_WasmIsPublishing=$(_IsPublishing)">
@@ -420,6 +417,7 @@
<_WasmAppIncludeThreadsWorker Condition="'$(WasmEnableThreads)' == 'true' or '$(MonoWasmBuildVariant)' == 'multithread'">true
<_WasmPThreadPoolSize Condition="'$(_WasmPThreadPoolSize)' == ''">-1
+ <_WasmIsPublishing Condition="'$(_WasmIsPublishing)' == '' and '$(_IsPublishing)' != ''">$(_IsPublishing)
@@ -445,6 +443,7 @@
ExtraConfig="@(WasmExtraConfig)"
NativeAssets="@(WasmNativeAsset)"
DebugLevel="$(WasmDebugLevel)"
+ IsPublish="$(_WasmIsPublishing)"
IncludeThreadsWorker="$(_WasmAppIncludeThreadsWorker)"
PThreadPoolSize="$(_WasmPThreadPoolSize)"
UseWebcil="$(WasmEnableWebcil)"
diff --git a/src/mono/wasm/runtime/lazyLoading.ts b/src/mono/wasm/runtime/lazyLoading.ts
index 55bcfd67101e8c..85058f89819b7c 100644
--- a/src/mono/wasm/runtime/lazyLoading.ts
+++ b/src/mono/wasm/runtime/lazyLoading.ts
@@ -26,7 +26,7 @@ export async function loadLazyAssembly(assemblyNameToLoad: string): Promise debugBuild=true & debugLevel=-1 => -1
- // - Build (release) => debugBuild=true & debugLevel=0 => 0
- // - Publish (debug) => debugBuild=false & debugLevel=-1 => 0
- // - Publish (release) => debugBuild=false & debugLevel=0 => 0
- config.debugLevel = hasDebuggingEnabled(config) ? config.debugLevel : 0;
-
if (config.diagnosticTracing === undefined && BuildConfiguration === "Debug") {
config.diagnosticTracing = true;
}
@@ -264,14 +257,13 @@ export async function mono_wasm_load_config(module: DotnetModuleInternal): Promi
}
}
-export function hasDebuggingEnabled(config: MonoConfigInternal): boolean {
+export function isDebuggingSupported(): boolean {
// Copied from blazor MonoDebugger.ts/attachDebuggerHotkey
if (!globalThis.navigator) {
return false;
}
- const hasReferencedPdbs = !!config.resources!.pdb;
- return (hasReferencedPdbs || config.debugLevel != 0) && (loaderHelpers.isChromium || loaderHelpers.isFirefox);
+ return loaderHelpers.isChromium || loaderHelpers.isFirefox;
}
async function loadBootConfig(module: DotnetModuleInternal): Promise {
diff --git a/src/mono/wasm/runtime/loader/globals.ts b/src/mono/wasm/runtime/loader/globals.ts
index 88b0d472de3ca8..0bd081ed8a82cc 100644
--- a/src/mono/wasm/runtime/loader/globals.ts
+++ b/src/mono/wasm/runtime/loader/globals.ts
@@ -12,7 +12,7 @@ import { assertIsControllablePromise, createPromiseController, getPromiseControl
import { mono_download_assets, resolve_single_asset_path, retrieve_asset_download } from "./assets";
import { setup_proxy_console } from "./logging";
import { invokeLibraryInitializers } from "./libraryInitializers";
-import { hasDebuggingEnabled } from "./config";
+import { isDebuggingSupported } from "./config";
import { logDownloadStatsToConsole, purgeUnusedCacheEntriesAsync } from "./assetsCache";
export const ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string";
@@ -102,9 +102,9 @@ export function setLoaderGlobals(
logDownloadStatsToConsole,
purgeUnusedCacheEntriesAsync,
- hasDebuggingEnabled,
retrieve_asset_download,
invokeLibraryInitializers,
+ isDebuggingSupported,
// from wasm-feature-detect npm package
exceptions,
diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts
index 324bdc78b0435d..6efa969a953a82 100644
--- a/src/mono/wasm/runtime/startup.ts
+++ b/src/mono/wasm/runtime/startup.ts
@@ -548,7 +548,7 @@ async function mono_wasm_before_memory_snapshot() {
if (runtimeHelpers.config.browserProfilerOptions)
mono_wasm_init_browser_profiler(runtimeHelpers.config.browserProfilerOptions);
- mono_wasm_load_runtime("unused", runtimeHelpers.config.debugLevel);
+ mono_wasm_load_runtime();
// we didn't have snapshot yet and the feature is enabled. Take snapshot now.
if (runtimeHelpers.config.startupMemoryCache) {
@@ -561,17 +561,21 @@ async function mono_wasm_before_memory_snapshot() {
endMeasure(mark, MeasuredBlock.memorySnapshot);
}
-export function mono_wasm_load_runtime(unused?: string, debugLevel?: number): void {
+export function mono_wasm_load_runtime(): void {
mono_log_debug("mono_wasm_load_runtime");
try {
const mark = startMeasure();
+ let debugLevel = runtimeHelpers.config.debugLevel;
if (debugLevel == undefined) {
debugLevel = 0;
if (runtimeHelpers.config.debugLevel) {
debugLevel = 0 + debugLevel;
}
}
- cwraps.mono_wasm_load_runtime(unused || "unused", debugLevel);
+ if (!loaderHelpers.isDebuggingSupported() || !runtimeHelpers.config.resources!.pdb) {
+ debugLevel = 0;
+ }
+ cwraps.mono_wasm_load_runtime("unused", debugLevel);
endMeasure(mark, MeasuredBlock.loadRuntime);
} catch (err: any) {
diff --git a/src/mono/wasm/runtime/types/internal.ts b/src/mono/wasm/runtime/types/internal.ts
index c43443a48da6bc..c0b14b72abe5da 100644
--- a/src/mono/wasm/runtime/types/internal.ts
+++ b/src/mono/wasm/runtime/types/internal.ts
@@ -145,7 +145,6 @@ export type LoaderHelpers = {
out(message: string): void;
err(message: string): void;
- hasDebuggingEnabled(config: MonoConfig): boolean,
retrieve_asset_download(asset: AssetEntry): Promise;
onDownloadResourceProgress?: (resourcesLoaded: number, totalResources: number) => void;
logDownloadStatsToConsole: () => void;
@@ -155,6 +154,7 @@ export type LoaderHelpers = {
invokeLibraryInitializers: (functionName: string, args: any[]) => Promise,
libraryInitializers?: { scriptName: string, exports: any }[];
+ isDebuggingSupported(): boolean,
isChromium: boolean,
isFirefox: boolean
diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs
index 5aba6b1ee48a0f..797956d23f8e4d 100644
--- a/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs
+++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs
@@ -4,6 +4,7 @@
using Library;
using System;
using System.Text.Json;
+using System.Text.Json.Serialization;
using System.Runtime.InteropServices.JavaScript;
public partial class LazyLoadingTest
@@ -13,7 +14,12 @@ public static void Run()
{
// System.Text.Json is marked as lazy loaded in the csproj ("BlazorWebAssemblyLazyLoad"), this method can be called only after the assembly is lazy loaded
// In the test case it is done in the JS before call to this method
- var text = JsonSerializer.Serialize(new Person("John", "Doe"));
+ var text = JsonSerializer.Serialize(new Person("John", "Doe"), PersonJsonSerializerContext.Default.Person);
TestOutput.WriteLine(text);
}
}
+
+[JsonSerializable(typeof(Person))]
+public partial class PersonJsonSerializerContext : JsonSerializerContext
+{
+}
\ No newline at end of file
diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js
index 8e3485bc2e67cd..5092e4cb945b75 100644
--- a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js
+++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js
@@ -33,6 +33,8 @@ switch (testCase) {
Math.floor(Math.random() * 5) + 5,
Math.floor(Math.random() * 5) + 10
];
+ console.log(`Failing test at assembly indexes [${failAtAssemblyNumbers.join(", ")}]`);
+ let alreadyFailed = [];
dotnet.withDiagnosticTracing(true).withResourceLoader((type, name, defaultUri, integrity, behavior) => {
if (type === "dotnetjs") {
// loadBootResource could return string with unqualified name of resource.
@@ -45,9 +47,10 @@ switch (testCase) {
}
assemblyCounter++;
- if (!failAtAssemblyNumbers.includes(assemblyCounter))
+ if (!failAtAssemblyNumbers.includes(assemblyCounter) || alreadyFailed.includes(defaultUri))
return defaultUri;
+ alreadyFailed.push(defaultUri);
testOutput("Throw error instead of downloading resource");
const error = new Error("Simulating a failed fetch");
error.silent = true;
@@ -106,6 +109,10 @@ try {
case "DownloadResourceProgressTest":
exit(0);
break;
+ case "DebugLevelTest":
+ testOutput("WasmDebugLevel: " + config.debugLevel);
+ exit(0);
+ break;
case "OutErrOverrideWorks":
dotnet.run();
break;
diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs
index 07c05113ac843f..748283e74e673b 100644
--- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs
+++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonBuilderHelper.cs
@@ -10,7 +10,7 @@
namespace Microsoft.NET.Sdk.WebAssembly
{
- public class BootJsonBuilderHelper(TaskLoggingHelper Log)
+ public class BootJsonBuilderHelper(TaskLoggingHelper Log, string DebugLevel, bool IsPublish)
{
public void ComputeResourcesHash(BootJsonData bootConfig)
{
@@ -73,5 +73,35 @@ static void AddDictionary(StringBuilder sb, Dictionary? res)
return null;
}
+
+ public int GetDebugLevel(bool hasPdb)
+ {
+ int? debugLevel = ParseOptionalInt(DebugLevel);
+
+ // If user didn't give us a value, check if we have any PDB.
+ if (debugLevel == null && hasPdb)
+ debugLevel = -1;
+
+ // Fallback to -1 for build, or 0 for publish
+ debugLevel ??= IsPublish ? 0 : -1;
+
+ return debugLevel.Value;
+ }
+
+ public bool? ParseOptionalBool(string value)
+ {
+ if (string.IsNullOrEmpty(value) || !bool.TryParse(value, out var boolValue))
+ return null;
+
+ return boolValue;
+ }
+
+ public int? ParseOptionalInt(string value)
+ {
+ if (string.IsNullOrEmpty(value) || !int.TryParse(value, out var intValue))
+ return null;
+
+ return intValue;
+ }
}
}
diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs
index ef42b6fa952f10..3f12c54e07f9c5 100644
--- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs
+++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs
@@ -71,6 +71,8 @@ public class GenerateWasmBootJson : Task
public ITaskItem[] LazyLoadedAssemblies { get; set; }
+ public bool IsPublish { get; set; }
+
public override bool Execute()
{
using var fileStream = File.Create(OutputPath);
@@ -91,17 +93,16 @@ public override bool Execute()
// Internal for tests
public void WriteBootJson(Stream output, string entryAssemblyName)
{
- var helper = new BootJsonBuilderHelper(Log);
+ var helper = new BootJsonBuilderHelper(Log, DebugLevel, IsPublish);
var result = new BootJsonData
{
resources = new ResourcesData(),
- startupMemoryCache = ParseOptionalBool(StartupMemoryCache),
+ startupMemoryCache = helper.ParseOptionalBool(StartupMemoryCache),
};
if (IsTargeting80OrLater())
{
- result.debugLevel = ParseOptionalInt(DebugLevel) ?? (DebugBuild ? 1 : 0);
result.mainAssemblyName = entryAssemblyName;
result.globalizationMode = GetGlobalizationMode().ToString().ToLowerInvariant();
@@ -127,7 +128,7 @@ public void WriteBootJson(Stream output, string entryAssemblyName)
result.runtimeOptions = runtimeOptions;
}
- bool? jiterpreter = ParseOptionalBool(Jiterpreter);
+ bool? jiterpreter = helper.ParseOptionalBool(Jiterpreter);
if (jiterpreter != null)
{
var runtimeOptions = result.runtimeOptions?.ToHashSet() ?? new HashSet(3);
@@ -329,6 +330,20 @@ public void WriteBootJson(Stream output, string entryAssemblyName)
}
}
+ if (IsTargeting80OrLater())
+ {
+ int? debugLevel = helper.ParseOptionalInt(DebugLevel);
+
+ // If user didn't give us a value, check if we have any PDB.
+ if (debugLevel == null && result.resources?.pdb?.Count > 0)
+ debugLevel = -1;
+
+ // Fallback to -1 for build, or 0 for publish
+ debugLevel ??= IsPublish ? 0 : -1;
+
+ result.debugLevel = debugLevel.Value;
+ }
+
if (ConfigurationFiles != null)
{
foreach (var configFile in ConfigurationFiles)
@@ -394,22 +409,6 @@ private GlobalizationMode GetGlobalizationMode()
return GlobalizationMode.Sharded;
}
- private static bool? ParseOptionalBool(string value)
- {
- if (string.IsNullOrEmpty(value) || !bool.TryParse(value, out var boolValue))
- return null;
-
- return boolValue;
- }
-
- private static int? ParseOptionalInt(string value)
- {
- if (string.IsNullOrEmpty(value) || !int.TryParse(value, out var intValue))
- return null;
-
- return intValue;
- }
-
private void AddToAdditionalResources(ITaskItem resource, Dictionary additionalResources, string resourceName, string behavior)
{
if (!additionalResources.ContainsKey(resourceName))
diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs
index 9c7d8a6799134e..d5e2aa53e14862 100644
--- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs
+++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs
@@ -27,6 +27,8 @@ public class WasmAppBuilder : WasmAppBuilderBaseTask
public bool WasmIncludeFullIcuData { get; set; }
public string? WasmIcuDataFileName { get; set; }
public string? RuntimeAssetsLocation { get; set; }
+ public string? DebugLevel { get; set; }
+ public bool IsPublish { get; set; }
//
// Extra json elements to add to _framework/blazor.boot.json
@@ -83,7 +85,7 @@ private GlobalizationMode GetGlobalizationMode()
protected override bool ExecuteInternal()
{
- var helper = new BootJsonBuilderHelper(Log);
+ var helper = new BootJsonBuilderHelper(Log, DebugLevel!, IsPublish);
if (!ValidateArguments())
return false;
@@ -115,6 +117,8 @@ protected override bool ExecuteInternal()
if (UseWebcil)
Log.LogMessage(MessageImportance.Normal, "Converting assemblies to Webcil");
+ int baseDebugLevel = helper.GetDebugLevel(false);
+
foreach (var assembly in _assemblies)
{
if (UseWebcil)
@@ -133,7 +137,7 @@ protected override bool ExecuteInternal()
{
FileCopyChecked(assembly, Path.Combine(runtimeAssetsPath, Path.GetFileName(assembly)), "Assemblies");
}
- if (DebugLevel != 0)
+ if (baseDebugLevel != 0)
{
var pdb = assembly;
pdb = Path.ChangeExtension(pdb, ".pdb");
@@ -191,7 +195,7 @@ protected override bool ExecuteInternal()
}
bootConfig.resources.assembly[Path.GetFileName(assemblyPath)] = Utils.ComputeIntegrity(bytes);
- if (DebugLevel != 0)
+ if (baseDebugLevel != 0)
{
var pdb = Path.ChangeExtension(assembly, ".pdb");
if (File.Exists(pdb))
@@ -205,7 +209,7 @@ protected override bool ExecuteInternal()
}
}
- bootConfig.debugLevel = DebugLevel;
+ bootConfig.debugLevel = helper.GetDebugLevel(bootConfig.resources.pdb?.Count > 0);
ProcessSatelliteAssemblies(args =>
{
diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs b/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs
index c533e404c41739..feee565ad4f6cc 100644
--- a/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs
+++ b/src/tasks/WasmAppBuilder/WasmAppBuilderBaseTask.cs
@@ -36,7 +36,6 @@ public abstract class WasmAppBuilderBaseTask : Task
// https://github.com/dotnet/icu/tree/maint/maint-67/icu-filters
public string[] IcuDataFileNames { get; set; } = Array.Empty();
- public int DebugLevel { get; set; }
public ITaskItem[] SatelliteAssemblies { get; set; } = Array.Empty();
public bool HybridGlobalization { get; set; }
public bool InvariantGlobalization { get; set; }
diff --git a/src/tasks/WasmAppBuilder/wasi/WasiAppBuilder.cs b/src/tasks/WasmAppBuilder/wasi/WasiAppBuilder.cs
index 0974904e6627bd..521284dd56c779 100644
--- a/src/tasks/WasmAppBuilder/wasi/WasiAppBuilder.cs
+++ b/src/tasks/WasmAppBuilder/wasi/WasiAppBuilder.cs
@@ -11,6 +11,7 @@ namespace Microsoft.WebAssembly.Build.Tasks;
public class WasiAppBuilder : WasmAppBuilderBaseTask
{
public bool IsSingleFileBundle { get; set; }
+ public bool OutputSymbolsToAppBundle { get; set; }
protected override bool ValidateArguments()
{
@@ -53,7 +54,7 @@ protected override bool ExecuteInternal()
{
FileCopyChecked(assembly, Path.Combine(asmRootPath, Path.GetFileName(assembly)), "Assemblies");
- if (DebugLevel != 0)
+ if (OutputSymbolsToAppBundle)
{
string pdb = Path.ChangeExtension(assembly, ".pdb");
if (File.Exists(pdb))