Skip to content

Commit e2be4d3

Browse files
authored
Add WasiPlayground and don't use hashing on Wasi (#7191)
2 parents 5779603 + 4e6a588 commit e2be4d3

File tree

13 files changed

+129
-31
lines changed

13 files changed

+129
-31
lines changed

Microsoft.Testing.Platform.slnf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"projects": [
55
"samples\\FSharpPlayground\\FSharpPlayground.fsproj",
66
"samples\\Playground\\Playground.csproj",
7+
"samples\\WasiPlayground\\WasiPlayground.csproj",
78
"src\\Platform\\Microsoft.Testing.Extensions.AzureDevOpsReport\\Microsoft.Testing.Extensions.AzureDevOpsReport.csproj",
89
"src\\Platform\\Microsoft.Testing.Extensions.AzureFoundry\\Microsoft.Testing.Extensions.AzureFoundry.csproj",
910
"src\\Platform\\Microsoft.Testing.Extensions.CrashDump\\Microsoft.Testing.Extensions.CrashDump.csproj",

TestFx.slnx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<Project Path="samples/FSharpPlayground/FSharpPlayground.fsproj" />
44
<Project Path="samples/FxExtensibility/FxExtensibility.csproj" />
55
<Project Path="samples/Playground/Playground.csproj" />
6+
<Project Path="samples/WasiPlayground/WasiPlayground.csproj" />
67
</Folder>
78
<Folder Name="/Solution Items/">
89
<File Path=".editorconfig" />
@@ -72,6 +73,7 @@
7273
<Project Path="src/Package/MSTest.Sdk/MSTest.Sdk.csproj" />
7374
<Project Path="src/Package/MSTest/MSTest.csproj" />
7475
</Folder>
76+
<Folder Name="/src/Platform/" />
7577
<Folder Name="/test/">
7678
<File Path="test/.editorconfig" />
7779
<File Path="test/Directory.Build.props" />

samples/WasiPlayground/Program.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using Microsoft.Testing.Extensions;
5+
using Microsoft.Testing.Platform.Builder;
6+
using Microsoft.Testing.Platform.Capabilities.TestFramework;
7+
using Microsoft.Testing.Platform.Extensions.Messages;
8+
using Microsoft.Testing.Platform.Extensions.TestFramework;
9+
10+
ITestApplicationBuilder testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
11+
12+
testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, _) => new DummyFramework());
13+
14+
testApplicationBuilder.AddTrxReportProvider();
15+
testApplicationBuilder.AddAppInsightsTelemetryProvider();
16+
testApplicationBuilder.AddCrashDumpProvider();
17+
testApplicationBuilder.AddHangDumpProvider();
18+
testApplicationBuilder.AddAzureDevOpsProvider();
19+
using ITestApplication testApplication = await testApplicationBuilder.BuildAsync();
20+
return await testApplication.RunAsync();
21+
22+
internal sealed class DummyFramework : ITestFramework, IDataProducer
23+
{
24+
public string Uid => nameof(DummyFramework);
25+
26+
public string Version => "1.0.0";
27+
28+
public string DisplayName => "DummyFramework";
29+
30+
public string Description => DisplayName;
31+
32+
public Type[] DataTypesProduced => [typeof(TestNodeUpdateMessage)];
33+
34+
public Task<CloseTestSessionResult> CloseTestSessionAsync(CloseTestSessionContext context)
35+
=> Task.FromResult(new CloseTestSessionResult() { IsSuccess = true });
36+
37+
public Task<CreateTestSessionResult> CreateTestSessionAsync(CreateTestSessionContext context)
38+
=> Task.FromResult(new CreateTestSessionResult() { IsSuccess = true });
39+
40+
public async Task ExecuteRequestAsync(ExecuteRequestContext context)
41+
{
42+
await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, new TestNode()
43+
{
44+
DisplayName = "Test display name",
45+
Uid = "Uid1",
46+
Properties = new PropertyBag(PassedTestNodeStateProperty.CachedInstance),
47+
}));
48+
context.Complete();
49+
}
50+
51+
public Task<bool> IsEnabledAsync() => Task.FromResult(true);
52+
}

