Skip to content

Commit

Permalink
[wasm] cleanup testing and host support in templatest and tests (#73785)
Browse files Browse the repository at this point in the history
* wip

* wip

* wip

* Single instance in create method.

* withMainAssembly

* withAsyncFlushOnExit

* Fix exporting INTERNAL api.

Move all legacy API object creation to dotnet.es6.post.js where module export is created.

* fix release build

* Move virtualWorkingDirectory initialization to the create method, so it is used in both scenarios (run & create).

* Fix applicationArguments in templates.

* Update WBT.

* Fix ENVIRONMENT_IS_*.

* Move pthreadPoolSize to MonoConfig (from internal).

Fix merge error.

* Fix ConsolePublishAndRun.

* Update readme.md in templates.

* Update WasmAppHost to always pass application arguments as query string.

Add API for parsing applications arguments passed by the WasmAppHost.

Co-authored-by: Marek Fišera <mara@neptuo.com>
  • Loading branch information
pavelsavara and maraf committed Aug 15, 2022
1 parent 3968ceb commit 906ec1d
Show file tree
Hide file tree
Showing 51 changed files with 1,113 additions and 1,052 deletions.
Expand Up @@ -240,6 +240,7 @@
<PlatformManifestFileEntry Include="dotnet.es6.pre.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.es6.lib.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.es6.post.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.es6.extpost.js" IsNative="true" />
<PlatformManifestFileEntry Include="corebindings.c" IsNative="true" />
<PlatformManifestFileEntry Include="driver.c" IsNative="true" />
<PlatformManifestFileEntry Include="pinvoke.c" IsNative="true" />
Expand Down
2 changes: 1 addition & 1 deletion src/mono/sample/wasm/browser-bench/Console/Makefile
Expand Up @@ -9,6 +9,6 @@ endif
PROJECT_NAME=Wasm.Console.Bench.Sample.csproj
CONSOLE_DLL=Wasm.Console.Bench.Sample.dll
MAIN_JS=test-main.js
ARGS=--run $(CONSOLE_DLL)
ARGS=

run: run-console
78 changes: 34 additions & 44 deletions src/mono/sample/wasm/browser/main.js
@@ -1,21 +1,4 @@
import createDotnetRuntime from './dotnet.js'

function wasm_exit(exit_code, reason) {
/* Set result in a tests_done element, to be read by xharness in runonly CI test */
const tests_done_elem = document.createElement("label");
tests_done_elem.id = "tests_done";
tests_done_elem.innerHTML = exit_code.toString();
if (exit_code) tests_done_elem.style.background = "red";
document.body.appendChild(tests_done_elem);

if (reason) console.error(reason);
console.log(`WASM EXIT ${exit_code}`);
}

/**
* @type {import('../../../wasm/runtime/dotnet').CreateDotnetRuntimeType}
*/
const createDotnetRuntimeTyped = createDotnetRuntime;
import { dotnet, exit } from './dotnet.js'

function add(a, b) {
return a + b;
Expand All @@ -24,29 +7,35 @@ function add(a, b) {
function sub(a, b) {
return a - b;
}

try {
const { runtimeBuildInfo, setModuleImports, getAssemblyExports, runMain } = await createDotnetRuntimeTyped({
configSrc: "./mono-config.json",
onConfigLoaded: (config) => {
// This is called during emscripten `dotnet.wasm` instantiation, after we fetched config.
console.log('user code Module.onConfigLoaded');
// config is loaded and could be tweaked before the rest of the runtime startup sequence
config.environmentVariables["MONO_LOG_LEVEL"] = "debug"
},
preInit: () => { console.log('user code Module.preInit'); },
preRun: () => { console.log('user code Module.preRun'); },
onRuntimeInitialized: () => {
console.log('user code Module.onRuntimeInitialized');
// here we could use API passed into this callback
// Module.FS.chdir("/");
},
onDotnetReady: () => {
// This is called after all assets are loaded.
console.log('user code Module.onDotnetReady');
},
postRun: () => { console.log('user code Module.postRun'); },
});

const { runtimeBuildInfo, setModuleImports, getAssemblyExports, runMain, getConfig } = await dotnet
.withConsoleForwarding()
.withElementOnExit()
.withModuleConfig({
configSrc: "./mono-config.json",
onConfigLoaded: (config) => {
// This is called during emscripten `dotnet.wasm` instantiation, after we fetched config.
console.log('user code Module.onConfigLoaded');
// config is loaded and could be tweaked before the rest of the runtime startup sequence
config.environmentVariables["MONO_LOG_LEVEL"] = "debug"
},
preInit: () => { console.log('user code Module.preInit'); },
preRun: () => { console.log('user code Module.preRun'); },
onRuntimeInitialized: () => {
console.log('user code Module.onRuntimeInitialized');
// here we could use API passed into this callback
// Module.FS.chdir("/");
},
onDotnetReady: () => {
// This is called after all assets are loaded.
console.log('user code Module.onDotnetReady');
},
postRun: () => { console.log('user code Module.postRun'); },
})
.create();


// at this point both emscripten and monoVM are fully initialized.
// we could use the APIs returned and resolved from createDotnetRuntime promise
// both exports are receiving the same object instances
Expand All @@ -60,17 +49,18 @@ try {
}
});

const exports = await getAssemblyExports("Wasm.Browser.Sample.dll");
const config = getConfig();
const exports = await getAssemblyExports(config.mainAssemblyName);
const meaning = exports.Sample.Test.TestMeaning();
console.debug(`meaning: ${meaning}`);
if (!exports.Sample.Test.IsPrime(meaning)) {
document.getElementById("out").innerHTML = `${meaning} as computed on dotnet ver ${runtimeBuildInfo.productVersion}`;
console.debug(`ret: ${meaning}`);
}

let exit_code = await runMain("Wasm.Browser.Sample.dll", []);
wasm_exit(exit_code);
let exit_code = await runMain(config.mainAssemblyName, []);
exit(exit_code);
}
catch (err) {
wasm_exit(2, err);
exit(2, err);
}
Expand Up @@ -6,7 +6,7 @@

<GenerateRunScriptForSample Condition="'$(ArchiveTests)' == 'true'">true</GenerateRunScriptForSample>
<ExpectedExitCode>2</ExpectedExitCode>
<RunScriptCommand>$(ExecXHarnessCmd) wasm test --app=. --engine=NodeJS --engine-arg=--stack-trace-limit=1000 --js-file=main.mjs --output-directory=$(XHarnessOutput) --expected-exit-code $(ExpectedExitCode) -- --run $(MSBuildProjectName).dll</RunScriptCommand>
<RunScriptCommand>$(ExecXHarnessCmd) wasm test --app=. --engine=NodeJS --engine-arg=--stack-trace-limit=1000 --js-file=main.mjs --output-directory=$(XHarnessOutput) --expected-exit-code $(ExpectedExitCode)</RunScriptCommand>
</PropertyGroup>

<ItemGroup>
Expand Down
22 changes: 5 additions & 17 deletions src/mono/sample/wasm/console-node/main.mjs
@@ -1,18 +1,6 @@
// @ts-check
// @ts-ignore
import createDotnetRuntime from './dotnet.js'
import process from 'process'
import { dotnet } from './dotnet.js'

/**
* @type {import('../../../wasm/runtime/dotnet').CreateDotnetRuntimeType}
*/
const createDotnetRuntimeTyped = createDotnetRuntime;

const { runMainAndExit } = await createDotnetRuntimeTyped({
disableDotnet6Compatibility: true,
configSrc: "./mono-config.json",
});

const app_args = process.argv.slice(2);
const dllName = "Wasm.Console.Node.Sample.dll";
await runMainAndExit(dllName, app_args);
dotnet
.withDiagnosticTracing(false)
.withApplicationArguments("dotnet", "is", "great!")
.run()
8 changes: 2 additions & 6 deletions src/mono/sample/wasm/console-v8/Wasm.Console.V8.Sample.csproj
@@ -1,17 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<WasmCopyAppZipToHelixTestDir Condition="'$(ArchiveTests)' == 'true'">true</WasmCopyAppZipToHelixTestDir>
<WasmMainJSPath>v8shim.cjs</WasmMainJSPath>
<WasmMainJSPath>main.mjs</WasmMainJSPath>
<WasmGenerateRunV8Script>true</WasmGenerateRunV8Script>

<GenerateRunScriptForSample Condition="'$(ArchiveTests)' == 'true'">true</GenerateRunScriptForSample>
<RunScriptCommand>$(ExecXHarnessCmd) wasm test --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --js-file=v8shim.cjs --output-directory=$(XHarnessOutput) -- --run $(MSBuildProjectName).dll</RunScriptCommand>
<RunScriptCommand>$(ExecXHarnessCmd) wasm test --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --engine-arg=--module --js-file=main.mjs --output-directory=$(XHarnessOutput) -- --run $(MSBuildProjectName).dll</RunScriptCommand>
</PropertyGroup>

<ItemGroup>
<WasmExtraFilesToDeploy Include="main.mjs" />
</ItemGroup>

<PropertyGroup>
<_SampleProject>Wasm.Console.V8.Sample.csproj</_SampleProject>
<_SampleAssembly>Wasm.Console.V8.Sample.dll</_SampleAssembly>
Expand Down
15 changes: 5 additions & 10 deletions src/mono/sample/wasm/console-v8/main.mjs
@@ -1,11 +1,6 @@
import createDotnetRuntime from './dotnet.js'
import { dotnet } from './dotnet.js'

const dllName = "Wasm.Console.V8.Sample.dll";
const app_args = Array.from(arguments);

async function main() {
const { runMainAndExit } = await createDotnetRuntime();
await runMainAndExit(dllName, app_args);
}

main();
dotnet
.withDiagnosticTracing(false)
.withApplicationArguments(...arguments)
.run()
4 changes: 0 additions & 4 deletions src/mono/sample/wasm/console-v8/v8shim.cjs

This file was deleted.

6 changes: 1 addition & 5 deletions src/mono/wasm/host/BrowserArguments.cs
Expand Up @@ -13,7 +13,6 @@ internal sealed class BrowserArguments
{
public string? HTMLPath { get; private set; }
public bool? ForwardConsoleOutput { get; private set; }
public bool UseQueryStringToPassArguments { get; private set; }
public string[] AppArgs { get; init; }
public CommonConfiguration CommonConfig { get; init; }

Expand All @@ -27,8 +26,7 @@ public BrowserArguments(CommonConfiguration commonConfig)

private OptionSet GetOptions() => new OptionSet
{
{ "forward-console", "Forward JS console output", v => ForwardConsoleOutput = true },
{ "use-query-string-for-args", "Use query string to pass arguments (Default: false)", v => UseQueryStringToPassArguments = true }
{ "forward-console", "Forward JS console output", v => ForwardConsoleOutput = true }
};

public void ParseJsonProperties(IDictionary<string, JsonElement>? properties)
Expand All @@ -37,8 +35,6 @@ public void ParseJsonProperties(IDictionary<string, JsonElement>? properties)
HTMLPath = htmlPathElement.GetString();
if (properties?.TryGetValue("forward-console", out JsonElement forwardConsoleElement) == true)
ForwardConsoleOutput = forwardConsoleElement.GetBoolean();
if (properties?.TryGetValue("use-query-string-for-args", out JsonElement useQueryElement) == true)
UseQueryStringToPassArguments = useQueryElement.GetBoolean();
}

public void Validate()
Expand Down
3 changes: 1 addition & 2 deletions src/mono/wasm/host/BrowserHost.cs
Expand Up @@ -76,8 +76,7 @@ private async Task RunAsync(ILoggerFactory loggerFactory, CancellationToken toke
_args.CommonConfig.HostProperties.WebServerPort,
token);

string[] fullUrls = BuildUrls(serverURLs,
_args.UseQueryStringToPassArguments ? _args.AppArgs : Array.Empty<string>());
string[] fullUrls = BuildUrls(serverURLs, _args.AppArgs);
Console.WriteLine();
foreach (string url in fullUrls)
Console.WriteLine($"App url: {url}");
Expand Down
4 changes: 2 additions & 2 deletions src/mono/wasm/runtime/CMakeLists.txt
Expand Up @@ -31,8 +31,8 @@ target_link_libraries(dotnet
${NATIVE_BIN_DIR}/libSystem.Security.Cryptography.Native.Browser.a)

set_target_properties(dotnet PROPERTIES
LINK_DEPENDS "${NATIVE_BIN_DIR}/src/emcc-default.rsp;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.pre.js;${NATIVE_BIN_DIR}/src/es6/runtime.es6.iffe.js;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.lib.js;${NATIVE_BIN_DIR}/src/pal_random.lib.js;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.post.js;"
LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-link.rsp ${CONFIGURATION_LINK_FLAGS} --extern-pre-js ${NATIVE_BIN_DIR}/src/es6/runtime.es6.iffe.js --pre-js ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.pre.js --js-library ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.lib.js --js-library ${NATIVE_BIN_DIR}/src/pal_random.lib.js --post-js ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.post.js "
LINK_DEPENDS "${NATIVE_BIN_DIR}/src/emcc-default.rsp;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.pre.js;${NATIVE_BIN_DIR}/src/es6/runtime.es6.iffe.js;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.lib.js;${NATIVE_BIN_DIR}/src/pal_random.lib.js;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.post.js;${NATIVE_BIN_DIR}/src/es6/dotnet.es6.extpost.js;"
LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-link.rsp ${CONFIGURATION_LINK_FLAGS} --extern-pre-js ${NATIVE_BIN_DIR}/src/es6/runtime.es6.iffe.js --pre-js ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.pre.js --js-library ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.lib.js --js-library ${NATIVE_BIN_DIR}/src/pal_random.lib.js --post-js ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.post.js --extern-post-js ${NATIVE_BIN_DIR}/src/es6/dotnet.es6.extpost.js "
RUNTIME_OUTPUT_DIRECTORY "${NATIVE_BIN_DIR}")

set(ignoreMeWasmOptFlags "${CONFIGURATION_WASM_OPT_FLAGS}")
Expand Down
3 changes: 3 additions & 0 deletions src/mono/wasm/runtime/assets.ts
@@ -1,3 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import cwraps from "./cwraps";
import { mono_wasm_load_icu_data } from "./icu";
import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, Module, runtimeHelpers } from "./imports";
Expand Down
2 changes: 1 addition & 1 deletion src/mono/wasm/runtime/dotnet-legacy.d.ts
Expand Up @@ -189,7 +189,7 @@ declare type MONOType = {
/**
* @deprecated Please use runMainAndExit instead
*/
mono_run_main_and_exit: (main_assembly_name: string, args: string[]) => Promise<void>;
mono_run_main_and_exit: (main_assembly_name: string, args: string[]) => Promise<number>;
/**
* @deprecated Please use config.assets instead
*/
Expand Down

0 comments on commit 906ec1d

Please sign in to comment.