diff --git a/src/mono/wasi/Wasi.Build.Tests/WasiTemplateTests.cs b/src/mono/wasi/Wasi.Build.Tests/WasiTemplateTests.cs index 85f7bacf6fcea1..dc2829e05bef5e 100644 --- a/src/mono/wasi/Wasi.Build.Tests/WasiTemplateTests.cs +++ b/src/mono/wasi/Wasi.Build.Tests/WasiTemplateTests.cs @@ -138,6 +138,47 @@ public void ConsolePublishAndRunForSingleFileBundle(string config, bool relinkin } + [Theory] + [InlineData("Debug", /*appendRID*/ true, /*useArtifacts*/ false)] + [InlineData("Debug", /*appendRID*/ true, /*useArtifacts*/ true)] + [InlineData("Debug", /*appendRID*/ false, /*useArtifacts*/ false)] + [InlineData("Debug", /*appendRID*/ false, /*useArtifacts*/ true)] + public void ConsoleBuildAndRunForDifferentOutputPaths(string config, bool appendRID, bool useArtifacts) + { + string extraPropertiesForDBP = ""; + if (appendRID) + extraPropertiesForDBP += "true"; + if (useArtifacts) + extraPropertiesForDBP += "true."; + + string id = $"{config}_{GetRandomId()}"; + string projectFile = CreateWasmTemplateProject(id, "wasiconsole"); + string projectName = Path.GetFileNameWithoutExtension(projectFile); + + if (!string.IsNullOrEmpty(extraPropertiesForDBP)) + AddItemsPropertiesToProject(Path.Combine(Path.GetDirectoryName(projectFile)!, "Directory.Build.props"), + extraPropertiesForDBP); + + var buildArgs = new BuildArgs(projectName, config, false, id, null); + buildArgs = ExpandBuildArgs(buildArgs); + + BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + DotnetWasmFromRuntimePack: true, + CreateProject: false, + Publish: false, + TargetFramework: BuildTestBase.DefaultTargetFramework, + UseCache: false)); + + CommandResult res = new RunCommand(s_buildEnv, _testOutput) + .WithWorkingDirectory(_projectDir!) + .ExecuteWithCapturedOutput($"run --no-silent --no-build -c {config} x y z") + .EnsureSuccessful(); + + Assert.Contains("Hello, Wasi Console!", res.Output); + } + private static readonly string s_simpleMainWithArgs = """ using System; diff --git a/src/mono/wasi/build/WasiApp.targets b/src/mono/wasi/build/WasiApp.targets index c5669bc8a561ca..1b8fc4e3fa9333 100644 --- a/src/mono/wasi/build/WasiApp.targets +++ b/src/mono/wasi/build/WasiApp.targets @@ -145,12 +145,20 @@ 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), $(RuntimeIdentifier), 'AppBundle')) + + + <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' == '' and '$(UseArtifactsOutput)' == '' and '$(AppendRuntimeIdentifierToOutputPath)' != 'false'">$([System.IO.Path]::Combine($(OutputPath), 'wasi-wasm', 'AppBundle')) + + + <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' == ''">$([System.IO.Path]::Combine($(OutputPath), 'AppBundle')) <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' != '' and !$([System.IO.Path]::IsPathRooted($(_AppBundleDirForRunCommand)))">$([System.IO.Path]::Combine($(MSBuildProjectDirectory), $(_AppBundleDirForRunCommand))) - + $(DOTNET_HOST_PATH) diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs index f8ccf6a5e31408..025ea7e38eef88 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs @@ -18,5 +18,7 @@ public record BlazorBuildOptions bool ExpectFingerprintOnDotnetJs = false, RuntimeVariant RuntimeType = RuntimeVariant.SingleThreaded, GlobalizationMode GlobalizationMode = GlobalizationMode.Sharded, - string PredefinedIcudt = "" + string PredefinedIcudt = "", + bool AssertAppBundle = true, + string? BinFrameworkDir = null ); diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmProjectProvider.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmProjectProvider.cs index 6ae7c8c4380dbc..ea6cc51fc6c9fa 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmProjectProvider.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmProjectProvider.cs @@ -18,7 +18,7 @@ public void AssertBundle(BlazorBuildOptions options) Config: options.Config, IsPublish: options.IsPublish, TargetFramework: options.TargetFramework, - BinFrameworkDir: FindBinFrameworkDir(options.Config, options.IsPublish, options.TargetFramework), + BinFrameworkDir: options.BinFrameworkDir ?? FindBinFrameworkDir(options.Config, options.IsPublish, options.TargetFramework), GlobalizationMode: options.GlobalizationMode, PredefinedIcudt: options.PredefinedIcudt, ExpectFingerprintOnDotnetJs: options.ExpectFingerprintOnDotnetJs, diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs index 79f16d31bbd275..ecf4cd7c135678 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs @@ -60,7 +60,7 @@ public string CreateBlazorWasmTemplateProject(string id) (CommandResult res, string logPath) = BlazorBuildInternal(options.Id, options.Config, publish: false, setWasmDevel: false, expectSuccess: options.ExpectSuccess, extraArgs); - if (options.ExpectSuccess) + if (options.ExpectSuccess && options.AssertAppBundle) AssertBundle(res.Output, options with { IsPublish = false }); return (res, logPath); @@ -73,26 +73,9 @@ public string CreateBlazorWasmTemplateProject(string id) (CommandResult res, string logPath) = BlazorBuildInternal(options.Id, options.Config, publish: true, setWasmDevel: false, expectSuccess: options.ExpectSuccess, extraArgs); - if (options.ExpectSuccess) + if (options.ExpectSuccess && options.AssertAppBundle) { AssertBundle(res.Output, options with { IsPublish = true }); - - if (options.ExpectedFileType == NativeFilesType.AOT) - { - // check for this too, so we know the format is correct for the negative - // test for jsinterop.webassembly.dll - Assert.Contains("Microsoft.JSInterop.dll -> Microsoft.JSInterop.dll.bc", res.Output); - - // make sure this assembly gets skipped - Assert.DoesNotContain("Microsoft.JSInterop.WebAssembly.dll -> Microsoft.JSInterop.WebAssembly.dll.bc", res.Output); - } - - 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 likely a test authoring error"); - else - Assert.False(File.Exists(Path.Combine(objBuildDir, "emcc-link.rsp")), $"Found unexpected files in {objBuildDir}, which gets created when relinking during Build"); } return (res, logPath); @@ -135,6 +118,28 @@ public void AssertBundle(string buildOutput, BlazorBuildOptions blazorBuildOptio } _provider.AssertBundle(blazorBuildOptions); + + if (!blazorBuildOptions.IsPublish) + return; + + // Publish specific checks + + if (blazorBuildOptions.ExpectedFileType == NativeFilesType.AOT) + { + // check for this too, so we know the format is correct for the negative + // test for jsinterop.webassembly.dll + Assert.Contains("Microsoft.JSInterop.dll -> Microsoft.JSInterop.dll.bc", buildOutput); + + // make sure this assembly gets skipped + Assert.DoesNotContain("Microsoft.JSInterop.WebAssembly.dll -> Microsoft.JSInterop.WebAssembly.dll.bc", buildOutput); + } + + string objBuildDir = Path.Combine(_projectDir!, "obj", blazorBuildOptions.Config, blazorBuildOptions.TargetFramework!, "wasm", "for-build"); + // Check that we linked only for publish + if (blazorBuildOptions.ExpectRelinkDirWhenPublishing) + 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(File.Exists(Path.Combine(objBuildDir, "emcc-link.rsp")), $"Found unexpected `emcc-link.rsp` in {objBuildDir}, which gets created when relinking during Build."); } protected string CreateProjectWithNativeReference(string id) diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleMultiThreadedTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleMultiThreadedTests.cs index 2815259aa9849e..c28f18a3c57469 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleMultiThreadedTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleMultiThreadedTests.cs @@ -21,7 +21,7 @@ public SimpleMultiThreadedTests(ITestOutputHelper output, SharedBuildPerTestClas } // dotnet-run needed for running with *build* so wwwroot has the index.html etc - // [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + // [Theory] // [InlineData("Debug")] // [InlineData("Release")] // public async Task BlazorBuildRunTest(string config) diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleRunTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleRunTests.cs index 3a8968c4d1458a..fdce8ea756f844 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleRunTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleRunTests.cs @@ -22,7 +22,7 @@ public SimpleRunTests(ITestOutputHelper output, SharedBuildPerTestClassFixture b _enablePerTestCleanup = true; } - [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [Theory] [InlineData("Debug")] [InlineData("Release")] public async Task BlazorBuildRunTest(string config) @@ -34,7 +34,49 @@ public async Task BlazorBuildRunTest(string config) await BlazorRunForBuildWithDotnetRun(new BlazorRunOptions() { Config = config }); } - [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [Theory] + [InlineData("Debug", /*appendRID*/ true, /*useArtifacts*/ false)] + [InlineData("Debug", /*appendRID*/ true, /*useArtifacts*/ true)] + [InlineData("Debug", /*appendRID*/ false, /*useArtifacts*/ true)] + [InlineData("Debug", /*appendRID*/ false, /*useArtifacts*/ false)] + public async Task BlazorBuildAndRunForDifferentOutputPaths(string config, bool appendRID, bool useArtifacts) + { + string id = $"{config}_{GetRandomId()}"; + string projectFile = CreateWasmTemplateProject(id, "blazorwasm"); + string projectName = Path.GetFileNameWithoutExtension(projectFile); + + string extraPropertiesForDBP = ""; + if (appendRID) + extraPropertiesForDBP += "true"; + if (useArtifacts) + extraPropertiesForDBP += "true."; + + string projectDirectory = Path.GetDirectoryName(projectFile)!; + if (!string.IsNullOrEmpty(extraPropertiesForDBP)) + AddItemsPropertiesToProject(Path.Combine(projectDirectory, "Directory.Build.props"), + extraPropertiesForDBP); + + var buildArgs = new BuildArgs(projectName, config, false, id, null); + buildArgs = ExpandBuildArgs(buildArgs); + + BlazorBuildOptions buildOptions = new(id, config, NativeFilesType.FromRuntimePack); + if (useArtifacts) + { + buildOptions = buildOptions with + { + BinFrameworkDir = Path.Combine(projectDirectory, + "bin", + id, + config.ToLower(), + "wwwroot", + "_framework") + }; + } + BlazorBuild(buildOptions); + await BlazorRunForBuildWithDotnetRun(new BlazorRunOptions() { Config = config }); + } + + [Theory] [InlineData("Debug", false)] [InlineData("Debug", true)] [InlineData("Release", false)] diff --git a/src/mono/wasm/Wasm.Build.Tests/BuildProjectOptions.cs b/src/mono/wasm/Wasm.Build.Tests/BuildProjectOptions.cs index 438dd1e9616576..c86c4cda6e7f93 100644 --- a/src/mono/wasm/Wasm.Build.Tests/BuildProjectOptions.cs +++ b/src/mono/wasm/Wasm.Build.Tests/BuildProjectOptions.cs @@ -26,5 +26,6 @@ public record BuildProjectOptions string TargetFramework = BuildTestBase.DefaultTargetFramework, string? MainJS = null, bool IsBrowserProject = true, - IDictionary? ExtraBuildEnvironmentVariables = null + IDictionary? ExtraBuildEnvironmentVariables = null, + string? BinFrameworkDir = null ); diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs b/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs index 94b00ede801293..c8cca6cd0774e7 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs @@ -91,7 +91,7 @@ public static int Main() Assert.Contains("Size: 26462 Height: 599, Width: 499", output); } - [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [Theory] [BuildAndRun(aot: false, host: RunHost.Chrome)] [BuildAndRun(aot: true, host: RunHost.Chrome)] public void ProjectUsingBrowserNativeCrypto(BuildArgs buildArgs, RunHost host, string id) diff --git a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs index 4930b2183a91e8..ff8a7c880453f5 100644 --- a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs @@ -375,7 +375,7 @@ public static int Main() Assert.Matches("warning\\sWASM0001.*Skipping.*Test::SomeFunction1.*because.*function\\spointer", output); } - [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [Theory] [BuildAndRun(host: RunHost.None)] public void IcallWithOverloadedParametersAndEnum(BuildArgs buildArgs, string id) { diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs index 0688948f84d676..76a64c9fe4e76a 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs @@ -179,7 +179,7 @@ public void ConsoleBuildThenPublish(string config) IsBrowserProject: false)); } - [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [Theory] [InlineData("Debug", false)] [InlineData("Debug", true)] [InlineData("Release", false)] @@ -187,7 +187,7 @@ public void ConsoleBuildThenPublish(string config) public void ConsoleBuildAndRunDefault(string config, bool relinking) => ConsoleBuildAndRun(config, relinking, string.Empty, DefaultTargetFramework); - [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [Theory] // [ActiveIssue("https://github.com/dotnet/runtime/issues/79313")] // [InlineData("Debug", "-f net7.0", "net7.0")] [InlineData("Debug", "-f net8.0", "net8.0")] @@ -253,7 +253,7 @@ void AddTestData(bool forConsole, bool runOutsideProjectDirectory) return data; } - [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [Theory] [MemberData(nameof(TestDataForAppBundleDir))] public async Task RunWithDifferentAppBundleLocations(bool forConsole, bool runOutsideProjectDirectory, string extraProperties) => await (forConsole @@ -354,7 +354,7 @@ public static TheoryData TestDataForConsolePublishAndRun() return data; } - [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [Theory] [MemberData(nameof(TestDataForConsolePublishAndRun))] public void ConsolePublishAndRun(string config, bool aot, bool relinking) { @@ -406,7 +406,7 @@ public void ConsolePublishAndRun(string config, bool aot, bool relinking) Assert.Contains("args[2] = z", res.Output); } - [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [Theory] [InlineData("", BuildTestBase.DefaultTargetFramework, DefaultRuntimeAssetsRelativePath)] [InlineData("", BuildTestBase.DefaultTargetFramework, "./")] // [ActiveIssue("https://github.com/dotnet/runtime/issues/79313")] @@ -434,5 +434,59 @@ public async Task BrowserBuildAndRun(string extraNewArgs, string targetFramework await runner.WaitForExitMessageAsync(TimeSpan.FromMinutes(2)); Assert.Contains("Hello, Browser!", string.Join(Environment.NewLine, runner.OutputLines)); } + + [Theory] + [InlineData("Debug", /*appendRID*/ true, /*useArtifacts*/ false)] + [InlineData("Debug", /*appendRID*/ true, /*useArtifacts*/ true)] + [InlineData("Debug", /*appendRID*/ false, /*useArtifacts*/ true)] + [InlineData("Debug", /*appendRID*/ false, /*useArtifacts*/ false)] + public void BuildAndRunForDifferentOutputPaths(string config, bool appendRID, bool useArtifacts) + { + string id = $"{config}_{GetRandomId()}"; + string projectFile = CreateWasmTemplateProject(id, "wasmconsole"); + string projectName = Path.GetFileNameWithoutExtension(projectFile); + + string extraPropertiesForDBP = ""; + if (appendRID) + extraPropertiesForDBP += "true"; + if (useArtifacts) + extraPropertiesForDBP += "true."; + + string projectDirectory = Path.GetDirectoryName(projectFile)!; + if (!string.IsNullOrEmpty(extraPropertiesForDBP)) + AddItemsPropertiesToProject(Path.Combine(projectDirectory, "Directory.Build.props"), + extraPropertiesForDBP); + + var buildOptions = new BuildProjectOptions( + DotnetWasmFromRuntimePack: true, + CreateProject: false, + HasV8Script: false, + MainJS: "main.mjs", + Publish: false, + TargetFramework: DefaultTargetFramework, + IsBrowserProject: false); + if (useArtifacts) + { + buildOptions = buildOptions with + { + BinFrameworkDir = Path.Combine( + projectDirectory, + "bin", + id, + $"{config.ToLower()}_{BuildEnvironment.DefaultRuntimeIdentifier}", + "AppBundle", + "_framework") + }; + } + + var buildArgs = new BuildArgs(projectName, config, false, id, null); + buildArgs = ExpandBuildArgs(buildArgs); + BuildTemplateProject(buildArgs, id: id, buildOptions); + + CommandResult res = new RunCommand(s_buildEnv, _testOutput) + .WithWorkingDirectory(_projectDir!) + .ExecuteWithCapturedOutput($"run --no-silent --no-build -c {config} x y z") + .EnsureSuccessful(); + } } } diff --git a/src/mono/wasm/Wasm.Build.Tests/TestMainJsProjectProvider.cs b/src/mono/wasm/Wasm.Build.Tests/TestMainJsProjectProvider.cs index d31a1fad077ba2..7042c4855549d2 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestMainJsProjectProvider.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestMainJsProjectProvider.cs @@ -82,7 +82,8 @@ public void AssertBundle(AssertTestMainJsAppBundleOptions assertOptions) public void AssertBundle(BuildArgs buildArgs, BuildProjectOptions buildProjectOptions) { - string binFrameworkDir = FindBinFrameworkDir(buildArgs.Config, + string binFrameworkDir = buildProjectOptions.BinFrameworkDir + ?? FindBinFrameworkDir(buildArgs.Config, buildProjectOptions.Publish, buildProjectOptions.TargetFramework); NativeFilesType expectedFileType = buildArgs.AOT diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 36d6aeb0ceb0d0..be1b7214e2c0bd 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -175,7 +175,15 @@ 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 '$(UseArtifactsOutput)' == '' and '$(AppendRuntimeIdentifierToOutputPath)' != 'false'">$([System.IO.Path]::Combine($(OutputPath), 'browser-wasm', 'AppBundle')) + + + <_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' == ''">$([System.IO.Path]::Combine($(OutputPath), 'AppBundle'))