Skip to content

Commit

Permalink
[wasm] Respect AppendRuntimeIdentifierToOutputPath, and `UseArtifac…
Browse files Browse the repository at this point in the history
…tsOutput` (#90365)

* [wasm] Remove all instances of `ConditionalTheory IsUsingWorkloads`

.. because we run tests in two modes:

1. with workloads - all the tests *without* `no-workload` category are
   run (thus the default)
2. no workloads - all the tests *with* `no-workload` category are run
   (thus need explicitly attributes)

* Allow custom bin framework dirs for asserting bundles

* [wasm] Respect `AppendRuntimeIdentifierToOutputPath`, and

.. `UseArtifactsOutput`.

Fixes #89744 .
  • Loading branch information
radical authored Aug 14, 2023
1 parent ad60861 commit f69470a
Show file tree
Hide file tree
Showing 13 changed files with 198 additions and 36 deletions.
41 changes: 41 additions & 0 deletions src/mono/wasi/Wasi.Build.Tests/WasiTemplateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 += "<AppendRuntimeIdentifierToOutputPath>true</AppendRuntimeIdentifierToOutputPath>";
if (useArtifacts)
extraPropertiesForDBP += "<UseArtifactsOutput>true</UseArtifactsOutput><ArtifactsPath>.</ArtifactsPath>";

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;
Expand Down
12 changes: 10 additions & 2 deletions src/mono/wasi/build/WasiApp.targets
Original file line number Diff line number Diff line change
Expand Up @@ -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>

<!-- This is the only case where OutputPath needs an additional part -->
<_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' == '' and '$(UseArtifactsOutput)' == '' and '$(AppendRuntimeIdentifierToOutputPath)' != 'false'">$([System.IO.Path]::Combine($(OutputPath), 'wasi-wasm', 'AppBundle'))</_AppBundleDirForRunCommand>

<!--
In case of UseArtifactsOutput==true, the path is like `OutputPath=./bin/wc0/debug_browser-wasm/`. And
it remains the same even if `AppendRuntimeIdentifierToOutputPath`==true .
-->
<_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' == ''">$([System.IO.Path]::Combine($(OutputPath), 'AppBundle'))</_AppBundleDirForRunCommand>

<!-- Ensure the path is absolute. In case of VS, the cwd might not be the correct one, so explicitly
use $(MSBuildProjectDirectory). -->
<_AppBundleDirForRunCommand Condition="'$(_AppBundleDirForRunCommand)' != '' and !$([System.IO.Path]::IsPathRooted($(_AppBundleDirForRunCommand)))">$([System.IO.Path]::Combine($(MSBuildProjectDirectory), $(_AppBundleDirForRunCommand)))</_AppBundleDirForRunCommand>
</PropertyGroup>
</PropertyGroup>

<PropertyGroup Condition="'$(WasmGenerateAppBundle)' == 'true'">
<RunCommand Condition="'$(DOTNET_HOST_PATH)' != '' and Exists($(DOTNET_HOST_PATH))">$(DOTNET_HOST_PATH)</RunCommand>
Expand Down
4 changes: 3 additions & 1 deletion src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
43 changes: 24 additions & 19 deletions src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
46 changes: 44 additions & 2 deletions src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleRunTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 += "<AppendRuntimeIdentifierToOutputPath>true</AppendRuntimeIdentifierToOutputPath>";
if (useArtifacts)
extraPropertiesForDBP += "<UseArtifactsOutput>true</UseArtifactsOutput><ArtifactsPath>.</ArtifactsPath>";

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)]
Expand Down
3 changes: 2 additions & 1 deletion src/mono/wasm/Wasm.Build.Tests/BuildProjectOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ public record BuildProjectOptions
string TargetFramework = BuildTestBase.DefaultTargetFramework,
string? MainJS = null,
bool IsBrowserProject = true,
IDictionary<string, string>? ExtraBuildEnvironmentVariables = null
IDictionary<string, string>? ExtraBuildEnvironmentVariables = null,
string? BinFrameworkDir = null
);
2 changes: 1 addition & 1 deletion src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
64 changes: 59 additions & 5 deletions src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,15 @@ public void ConsoleBuildThenPublish(string config)
IsBrowserProject: false));
}

[ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))]
[Theory]
[InlineData("Debug", false)]
[InlineData("Debug", true)]
[InlineData("Release", false)]
[InlineData("Release", true)]
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")]
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -354,7 +354,7 @@ public static TheoryData<string, bool, bool> TestDataForConsolePublishAndRun()
return data;
}

[ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))]
[Theory]
[MemberData(nameof(TestDataForConsolePublishAndRun))]
public void ConsolePublishAndRun(string config, bool aot, bool relinking)
{
Expand Down Expand Up @@ -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")]
Expand Down Expand Up @@ -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 += "<AppendRuntimeIdentifierToOutputPath>true</AppendRuntimeIdentifierToOutputPath>";
if (useArtifacts)
extraPropertiesForDBP += "<UseArtifactsOutput>true</UseArtifactsOutput><ArtifactsPath>.</ArtifactsPath>";

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();
}
}
}
3 changes: 2 additions & 1 deletion src/mono/wasm/Wasm.Build.Tests/TestMainJsProjectProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit f69470a

Please sign in to comment.