From 79e022f2c7c0d2d89cf6b39dc97c89c4945523e4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 13 Sep 2022 09:47:58 -0700 Subject: [PATCH] [release/7.0] Fix running WebAssembly Browser App from VS (#75508) * trying to fix 75356 * Trying to fix for running from VS and from command line * Remove unused spaces * Fix again * Addressing @radical comments * OutputPath can be missing the rid during the evaluation * more cleanup * Replacing NormalizeDirectory with [System.IO.Path]::Combine * [wasm] Add tests for running templates outside project directory * Add tests for browser template * fix Co-authored-by: Thays Grazia Co-authored-by: Ankit Jain --- src/mono/wasm/build/WasmApp.targets | 30 +++-- .../Wasm.Build.Tests/WasmTemplateTests.cs | 112 +++++++++++++++++- 2 files changed, 131 insertions(+), 11 deletions(-) diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 1c5cb83387488..3266e12f988d0 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -113,20 +113,34 @@ -1 + + + + + <_AppBundleDirForRunCommand Condition="'$(WasmAppDir)' != ''">$(WasmAppDir) + + - <_AppBundleDirForRunCommand Condition="Exists('$(WasmAppDir)/$(AssemblyName).runtimeconfig.json')">$(WasmAppDir) - <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' == '' and Exists('$(OutputPath)/AppBundle')">$([MSBuild]::NormalizeDirectory($(OutputPath), 'AppBundle')) - <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' == '' and Exists('$(OutputPath)/browser-wasm/AppBundle')">$([MSBuild]::NormalizeDirectory($(OutputPath), 'browser-wasm', 'AppBundle')) - <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' == ''">OutputPath=$(OutputPath), OutDir=$(OutDir) + The path might not have been created yet, for example when creating a new project in VS, so don't use an Exists() check + --> + <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' == ''">$([System.IO.Path]::Combine($(OutputPath), 'browser-wasm', 'AppBundle')) + + + <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' != '' and !$([System.IO.Path]::IsPathRooted($(_AppBundleDirForRunCommand)))">$([System.IO.Path]::Combine($(MSBuildProjectDirectory), $(_AppBundleDirForRunCommand))) $(DOTNET_HOST_PATH) dotnet - exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --runtime-config "$(_AppBundleDirForRunCommand)/$(AssemblyName).runtimeconfig.json" $(WasmHostArguments) + + <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(_AppBundleDirForRunCommand), '$(AssemblyName).runtimeconfig.json')) + exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --runtime-config "$(_RuntimeConfigJsonPath)" $(WasmHostArguments) $(_AppBundleDirForRunCommand) diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs index 08fc1180c849b..285e1b665752c 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs @@ -21,7 +21,7 @@ public WasmTemplateTests(ITestOutputHelper output, SharedBuildPerTestClassFixtur { } - private void updateProgramCS() + private void UpdateProgramCS() { string programText = """ Console.WriteLine("Hello, Console!"); @@ -188,7 +188,7 @@ public void ConsoleBuildAndRun(string config, bool relinking) string projectFile = CreateWasmTemplateProject(id, "wasmconsole"); string projectName = Path.GetFileNameWithoutExtension(projectFile); - updateProgramCS(); + UpdateProgramCS(); UpdateConsoleMainJs(); if (relinking) AddItemsPropertiesToProject(projectFile, "true"); @@ -216,6 +216,112 @@ public void ConsoleBuildAndRun(string config, bool relinking) Assert.Contains("args[2] = z", output); } + public static TheoryData TestDataForAppBundleDir() + { + var data = new TheoryData(); + AddTestData(forConsole: true, runOutsideProjectDirectory: false); + AddTestData(forConsole: true, runOutsideProjectDirectory: true); + + AddTestData(forConsole: false, runOutsideProjectDirectory: false); + AddTestData(forConsole: false, runOutsideProjectDirectory: true); + + void AddTestData(bool forConsole, bool runOutsideProjectDirectory) + { + data.Add(runOutsideProjectDirectory, forConsole, string.Empty); + + data.Add(runOutsideProjectDirectory, forConsole, + $"{Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())}"); + data.Add(runOutsideProjectDirectory, forConsole, + $"{Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())}"); + } + + return data; + } + + [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [MemberData(nameof(TestDataForAppBundleDir))] + public async Task RunWithDifferentAppBundleLocations(bool forConsole, bool runOutsideProjectDirectory, string extraProperties) + => await (forConsole + ? ConsoleRunWithAndThenWithoutBuildAsync("Release", extraProperties, runOutsideProjectDirectory) + : BrowserRunTwiceWithAndThenWithoutBuildAsync("Release", extraProperties, runOutsideProjectDirectory)); + + private async Task BrowserRunTwiceWithAndThenWithoutBuildAsync(string config, string extraProperties = "", bool runOutsideProjectDirectory = false) + { + string id = $"browser_{config}_{Path.GetRandomFileName()}"; + string projectFile = CreateWasmTemplateProject(id, "wasmbrowser"); + + UpdateBrowserMainJs(); + + if (!string.IsNullOrEmpty(extraProperties)) + AddItemsPropertiesToProject(projectFile, extraProperties: extraProperties); + + string workingDir = runOutsideProjectDirectory ? Path.GetTempPath() : _projectDir!; + + { + using var runCommand = new RunCommand(s_buildEnv, _testOutput) + .WithWorkingDirectory(workingDir); + + await using var runner = new BrowserRunner(); + var page = await runner.RunAsync(runCommand, $"run -c {config} --project {projectFile} --forward-console"); + await runner.WaitForExitMessageAsync(TimeSpan.FromMinutes(2)); + Assert.Contains("Hello, Browser!", string.Join(Environment.NewLine, runner.OutputLines)); + } + + { + using var runCommand = new RunCommand(s_buildEnv, _testOutput) + .WithWorkingDirectory(workingDir); + + await using var runner = new BrowserRunner(); + var page = await runner.RunAsync(runCommand, $"run -c {config} --no-build --project {projectFile} --forward-console"); + await runner.WaitForExitMessageAsync(TimeSpan.FromMinutes(2)); + Assert.Contains("Hello, Browser!", string.Join(Environment.NewLine, runner.OutputLines)); + } + } + + private Task ConsoleRunWithAndThenWithoutBuildAsync(string config, string extraProperties = "", bool runOutsideProjectDirectory = false) + { + string id = $"console_{config}_{Path.GetRandomFileName()}"; + string projectFile = CreateWasmTemplateProject(id, "wasmconsole"); + + UpdateProgramCS(); + UpdateConsoleMainJs(); + + if (!string.IsNullOrEmpty(extraProperties)) + AddItemsPropertiesToProject(projectFile, extraProperties: extraProperties); + + string workingDir = runOutsideProjectDirectory ? Path.GetTempPath() : _projectDir!; + + { + string runArgs = $"run -c {config} --project {projectFile}"; + runArgs += " x y z"; + using var cmd = new RunCommand(s_buildEnv, _testOutput, label: id) + .WithWorkingDirectory(workingDir) + .WithEnvironmentVariables(s_buildEnv.EnvVars); + var res = cmd.ExecuteWithCapturedOutput(runArgs).EnsureExitCode(42); + + Assert.Contains("args[0] = x", res.Output); + Assert.Contains("args[1] = y", res.Output); + Assert.Contains("args[2] = z", res.Output); + } + + _testOutput.WriteLine($"{Environment.NewLine}[{id}] Running again with --no-build{Environment.NewLine}"); + + { + // Run with --no-build + string runArgs = $"run -c {config} --project {projectFile} --no-build"; + runArgs += " x y z"; + using var cmd = new RunCommand(s_buildEnv, _testOutput, label: id) + .WithWorkingDirectory(workingDir); + var res = cmd.ExecuteWithCapturedOutput(runArgs).EnsureExitCode(42); + + Assert.Contains("args[0] = x", res.Output); + Assert.Contains("args[1] = y", res.Output); + Assert.Contains("args[2] = z", res.Output); + } + + return Task.CompletedTask; + } + public static TheoryData TestDataForConsolePublishAndRun() { var data = new TheoryData(); @@ -242,7 +348,7 @@ public void ConsolePublishAndRun(string config, bool aot, bool relinking) string projectFile = CreateWasmTemplateProject(id, "wasmconsole"); string projectName = Path.GetFileNameWithoutExtension(projectFile); - updateProgramCS(); + UpdateProgramCS(); UpdateConsoleMainJs(); if (aot)