Skip to content

Allow running on wasm platform #5366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jjonescz opened this issue Apr 3, 2025 · 6 comments
Open

Allow running on wasm platform #5366

jjonescz opened this issue Apr 3, 2025 · 6 comments
Assignees
Labels
Area: MTP Belongs to the Microsoft.Testing.Platform core library

Comments

@jjonescz
Copy link
Member

jjonescz commented Apr 3, 2025

Describe the bug

When I run MTP on wasi-wasm runtime, it fails.

Steps To Reproduce

Create wasi-wasm app with .NET 10 Preview 2

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <RuntimeIdentifier>wasi-wasm</RuntimeIdentifier>
    <OutputType>Exe</OutputType>
    <PublishTrimmed>true</PublishTrimmed>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="TUnit" Version="0.19.32" />
  </ItemGroup>
</Project>

Install wasi workload

dotnet workload install wasi-experimental

Build it

dotnet build

Run it

cd bin\Debug\net10.0\wasi-wasm\AppBundle
wasmtime run --wasi http --dir . -- dotnet.wasm App1

Expected behavior

Runs.

Actual behavior

Unhandled Exception:
System.PlatformNotSupportedException: Arg_PlatformNotSupported
   at System.Runtime.InteropServices.PosixSignalRegistration.Register(PosixSignal signal, Action`1 handler)
   at System.Runtime.InteropServices.PosixSignalRegistration.Create(PosixSignal signal, Action`1 handler)
   at System.Console.add_CancelKeyPress(ConsoleCancelEventHandler value)
   at Microsoft.Testing.Platform.Helpers.SystemConsole.add_CancelKeyPress(ConsoleCancelEventHandler value)
   at Microsoft.Testing.Platform.Services.CTRLPlusCCancellationTokenSource..ctor(IConsole console, ILogger logger)
   at Microsoft.Testing.Platform.Hosts.TestHostBuilder.BuildAsync(ApplicationLoggingState loggingState, TestApplicationOptions testApplicationOptions, IUnhandledExceptionsHandler unhandledExceptionsHandler, DateTimeOffset createBuilderStart)
   at Microsoft.Testing.Platform.Builder.TestApplicationBuilder.BuildAsync()
   at TestingPlatformEntryPoint.Main(String[] args)
   at TestingPlatformEntryPoint.<Main>(String[] args)

Additional context

This particular error would likely go away if WASM was added to this exclusion list:

[SupportedOSPlatformGuard("android")]
[SupportedOSPlatformGuard("ios")]
[SupportedOSPlatformGuard("tvos")]
[SupportedOSPlatformGuard("browser")]
private static bool IsCancelKeyPressNotSupported()
=> RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")) ||
RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")) ||
RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")) ||
RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"));

Then more places might need fixing similarly. I'm not sure if there is anything else blocking wasm support, would need to get past the first error and see what happens next.

Similar issue: #2196

@Youssef1313 Youssef1313 added the Area: MTP Belongs to the Microsoft.Testing.Platform core library label Apr 3, 2025
@Youssef1313
Copy link
Member

Youssef1313 commented Apr 3, 2025

We were following the same as runtime when annotating the API:

https://github.com/dotnet/runtime/blob/15872212c29cecc8d82da4548c3060f2614665f7/src/libraries/System.Console/src/System/Console.cs#L560-L564

