diff --git a/Directory.Build.props b/Directory.Build.props
index d957a798303ade..94fde902d806a5 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -71,6 +71,7 @@
$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', 'Debug', '$(NetCoreAppToolCurrent)', 'publish'))
$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'WasmAppBuilder', 'Debug', '$(NetCoreAppToolCurrent)', 'publish'))
$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'WasmBuildTasks', 'Debug', '$(NetCoreAppToolCurrent)', 'publish'))
+ $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'WorkloadBuildTasks', 'Debug', '$(NetCoreAppToolCurrent)', 'publish'))
$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', 'Debug', '$(NetCoreAppToolCurrent)'))
$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'RuntimeConfigParser', 'Debug', '$(NetCoreAppToolCurrent)'))
@@ -82,6 +83,7 @@
$([MSBuild]::NormalizePath('$(AndroidAppBuilderDir)', 'AndroidAppBuilder.dll'))
$([MSBuild]::NormalizePath('$(WasmAppBuilderDir)', 'WasmAppBuilder.dll'))
$([MSBuild]::NormalizePath('$(WasmBuildTasksDir)', 'WasmBuildTasks.dll'))
+ $([MSBuild]::NormalizePath('$(WorkloadBuildTasksDir)', 'WorkloadBuildTasks.dll'))
$([MSBuild]::NormalizePath('$(MonoAOTCompilerDir)', 'MonoAOTCompiler.dll'))
$([MSBuild]::NormalizePath('$(RuntimeConfigParserDir)', 'RuntimeConfigParser.dll'))
$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'coreclr', '$(TargetOS).$(TargetArchitecture).$(Configuration)'))
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 1a6424850bbcdf..b758afbe200d9b 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -210,7 +210,7 @@
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
b89374348ff2344a625677584be9dfc9bea2b971
-
+
https://github.com/dotnet/emsdk
f5349765b7af1970c5b25cce4ed278544907cbe0
diff --git a/eng/Versions.props b/eng/Versions.props
index d8104e89eb4447..43f671458a6ab3 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -159,6 +159,7 @@
2.0.4
4.12.0
2.14.3
+ 6.0.100-preview.7.21326.4
5.0.0-preview-20201009.2
@@ -178,7 +179,7 @@
11.1.0-alpha.1.21328.1
11.1.0-alpha.1.21328.1
- 6.0.0-preview.7.21330.1
- $(MicrosoftNETRuntimeEmscripten2023Nodewinx64Version)
+ 6.0.0-preview.7.21330.1
+ $(MicrosoftNETWorkloadEmscriptenManifest60100)
diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml
index 666641354bf5a6..cf984c79847739 100644
--- a/eng/pipelines/runtime-staging.yml
+++ b/eng/pipelines/runtime-staging.yml
@@ -389,6 +389,7 @@ jobs:
extraHelixArguments: /p:BrowserHost=windows
scenarios:
- normal
+ - buildwasmapps
condition: >-
or(
eq(variables['librariesContainsChange'], true),
diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets
index 517ebf719850c1..c3107ec4a060a7 100644
--- a/eng/testing/tests.mobile.targets
+++ b/eng/testing/tests.mobile.targets
@@ -7,6 +7,10 @@
true
BundleTestAppleApp;BundleTestAndroidApp
+
+
+ true
@@ -291,5 +295,10 @@
AfterTargets="Build"
DependsOnTargets="Publish;$(BundleTestAppTargets);ArchiveTests" />
+
+
diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets
index dd40856e629b1b..1e7ec3b173dc33 100644
--- a/eng/testing/tests.targets
+++ b/eng/testing/tests.targets
@@ -1,13 +1,15 @@
-
+
RunnerTemplate.cmd
RunnerTemplate.sh
AppleRunnerTemplate.sh
AndroidRunnerTemplate.sh
WasmRunnerTemplate.sh
WasmRunnerTemplate.cmd
+
- $(MSBuildThisFileDirectory)$(RunScriptInputName)
+
+ $(MSBuildThisFileDirectory)$(RunScriptInputName)
RunTests.sh
RunTests.cmd
diff --git a/eng/testing/tests.wasm.targets b/eng/testing/tests.wasm.targets
index aa4fb305dbd425..cd2fa3e4e131d1 100644
--- a/eng/testing/tests.wasm.targets
+++ b/eng/testing/tests.wasm.targets
@@ -60,6 +60,11 @@
$(BundleTestWasmAppDependsOn);_BundleAOTTestWasmAppForHelix
+
+
+
+
+
--interpreter
+
+ $(ArtifactsBinDir)dotnet-workload\
+ $([MSBuild]::NormalizeDirectory($(SdkPathForWorkloadTesting)))
+
+ $(SdkPathForWorkloadTesting)version-$(SdkVersionForWorkloadTesting).stamp
+
+
diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets
index b10705260f4fcf..8107182949bc38 100644
--- a/src/libraries/Directory.Build.targets
+++ b/src/libraries/Directory.Build.targets
@@ -7,6 +7,11 @@
$(TestStrongNameKeyId)
+
+ true
+ $(SdkPathForWorkloadTesting)workload.stamp
+
+
@@ -346,4 +351,87 @@
Text="Analyzers must only target netstandard2.0 since they run in the compiler which targets netstandard2.0. The following files were found to target '%(_AnalyzerPackFile.TargetFramework)': @(_AnalyzerPackFile)" />
+
+
+
+
+
+
+
+
+
+ <_DotNetInstallScriptPath Condition="!$([MSBuild]::IsOSPlatform('windows'))">$(DOTNET_INSTALL_DIR)/dotnet-install.sh
+ <_DotNetInstallScriptPath Condition=" $([MSBuild]::IsOSPlatform('windows'))">$(DOTNET_INSTALL_DIR)/dotnet-install.ps1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_NuGetSourceForWorkloads Include="dotnet6" Value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json" />
+
+
+
+
+
+
+
+ $(SdkPathForWorkloadTesting)packs\Microsoft.NETCore.App.Runtime.AOT.$(NETCoreSdkRuntimeIdentifier).Cross.$(RuntimeIdentifier)\$(PackageVersion)
+
+
+
+
+
+
+
+ <_SdkPropsProperties Condition="!$([MSBuild]::IsOsPlatform('Windows'))" Include="ExeSuffix" Value="" />
+ <_SdkPropsProperties Condition="$([MSBuild]::IsOsPlatform('Windows'))" Include="ExeSuffix" Value=".exe" />
+ <_SdkPropsProperties Include="TargetRid" Value="browser-wasm" />
+
+
+
+
+
+
+
+
diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj
index 3e924e083abd51..fc2fee13d5c33c 100644
--- a/src/libraries/pretest.proj
+++ b/src/libraries/pretest.proj
@@ -22,6 +22,9 @@
+
+
+
- <_ProjectsToBuild Include="$(PerScenarioProjectFile)">
+ <_BaseProjectsToBuild Include="$(PerScenarioProjectFile)" Condition="'%(_Scenarios.Identity)' != 'buildwasmapps'">
$(_PropertiesToPass);Scenario=%(_Scenarios.Identity);TestArchiveRuntimeFile=$(TestArchiveRuntimeFile)
- %(_ProjectsToBuild.AdditionalProperties);NeedsToBuildWasmAppsOnHelix=$(NeedsToBuildWasmAppsOnHelix)
-
+ %(_BaseProjectsToBuild.AdditionalProperties);NeedsToBuildWasmAppsOnHelix=$(NeedsToBuildWasmAppsOnHelix)
+
+
+
+
+ <_TestValues Include="true;false" />
+
+ <_OtherProjectsToBuild Include="$(PerScenarioProjectFile)">
+ $(_PropertiesToPass);Scenario=BuildWasmApps;TestArchiveRuntimeFile=$(TestArchiveRuntimeFile);TestUsingWorkloads=%(_TestValues.Identity)
+ %(_OtherProjectsToBuild.AdditionalProperties);NeedsToBuildWasmAppsOnHelix=$(NeedsToBuildWasmAppsOnHelix)
+
+
+
+
+ <_ProjectsToBuild Include="@(_BaseProjectsToBuild);@(_OtherProjectsToBuild)" />
diff --git a/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj
index 12d402fcb7e397..49d45b7c6053a0 100644
--- a/src/libraries/sendtohelixhelp.proj
+++ b/src/libraries/sendtohelixhelp.proj
@@ -7,6 +7,7 @@
true
+ true
$(BUILD_BUILDNUMBER)
@@ -53,6 +54,9 @@
$(WaitForWorkItemCompletion)
true
+
+ true
+ true
@@ -97,7 +101,7 @@
true
- true
+ true
@@ -105,11 +109,21 @@
-
- true
- true
- true
-
+
+
+
+ false
+ true
+
+
+
+
+ true
+ true
+ true
+
+
+
- powershell -command "New-SelfSignedCertificate -FriendlyName 'ASP.NET Core HTTPS development certificate' -DnsName @('localhost') -Subject 'CN = localhost' -KeyAlgorithm RSA -KeyLength 2048 -HashAlgorithm sha256 -CertStoreLocation 'Cert:\CurrentUser\My' -TextExtension @('2.5.29.37={text}1.3.6.1.5.5.7.3.1','1.3.6.1.4.1.311.84.1.1={hex}02','2.5.29.19={text}') -KeyUsage DigitalSignature,KeyEncipherment" &&
-
-
- $(HelixCommand)call RunTests.cmd
- $(HelixCommand) --runtime-path %HELIX_CORRELATION_PAYLOAD%
-
- $(HelixCommand)./RunTests.sh
- $(HelixCommand) --runtime-path "$HELIX_CORRELATION_PAYLOAD"
-
-
@@ -224,6 +228,34 @@
+
+ @(HelixPreCommand)
+ $(HelixCommandPrefix) @(HelixCommandPrefixItem -> 'set %(Identity)', ' & ')
+ $(HelixCommandPrefix) @(HelixCommandPrefixItem, ' ')
+ true
+
+
+
+ $(HelixCommandPrefix)
+ $(HelixCommandPrefix) &
+
+ $(HelixCommand) dotnet dev-certs https &&
+
+
+ $(HelixCommand) powershell -command "New-SelfSignedCertificate -FriendlyName 'ASP.NET Core HTTPS development certificate' -DnsName @('localhost') -Subject 'CN = localhost' -KeyAlgorithm RSA -KeyLength 2048 -HashAlgorithm sha256 -CertStoreLocation 'Cert:\CurrentUser\My' -TextExtension @('2.5.29.37={text}1.3.6.1.5.5.7.3.1','1.3.6.1.4.1.311.84.1.1={hex}02','2.5.29.19={text}') -KeyUsage DigitalSignature,KeyEncipherment" &&
+
+
+ $(HelixCommand)call RunTests.cmd
+ $(HelixCommand) --runtime-path %HELIX_CORRELATION_PAYLOAD%
+
+ $(HelixCommand)./RunTests.sh
+ $(HelixCommand) --runtime-path "$HELIX_CORRELATION_PAYLOAD"
+
+
@@ -302,7 +334,15 @@
-
+
+
+
+
+
+
+
+
@@ -311,7 +351,7 @@
-
+
@@ -374,7 +414,7 @@
-
+
@@ -392,6 +432,7 @@
+
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 34588fb46c28cc..35dd69f071a68f 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -349,9 +349,11 @@
Condition="'$(TestTrimming)' == 'true'"
AdditionalProperties="%(AdditionalProperties);SkipTrimmingProjectsRestore=true" />
+
+
@@ -378,10 +380,11 @@
BuildInParallel="false" />
-
+
+
+ BuildInParallel="true" />
diff --git a/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj b/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj
index 874775fe7e47f2..3db38ddbbe86a2 100644
--- a/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj
+++ b/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj
@@ -3,6 +3,7 @@
Provides the tasks+targets, for consumption by wasm based workloads
+ $(IntermediateOutputPath)AutoImport.props
@@ -10,12 +11,23 @@
-
+
+
+
+ <_AutoImportValues Include="PackageVersion" Value="$(PackageVersion)" />
+
+
+
+
+
diff --git a/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/AutoImport.props b/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/AutoImport.props
deleted file mode 100644
index f29ea9ae7da307..00000000000000
--- a/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/AutoImport.props
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- true
-
-
\ No newline at end of file
diff --git a/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/AutoImport.props.in b/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/AutoImport.props.in
new file mode 100644
index 00000000000000..f925992ce31e4f
--- /dev/null
+++ b/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/AutoImport.props.in
@@ -0,0 +1,8 @@
+
+
+ true
+ true
+ ${PackageVersion}
+ $([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', '..', '..'))
+
+
diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/Microsoft.NET.Workload.Mono.Toolchain.Manifest.pkgproj b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/Microsoft.NET.Workload.Mono.Toolchain.Manifest.pkgproj
index 0f6c403f4104e4..747da02070f2f9 100644
--- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/Microsoft.NET.Workload.Mono.Toolchain.Manifest.pkgproj
+++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/Microsoft.NET.Workload.Mono.Toolchain.Manifest.pkgproj
@@ -13,11 +13,12 @@
$(IntermediateOutputPath)WorkloadManifest.json
+ $(IntermediateOutputPath)WorkloadManifest.targets
-
+
@@ -37,6 +38,11 @@
TemplateFile="WorkloadManifest.json.in"
Properties="@(_WorkloadManifestValues)"
OutputPath="$(WorkloadManifestPath)" />
+
+
diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.json.in b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.json.in
index 4c50a08f007c82..b6d9d465f8a53a 100644
--- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.json.in
+++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.json.in
@@ -1,5 +1,8 @@
{
"version": "${WorkloadVersion}",
+ "depends-on": {
+ "Microsoft.NET.Workload.Emscripten": "${EmscriptenVersion}"
+ }
"workloads": {
"microsoft-net-sdk-blazorwebassembly-aot": {
"description": "Browser Runtime native performance tools",
@@ -11,7 +14,7 @@
"Microsoft.NET.Runtime.Emscripten.Python",
"Microsoft.NET.Runtime.Emscripten.Sdk"
],
- "extends": [ "microsoft-net-runtime-mono-tooling" ],
+ "extends": [ "microsoft-net-runtime-mono-tooling", "microsoft-net-sdk-emscripten" ],
"platforms": [ "win-x64", "linux-x64", "osx-x64", "osx-arm64" ]
},
"microsoft-net-runtime-android": {
@@ -154,13 +157,13 @@
"osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-arm64"
}
},
- "Microsoft.NETCore.App.Runtime.Mono.maccatalyst": {
+ "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-arm64": {
+ "kind": "framework",
+ "version": "${PackageVersion}",
+ },
+ "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64": {
"kind": "framework",
"version": "${PackageVersion}",
- "alias-to": {
- "osx-arm64": "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-arm64",
- "osx-x64": "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64"
- }
},
"Microsoft.NETCore.App.Runtime.Mono.ios-arm" : {
"kind": "framework",
@@ -170,54 +173,67 @@
"kind": "framework",
"version": "${PackageVersion}"
},
- "Microsoft.NETCore.App.Runtime.Mono.iossimulator" : {
+ "Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64" : {
+ "kind": "framework",
+ "version": "${PackageVersion}",
+ },
+ "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x64" : {
"kind": "framework",
"version": "${PackageVersion}",
- "alias-to": {
- "osx-arm64": "Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64",
- "osx-x64": "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x64"
- }
},
"Microsoft.NETCore.App.Runtime.Mono.iossimulator-x86" : {
"kind": "framework",
"version": "${PackageVersion}",
- "alias-to": {
- "osx-x64": "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x86"
- }
},
"Microsoft.NETCore.App.Runtime.AOT.Cross.tvos-arm64": {
"kind": "Sdk",
"version": "${PackageVersion}",
"alias-to": {
- "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvos-arm64",
"osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvos-arm64",
+ "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvos-arm64",
}
},
"Microsoft.NETCore.App.Runtime.Mono.tvos-arm64" : {
"kind": "framework",
"version": "${PackageVersion}"
},
- "Microsoft.NETCore.App.Runtime.Mono.tvossimulator" : {
+ "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-arm64" : {
"kind": "framework",
"version": "${PackageVersion}",
+ },
+ "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-x64" : {
+ "kind": "framework",
+ "version": "${PackageVersion}",
+ },
+ "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst-arm64": {
+ "kind": "Sdk",
+ "version": "${PackageVersion}",
"alias-to": {
- "osx-arm64": "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-arm64",
- "osx-x64": "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-x64"
+ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-arm64",
+ "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-arm64"
}
},
- "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst": {
+ "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst-x64": {
"kind": "Sdk",
"version": "${PackageVersion}",
"alias-to": {
- "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-arm64",
+ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-x64",
"osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-x64"
}
},
- "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator": {
+ "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator-arm64": {
"kind": "Sdk",
"version": "${PackageVersion}",
"alias-to": {
"osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-arm64",
+ "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-arm64"
+ }
+ },
+ "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator-x64": {
+ "kind": "Sdk",
+ "version": "${PackageVersion}",
+ "alias-to": {
+ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-x64",
"osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-x64"
}
},
@@ -237,11 +253,19 @@
"osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.ios-arm64",
}
},
- "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator": {
+ "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-arm64": {
"kind": "Sdk",
"version": "${PackageVersion}",
"alias-to": {
"osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-arm64",
+ "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-arm64"
+ }
+ },
+ "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x64": {
+ "kind": "Sdk",
+ "version": "${PackageVersion}",
+ "alias-to": {
+ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x64",
"osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x64"
}
},
@@ -249,6 +273,7 @@
"kind": "Sdk",
"version": "${PackageVersion}",
"alias-to": {
+ "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x86",
"osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x86"
}
},
@@ -266,34 +291,5 @@
"kind": "framework",
"version": "${PackageVersion}"
},
- "Microsoft.NET.Runtime.Emscripten.Node" : {
- "kind": "Sdk",
- "version": "${EmscriptenVersion}",
- "alias-to": {
- "win-x64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Node.win-x64",
- "linux-x64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Node.linux-x64",
- "osx-x64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Node.osx-x64",
- "osx-arm64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Node.osx-x64"
- }
- },
- "Microsoft.NET.Runtime.Emscripten.Python" : {
- "kind": "Sdk",
- "version": "${EmscriptenVersion}",
- "alias-to": {
- "win-x64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Python.win-x64",
- "osx-x64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Python.osx-x64",
- "osx-arm64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Python.osx-x64"
- }
- },
- "Microsoft.NET.Runtime.Emscripten.Sdk" : {
- "kind": "Sdk",
- "version": "${EmscriptenVersion}",
- "alias-to": {
- "win-x64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64",
- "linux-x64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.linux-x64",
- "osx-x64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.osx-x64",
- "osx-arm64": "Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.osx-x64"
- }
- }
}
-}
\ No newline at end of file
+}
diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets.in
similarity index 54%
rename from src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets
rename to src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets.in
index 2102eabc36ce6d..c2cd58193ceb64 100644
--- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets
+++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets.in
@@ -1,4 +1,9 @@
+
+ ${PackageVersion}
+ true
+
+
true
$(WasmNativeWorkload)
@@ -20,27 +25,55 @@
+
+
-
+
+
+
-
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+ <_MonoWorkloadTargetsMobile>true
+ <_MonoWorkloadRuntimePackPackageVersion>${PackageVersion}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mono/wasm/build/WasmApp.LocalBuild.props b/src/mono/wasm/build/WasmApp.LocalBuild.props
index 01003f59172fa3..69a719a0e6d1e1 100644
--- a/src/mono/wasm/build/WasmApp.LocalBuild.props
+++ b/src/mono/wasm/build/WasmApp.LocalBuild.props
@@ -22,6 +22,9 @@
+
+ true
+
<_NetCoreAppToolCurrent>net6.0
diff --git a/src/mono/wasm/build/WasmApp.LocalBuild.targets b/src/mono/wasm/build/WasmApp.LocalBuild.targets
index 636f0b1d257b94..fac5252a4ef34a 100644
--- a/src/mono/wasm/build/WasmApp.LocalBuild.targets
+++ b/src/mono/wasm/build/WasmApp.LocalBuild.targets
@@ -37,14 +37,14 @@
false
-
-
+
$(MicrosoftNetCoreAppRuntimePackLocationToUse)
+
-
+
diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets
index e1de26e4a4cde8..218635961a4bc1 100644
--- a/src/mono/wasm/build/WasmApp.Native.targets
+++ b/src/mono/wasm/build/WasmApp.Native.targets
@@ -31,11 +31,6 @@
<_ExeExt Condition="$([MSBuild]::IsOSPlatform('WINDOWS'))">.exe
true
- $([MSBuild]::NormalizeDirectory($(NuGetPackageRoot), 'microsoft.netcore.app.runtime.mono.browser-wasm', '$(BundledNETCoreAppPackageVersion)'))
- $([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackDir), 'runtimes', 'browser-wasm'))
- $([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidDir)))
- $([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidDir), 'native'))
-
<_WasmRuntimePackIncludeDir>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'include'))
<_WasmRuntimePackSrcDir>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'src'))
<_EmccPropsPath>$(_WasmRuntimePackSrcDir)Emcc.props
@@ -177,11 +172,6 @@
<_EmccCommonFlags Include="-v" Condition="'$(EmccVerbose)' != 'false'" />
-
- <_WasmRuntimePackIncludeDir>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'include'))
- <_WasmRuntimePackSrcDir>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'src'))
-
-
<_DotnetJSSrcFile Include="$(_WasmRuntimePackSrcDir)\*.js" />
@@ -360,6 +350,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_aot (const char *desc) { mono_
+
<_MonoAotCrossCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','browser-wasm'))
diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets
index 034287436892bf..73641884666315 100644
--- a/src/mono/wasm/build/WasmApp.targets
+++ b/src/mono/wasm/build/WasmApp.targets
@@ -81,7 +81,12 @@
false
+
+ $([MSBuild]::NormalizeDirectory($(WorkloadPacksDir), 'Microsoft.NETCore.App.Runtime.Mono.browser-wasm', '$(RuntimePackInWorkloadVersion)'))
+
+
$([MSBuild]::NormalizeDirectory($(NuGetPackageRoot), 'microsoft.netcore.app.runtime.mono.browser-wasm', '$(BundledNETCoreAppPackageVersion)'))
+
$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackDir), 'runtimes', 'browser-wasm'))
$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidDir)))
$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidDir), 'native'))
diff --git a/src/mono/wasm/data/aot-tests/ProxyProjectForAOTOnHelix.proj b/src/mono/wasm/data/aot-tests/ProxyProjectForAOTOnHelix.proj
index cdd5e95a4e2108..3a7b66fac7389f 100644
--- a/src/mono/wasm/data/aot-tests/ProxyProjectForAOTOnHelix.proj
+++ b/src/mono/wasm/data/aot-tests/ProxyProjectForAOTOnHelix.proj
@@ -22,7 +22,7 @@
-
diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj
index ffc2fb92825ba5..4c5983255908cc 100644
--- a/src/mono/wasm/wasm.proj
+++ b/src/mono/wasm/wasm.proj
@@ -107,7 +107,7 @@
<_EmccVersionRaw>%(_ReversedVersionLines.Identity)
- <_EmccVersionRegexPattern>^ *emcc \([^\)]+\) *([^ \(]+) *\(([^\)]+)\)$
+ <_EmccVersionRegexPattern>^ *emcc \([^\)]+\) *([0-9\.]+).*\(([^\)]+)\)$
<_EmccVersion>$([System.Text.RegularExpressions.Regex]::Match($(_EmccVersionRaw), $(_EmccVersionRegexPattern)).Groups[1].Value)
<_EmccVersionHash>$([System.Text.RegularExpressions.Regex]::Match($(_EmccVersionRaw), $(_EmccVersionRegexPattern)).Groups[2].Value)
diff --git a/src/tasks/Common/Utils.cs b/src/tasks/Common/Utils.cs
index ea2aba607dd8e0..7b25107d56f983 100644
--- a/src/tasks/Common/Utils.cs
+++ b/src/tasks/Common/Utils.cs
@@ -185,12 +185,12 @@ internal static string CreateTemporaryBatchFile(string command)
}
#if NETCOREAPP
- public static void DirectoryCopy(string sourceDir, string destDir, Func predicate)
+ public static void DirectoryCopy(string sourceDir, string destDir, Func? predicate=null)
{
string[] files = Directory.GetFiles(sourceDir, "*", SearchOption.AllDirectories);
foreach (string file in files)
{
- if (!predicate(file))
+ if (predicate != null && !predicate(file))
continue;
string relativePath = Path.GetRelativePath(sourceDir, file);
diff --git a/src/tasks/WorkloadBuildTasks/InstallWorkload.cs b/src/tasks/WorkloadBuildTasks/InstallWorkload.cs
new file mode 100644
index 00000000000000..063862273ad053
--- /dev/null
+++ b/src/tasks/WorkloadBuildTasks/InstallWorkload.cs
@@ -0,0 +1,475 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+#nullable enable
+
+namespace Microsoft.Workload.Build.Tasks
+{
+ public class InstallWorkload : Task
+ {
+ [Required, NotNull]
+ public ITaskItem? WorkloadId { get; set; }
+
+ [Required, NotNull]
+ public ITaskItem? ManifestPackage { get; set; }
+
+ [Required, NotNull]
+ public ITaskItem? BuiltNuGetsPath { get; set; }
+
+ [Required, NotNull]
+ public string? OutputDir { get; set; }
+
+ public ITaskItem[]? ExtraNuGetSources { get; set; }
+ public string? Rid { get; set; }
+
+ private readonly string _tempDir = Path.Combine(Path.GetTempPath(), "install-workload", Path.GetRandomFileName());
+ private string? _packsDir;
+ private const string s_stampFileName = ".installed.stamp";
+
+ private static string? GetRid()
+ {
+ if (OperatingSystem.IsWindows())
+ return Environment.Is64BitProcess ? "win-x64": "win-x86";
+ else if (OperatingSystem.IsMacOS())
+ return "osx-x64";
+ else if (OperatingSystem.IsLinux())
+ return "linux-x64";
+ else
+ return null;
+ }
+
+ public override bool Execute()
+ {
+ Utils.Logger = Log;
+
+ if (!HasMetadata(ManifestPackage, nameof(ManifestPackage), "VersionBand") ||
+ !HasMetadata(ManifestPackage, nameof(ManifestPackage), "Version") ||
+ !HasMetadata(WorkloadId, nameof(WorkloadId), "Name"))
+ {
+ return false;
+ }
+
+ if (!Directory.Exists(OutputDir))
+ {
+ Log.LogError($"Cannot find OutputDir={OutputDir}");
+ return false;
+ }
+
+ _packsDir = Path.Combine(OutputDir, "packs");
+ Rid ??= GetRid();
+ if (Rid == null)
+ {
+ Log.LogError("Unsupported platform");
+ return false;
+ }
+
+ if (!InstallWorkloadManifest(out ManifestInformation? manifest, out string? manifestNupkgPath))
+ return false;
+
+ IEnumerable references = GetPackageReferencesForWorkload(manifest, WorkloadId.ItemSpec);
+ IEnumerable remaining = LayoutPacksFromBuiltNuGets(references);
+ if (!remaining.Any())
+ return !Log.HasLoggedErrors;
+
+ if (!InstallPacksWithNuGetRestore(remaining))
+ return false;
+
+ return !Log.HasLoggedErrors;
+ }
+
+ private bool InstallWorkloadManifest([NotNullWhen(true)] out ManifestInformation? manifest, [NotNullWhen(true)] out string? manifestNupkgPath)
+ {
+ manifest = null;
+ manifestNupkgPath = null;
+
+ string builtNuGetsFullPath = BuiltNuGetsPath.GetMetadata("FullPath");
+ string pkgName = ManifestPackage.ItemSpec;
+ string pkgVersion = ManifestPackage.GetMetadata("Version");
+
+ var nupkgFileName = $"{pkgName}.{pkgVersion}.nupkg";
+ var nupkgPath = Path.Combine(builtNuGetsFullPath, nupkgFileName);
+ if (!File.Exists(nupkgPath))
+ {
+ Log.LogError($"Could not find nupkg for the manifest at {nupkgPath}");
+ return false;
+ }
+
+ string baseManifestDir = Path.Combine(OutputDir, "sdk-manifests");
+
+ string tmpManifestDir = Path.Combine(_tempDir, "manifest");
+ ZipFile.ExtractToDirectory(nupkgPath, tmpManifestDir);
+
+ var sourceManifestDirectory = Path.Combine(tmpManifestDir, "data");
+ var targetManifestDirectory = Path.Combine(baseManifestDir, ManifestPackage.GetMetadata("VersionBand"), WorkloadId.GetMetadata("Name"));
+ if (!CopyDirectory(sourceManifestDirectory, targetManifestDirectory))
+ return false;
+
+ string jsonPath = Path.Combine(targetManifestDirectory, "WorkloadManifest.json");
+ if (!File.Exists(jsonPath))
+ {
+ Log.LogError($"Could not find WorkloadManifest.json at {jsonPath}");
+ return false;
+ }
+
+ manifest = JsonSerializer.Deserialize(
+ File.ReadAllBytes(jsonPath),
+ new JsonSerializerOptions(JsonSerializerDefaults.Web)
+ {
+ AllowTrailingCommas = true,
+ ReadCommentHandling = JsonCommentHandling.Skip
+ });
+
+ if (manifest == null)
+ {
+ Log.LogError($"Could not parse manifest from {jsonPath}.");
+ return false;
+ }
+
+ manifestNupkgPath = nupkgPath;
+ return true;
+ }
+
+ private IEnumerable LayoutPacksFromBuiltNuGets(IEnumerable references)
+ {
+ string builtNuGetsFullPath = BuiltNuGetsPath.GetMetadata("FullPath");
+
+ var allFiles = string.Join($"{Environment.NewLine} ", Directory.EnumerateFiles(builtNuGetsFullPath, "*", new EnumerationOptions { RecurseSubdirectories = true }));
+ Log.LogMessage(MessageImportance.Low, $"Files in {builtNuGetsFullPath}: {allFiles}");
+
+ List remaining = new(references.Count());
+ foreach (var reference in references)
+ {
+ var nupkgFileName = $"{reference.Name}.{reference.Version}.nupkg";
+ var nupkgPath = Path.Combine(builtNuGetsFullPath, nupkgFileName);
+ if (!File.Exists(nupkgPath))
+ {
+ string[] found = Directory.GetFiles(builtNuGetsFullPath, nupkgFileName, new EnumerationOptions
+ {
+ MatchCasing = MatchCasing.CaseInsensitive,
+ RecurseSubdirectories = true
+ });
+
+ if (found.Length == 0)
+ {
+ remaining.Add(reference);
+ continue;
+ }
+
+ nupkgPath = found[0];
+ nupkgFileName = Path.GetFileName(nupkgPath);
+ }
+
+ string installedPackDir = Path.Combine(_packsDir!, reference.Name, reference.Version);
+ string stampFilePath = Path.Combine(installedPackDir, s_stampFileName);
+ if (!IsFileNewer(nupkgPath, stampFilePath))
+ {
+ Log.LogMessage(MessageImportance.Normal, $"Skipping {reference.Name}/{reference.Version} as it is already installed in {installedPackDir}.{Environment.NewLine} {nupkgPath} is older than {stampFilePath}");
+ continue;
+ }
+
+ if (Directory.Exists(installedPackDir))
+ {
+ Log.LogMessage(MessageImportance.Normal, $"Deleting {installedPackDir}");
+ Directory.Delete(installedPackDir, recursive: true);
+ }
+
+ Log.LogMessage(MessageImportance.High, $"Extracting {nupkgPath} => {installedPackDir}");
+ ZipFile.ExtractToDirectory(nupkgPath, installedPackDir);
+
+ // Add .nupkg.sha512, so it gets picked up when resolving nugets
+ File.WriteAllText(Path.Combine(installedPackDir, $"{nupkgFileName}.sha512"), string.Empty);
+
+ File.WriteAllText(stampFilePath, string.Empty);
+ }
+
+ return remaining;
+ }
+
+ private IEnumerable GetPackageReferencesForWorkload(ManifestInformation manifest, string workloadId)
+ {
+ var workload = manifest.Workloads[workloadId];
+ var subset = workload.Packs;
+ if (workload.Extends.Count > 0)
+ {
+ subset = new List(subset);
+ //FIXME: use exceptions!
+ if (!ProcessWorkload(workload))
+ throw new KeyNotFoundException();
+ }
+
+ List references = new();
+ foreach (var item in manifest.Packs)
+ {
+ if (subset != null && !subset.Contains(item.Key))
+ {
+ Log.LogMessage(MessageImportance.Low, $"Ignoring pack {item.Key} as it is not in the workload");
+ continue;
+ }
+
+ var packageName = item.Key;
+ if (item.Value.AliasTo is Dictionary alias)
+ {
+ alias.TryGetValue(Rid!, out packageName);
+ }
+
+ if (!string.IsNullOrEmpty(packageName) && !packageName.Contains("cross", StringComparison.InvariantCultureIgnoreCase))
+ references.Add(new PackageReference(packageName, item.Value.Version));
+ }
+
+ return references;
+
+ bool ProcessWorkload(WorkloadInformation workload)
+ {
+ if (workload.Extends == null || workload.Extends.Count == 0)
+ return true;
+
+ foreach (var w in workload.Extends)
+ {
+ if (!manifest.Workloads.TryGetValue(w, out WorkloadInformation? depWorkload))
+ {
+ Log.LogError($"Could not find workload {w} needed by {workload.Description} in the manifest");
+ return false;
+ }
+ //FIXME:
+
+ if (!ProcessWorkload(depWorkload))
+ return false;
+
+ subset.AddRange(depWorkload.Packs);
+ }
+
+ return true;
+ }
+ }
+
+ private bool InstallPacksWithNuGetRestore(IEnumerable references)
+ {
+ var remaining = SkipInstalledPacks(references);
+ if (!remaining.Any())
+ return true;
+
+ return TryRestorePackages(remaining, out PackageReference[]? restored) &&
+ LayoutPacksFromRestoredNuGets(restored);
+
+ IEnumerable SkipInstalledPacks(IEnumerable candidates)
+ {
+ List needed = new List(candidates.Count());
+ foreach (PackageReference pr in candidates)
+ {
+ var installedPackDir = Path.Combine(_packsDir!, pr.Name, pr.Version);
+ var packStampFile = Path.Combine(installedPackDir, s_stampFileName);
+
+ if (File.Exists(packStampFile))
+ {
+ Log.LogMessage(MessageImportance.Normal, $"Skipping {pr.Name}/{pr.Version} as it is already installed in {installedPackDir}.{Environment.NewLine} {packStampFile} exists.");
+ continue;
+ }
+
+ needed.Add(pr);
+ }
+
+ return needed;
+ }
+
+ bool LayoutPacksFromRestoredNuGets(IEnumerable restored)
+ {
+ foreach (var pkgRef in restored)
+ {
+ if (pkgRef.RestoredPath == null)
+ {
+ Log.LogError($"Failed to restore {pkgRef.Name}/{pkgRef.Version}");
+ return false;
+ }
+
+ var source = pkgRef.RestoredPath;
+ var destDir = Path.Combine(_packsDir!, pkgRef.Name, pkgRef.Version);
+ if (!CopyDirectory(source, destDir))
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ private bool TryRestorePackages(IEnumerable references, [NotNullWhen(true)]out PackageReference[]? restoredPackages)
+ {
+ if (!references.Any())
+ {
+ restoredPackages = Array.Empty();
+ return true;
+ }
+
+ restoredPackages = null;
+
+ var restoreProject = Path.Combine(_tempDir, "restore", "Restore.csproj");
+ var restoreProjectDirectory = Directory.CreateDirectory(Path.GetDirectoryName(restoreProject)!);
+
+ File.WriteAllText(Path.Combine(restoreProjectDirectory.FullName, "Directory.Build.props"), "");
+ File.WriteAllText(Path.Combine(restoreProjectDirectory.FullName, "Directory.Build.targets"), "");
+
+ StringBuilder projectFileBuilder = new();
+ projectFileBuilder.Append(@"
+
+
+ net6.0
+ $(NoWarn);NU1213
+
+
+");
+
+ foreach (var reference in references)
+ {
+ string itemName = "PackageReference";
+ projectFileBuilder.AppendLine($"<{itemName} Include=\"{reference.Name}\" Version=\"{reference.Version}\" />");
+ }
+
+ projectFileBuilder.Append(@"
+
+
+");
+ File.WriteAllText(restoreProject, projectFileBuilder.ToString());
+
+ if (ExtraNuGetSources?.Length > 0)
+ {
+ StringBuilder nugetConfigBuilder = new();
+ nugetConfigBuilder.AppendLine($"{Environment.NewLine}");
+
+ foreach (ITaskItem source in ExtraNuGetSources)
+ {
+ string key = source.ItemSpec;
+ string value = source.GetMetadata("Value");
+ if (string.IsNullOrEmpty(value))
+ {
+ Log.LogError($"ExtraNuGetSource {key} is missing Value metadata");
+ return false;
+ }
+
+ nugetConfigBuilder.AppendLine($@"");
+ }
+
+ nugetConfigBuilder.AppendLine($"{Environment.NewLine}");
+
+ File.WriteAllText(Path.Combine(restoreProjectDirectory.FullName, "nuget.config"), nugetConfigBuilder.ToString());
+ }
+
+ string restoreDir = Path.Combine(_tempDir, "nuget-packages");
+ if (Directory.Exists(restoreDir))
+ {
+ Log.LogMessage(MessageImportance.Low, $"Deleting {restoreDir}");
+ Directory.Delete(restoreDir, recursive: true);
+ }
+
+ Log.LogMessage(MessageImportance.High, $"Restoring packages: {string.Join(", ", references.Select(r => $"{r.Name}/{r.Version}"))}");
+
+ string args = $"restore {restoreProject} /p:RestorePackagesPath={restoreDir}";
+ (int exitCode, string output) = Utils.TryRunProcess("dotnet", args, silent: false, debugMessageImportance: MessageImportance.Normal);
+ if (exitCode != 0)
+ {
+ Log.LogError($"Restoring packages returned exit code: {exitCode}. Output:{Environment.NewLine}{output}");
+ return false;
+ }
+
+ restoredPackages = references.Select(reference =>
+ {
+ var expectedPath = Path.Combine(restoreDir, reference.Name.ToLower(), reference.Version);
+ if (Directory.Exists(expectedPath))
+ {
+ reference = reference with { RestoredPath = expectedPath };
+ File.WriteAllText(Path.Combine(reference.RestoredPath, s_stampFileName), string.Empty);
+ }
+ return reference;
+ }).ToArray();
+
+ return true;
+ }
+
+ private bool CopyDirectory(string srcDir, string destDir)
+ {
+ try
+ {
+ Log.LogMessage(MessageImportance.Low, $"Copying {srcDir} to {destDir}");
+ if (Directory.Exists(destDir))
+ {
+ Log.LogMessage(MessageImportance.Normal, $"Deleting {destDir}");
+ Directory.Delete(destDir, recursive: true);
+ }
+
+ Directory.CreateDirectory(destDir);
+ Utils.DirectoryCopy(srcDir, destDir);
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Log.LogError($"Failed while copying {srcDir} => {destDir}: {ex.Message}");
+ if (ex is IOException)
+ return false;
+
+ throw;
+ }
+ }
+
+ private bool HasMetadata(ITaskItem item, string itemName, string metadataName)
+ {
+ if (!string.IsNullOrEmpty(item.GetMetadata(metadataName)))
+ return true;
+
+ Log.LogError($"{itemName} item ({item.ItemSpec}) is missing Name metadata");
+ return false;
+ }
+
+ private static bool IsFileNewer(string sourceFile, string stampFile)
+ {
+ if (!File.Exists(sourceFile))
+ return true;
+
+ if (!File.Exists(stampFile))
+ return true;
+
+ return File.GetLastWriteTimeUtc(sourceFile) > File.GetLastWriteTimeUtc(stampFile);
+ }
+
+ private record PackageReference(string Name, string Version, string? RestoredPath=null);
+
+ private record ManifestInformation(
+ object Version,
+ string Description,
+
+ [property: JsonPropertyName("depends-on")]
+ IDictionary DependsOn,
+ IDictionary Workloads,
+ IDictionary Packs,
+ object Data
+ );
+
+ private record WorkloadInformation(
+ bool Abstract,
+ string Kind,
+ string Description,
+
+ List Packs,
+ List Extends,
+ List Platforms
+ );
+
+ private record PackVersionInformation(
+ string Kind,
+ string Version,
+ [property: JsonPropertyName("alias-to")]
+ Dictionary AliasTo
+ );
+ }
+}
diff --git a/src/tasks/WorkloadBuildTasks/WorkloadBuildTasks.csproj b/src/tasks/WorkloadBuildTasks/WorkloadBuildTasks.csproj
index 328672b45145bc..537418ef31dc6d 100644
--- a/src/tasks/WorkloadBuildTasks/WorkloadBuildTasks.csproj
+++ b/src/tasks/WorkloadBuildTasks/WorkloadBuildTasks.csproj
@@ -6,6 +6,8 @@
$(NoWarn),CA1050
+
+
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/BlazorWasmTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/BlazorWasmTests.cs
new file mode 100644
index 00000000000000..891386e2e1e17d
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BlazorWasmTests.cs
@@ -0,0 +1,49 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using Xunit;
+using Xunit.Abstractions;
+// using FluentAssertions;
+
+#nullable enable
+
+namespace Wasm.Build.Tests
+{
+ public class BlazorWasmTests : BuildTestBase
+ {
+ public BlazorWasmTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
+ : base(output, buildContext)
+ {
+ }
+
+ [ConditionalFact(typeof(BuildTestBase), nameof(IsUsingWorkloads))]
+ public void PublishTemplateProject()
+ {
+ InitPaths("id");
+ if (Directory.Exists(_projectDir))
+ Directory.Delete(_projectDir, recursive: true);
+ Directory.CreateDirectory(_projectDir);
+ Directory.CreateDirectory(Path.Combine(_projectDir, ".nuget"));
+
+ File.Copy(Path.Combine(BuildEnvironment.TestDataPath, "nuget6.config"), Path.Combine(_projectDir, "nuget.config"));
+ File.Copy(Path.Combine(BuildEnvironment.TestDataPath, "Blazor.Directory.Build.props"), Path.Combine(_projectDir, "Directory.Build.props"));
+ File.Copy(Path.Combine(BuildEnvironment.TestDataPath, "Blazor.Directory.Build.targets"), Path.Combine(_projectDir, "Directory.Build.targets"));
+
+ new DotNetCommand(s_buildEnv)
+ .WithWorkingDirectory(_projectDir)
+ .ExecuteWithCapturedOutput("new blazorwasm")
+ .EnsureSuccessful();
+
+ new DotNetCommand(s_buildEnv)
+ .WithWorkingDirectory(_projectDir)
+ .ExecuteWithCapturedOutput("publish -bl -p:RunAOTCompilation=true")
+ .EnsureSuccessful();
+
+ //TODO: validate the build somehow?
+ // compare dotnet.wasm?
+ // playwright?
+ }
+ }
+}
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildEnvironment.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildEnvironment.cs
new file mode 100644
index 00000000000000..0b9d74868e9861
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildEnvironment.cs
@@ -0,0 +1,132 @@
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace Wasm.Build.Tests
+{
+ public class BuildEnvironment
+ {
+ public string DotNet { get; init; }
+ public string RuntimePackDir { get; init; }
+ public bool IsWorkload { get; init; }
+ public string DefaultBuildArgs { get; init; }
+ public IDictionary EnvVars { get; init; }
+ public string DirectoryBuildPropsContents { get; init; }
+ public string DirectoryBuildTargetsContents { get; init; }
+ public string RuntimeNativeDir { get; init; }
+ public string LogRootPath { get; init; }
+
+ public static readonly string RelativeTestAssetsPath = @"..\testassets\";
+ public static readonly string TestAssetsPath = Path.Combine(AppContext.BaseDirectory, "testassets");
+ public static readonly string TestDataPath = Path.Combine(AppContext.BaseDirectory, "data");
+
+ private static string s_runtimeConfig = "Release";
+ private const string s_testLogPathEnvVar = "TEST_LOG_PATH";
+
+ public BuildEnvironment()
+ {
+ DirectoryInfo? solutionRoot = new (AppContext.BaseDirectory);
+ while (solutionRoot != null)
+ {
+ if (File.Exists(Path.Combine(solutionRoot.FullName, "NuGet.config")))
+ {
+ break;
+ }
+
+ solutionRoot = solutionRoot.Parent;
+ }
+
+ string? sdkForWorkloadPath = Environment.GetEnvironmentVariable("SDK_FOR_WORKLOAD_TESTING_PATH");
+ if (!string.IsNullOrEmpty(sdkForWorkloadPath))
+ {
+
+ DotNet = Path.Combine(sdkForWorkloadPath, "dotnet");
+ var workloadPacksVersion = Environment.GetEnvironmentVariable("WORKLOAD_PACKS_VER");
+ if (string.IsNullOrEmpty(workloadPacksVersion))
+ throw new Exception($"Cannot test with workloads without WORKLOAD_PACKS_VER environment variable being set");
+
+ RuntimePackDir = Path.Combine(sdkForWorkloadPath, "packs", "Microsoft.NETCore.App.Runtime.Mono.browser-wasm", workloadPacksVersion);
+ DirectoryBuildPropsContents = s_directoryBuildPropsForWorkloads;
+ DirectoryBuildTargetsContents = s_directoryBuildTargetsForWorkloads;
+ EnvVars = new Dictionary()
+ {
+ // `runtime` repo's build environment sets these, and they
+ // mess up the build for the test project, which is using a different
+ // dotnet
+ ["DOTNET_INSTALL_DIR"] = sdkForWorkloadPath,
+ ["DOTNET_MULTILEVEL_LOOKUP"] = "0",
+ ["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "1",
+ ["MSBuildSDKsPath"] = string.Empty,
+ ["PATH"] = $"{sdkForWorkloadPath}{Path.PathSeparator}{Environment.GetEnvironmentVariable("PATH")}"
+ };
+
+ var appRefDir = Environment.GetEnvironmentVariable("AppRefDir");
+ if (string.IsNullOrEmpty(appRefDir))
+ throw new Exception($"Cannot test with workloads without AppRefDir environment variable being set");
+
+ DefaultBuildArgs = $" /p:AppRefDir={appRefDir}";
+ IsWorkload = true;
+ }
+ else
+ {
+ string emsdkPath;
+ if (solutionRoot == null)
+ {
+ string? buildDir = Environment.GetEnvironmentVariable("WasmBuildSupportDir");
+
+ if (buildDir == null || !Directory.Exists(buildDir))
+ throw new Exception($"Could not find the solution root, or a build dir: {buildDir}");
+
+ emsdkPath = Path.Combine(buildDir, "emsdk");
+ RuntimePackDir = Path.Combine(buildDir, "microsoft.netcore.app.runtime.browser-wasm");
+ DefaultBuildArgs = $" /p:WasmBuildSupportDir={buildDir} /p:EMSDK_PATH={emsdkPath} ";
+ }
+ else
+ {
+ string artifactsBinDir = Path.Combine(solutionRoot.FullName, "artifacts", "bin");
+ RuntimePackDir = Path.Combine(artifactsBinDir, "microsoft.netcore.app.runtime.browser-wasm", s_runtimeConfig);
+
+ string? emsdkEnvValue = Environment.GetEnvironmentVariable("EMSDK_PATH");
+ if (string.IsNullOrEmpty(emsdkEnvValue))
+ emsdkPath = Path.Combine(solutionRoot.FullName, "src", "mono", "wasm", "emsdk");
+ else
+ emsdkPath = emsdkEnvValue;
+
+ DefaultBuildArgs = $" /p:RuntimeSrcDir={solutionRoot.FullName} /p:RuntimeConfig={s_runtimeConfig} /p:EMSDK_PATH={emsdkPath} ";
+ }
+
+ IsWorkload = false;
+ DotNet = "dotnet";
+ EnvVars = new Dictionary()
+ {
+ ["EMSDK_PATH"] = emsdkPath
+ };
+
+ DirectoryBuildPropsContents = s_directoryBuildPropsForLocal;
+ DirectoryBuildTargetsContents = s_directoryBuildTargetsForLocal;
+ }
+
+ RuntimeNativeDir = Path.Combine(RuntimePackDir, "runtimes", "browser-wasm", "native");
+
+ string? logPathEnvVar = Environment.GetEnvironmentVariable(s_testLogPathEnvVar);
+ if (!string.IsNullOrEmpty(logPathEnvVar))
+ {
+ LogRootPath = logPathEnvVar;
+ if (!Directory.Exists(LogRootPath))
+ {
+ Directory.CreateDirectory(LogRootPath);
+ }
+ }
+ else
+ {
+ LogRootPath = Environment.CurrentDirectory;
+ }
+ }
+
+ protected static string s_directoryBuildPropsForWorkloads = File.ReadAllText(Path.Combine(TestDataPath, "Workloads.Directory.Build.props"));
+ protected static string s_directoryBuildTargetsForWorkloads = File.ReadAllText(Path.Combine(TestDataPath, "Workloads.Directory.Build.targets"));
+ protected static string s_directoryBuildPropsForLocal = File.ReadAllText(Path.Combine(TestDataPath, "Local.Directory.Build.props"));
+ protected static string s_directoryBuildTargetsForLocal = File.ReadAllText(Path.Combine(TestDataPath, "Local.Directory.Build.targets"));
+ }
+}
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs
index b87ff5c70bfc24..021ce531b17b32 100644
--- a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs
@@ -10,6 +10,7 @@
using System.Linq;
using System.Reflection;
using System.Text;
+using System.Text.RegularExpressions;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;
@@ -20,15 +21,9 @@ namespace Wasm.Build.Tests
{
public abstract class BuildTestBase : IClassFixture, IDisposable
{
- protected const string TestLogPathEnvVar = "TEST_LOG_PATH";
protected const string SkipProjectCleanupEnvVar = "SKIP_PROJECT_CLEANUP";
protected const string XHarnessRunnerCommandEnvVar = "XHARNESS_CLI_PATH";
- protected const string s_targetFramework = "net5.0";
- protected static string s_runtimeConfig = "Release";
- protected static string s_runtimePackDir;
- protected static string s_defaultBuildArgs;
- protected static readonly string s_logRoot;
- protected static readonly string s_emsdkPath;
+ protected const string s_targetFramework = "net6.0";
protected static readonly bool s_skipProjectCleanup;
protected static readonly string s_xharnessRunnerCommand;
protected string? _projectDir;
@@ -37,76 +32,53 @@ public abstract class BuildTestBase : IClassFixture s_buildEnv.IsWorkload;
+ public static bool IsNotUsingWorkloads => !s_buildEnv.IsWorkload;
- if (buildDir == null || !Directory.Exists(buildDir))
- throw new Exception($"Could not find the solution root, or a build dir: {buildDir}");
-
- s_emsdkPath = Path.Combine(buildDir, "emsdk");
- s_runtimePackDir = Path.Combine(buildDir, "microsoft.netcore.app.runtime.browser-wasm");
- s_defaultBuildArgs = $" /p:WasmBuildSupportDir={buildDir} /p:EMSDK_PATH={s_emsdkPath} ";
- }
- else
- {
- string artifactsBinDir = Path.Combine(solutionRoot.FullName, "artifacts", "bin");
- s_runtimePackDir = Path.Combine(artifactsBinDir, "microsoft.netcore.app.runtime.browser-wasm", s_runtimeConfig);
+ static BuildTestBase()
+ {
+ s_buildEnv = new BuildEnvironment();
+ s_runtimePackPathRegex = new Regex(s_runtimePackPathPattern);
- string? emsdk = Environment.GetEnvironmentVariable("EMSDK_PATH");
- if (string.IsNullOrEmpty(emsdk))
- emsdk = Path.Combine(solutionRoot.FullName, "src", "mono", "wasm", "emsdk");
- s_emsdkPath = emsdk;
+ string? cleanupVar = Environment.GetEnvironmentVariable(SkipProjectCleanupEnvVar);
+ s_skipProjectCleanup = !string.IsNullOrEmpty(cleanupVar) && cleanupVar == "1";
- s_defaultBuildArgs = $" /p:RuntimeSrcDir={solutionRoot.FullName} /p:RuntimeConfig={s_runtimeConfig} /p:EMSDK_PATH={s_emsdkPath} ";
- }
+ s_xharnessRunnerCommand = GetEnvironmentVariableOrDefault(XHarnessRunnerCommandEnvVar, "xharness");
- string? logPathEnvVar = Environment.GetEnvironmentVariable(TestLogPathEnvVar);
- if (!string.IsNullOrEmpty(logPathEnvVar))
+ string? nugetPackagesPath = Environment.GetEnvironmentVariable("NUGET_PACKAGES");
+ if (!string.IsNullOrEmpty(nugetPackagesPath))
{
- s_logRoot = logPathEnvVar;
- if (!Directory.Exists(s_logRoot))
+ if (!Directory.Exists(nugetPackagesPath))
+ {
+ Directory.CreateDirectory(nugetPackagesPath);
+ Console.WriteLine ($"-- Created {nugetPackagesPath}");
+ }
+ else
{
- Directory.CreateDirectory(s_logRoot);
+ Console.WriteLine ($"-- already exists {nugetPackagesPath}");
}
}
else
{
- s_logRoot = Environment.CurrentDirectory;
+ Console.WriteLine ($"-- NUGET_PACKAGES envvar was empty");
}
- string? cleanupVar = Environment.GetEnvironmentVariable(SkipProjectCleanupEnvVar);
- s_skipProjectCleanup = !string.IsNullOrEmpty(cleanupVar) && cleanupVar == "1";
-
- string? harnessVar = Environment.GetEnvironmentVariable(XHarnessRunnerCommandEnvVar);
- if (string.IsNullOrEmpty(harnessVar))
- {
- s_xharnessRunnerCommand = "xharness";
- }
- else
- {
- s_xharnessRunnerCommand = $"exec {harnessVar}";
- }
+ Console.WriteLine ("");
+ Console.WriteLine ($"==============================================================================================");
+ Console.WriteLine ($"=============== Running with {(s_buildEnv.IsWorkload ? "Workloads" : "EMSDK")} ===============");
+ Console.WriteLine ($"==============================================================================================");
+ Console.WriteLine ("");
}
public BuildTestBase(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
{
_buildContext = buildContext;
_testOutput = output;
- _logPath = s_logRoot; // FIXME:
+ _logPath = s_buildEnv.LogRootPath; // FIXME:
}
/*
@@ -154,11 +126,16 @@ protected string RunAndTestWasmApp(BuildArgs buildArgs,
envVars["XHARNESS_DISABLE_COLORED_OUTPUT"] = "true";
if (buildArgs.AOT)
{
- envVars["EMSDK_PATH"] = s_emsdkPath;
envVars["MONO_LOG_LEVEL"] = "debug";
envVars["MONO_LOG_MASK"] = "aot";
}
+ if (s_buildEnv.EnvVars != null)
+ {
+ foreach (var kvp in s_buildEnv.EnvVars)
+ envVars[kvp.Key] = kvp.Value;
+ }
+
string bundleDir = Path.Combine(GetBinDir(baseDir: buildDir, config: buildArgs.Config), "AppBundle");
(string testCommand, string extraXHarnessArgs) = host switch
{
@@ -215,7 +192,7 @@ protected static string RunWithXHarness(string testCommand, string testLogPath,
// App arguments
if (envVars != null)
{
- var setenv = string.Join(' ', envVars.Select(kvp => $"--setenv={kvp.Key}={kvp.Value}").ToArray());
+ var setenv = string.Join(' ', envVars.Select(kvp => $"\"--setenv={kvp.Key}={kvp.Value}\"").ToArray());
args.Append($" {setenv}");
}
@@ -224,7 +201,7 @@ protected static string RunWithXHarness(string testCommand, string testLogPath,
_testOutput.WriteLine(string.Empty);
_testOutput.WriteLine($"---------- Running with {testCommand} ---------");
- var (exitCode, output) = RunProcess("dotnet", _testOutput,
+ var (exitCode, output) = RunProcess(s_buildEnv.DotNet, _testOutput,
args: args.ToString(),
workingDir: bundleDir,
envVars: envVars,
@@ -235,7 +212,8 @@ protected static string RunWithXHarness(string testCommand, string testLogPath,
if (exitCode != xharnessExitCode)
{
_testOutput.WriteLine($"Exit code: {exitCode}");
- Assert.True(exitCode == expectedAppExitCode, $"[{testCommand}] Exit code, expected {expectedAppExitCode} but got {exitCode}");
+ if (exitCode != expectedAppExitCode)
+ throw new XunitException($"[{testCommand}] Exit code, expected {expectedAppExitCode} but got {exitCode} for command: {testCommand} {args}");
}
return output;
@@ -245,7 +223,7 @@ protected static string RunWithXHarness(string testCommand, string testLogPath,
protected void InitPaths(string id)
{
_projectDir = Path.Combine(AppContext.BaseDirectory, id);
- _logPath = Path.Combine(s_logRoot, id);
+ _logPath = Path.Combine(s_buildEnv.LogRootPath, id);
Directory.CreateDirectory(_logPath);
}
@@ -253,8 +231,11 @@ protected void InitPaths(string id)
protected static void InitProjectDir(string dir)
{
Directory.CreateDirectory(dir);
- File.WriteAllText(Path.Combine(dir, "Directory.Build.props"), s_directoryBuildProps);
- File.WriteAllText(Path.Combine(dir, "Directory.Build.targets"), s_directoryBuildTargets);
+ File.WriteAllText(Path.Combine(dir, "Directory.Build.props"), s_buildEnv.DirectoryBuildPropsContents);
+ File.WriteAllText(Path.Combine(dir, "Directory.Build.targets"), s_buildEnv.DirectoryBuildTargetsContents);
+
+ File.Copy(Path.Combine(BuildEnvironment.TestDataPath, "nuget6.config"), Path.Combine(dir, "nuget.config"));
+ Directory.CreateDirectory(Path.Combine(dir, ".nuget"));
}
protected const string SimpleProjectTemplate =
@@ -285,8 +266,8 @@ protected static BuildArgs ExpandBuildArgs(BuildArgs buildArgs, string extraProp
}
public (string projectDir, string buildOutput) BuildProject(BuildArgs buildArgs,
- Action initProject,
string id,
+ Action? initProject = null,
bool? dotnetWasmFromRuntimePack = null,
bool hasIcudt = true,
bool useCache = true,
@@ -301,7 +282,7 @@ protected static BuildArgs ExpandBuildArgs(BuildArgs buildArgs, string extraProp
_projectDir = product.ProjectDir;
// use this test's id for the run logs
- _logPath = Path.Combine(s_logRoot, id);
+ _logPath = Path.Combine(s_buildEnv.LogRootPath, id);
return (_projectDir, "FIXME");
}
@@ -321,13 +302,14 @@ protected static BuildArgs ExpandBuildArgs(BuildArgs buildArgs, string extraProp
StringBuilder sb = new();
sb.Append("publish");
- sb.Append(s_defaultBuildArgs);
+ sb.Append($" {s_buildEnv.DefaultBuildArgs}");
sb.Append($" /p:Configuration={buildArgs.Config}");
string logFilePath = Path.Combine(_logPath, $"{buildArgs.ProjectName}.binlog");
_testOutput.WriteLine($"-------- Building ---------");
_testOutput.WriteLine($"Binlog path: {logFilePath}");
+ Console.WriteLine($"Binlog path: {logFilePath}");
sb.Append($" /bl:\"{logFilePath}\" /v:minimal /nologo");
if (buildArgs.ExtraBuildArgs != null)
sb.Append($" {buildArgs.ExtraBuildArgs} ");
@@ -337,12 +319,16 @@ protected static BuildArgs ExpandBuildArgs(BuildArgs buildArgs, string extraProp
(int exitCode, string buildOutput) result;
try
{
- result = AssertBuild(sb.ToString(), id, expectSuccess: expectSuccess);
+ result = AssertBuild(sb.ToString(), id, expectSuccess: expectSuccess, envVars: s_buildEnv.EnvVars);
+
+ //AssertRuntimePackPath(result.buildOutput);
+
+ // check that we are using the correct runtime pack!
+
if (expectSuccess)
{
string bundleDir = Path.Combine(GetBinDir(config: buildArgs.Config), "AppBundle");
- dotnetWasmFromRuntimePack ??= !buildArgs.AOT;
- AssertBasicAppBundle(bundleDir, buildArgs.ProjectName, buildArgs.Config, hasIcudt, dotnetWasmFromRuntimePack.Value);
+ AssertBasicAppBundle(bundleDir, buildArgs.ProjectName, buildArgs.Config, hasIcudt, dotnetWasmFromRuntimePack ?? !buildArgs.AOT);
}
if (useCache)
@@ -361,8 +347,20 @@ protected static BuildArgs ExpandBuildArgs(BuildArgs buildArgs, string extraProp
}
}
+ static void AssertRuntimePackPath(string buildOutput)
+ {
+ var match = s_runtimePackPathRegex.Match(buildOutput);
+ if (!match.Success || match.Groups.Count != 2)
+ throw new XunitException($"Could not find the pattern in the build output: '{s_runtimePackPathPattern}'.{Environment.NewLine}Build output: {buildOutput}");
+
+ string actualPath = match.Groups[1].Value;
+ if (string.Compare(actualPath, s_buildEnv.RuntimePackDir) != 0)
+ throw new XunitException($"Runtime pack path doesn't match.{Environment.NewLine}Expected: {s_buildEnv.RuntimePackDir}{Environment.NewLine}Actual: {actualPath}");
+ }
+
protected static void AssertBasicAppBundle(string bundleDir, string projectName, string config, bool hasIcudt=true, bool dotnetWasmFromRuntimePack=true)
{
+ Console.WriteLine ($"AssertBasicAppBundle: {dotnetWasmFromRuntimePack}");
AssertFilesExist(bundleDir, new []
{
"index.html",
@@ -398,16 +396,15 @@ protected static void AssertBasicAppBundle(string bundleDir, string projectName,
protected static void AssertDotNetWasmJs(string bundleDir, bool fromRuntimePack)
{
- string nativeDir = GetRuntimeNativeDir();
-
- AssertNativeFile("dotnet.wasm");
- AssertNativeFile("dotnet.js");
-
- void AssertNativeFile(string file)
- => AssertFile(Path.Combine(nativeDir, file),
- Path.Combine(bundleDir, file),
- $"Expected {file} to be {(fromRuntimePack ? "the same as" : "different from")} the runtime pack",
- same: fromRuntimePack);
+ AssertFile(Path.Combine(s_buildEnv.RuntimeNativeDir, "dotnet.wasm"),
+ Path.Combine(bundleDir, "dotnet.wasm"),
+ "Expected dotnet.wasm to be same as the runtime pack",
+ same: fromRuntimePack);
+
+ AssertFile(Path.Combine(s_buildEnv.RuntimeNativeDir, "dotnet.js"),
+ Path.Combine(bundleDir, "dotnet.js"),
+ "Expected dotnet.js to be same as the runtime pack",
+ same: fromRuntimePack);
}
protected static void AssertFilesDontExist(string dir, string[] filenames, string? label = null)
@@ -454,9 +451,9 @@ protected static void AssertFile(string file0, string file1, string? label=null,
Assert.True(finfo0.Length != finfo1.Length, $"{label}: File sizes should not match for {file0} ({finfo0.Length}), and {file1} ({finfo1.Length})");
}
- protected (int exitCode, string buildOutput) AssertBuild(string args, string label="build", bool expectSuccess=true)
+ protected (int exitCode, string buildOutput) AssertBuild(string args, string label="build", bool expectSuccess=true, IDictionary? envVars=null)
{
- var result = RunProcess("dotnet", _testOutput, args, workingDir: _projectDir, label: label);
+ var result = RunProcess(s_buildEnv.DotNet, _testOutput, args, workingDir: _projectDir, label: label, envVars: envVars);
if (expectSuccess)
Assert.True(0 == result.exitCode, $"Build process exited with non-zero exit code: {result.exitCode}");
else
@@ -465,9 +462,6 @@ protected static void AssertFile(string file0, string file1, string? label=null,
return result;
}
- // protected string GetObjDir(string targetFramework=s_targetFramework, string? baseDir=null, string config="Debug")
- // => Path.Combine(baseDir ?? _projectDir, "obj", config, targetFramework, "browser-wasm", "wasm");
-
protected string GetBinDir(string config, string targetFramework=s_targetFramework, string? baseDir=null)
{
var dir = baseDir ?? _projectDir;
@@ -475,12 +469,6 @@ protected string GetBinDir(string config, string targetFramework=s_targetFramewo
return Path.Combine(dir!, "bin", config, targetFramework, "browser-wasm");
}
- protected static string GetRuntimePackDir() => s_runtimePackDir;
-
- protected static string GetRuntimeNativeDir()
- => Path.Combine(GetRuntimePackDir(), "runtimes", "browser-wasm", "native");
-
-
public static (int exitCode, string buildOutput) RunProcess(string path,
ITestOutputHelper _testOutput,
string args = "",
@@ -570,6 +558,12 @@ public void Dispose()
_buildContext.RemoveFromCache(_projectDir);
}
+ private static string GetEnvironmentVariableOrDefault(string envVarName, string defaultValue)
+ {
+ string? value = Environment.GetEnvironmentVariable(envVarName);
+ return string.IsNullOrEmpty(value) ? defaultValue : value;
+ }
+
protected static string s_mainReturns42 = @"
public class TestClass {
public static int Main()
@@ -577,49 +571,6 @@ public static int Main()
return 42;
}
}";
-
- protected static string s_directoryBuildProps = @"
-
- <_WasmTargetsDir Condition=""'$(RuntimeSrcDir)' != ''"">$(RuntimeSrcDir)\src\mono\wasm\build\
- <_WasmTargetsDir Condition=""'$(WasmBuildSupportDir)' != ''"">$(WasmBuildSupportDir)\wasm\
- $(WasmBuildSupportDir)\emsdk\
-
-
-
-
-
-
- PrepareForWasmBuild;$(WasmBuildAppDependsOn)
-
-";
-
- protected static string s_directoryBuildTargets = @"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-";
-
}
public record BuildArgs(string ProjectName, string Config, bool AOT, string ProjectFileContents, string? ExtraBuildArgs);
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/CommandBase.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/CommandBase.cs
new file mode 100644
index 00000000000000..96304f335fb322
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/CommandBase.cs
@@ -0,0 +1,200 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using System.Threading.Tasks;
+
+#nullable enable
+
+namespace Wasm.Build.Tests
+{
+ public class Command
+ {
+ private StringBuilder _extraArgsBuilder = new();
+ private string _label;
+
+ protected string _command;
+
+ public Process? CurrentProcess { get; private set; }
+
+ public Dictionary Environment { get; } = new Dictionary();
+
+ public event DataReceivedEventHandler? ErrorDataReceived;
+
+ public event DataReceivedEventHandler? OutputDataReceived;
+
+ public string? WorkingDirectory { get; set; }
+
+ public Command(string command, string label="")
+ {
+ _command = command;
+ _label = label;
+ }
+
+ public Command WithWorkingDirectory(string dir)
+ {
+ WorkingDirectory = dir;
+ return this;
+ }
+
+ public Command WithEnvironmentVariable(string key, string value)
+ {
+ Environment[key] = value;
+ return this;
+ }
+
+ public Command WithEnvironmentVariables(IDictionary? extraEnvVars)
+ {
+ if (extraEnvVars != null)
+ {
+ foreach ((string key, string value) in extraEnvVars)
+ Environment[key] = value;
+ }
+
+ return this;
+ }
+
+ public virtual CommandResult Execute(string args = "")
+ {
+ return Task.Run(async () => await ExecuteAsync(args)).Result;
+ }
+
+ public async virtual Task ExecuteAsync(string args = "")
+ {
+ var resolvedCommand = _command;
+ string fullArgs = GetFullArgs(args);
+ Console.WriteLine($"[{_label}] Executing - {resolvedCommand} {fullArgs} - {WorkingDirectoryInfo()}");
+ return await ExecuteAsyncInternal(resolvedCommand, fullArgs);
+ }
+
+ public virtual CommandResult ExecuteWithCapturedOutput(string args = "")
+ {
+ var resolvedCommand = _command;
+ string fullArgs = GetFullArgs(args);
+ Console.WriteLine($"[{_label}] Executing (Captured Output) - {resolvedCommand} {fullArgs} - {WorkingDirectoryInfo()}");
+ return Task.Run(async () => await ExecuteAsyncInternal(resolvedCommand, fullArgs)).Result;
+ }
+
+ protected virtual string GetFullArgs(string args) => $"{args} {_extraArgsBuilder}";
+
+ private async Task ExecuteAsyncInternal(string executable, string args)
+ {
+ var output = new List();
+ CurrentProcess = CreateProcess(executable, args);
+ CurrentProcess.ErrorDataReceived += (s, e) =>
+ {
+ if (e.Data == null)
+ return;
+
+ output.Add($"[{_label}] {e.Data}");
+ var handler = ErrorDataReceived;
+ if (handler != null)
+ {
+ handler(s, e);
+ }
+ };
+
+ CurrentProcess.OutputDataReceived += (s, e) =>
+ {
+ if (e.Data == null)
+ return;
+
+ output.Add($"[{_label}] {e.Data}");
+ var handler = OutputDataReceived;
+ if (handler != null)
+ {
+ handler(s, e);
+ }
+ };
+
+ var completionTask = CurrentProcess.StartAndWaitForExitAsync();
+ CurrentProcess.BeginOutputReadLine();
+ CurrentProcess.BeginErrorReadLine();
+ await completionTask;
+
+ CurrentProcess.WaitForExit();
+ RemoveNullTerminator(output);
+
+ return new CommandResult(
+ CurrentProcess.StartInfo,
+ CurrentProcess.ExitCode,
+ string.Join(System.Environment.NewLine, output));
+ }
+
+ private Process CreateProcess(string executable, string args)
+ {
+ var psi = new ProcessStartInfo
+ {
+ FileName = executable,
+ Arguments = args,
+ RedirectStandardError = true,
+ RedirectStandardOutput = true,
+ RedirectStandardInput = true,
+ UseShellExecute = false
+ };
+
+ psi.Environment["DOTNET_MULTILEVEL_LOOKUP"] = "0";
+ psi.Environment["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "1";
+
+ AddEnvironmentVariablesTo(psi);
+ AddWorkingDirectoryTo(psi);
+ var process = new Process
+ {
+ StartInfo = psi
+ };
+
+ process.EnableRaisingEvents = true;
+ return process;
+ }
+
+ public Command WithExtraArgs(string extraArgs)
+ {
+ _extraArgsBuilder.Append($" {extraArgs}");
+ return this;
+ }
+
+ private string WorkingDirectoryInfo()
+ {
+ if (WorkingDirectory == null)
+ {
+ return "";
+ }
+
+ return $" in pwd {WorkingDirectory}";
+ }
+
+ private void RemoveNullTerminator(List strings)
+ {
+ var count = strings.Count;
+
+ if (count < 1)
+ {
+ return;
+ }
+
+ if (strings[count - 1] == null)
+ {
+ strings.RemoveAt(count - 1);
+ }
+ }
+
+ private void AddEnvironmentVariablesTo(ProcessStartInfo psi)
+ {
+ foreach (var item in Environment)
+ {
+ psi.Environment[item.Key] = item.Value;
+ }
+ }
+
+ private void AddWorkingDirectoryTo(ProcessStartInfo psi)
+ {
+ if (!string.IsNullOrWhiteSpace(WorkingDirectory))
+ {
+ psi.WorkingDirectory = WorkingDirectory;
+ }
+ }
+ }
+}
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/CommandResult.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/CommandResult.cs
new file mode 100644
index 00000000000000..b20b81fe796a3a
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/CommandResult.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Diagnostics;
+using System.Text;
+using Xunit.Sdk;
+
+namespace Wasm.Build.Tests
+{
+ // taken from https://github.com/dotnet/arcade/blob/main/src/Common/Microsoft.Arcade.Common/CommandResult.cs
+ public struct CommandResult
+ {
+ public static readonly CommandResult Empty = new CommandResult();
+
+ public ProcessStartInfo StartInfo { get; }
+ public int ExitCode { get; }
+ public string Output { get; }
+
+ public CommandResult(ProcessStartInfo startInfo, int exitCode, string output)
+ {
+ StartInfo = startInfo;
+ ExitCode = exitCode;
+ Output = output;
+ }
+
+ public void EnsureSuccessful(string messagePrefix = "", bool suppressOutput = false)
+ {
+ if (ExitCode != 0)
+ {
+ StringBuilder message = new StringBuilder($"{messagePrefix} Command failed with exit code {ExitCode}: {StartInfo.FileName} {StartInfo.Arguments}");
+
+ if (!suppressOutput)
+ {
+ if (!string.IsNullOrEmpty(Output))
+ {
+ message.AppendLine($"{Environment.NewLine}Standard Output:{Environment.NewLine}{Output}");
+ }
+ }
+
+ throw new XunitException(message.ToString());
+ }
+ }
+ }
+}
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/DotNetCommand.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/DotNetCommand.cs
new file mode 100644
index 00000000000000..329bc9a9954c26
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/DotNetCommand.cs
@@ -0,0 +1,15 @@
+using System.Threading.Tasks;
+
+namespace Wasm.Build.Tests
+{
+ public class DotNetCommand : Command
+ {
+ private BuildEnvironment _buildEnvironment;
+ public DotNetCommand(BuildEnvironment buildEnv) : base(buildEnv.DotNet)
+ {
+ _buildEnvironment = buildEnv;
+ WithEnvironmentVariables(buildEnv.EnvVars);
+ WithExtraArgs(buildEnv.DefaultBuildArgs);
+ }
+ }
+}
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/LocalEMSDKTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/LocalEMSDKTests.cs
new file mode 100644
index 00000000000000..30ed330bf17910
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/LocalEMSDKTests.cs
@@ -0,0 +1,62 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.IO;
+using Xunit;
+using Xunit.Abstractions;
+
+#nullable enable
+
+namespace Wasm.Build.Tests
+{
+ public class LocalEMSDKTests : BuildTestBase
+ {
+ public LocalEMSDKTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : base(output, buildContext)
+ {}
+
+ [ConditionalTheory(typeof(BuildTestBase), nameof(IsNotUsingWorkloads))]
+ [BuildAndRun(aot: true, host: RunHost.None, parameters: new object[]
+ { "", "error :.*emscripten.*required for AOT" })]
+ [BuildAndRun(aot: true, host: RunHost.None, parameters: new object[]
+ { "/non-existant/foo", "error.*\\(EMSDK_PATH\\)=/non-existant/foo.*required for AOT" })]
+ public void AOT_ErrorWhenMissingEMSDK(BuildArgs buildArgs, string emsdkPath, string errorPattern, string id)
+ {
+ string projectName = $"missing_emsdk";
+ buildArgs = buildArgs with {
+ ProjectName = projectName,
+ ExtraBuildArgs = $"/p:EMSDK_PATH={emsdkPath}"
+ };
+ buildArgs = ExpandBuildArgs(buildArgs);
+
+ (_, string buildOutput) = BuildProject(buildArgs,
+ initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42),
+ id: id,
+ expectSuccess: false);
+
+ Assert.Matches(errorPattern, buildOutput);
+ }
+
+ [ConditionalTheory(typeof(BuildTestBase), nameof(IsNotUsingWorkloads))]
+ [BuildAndRun(host: RunHost.None, parameters: new object[]
+ { "", "error.*emscripten.*required for building native files" })]
+ [BuildAndRun(host: RunHost.None, parameters: new object[]
+ { "/non-existant/foo", "error.*\\(EMSDK_PATH\\)=/non-existant/foo.*required for building native files" })]
+ public void Relinking_ErrorWhenMissingEMSDK(BuildArgs buildArgs, string emsdkPath, string errorPattern, string id)
+ {
+ string projectName = $"simple_native_build";
+ buildArgs = buildArgs with {
+ ProjectName = projectName,
+ ExtraBuildArgs = $"/p:EMSDK_PATH={emsdkPath}"
+ };
+ buildArgs = ExpandBuildArgs(buildArgs, extraProperties: "true");
+
+ (_, string buildOutput) = BuildProject(buildArgs,
+ initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42),
+ id: id,
+ expectSuccess: false);
+
+ Assert.Matches(errorPattern, buildOutput);
+ }
+ }
+ }
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeBuildTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeBuildTests.cs
index 9f87757175c970..130e59e0ea2a9c 100644
--- a/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeBuildTests.cs
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeBuildTests.cs
@@ -27,27 +27,7 @@ public NativeBuildTests(ITestOutputHelper output, SharedBuildPerTestClassFixture
public void SimpleNativeBuild(BuildArgs buildArgs, RunHost host, string id)
=> NativeBuild("simple_native_build", s_mainReturns42, buildArgs, host, id);
- [Theory]
- [BuildAndRun(host: RunHost.None, parameters: new object[]
- { "", "error.*emscripten.*required for building native files" })]
- [BuildAndRun(host: RunHost.None, parameters: new object[]
- { "/non-existant/foo", "error.*\\(EMSDK_PATH\\)=/non-existant/foo.*required for building native files" })]
- public void Relinking_ErrorWhenMissingEMSDK(BuildArgs buildArgs, string emsdkPath, string errorPattern, string id)
- {
- string projectName = $"simple_native_build";
- buildArgs = buildArgs with {
- ProjectName = projectName,
- ExtraBuildArgs = $"/p:EMSDK_PATH={emsdkPath}"
- };
- buildArgs = ExpandBuildArgs(buildArgs, extraProperties: "true");
- (_, string buildOutput) = BuildProject(buildArgs,
- initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42),
- id: id,
- expectSuccess: false);
-
- Assert.Matches(errorPattern, buildOutput);
- }
private void NativeBuild(string projectNamePrefix, string projectContents, BuildArgs buildArgs, RunHost host, string id)
{
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/ProcessExtensions.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/ProcessExtensions.cs
new file mode 100644
index 00000000000000..ca60d32d22a07d
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/ProcessExtensions.cs
@@ -0,0 +1,136 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Wasm.Build.Tests
+{
+ internal static class ProcessExtensions
+ {
+#if NET451
+ private static readonly bool _isWindows = true;
+#else
+ private static readonly bool _isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+#endif
+ private static readonly TimeSpan _defaultTimeout = TimeSpan.FromSeconds(30);
+
+ public static void KillTree(this Process process)
+ {
+ process.KillTree(_defaultTimeout);
+ }
+
+ public static void KillTree(this Process process, TimeSpan timeout)
+ {
+ string stdout;
+ if (_isWindows)
+ {
+ RunProcessAndWaitForExit(
+ "taskkill",
+ $"/T /F /PID {process.Id}",
+ timeout,
+ out stdout);
+ }
+ else
+ {
+ var children = new HashSet();
+ GetAllChildIdsUnix(process.Id, children, timeout);
+ foreach (var childId in children)
+ {
+ KillProcessUnix(childId, timeout);
+ }
+ KillProcessUnix(process.Id, timeout);
+ }
+ }
+
+ private static void GetAllChildIdsUnix(int parentId, ISet children, TimeSpan timeout)
+ {
+ string stdout;
+ var exitCode = RunProcessAndWaitForExit(
+ "pgrep",
+ $"-P {parentId}",
+ timeout,
+ out stdout);
+
+ if (exitCode == 0 && !string.IsNullOrEmpty(stdout))
+ {
+ using (var reader = new StringReader(stdout))
+ {
+ while (true)
+ {
+ var text = reader.ReadLine();
+ if (text == null)
+ {
+ return;
+ }
+
+ int id;
+ if (int.TryParse(text, out id))
+ {
+ children.Add(id);
+ // Recursively get the children
+ GetAllChildIdsUnix(id, children, timeout);
+ }
+ }
+ }
+ }
+ }
+
+ private static void KillProcessUnix(int processId, TimeSpan timeout)
+ {
+ string stdout;
+ RunProcessAndWaitForExit(
+ "kill",
+ $"-TERM {processId}",
+ timeout,
+ out stdout);
+ }
+
+ private static int RunProcessAndWaitForExit(string fileName, string arguments, TimeSpan timeout, out string stdout)
+ {
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = fileName,
+ Arguments = arguments,
+ RedirectStandardOutput = true,
+ UseShellExecute = false
+ };
+
+ var process = Process.Start(startInfo);
+
+ stdout = null;
+ if (process.WaitForExit((int)timeout.TotalMilliseconds))
+ {
+ stdout = process.StandardOutput.ReadToEnd();
+ }
+ else
+ {
+ process.Kill();
+ }
+
+ return process.ExitCode;
+ }
+
+ public static Task StartAndWaitForExitAsync(this Process subject)
+ {
+ var taskCompletionSource = new TaskCompletionSource
-
-
- <_PreCommand Condition="'$(OS)' != 'Windows_NT'">WasmBuildSupportDir=%24{HELIX_CORRELATION_PAYLOAD}/build
- <_PreCommand Condition="'$(OS)' == 'Windows_NT'">set WasmBuildSupportDir=%HELIX_CORRELATION_PAYLOAD%/build &
-
-
-
- <_PreCommand Condition="'$(OS)' != 'Windows_NT'">$(_PreCommand) TEST_LOG_PATH=%24{XHARNESS_OUT}/logs
- <_PreCommand Condition="'$(OS)' != 'Windows_NT'">$(_PreCommand) HARNESS_RUNNER=%24{HARNESS_RUNNER}
- <_PreCommand Condition="'$(OS)' == 'Windows_NT'">$(_PreCommand) set TEST_LOG_PATH=%XHARNESS_OUT%\logs &
- <_PreCommand Condition="'$(OS)' == 'Windows_NT'">$(_PreCommand) set HARNESS_RUNNER=%HARNESS_RUNNER% &
-
- $(_PreCommand) dotnet exec xunit.console.dll $(AssemblyName).dll -xml %24XHARNESS_OUT/testResults.xml
- $(_PreCommand) dotnet.exe exec xunit.console.dll $(AssemblyName).dll -xml %XHARNESS_OUT%\testResults.xml
- $(RunScriptCommand) -nocolor
- $(RunScriptCommand) -verbose
+ RunScriptTemplate.sh
+ $(MSBuildThisFileDirectory)data\$(RunScriptInputName)
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ dotnet exec xunit.console.dll $(AssemblyName).dll -xml %24XHARNESS_OUT/testResults.xml
+ dotnet.exe exec xunit.console.dll $(AssemblyName).dll -xml %XHARNESS_OUT%\testResults.xml
+ $(RunScriptCommand) -nocolor
+ $(RunScriptCommand) -verbose
+
+ $(RunScriptCommand) -method $(XUnitMethodName)
+ $(RunScriptCommand) -class $(XUnitClassName)
+
+
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmBuildAppTest.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmBuildAppTest.cs
index e426c9523d9f79..59b82318a12424 100644
--- a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmBuildAppTest.cs
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmBuildAppTest.cs
@@ -60,28 +60,6 @@ public static int Main()
}
}", buildArgs, host, id);
- [Theory]
- [BuildAndRun(aot: true, host: RunHost.None, parameters: new object[]
- { "", "error :.*emscripten.*required for AOT" })]
- [BuildAndRun(aot: true, host: RunHost.None, parameters: new object[]
- { "/non-existant/foo", "error.*\\(EMSDK_PATH\\)=/non-existant/foo.*required for AOT" })]
- public void AOT_ErrorWhenMissingEMSDK(BuildArgs buildArgs, string emsdkPath, string errorPattern, string id)
- {
- string projectName = $"missing_emsdk";
- buildArgs = buildArgs with {
- ProjectName = projectName,
- ExtraBuildArgs = $"/p:EMSDK_PATH={emsdkPath}"
- };
- buildArgs = ExpandBuildArgs(buildArgs);
-
- (_, string buildOutput) = BuildProject(buildArgs,
- initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42),
- id: id,
- expectSuccess: false);
-
- Assert.Matches(errorPattern, buildOutput);
- }
-
private static string s_bug49588_ProgramCS = @"
using System;
public class TestClass {
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/WorkloadTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/WorkloadTests.cs
new file mode 100644
index 00000000000000..e50d88db04a8a5
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/WorkloadTests.cs
@@ -0,0 +1,118 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Xml;
+using System.Xml.Serialization;
+using Xunit;
+using Xunit.Abstractions;
+using Xunit.Sdk;
+
+#nullable enable
+
+namespace Wasm.Build.Tests
+{
+ public class WorkloadTests : BuildTestBase
+ {
+ public WorkloadTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
+ : base(output, buildContext)
+ {
+ }
+
+ [ConditionalFact(typeof(BuildTestBase), nameof(IsUsingWorkloads))]
+ public void FilesInUnixFilesPermissionsXmlExist()
+ {
+ // not doing any project generation here
+ _enablePerTestCleanup = false;
+
+ // find all the UnixFilePermissions ..
+ string packsDir = Path.Combine(Path.GetDirectoryName(s_buildEnv.DotNet)!, "packs");
+ Assert.True(Directory.Exists(packsDir), $"Could not find packs directory {packsDir}");
+
+ var unixPermFiles = Directory.EnumerateFiles(packsDir, "UnixFilePermissions.xml", new EnumerationOptions { RecurseSubdirectories = true });
+ foreach (string unixPermFile in unixPermFiles)
+ {
+ Assert.True(File.Exists(unixPermFile), $"Could not find {unixPermFile}");
+ FileList? list = FileList.Deserialize(unixPermFile);
+ if (list == null)
+ throw new Exception($"Could not read unix permissions file {unixPermFile}");
+
+ // File is in ///data/UnixFilePermissions.xml
+ // and
+ string thisPackDir = Path.Combine(Path.GetDirectoryName(unixPermFile)!, "..");
+ foreach (FileListFile flf in list.File)
+ {
+ if (flf.Path == null)
+ throw new Exception($"Path for FileListFile should not be null. xml: {unixPermFile}");
+
+ var targetFile = Path.Combine(thisPackDir, flf.Path);
+ Assert.True(File.Exists(targetFile), $"Expected file {targetFile} to exist in the pack, as it is referenced in {unixPermFile}");
+ }
+ }
+
+ // We don't install the cross compiler pack from nupkg, so we don't
+ // have the unixFilePermissions for that
+ // Expect just the emscripten ones here for now
+
+ // linux doesn't have Emscripten.Python package, so only 2 there
+ int expectedPermFileCount = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? 2 : 3;
+
+ int permFileCount = unixPermFiles.Count();
+ if (permFileCount != expectedPermFileCount)
+ throw new XunitException($"Expected to find 3 UnixFilePermissions.xml files, from emscripten packages. But got {permFileCount}."
+ + $"{Environment.NewLine}Files: {string.Join(", ", unixPermFiles)}");
+ }
+ }
+
+ [Serializable]
+ [XmlType(AnonymousType = true)]
+ [XmlRoot(Namespace = "", IsNullable = false)]
+ public class FileList
+ {
+ private FileListFile[]? fileField;
+
+ [XmlElement("File")]
+ public FileListFile[] File
+ {
+ get => fileField ?? Array.Empty();
+ set => fileField = value;
+ }
+
+ public static FileList? Deserialize(string pathToXml)
+ {
+ var serializer = new XmlSerializer(typeof(FileList));
+
+ using var fs = new FileStream(pathToXml, FileMode.Open, FileAccess.Read);
+ var reader = XmlReader.Create(fs);
+ FileList? fileList = (FileList?)serializer.Deserialize(reader);
+ return fileList;
+ }
+ }
+
+ // From https://github.com/dotnet/sdk/blob/main/src/Cli/dotnet/NugetPackageDownloader/WorkloadUnixFilePermissionsFileList.cs
+ [Serializable]
+ [XmlType(AnonymousType = true)]
+ public class FileListFile
+ {
+ private string? pathField;
+
+ private string? permissionField;
+
+ [XmlAttribute]
+ public string? Path
+ {
+ get => pathField;
+ set => pathField = value;
+ }
+
+ [XmlAttribute]
+ public string? Permission
+ {
+ get => permissionField;
+ set => permissionField = value;
+ }
+ }
+}
diff --git a/src/tests/BuildWasmApps/testassets/LibraryWithResources/Directory.Build.props b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Blazor.Directory.Build.props
similarity index 100%
rename from src/tests/BuildWasmApps/testassets/LibraryWithResources/Directory.Build.props
rename to src/tests/BuildWasmApps/Wasm.Build.Tests/data/Blazor.Directory.Build.props
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Blazor.Directory.Build.targets b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Blazor.Directory.Build.targets
new file mode 100644
index 00000000000000..1ae8c2cd6ff9fa
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Blazor.Directory.Build.targets
@@ -0,0 +1,77 @@
+
+
+ <_MicrosoftNetCoreAppRefDir>$(AppRefDir)\
+ Microsoft.NETCore.App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_targetingPackReferenceExclusion Include="$(TargetName)" />
+ <_targetingPackReferenceExclusion Include="@(_ResolvedProjectReferencePaths->'%(Filename)')" />
+ <_targetingPackReferenceExclusion Include="@(DefaultReferenceExclusion)" />
+
+
+
+ <_targetingPackReferenceWithExclusion Include="@(Reference)">
+ %(_targetingPackReferenceExclusion.Identity)
+
+
+
+
+
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Local.Directory.Build.props b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Local.Directory.Build.props
new file mode 100644
index 00000000000000..1a9c112e747d9b
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Local.Directory.Build.props
@@ -0,0 +1,14 @@
+
+
+ <_WasmTargetsDir Condition="'$(RuntimeSrcDir)' != ''">$(RuntimeSrcDir)\src\mono\wasm\build\
+ <_WasmTargetsDir Condition="'$(WasmBuildSupportDir)' != ''">$(WasmBuildSupportDir)\wasm\
+ $(WasmBuildSupportDir)\emsdk\
+ true
+
+
+
+
+
+ PrepareForWasmBuild;$(WasmBuildAppDependsOn)
+
+
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Local.Directory.Build.targets b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Local.Directory.Build.targets
new file mode 100644
index 00000000000000..8c0b1e7e46ee71
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Local.Directory.Build.targets
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.sh b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.sh
new file mode 100644
index 00000000000000..d210c70ad068b1
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+EXECUTION_DIR=$(dirname $0)
+
+cd $EXECUTION_DIR
+
+if [ -z "$HELIX_WORKITEM_UPLOAD_ROOT" ]; then
+ XHARNESS_OUT="$EXECUTION_DIR/xharness-output"
+else
+ XHARNESS_OUT="$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output"
+fi
+
+if [ ! -z "$XHARNESS_CLI_PATH" ]; then
+ # When running in CI, we only have the .NET runtime available
+ # We need to call the XHarness CLI DLL directly via dotnet exec
+ HARNESS_RUNNER="dotnet exec $XHARNESS_CLI_PATH"
+else
+ HARNESS_RUNNER="dotnet xharness"
+fi
+
+function set_env_vars()
+{
+ if [ "x$TEST_USING_WORKLOADS" = "xtrue" ]; then
+ export PATH=$BASE_DIR/dotnet-workload:$PATH
+ export SDK_FOR_WORKLOAD_TESTING_PATH=$BASE_DIR/dotnet-workload
+ export AppRefDir=$BASE_DIR/microsoft.netcore.app.ref
+ elif [ ! -z "$HELIX_WORKITEM_UPLOAD_ROOT" ]; then
+ export WasmBuildSupportDir=$BASE_DIR/build
+ fi
+}
+
+export TEST_LOG_PATH=${XHARNESS_OUT}/logs
+
+[[RunCommands]]
+
+_exitCode=$?
+
+echo "XHarness artifacts: $XHARNESS_OUT"
+
+exit $_exitCode
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.props b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.props
new file mode 100644
index 00000000000000..6d8504088b955a
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.props
@@ -0,0 +1,7 @@
+
+
+ browser-wasm
+ true
+ true
+
+
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.targets b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.targets
new file mode 100644
index 00000000000000..76e0b3ea82eaff
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.targets
@@ -0,0 +1,95 @@
+
+
+ PrepareForWasmBuild;$(WasmBuildAppDependsOn)
+ <_MicrosoftNetCoreAppRefDir>$(AppRefDir)\
+ Microsoft.NETCore.App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_targetingPackReferenceExclusion Include="$(TargetName)" />
+ <_targetingPackReferenceExclusion Include="@(_ResolvedProjectReferencePaths->'%(Filename)')" />
+ <_targetingPackReferenceExclusion Include="@(DefaultReferenceExclusion)" />
+
+
+
+ <_targetingPackReferenceWithExclusion Include="@(Reference)">
+ %(_targetingPackReferenceExclusion.Identity)
+
+
+
+
+
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/nuget6.config b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/nuget6.config
new file mode 100644
index 00000000000000..434eac8408326f
--- /dev/null
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/nuget6.config
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tests/BuildWasmApps/testassets/LibraryWithResources/Directory.Build.targets b/src/tests/BuildWasmApps/testassets/LibraryWithResources/Directory.Build.targets
deleted file mode 100644
index 058246e4086204..00000000000000
--- a/src/tests/BuildWasmApps/testassets/LibraryWithResources/Directory.Build.targets
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/tests/BuildWasmApps/testassets/LibraryWithResources/LibraryWithResources.csproj b/src/tests/BuildWasmApps/testassets/LibraryWithResources/LibraryWithResources.csproj
deleted file mode 100644
index 91961dd7d6b422..00000000000000
--- a/src/tests/BuildWasmApps/testassets/LibraryWithResources/LibraryWithResources.csproj
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
- net5.0
-
-
-
-
-
-
diff --git a/src/tests/BuildWasmApps/testassets/LibraryWithResources/Class1.cs b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/Class1.cs
similarity index 100%
rename from src/tests/BuildWasmApps/testassets/LibraryWithResources/Class1.cs
rename to src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/Class1.cs
diff --git a/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj
new file mode 100644
index 00000000000000..5198d9c2109d4e
--- /dev/null
+++ b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj
@@ -0,0 +1,5 @@
+
+
+ net6.0
+
+
diff --git a/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/resx/words.es-ES.resx b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/resx/words.es-ES.resx
new file mode 100644
index 00000000000000..775397b15a2b9f
--- /dev/null
+++ b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/resx/words.es-ES.resx
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ ciao
+
+
+
+ hola
+
+
diff --git a/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/resx/words.ja-JP.resx b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/resx/words.ja-JP.resx
new file mode 100644
index 00000000000000..c843811244c256
--- /dev/null
+++ b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/resx/words.ja-JP.resx
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ さようなら
+
+
+
+ こんにちは
+
+
diff --git a/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/resx/words.resx b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/resx/words.resx
new file mode 100644
index 00000000000000..c3d5a787420866
--- /dev/null
+++ b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/resx/words.resx
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ bye
+
+
+
+ hello
+
+
diff --git a/src/tests/BuildWasmApps/testassets/SatelliteAssemblyInMain/resx/words.es-ES.resx b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyInMain/resx/words.es-ES.resx
new file mode 100644
index 00000000000000..775397b15a2b9f
--- /dev/null
+++ b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyInMain/resx/words.es-ES.resx
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ ciao
+
+
+
+ hola
+
+
diff --git a/src/tests/BuildWasmApps/testassets/SatelliteAssemblyInMain/resx/words.ja-JP.resx b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyInMain/resx/words.ja-JP.resx
new file mode 100644
index 00000000000000..c843811244c256
--- /dev/null
+++ b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyInMain/resx/words.ja-JP.resx
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ さようなら
+
+
+
+ こんにちは
+
+
diff --git a/src/tests/BuildWasmApps/testassets/SatelliteAssemblyInMain/resx/words.resx b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyInMain/resx/words.resx
new file mode 100644
index 00000000000000..c3d5a787420866
--- /dev/null
+++ b/src/tests/BuildWasmApps/testassets/SatelliteAssemblyInMain/resx/words.resx
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ bye
+
+
+
+ hello
+
+
diff --git a/src/tests/FunctionalTests/WebAssembly/Browser/AOT/Program.cs b/src/tests/FunctionalTests/WebAssembly/Browser/AOT/Program.cs
deleted file mode 100644
index 743f481896fcb5..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Browser/AOT/Program.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace Sample
-{
- public class Test
- {
- public static void Main(string[] args)
- {
- Console.WriteLine ("Hello, World!");
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int TestMeaning()
- {
- return 42;
- }
- }
-}
diff --git a/src/tests/FunctionalTests/WebAssembly/Browser/AOT/WebAssembly.Browser.AOT.Test.csproj b/src/tests/FunctionalTests/WebAssembly/Browser/AOT/WebAssembly.Browser.AOT.Test.csproj
deleted file mode 100644
index 06ffa371ace9a9..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Browser/AOT/WebAssembly.Browser.AOT.Test.csproj
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- true
- WasmTestOnBrowser
- 42
- true
- runtime.js
-
-
-
-
-
- Always
-
-
-
-
-
-
-
diff --git a/src/tests/FunctionalTests/WebAssembly/Browser/AOT/index.html b/src/tests/FunctionalTests/WebAssembly/Browser/AOT/index.html
deleted file mode 100644
index 642987d23c5e2b..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Browser/AOT/index.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
- TESTS
-
-
-
-
-
- Result from Sample.Test.TestMeaning:
-
-
-
-
-
-
-
diff --git a/src/tests/FunctionalTests/WebAssembly/Browser/AOT/runtime.js b/src/tests/FunctionalTests/WebAssembly/Browser/AOT/runtime.js
deleted file mode 100644
index 11f8d64f60c514..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Browser/AOT/runtime.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-var Module = {
-
- config: null,
-
- preInit: async function() {
- await MONO.mono_wasm_load_config("./mono-config.json"); // sets Module.config implicitly
- },
-
- onRuntimeInitialized: function () {
- if (!Module.config || Module.config.error) {
- console.log("No config found");
- test_exit(1);
- throw(Module.config.error);
- }
-
- Module.config.loaded_cb = function () {
- try {
- App.init ();
- } catch (error) {
- test_exit(1);
- throw (error);
- }
- };
- Module.config.fetch_file_cb = function (asset) {
- return fetch (asset, { credentials: 'same-origin' });
- }
-
- try
- {
- MONO.mono_load_runtime_and_bcl_args (Module.config);
- } catch (error) {
- test_exit(1);
- throw(error);
- }
- },
-};
diff --git a/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/Program.cs b/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/Program.cs
deleted file mode 100644
index 743f481896fcb5..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/Program.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace Sample
-{
- public class Test
- {
- public static void Main(string[] args)
- {
- Console.WriteLine ("Hello, World!");
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int TestMeaning()
- {
- return 42;
- }
- }
-}
diff --git a/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/WebAssembly.Browser.NormalInterp.Test.csproj b/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/WebAssembly.Browser.NormalInterp.Test.csproj
deleted file mode 100644
index db384e014d64af..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/WebAssembly.Browser.NormalInterp.Test.csproj
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- true
- false
- true
- WasmTestOnBrowser
- 42
- runtime.js
-
-
-
-
- Always
-
-
-
-
-
-
-
diff --git a/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/index.html b/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/index.html
deleted file mode 100644
index 9de05f5031b325..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/index.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
- TESTS
-
-
-
-
-
- Result from Sample.Test.TestMeaning:
-
-
-
-
-
-
-
diff --git a/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/runtime.js b/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/runtime.js
deleted file mode 100644
index b5227472674c6b..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Browser/NormalInterp/runtime.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-var Module = {
-
- config: null,
-
- preInit: async function() {
- await MONO.mono_wasm_load_config("./mono-config.json"); // sets Module.config implicitly
- },
-
- onRuntimeInitialized: function () {
- if (!Module.config || Module.config.error) {
- console.log("No config found");
- test_exit(1);
- throw(Module.config.error);
- }
-
- Module.config.loaded_cb = function () {
- try {
- App.init ();
- } catch (error) {
- test_exit(1);
- throw (error);
- }
- };
- Module.config.fetch_file_cb = function (asset) {
- return fetch (asset, { credentials: 'same-origin' });
- }
-
- try
- {
- MONO.mono_load_runtime_and_bcl_args (Module.config);
- } catch (error) {
- test_exit(1);
- throw(error);
- }
- },
-};
diff --git a/src/tests/FunctionalTests/WebAssembly/Console/AOT/Program.cs b/src/tests/FunctionalTests/WebAssembly/Console/AOT/Program.cs
deleted file mode 100644
index 20df95f3a578b5..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Console/AOT/Program.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Threading.Tasks;
-
-public class Test
-{
- public static async Task Main(string[] args)
- {
- await Task.Delay(1);
- Console.WriteLine("Hello Wasm AOT Functional Test!");
- return 42;
- }
-}
\ No newline at end of file
diff --git a/src/tests/FunctionalTests/WebAssembly/Console/AOT/WebAssembly.Console.AOT.Test.csproj b/src/tests/FunctionalTests/WebAssembly/Console/AOT/WebAssembly.Console.AOT.Test.csproj
deleted file mode 100644
index 60f8759a10ed16..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Console/AOT/WebAssembly.Console.AOT.Test.csproj
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- true
- true
- 42
- true
-
-
-
-
-
diff --git a/src/tests/FunctionalTests/WebAssembly/Console/NormalInterp/Program.cs b/src/tests/FunctionalTests/WebAssembly/Console/NormalInterp/Program.cs
deleted file mode 100644
index 5d2a7280f1493f..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Console/NormalInterp/Program.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Threading.Tasks;
-
-public class Test
-{
- public static async Task Main(string[] args)
- {
- await Task.Delay(1);
- Console.WriteLine("Hello From Wasm!");
- return 42;
- }
-}
\ No newline at end of file
diff --git a/src/tests/FunctionalTests/WebAssembly/Console/NormalInterp/WebAssembly.Console.NormalInterp.Test.csproj b/src/tests/FunctionalTests/WebAssembly/Console/NormalInterp/WebAssembly.Console.NormalInterp.Test.csproj
deleted file mode 100644
index 407030c25ac41c..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/Console/NormalInterp/WebAssembly.Console.NormalInterp.Test.csproj
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- false
- true
- 42
-
-
-
-
-
diff --git a/src/tests/FunctionalTests/WebAssembly/TopLevel/NormalInterp/Program.cs b/src/tests/FunctionalTests/WebAssembly/TopLevel/NormalInterp/Program.cs
deleted file mode 100644
index 787fe939765d16..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/TopLevel/NormalInterp/Program.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Threading.Tasks;
-
-await Task.Delay(1);
-Console.WriteLine("Hello From Wasm!");
-return 42;
diff --git a/src/tests/FunctionalTests/WebAssembly/TopLevel/NormalInterp/WebAssembly.TopLevel.NormalInterp.Test.csproj b/src/tests/FunctionalTests/WebAssembly/TopLevel/NormalInterp/WebAssembly.TopLevel.NormalInterp.Test.csproj
deleted file mode 100644
index 407030c25ac41c..00000000000000
--- a/src/tests/FunctionalTests/WebAssembly/TopLevel/NormalInterp/WebAssembly.TopLevel.NormalInterp.Test.csproj
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- false
- true
- 42
-
-
-
-
-