samples/WasiPlayground/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# WasiPlayground
2+
3+
To run this project:
4+
5+
1. Run `dotnet workload install wasi-experimental`
6+
2. Run `dotnet build`
7+
3. Install wasmtime. See docs at <https://docs.wasmtime.dev/cli-install.html>.
8+
4. Open command-line in AppBundle directory (`artifacts\bin\WasiPlayground\Debug\net10.0\wasi-wasm\AppBundle`)
9+
5. Run `wasmtime run --wasi http --dir . -- dotnet.wasm WasiPlayground`
10+
11+
## Status
12+
13+
As of today, this will produce this exception (it's not yet supported by MTP).
14+
15+
```console
16+
Unhandled Exception:
17+
System.PlatformNotSupportedException: Arg_PlatformNotSupported
18+
at System.Threading.Tasks.Task.InternalWaitCore(Int32 millisecondsTimeout, CancellationToken cancellationToken)
19+
at System.Threading.Tasks.Task.InternalWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
20+
at Program.<Main>(String[] args)
21+
```
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFrameworks>net10.0</TargetFrameworks>
6+
<RuntimeIdentifier>wasi-wasm</RuntimeIdentifier>
7+
<PublishTrimmed>true</PublishTrimmed>
8+
9+
<Nullable>enable</Nullable>
10+
<OutputType>Exe</OutputType>
11+
<IsTestingPlatformApplication>true</IsTestingPlatformApplication>
12+
</PropertyGroup>
13+
14+
<ItemGroup>
15+
<ProjectReference Include="$(RepoRoot)src\Platform\Microsoft.Testing.Platform\Microsoft.Testing.Platform.csproj" />
16+
<ProjectReference Include="$(RepoRoot)src\Platform\Microsoft.Testing.Extensions.CrashDump\Microsoft.Testing.Extensions.CrashDump.csproj" />
17+
<ProjectReference Include="$(RepoRoot)src\Platform\Microsoft.Testing.Extensions.HangDump\Microsoft.Testing.Extensions.HangDump.csproj" />
18+
<ProjectReference Include="$(RepoRoot)src\Platform\Microsoft.Testing.Extensions.TrxReport\Microsoft.Testing.Extensions.TrxReport.csproj" />
19+
<ProjectReference Include="$(RepoRoot)src\Platform\Microsoft.Testing.Extensions.Telemetry\Microsoft.Testing.Extensions.Telemetry.csproj" />
20+
<ProjectReference Include="$(RepoRoot)src\Platform\Microsoft.Testing.Extensions.AzureDevOpsReport\Microsoft.Testing.Extensions.AzureDevOpsReport.csproj" />
21+
</ItemGroup>
22+
23+
<ItemGroup>
24+
<ProjectCapability Include="DiagnoseCapabilities" />
25+
<ProjectCapability Include="TestingPlatformServer" />
26+
<ProjectCapability Include="TestContainer" />
27+
</ItemGroup>
28+
29+
</Project>

src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadHandler.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public HotReloadHandler(IConsole console, IOutputDevice outputDevice, IOutputDev
4646
[SupportedOSPlatformGuard("android")]
4747
[SupportedOSPlatformGuard("ios")]
4848
[SupportedOSPlatformGuard("tvos")]
49+
[SupportedOSPlatformGuard("wasi")]
4950
[SupportedOSPlatformGuard("browser")]
5051
private static bool IsCancelKeyPressNotSupported()
5152
=> RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")) ||

src/Platform/Microsoft.Testing.Platform/Helpers/Sha256Hasher.cs

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,12 @@ namespace Microsoft.Testing.Platform.Helpers;
1010
[ExcludeFromCodeCoverage]
1111
internal static class Sha256Hasher
1212
{
13+
// https://github.com/dotnet/runtime/issues/99126
14+
[UnsupportedOSPlatform("wasi")]
1315
public static string HashWithNormalizedCasing(string text)
1416
{
15-
try
16-
{
17-
byte[] bytes = Encoding.UTF8.GetBytes(text.ToUpperInvariant());
18-
byte[] hash = SHA256.HashData(bytes);
19-
return Convert.ToHexStringLower(hash);
20-
}
21-
catch (PlatformNotSupportedException)
22-
{
23-
// SHA256 is not supported on WASM WASI and similar platforms.
24-
// Fall back to a simple non-cryptographic hash for telemetry purposes.
25-
return ComputeNonCryptographicHash(text.ToUpperInvariant());
26-
}
27-
}
28-
29-
private static string ComputeNonCryptographicHash(string text)
30-
{
31-
// Use a simple deterministic hash for platforms without SHA256 support.
32-
// This is sufficient for telemetry correlation purposes.
33-
int hash = text.GetHashCode();
34-
byte[] hashBytes = BitConverter.GetBytes(hash);
35-
36-
// Expand to 32 bytes (SHA256 size) for consistency by repeating the pattern
37-
byte[] expandedHash = new byte[32];
38-
for (int i = 0; i < expandedHash.Length; i++)
39-
{
40-
expandedHash[i] = hashBytes[i % hashBytes.Length];
41-
}
42-
43-
return Convert.ToHexStringLower(expandedHash);
17+
byte[] bytes = Encoding.UTF8.GetBytes(text.ToUpperInvariant());
18+
byte[] hash = SHA256.HashData(bytes);
19+
return Convert.ToHexStringLower(hash);
4420
}
4521
}

src/Platform/Microsoft.Testing.Platform/Helpers/System/ITask.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ internal interface ITask
1212

1313
Task<T> Run<T>(Func<Task<T>?> function, CancellationToken cancellationToken);
1414

15+
[UnsupportedOSPlatform("browser")]
16+
[UnsupportedOSPlatform("wasi")]
1517
Task RunLongRunning(Func<Task> action, string name, CancellationToken cancellationToken);
1618

1719
Task WhenAll(params Task[] tasks);

src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemTask.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public Task<T> Run<T>(Func<Task<T>?> function, CancellationToken cancellationTok
1515
=> Task.Run(function, cancellationToken);
1616

1717
[UnsupportedOSPlatform("browser")]
18+
[UnsupportedOSPlatform("wasi")]
1819
public Task RunLongRunning(Func<Task> action, string name, CancellationToken cancellationToken)
1920
{
2021
// We create custom thread so we can assign the name that will help us to identify the thread in the dump

src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,11 @@ private void AddApplicationTelemetryMetadata(IServiceProvider serviceProvider, D
648648
?? _testApplicationModuleInfo.TryGetAssemblyName()
649649
?? "unknown";
650650

651-
builderMetadata[TelemetryProperties.HostProperties.TestHostPropertyName] = Sha256Hasher.HashWithNormalizedCasing(moduleName);
651+
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Create("WASI")))
652+
{
653+
builderMetadata[TelemetryProperties.HostProperties.TestHostPropertyName] = Sha256Hasher.HashWithNormalizedCasing(moduleName);
654+
}
655+
652656
builderMetadata[TelemetryProperties.HostProperties.FrameworkDescriptionPropertyName] = RuntimeInformation.FrameworkDescription;
653657
builderMetadata[TelemetryProperties.HostProperties.ProcessArchitecturePropertyName] = RuntimeInformation.ProcessArchitecture;
654658
builderMetadata[TelemetryProperties.HostProperties.OSArchitecturePropertyName] = RuntimeInformation.OSArchitecture;

0 commit comments

Comments
 (0)