(On our side, we are missing <SupportedPlatform Include="wasi" /> though, but then we still won't get warnings because the annotations on .NET runtime may not be accurate.

@Youssef1313
Copy link
Member

Youssef1313 commented Apr 5, 2025

@jjonescz Can you please try with 1.7.0-preview.25204.3 from feed https://pkgs.dev.azure.com/dnceng/public/_packaging/test-tools/nuget/v3/index.json and let me know what the next issue (if any) is please

@jjonescz
Copy link
Member Author

jjonescz commented Apr 5, 2025

Next up is banner:

System.PlatformNotSupportedException: SystemRuntimeInteropServicesJavaScript_PlatformNotSupported
   at System.Runtime.InteropServices.JavaScript.JSMarshalerType.get_Discard()
   at Microsoft.Testing.Platform.OutputDevice.BrowserOutputDevice.ConsoleLog(String message)
   at Microsoft.Testing.Platform.OutputDevice.BrowserOutputDevice.DisplayBannerAsync(String bannerMessage)
   at Microsoft.Testing.Platform.OutputDevice.ProxyOutputDevice.DisplayBannerAsync(String bannerMessage)
   at Microsoft.Testing.Platform.Hosts.TestHostBuilder.DisplayBannerIfEnabledAsync(ApplicationLoggingState loggingState, ProxyOutputDevice outputDevice, ITestFrameworkCapabilities testFrameworkCapabilities)
   at Microsoft.Testing.Platform.Hosts.TestHostBuilder.BuildAsync(ApplicationLoggingState loggingState, TestApplicationOptions testApplicationOptions, IUnhandledExceptionsHandler unhandledExceptionsHandler, DateTimeOffset createBuilderStart)
   at Microsoft.Testing.Platform.Builder.TestApplicationBuilder.BuildAsync()
   at TestingPlatformEntryPoint.Main(String[] args)
   at TestingPlatformEntryPoint.<Main>(String[] args)

But I can work around that by passing --env TESTINGPLATFORM_NOBANNER=1 to wasmtime.

Next up is SHA256:

System.PlatformNotSupportedException: SystemSecurityCryptography_PlatformNotSupported
   at System.Security.Cryptography.SHA256.HashData(Byte[] source)
   at Microsoft.Testing.Platform.Helpers.Sha256Hasher.Hash(String text)
   at Microsoft.Testing.Platform.Helpers.Sha256Hasher.HashWithNormalizedCasing(String text)
   at Microsoft.Testing.Platform.Hosts.TestHostBuilder.AddApplicationMetadata(IServiceProvider serviceProvider, Dictionary`2 builderMetadata)
   at Microsoft.Testing.Platform.Hosts.TestHostBuilder.BuildAsync(ApplicationLoggingState loggingState, TestApplicationOptions testApplicationOptions, IUnhandledExceptionsHandler unhandledExceptionsHandler, DateTimeOffset createBuilderStart)
   at Microsoft.Testing.Platform.Builder.TestApplicationBuilder.BuildAsync()
   at TestingPlatformEntryPoint.Main(String[] args)
   at TestingPlatformEntryPoint.<Main>(String[] args)

That's tracked by dotnet/runtime#99126. I don't think it makes sense to add a workaround for this in testfx. So feel free to close this issue. Thanks!

@Youssef1313
Copy link
Member

But I can work around that by passing --env TESTINGPLATFORM_NOBANNER=1 to wasmtime.

That won't be sufficient as ConsoleLog will be called in other code paths later that are not controllable via env variables. But generally I think we will need proper API annotations from .NET runtime so we get analyzer warnings instead of chasing things one-by-one this way.

For SHA256, this code path is for telemetry, which we can completely skip automatically when we know the API is not supported. Or you can also opt-out by setting TESTINGPLATFORM_TELEMETRY_OPTOUT environment variable to 1. But I'm expecting you will get to BrowserOutputDevice.ConsoleLog again.

I'm also not sure what differences are between wasi and browser. In BrowserOutputDevice we simply try to call console.log but looks like this doesn't work in wasi. Then I'm not sure if our regular TerminalOutputDevice will work or not, and what's the current threading support status for wasi. To my last knowledge for browser, it's an opt-in feature? I expect wasi to probably be the same?

@lewing Is wasi expected to still be experimental when .NET 10 is GA?

@jjonescz
Copy link
Member Author

jjonescz commented Apr 5, 2025

I think we will need proper API annotations from .NET runtime so we get analyzer warnings instead of chasing things one-by-one this way.

Yes, that's mentioned in dotnet/runtime#99126 (comment) - there are no annotations yet since wasi-wasm is experimental.

Or you can also opt-out by setting TESTINGPLATFORM_TELEMETRY_OPTOUT environment variable to 1.

Thanks, fwiw, after that I get to this point:

System.PlatformNotSupportedException: Arg_PlatformNotSupported
   at System.Threading.Tasks.Task.InternalWaitCore(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.InternalWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at TestingPlatformEntryPoint.<Main>(String[] args)

As you say, that's probably because threading is not supported.

@Youssef1313
Copy link
Member

Youssef1313 commented Apr 5, 2025

Hmm, I'm interpreting the last one for Task.InternalWait as any async Main entry point that doesn't completely synchronously isn't going to work. e.g, a simple await Task.Delay(...) in async Main won't work. I'll need to discuss more with runtime team to better understand the current situation, what's supported and what is not, and when more support is expected to happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: MTP Belongs to the Microsoft.Testing.Platform core library
Projects
None yet
Development

No branches or pull requests

2 participants