diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets index dd40856e629b1b931bd1d0de427e00bfc4cbd6a5..1e7ec3b173dc339136505aeaa907ef8778219103 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/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj index 12d402fcb7e3971cc8c96d7fd49d56bf263e6df5..d6d9a78c22e600e69a8390a9027cb253f0662419 100644 --- a/src/libraries/sendtohelixhelp.proj +++ b/src/libraries/sendtohelixhelp.proj @@ -311,7 +311,7 @@ - + diff --git a/src/mono/wasm/build/WasmApp.LocalBuild.props b/src/mono/wasm/build/WasmApp.LocalBuild.props index 01003f59172fa3489e86276e052ca08a117ca4f1..69a719a0e6d1e1ca32236aa859c4ef45b900f20b 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 636f0b1d257b94871e1ef86883ee36e7dc31d7cb..fac5252a4ef34aa63eb5a6f9c6d37a4994e0b002 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 50e491ac060f7599a1ba28cf00ff13f6b3a26884..4b8335a74d6d2a4fd7f2a76ec68cf6e08037e8ff 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 @@ -178,11 +173,6 @@ <_EmccCommonFlags Include="-v" Condition="'$(EmccVerbose)' != 'false'" /> - - <_WasmRuntimePackIncludeDir>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'include')) - <_WasmRuntimePackSrcDir>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'src')) - - <_DotnetJSSrcFile Include="$(_WasmRuntimePackSrcDir)\*.js" /> @@ -361,6 +351,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_aot (const char *desc) { mono_ + <_MonoAotCrossCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','browser-wasm')) 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 0000000000000000000000000000000000000000..c58c4b55f3da920ca13648f61bd13a41945f9402 --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BlazorWasmTests.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using Xunit; +using Xunit.Abstractions; + +#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 0000000000000000000000000000000000000000..231b215f88b58811a8894640296f93464b560392 --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildEnvironment.cs @@ -0,0 +1,136 @@ +// 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.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; + } + } + + // FIXME: update these to use Workload variants of the file, with the workload support + protected static string s_directoryBuildPropsForWorkloads = File.ReadAllText(Path.Combine(TestDataPath, "Local.Directory.Build.props")); + protected static string s_directoryBuildTargetsForWorkloads = File.ReadAllText(Path.Combine(TestDataPath, "Local.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 b87ff5c70bfc24ed1e74e23891e73f5ed2712e10..021ce531b17b32ad53d4782d99aebdb5b9adecfe 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 @@ public BuildTestBase(ITestOutputHelper output, SharedBuildPerTestClassFixture bu 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 @@ public BuildTestBase(ITestOutputHelper output, SharedBuildPerTestClassFixture bu // 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 @@ public BuildTestBase(ITestOutputHelper output, SharedBuildPerTestClassFixture bu _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 @@ public BuildTestBase(ITestOutputHelper output, SharedBuildPerTestClassFixture bu 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 @@ public BuildTestBase(ITestOutputHelper output, SharedBuildPerTestClassFixture bu 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/CommandResult.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/CommandResult.cs new file mode 100644 index 0000000000000000000000000000000000000000..24228f652a033c29c1649aabbf3c9e27d18578ff --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/CommandResult.cs @@ -0,0 +1,45 @@ +// 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.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 0000000000000000000000000000000000000000..2fefb87c0f0078bd66156301f6daac8a7f25cab1 --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/DotNetCommand.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Wasm.Build.Tests +{ + public class DotNetCommand : ToolCommand + { + private BuildEnvironment _buildEnvironment; + + public DotNetCommand(BuildEnvironment buildEnv) : base(buildEnv.DotNet) + { + _buildEnvironment = buildEnv; + WithEnvironmentVariables(buildEnv.EnvVars); + } + + protected override string GetFullArgs(params string[] args) + => $"{_buildEnvironment.DefaultBuildArgs} {string.Join(" ", args)}"; + } +} 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 0000000000000000000000000000000000000000..30ed330bf17910e3bc1017ff35cabace9276f08f --- /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 9f87757175c970416d21fd0ba5b39eb096ad7d11..130e59e0ea2a9c43705e5eefabfbab204b328596 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 0000000000000000000000000000000000000000..ca60d32d22a07d626baee6cad004471607e28b38 --- /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(); + + subject.EnableRaisingEvents = true; + + subject.Exited += (s, a) => + { + taskCompletionSource.SetResult(null); + + subject.Dispose(); + }; + + subject.Start(); + + return taskCompletionSource.Task; + } + } +} diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/RebuildTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/RebuildTests.cs index ecbcbdd75c05c29b490bc88f2cbc0e7d147b7387..769d22fa660dc9bfe3bd778c862a31898439f6a2 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/RebuildTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/RebuildTests.cs @@ -5,6 +5,7 @@ using System.IO; using Xunit; using Xunit.Abstractions; +using Xunit.Sdk; #nullable enable @@ -38,7 +39,7 @@ public void NoOpRebuild(BuildArgs buildArgs, bool nativeRelink, RunHost host, st Run(); if (!_buildContext.TryGetBuildFor(buildArgs, out BuildProduct? product)) - Assert.True(false, $"Test bug: could not get the build product in the cache"); + throw new XunitException($"Test bug: could not get the build product in the cache"); File.Move(product!.LogFile, Path.ChangeExtension(product.LogFile!, ".first.binlog")); @@ -46,9 +47,8 @@ public void NoOpRebuild(BuildArgs buildArgs, bool nativeRelink, RunHost host, st // no-op Rebuild BuildProject(buildArgs, - () => {}, - dotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, id: id, + dotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, createProject: false, useCache: false); diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/SatelliteAssembliesTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/SatelliteAssembliesTests.cs index e9d973650dcae62955b05af0bcec72bc67a6c177..45ce2b37ed273641e0ac643bec3c7a899a721027 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/SatelliteAssembliesTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/SatelliteAssembliesTests.cs @@ -1,6 +1,7 @@ // 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.IO; using System.Linq; @@ -44,11 +45,14 @@ public SatelliteAssembliesTests(ITestOutputHelper output, SharedBuildPerTestClas buildArgs = buildArgs with { ProjectName = projectName }; buildArgs = ExpandBuildArgs(buildArgs, projectTemplate: s_resourcesProjectTemplate, - extraProperties: $"{(nativeRelink ? "true" : "false")}", - extraItems: $""); + extraProperties: $"{(nativeRelink ? "true" : "false")}"); BuildProject(buildArgs, - initProject: () => CreateProgramForCultureTest($"{projectName}.words", "TestClass"), + initProject: () => + { + Utils.DirectoryCopy(Path.Combine(BuildEnvironment.TestAssetsPath, "resx"), Path.Combine(_projectDir!, "resx")); + CreateProgramForCultureTest(_projectDir!, $"{projectName}.resx.words", "TestClass"); + }, dotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, id: id); @@ -71,7 +75,7 @@ public SatelliteAssembliesTests(ITestOutputHelper output, SharedBuildPerTestClas RunHost host, string id) { - string projectName = $"sat_asm_proj_ref"; + string projectName = $"SatelliteAssemblyFromProjectRef"; bool dotnetWasmFromRuntimePack = !nativeRelink && !buildArgs.AOT; buildArgs = buildArgs with { ProjectName = projectName }; @@ -81,9 +85,17 @@ public SatelliteAssembliesTests(ITestOutputHelper output, SharedBuildPerTestClas extraItems: $""); BuildProject(buildArgs, - initProject: () => CreateProgramForCultureTest("LibraryWithResources.words", "LibraryWithResources.Class1"), dotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, - id: id); + id: id, + initProject: () => + { + string rootDir = _projectDir!; + _projectDir = Path.Combine(rootDir, projectName); + + Directory.CreateDirectory(_projectDir); + Utils.DirectoryCopy(Path.Combine(BuildEnvironment.TestAssetsPath, "SatelliteAssemblyFromProjectRef"), rootDir); + CreateProgramForCultureTest(_projectDir, "LibraryWithResources.resx.words", "LibraryWithResources.Class1"); + }); string output = RunAndTestWasmApp(buildArgs, expectedExitCode: 42, @@ -105,11 +117,10 @@ public void CheckThatSatelliteAssembliesAreNotAOTed(BuildArgs buildArgs, string extraProperties: $@" -O0 -O0", - extraItems: $""); + extraItems: $""); - System.Console.WriteLine ($"--- aot: {buildArgs.AOT}"); BuildProject(buildArgs, - initProject: () => CreateProgramForCultureTest($"{projectName}.words", "TestClass"), + initProject: () => CreateProgramForCultureTest(_projectDir!, $"{projectName}.words", "TestClass"), dotnetWasmFromRuntimePack: false, id: id); @@ -124,8 +135,8 @@ public void CheckThatSatelliteAssembliesAreNotAOTed(BuildArgs buildArgs, string } #pragma warning restore xUnit1026 - private void CreateProgramForCultureTest(string resourceName, string typeName) - => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), + private void CreateProgramForCultureTest(string dir, string resourceName, string typeName) + => File.WriteAllText(Path.Combine(dir, "Program.cs"), s_cultureResourceTestProgram .Replace("##RESOURCE_NAME##", resourceName) .Replace("##TYPE_NAME##", typeName)); diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/SharedBuildPerTestClassFixture.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/SharedBuildPerTestClassFixture.cs index e84a151bd5b02dd1905ac4a39a88346547c79b2e..2c43614ea416994450a751625937143e57fecdac 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/SharedBuildPerTestClassFixture.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/SharedBuildPerTestClassFixture.cs @@ -44,7 +44,7 @@ private void RemoveDirectory(string path) { try { - Directory.Delete(path, recursive: true); + Directory.Delete(path, recursive: true); } catch (Exception ex) { diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/ToolCommand.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/ToolCommand.cs new file mode 100644 index 0000000000000000000000000000000000000000..b45fefac9acda510769f81dcd178266f856f96e6 --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/ToolCommand.cs @@ -0,0 +1,184 @@ +// 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.Threading.Tasks; + +#nullable enable + +namespace Wasm.Build.Tests +{ + public class ToolCommand + { + 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 ToolCommand(string command, string label="") + { + _command = command; + _label = label; + } + + public ToolCommand WithWorkingDirectory(string dir) + { + WorkingDirectory = dir; + return this; + } + + public ToolCommand WithEnvironmentVariable(string key, string value) + { + Environment[key] = value; + return this; + } + + public ToolCommand WithEnvironmentVariables(IDictionary? extraEnvVars) + { + if (extraEnvVars != null) + { + foreach ((string key, string value) in extraEnvVars) + Environment[key] = value; + } + + return this; + } + + public virtual CommandResult Execute(params string[] args) + { + return Task.Run(async () => await ExecuteAsync(args)).Result; + } + + public async virtual Task ExecuteAsync(params 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(params 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(params string[] args) => string.Join(" ", args); + + 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}"); + ErrorDataReceived?.Invoke(s, e); + }; + + CurrentProcess.OutputDataReceived += (s, e) => + { + if (e.Data == null) + return; + + output.Add($"[{_label}] {e.Data}"); + OutputDataReceived?.Invoke(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; + } + + 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/Utils.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/Utils.cs new file mode 100644 index 0000000000000000000000000000000000000000..048368cc4300403e7d690c665714d4aeb3e0c8c3 --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/Utils.cs @@ -0,0 +1,58 @@ +// 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.IO; +using System.Runtime.InteropServices; +using System.Text; +internal static class Utils +{ + public static void DirectoryCopy(string sourceDirName, string destDirName, Func? predicate=null, bool copySubDirs=true, bool silent=false) + { + // Get the subdirectories for the specified directory. + DirectoryInfo dir = new DirectoryInfo(sourceDirName); + + if (!dir.Exists) + { + throw new DirectoryNotFoundException( + "Source directory does not exist or could not be found: " + + sourceDirName); + } + + DirectoryInfo[] dirs = dir.GetDirectories(); + + // If the destination directory doesn't exist, create it. + Directory.CreateDirectory(destDirName); + + // Get the files in the directory and copy them to the new location. + FileInfo[] files = dir.GetFiles(); + foreach (FileInfo file in files) + { + string fullPath = file.ToString(); + if (predicate != null && !predicate(fullPath)) + { + // if (!silent) + // e(MessageImportance.Low, $"Skipping {fullPath}"); + continue; + } + + string tempPath = Path.Combine(destDirName, file.Name); + // if (!silent) + // Logger?.LogMessage(MessageImportance.Low, $"Copying {fullPath} to {tempPath}"); + file.CopyTo(tempPath, false); + } + + // If copying subdirectories, copy them and their contents to new location. + if (copySubDirs) + { + foreach (DirectoryInfo subdir in dirs) + { + string tempPath = Path.Combine(destDirName, subdir.Name); + DirectoryCopy(subdir.FullName, tempPath, predicate, copySubDirs, silent); + } + } + } + +} diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/Wasm.Build.Tests.csproj b/src/tests/BuildWasmApps/Wasm.Build.Tests/Wasm.Build.Tests.csproj index 20a1972430746f0550f97fbeb4e19e32d61f84a9..0f06b6f08dfe1ea87850f395173f7102dfa30358 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/Wasm.Build.Tests.csproj +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/Wasm.Build.Tests.csproj @@ -13,31 +13,53 @@ TEST_DEBUG_CONFIG_ALSO false + true - - - - <_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 e426c9523d9f79739e52ed11f54e04db974f45d8..59b82318a12424de1a32b3240fd6d3988e3d3ab9 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 0000000000000000000000000000000000000000..89b656ee444e4282f3db8088036252f717fa015f --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/WorkloadTests.cs @@ -0,0 +1,109 @@ +// 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.Xml; +using System.Xml.Serialization; +using Xunit; +using Xunit.Abstractions; + +#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 + Assert.Equal(3, unixPermFiles.Count()); + } + } + + [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 0000000000000000000000000000000000000000..1ae8c2cd6ff9fa4d4f09b3269aab98869aaa6448 --- /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 0000000000000000000000000000000000000000..1a9c112e747d9b413d9cc0a85357858e38886109 --- /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 0000000000000000000000000000000000000000..8c0b1e7e46ee7108097f2ad17131ed1fc3644f76 --- /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 0000000000000000000000000000000000000000..d210c70ad068b18ab3a93c620f614d8951f528dd --- /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/nuget6.config b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/nuget6.config new file mode 100644 index 0000000000000000000000000000000000000000..434eac8408326f68e9550d6436ee75a61746545e --- /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 058246e40862046ca3e0e99c26508fed3b024525..0000000000000000000000000000000000000000 --- 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 91961dd7d6b4229fbc0283eeb5bfb1bdee365bfe..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..5198d9c2109d4e6082208ff0406057c376986a63 --- /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 0000000000000000000000000000000000000000..775397b15a2b9f3632d6e762e17697377d28b8ad --- /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 0000000000000000000000000000000000000000..c843811244c256f49962534c75788adb03008a98 --- /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 0000000000000000000000000000000000000000..c3d5a787420866effe35ff2dbc90d639002e1648 --- /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 0000000000000000000000000000000000000000..775397b15a2b9f3632d6e762e17697377d28b8ad --- /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 0000000000000000000000000000000000000000..c843811244c256f49962534c75788adb03008a98 --- /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 0000000000000000000000000000000000000000..c3d5a787420866effe35ff2dbc90d639002e1648 --- /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 743f481896fcb51816794074fd45d6d2798881cb..0000000000000000000000000000000000000000 --- 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 06ffa371ace9a9402cb61a0bd48730cdaf3e1571..0000000000000000000000000000000000000000 --- 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 642987d23c5e2be5241c233f85705a32b3ce1488..0000000000000000000000000000000000000000 --- 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 11f8d64f60c51440cfb98e29da778eab6fecc3f8..0000000000000000000000000000000000000000 --- 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 743f481896fcb51816794074fd45d6d2798881cb..0000000000000000000000000000000000000000 --- 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 db384e014d64afbb0f27b4640c27b61d139ba307..0000000000000000000000000000000000000000 --- 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 9de05f5031b3251689300a1aef3b6e1254ca373c..0000000000000000000000000000000000000000 --- 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 b5227472674c6b212d8344e571079de320ac860b..0000000000000000000000000000000000000000 --- 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 20df95f3a578b504d7da034e86a6c4d2425027fc..0000000000000000000000000000000000000000 --- 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 60f8759a10ed16912304c0c5486b473f27c71cc6..0000000000000000000000000000000000000000 --- 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 5d2a7280f1493ff20de8120477311b99d5f83a79..0000000000000000000000000000000000000000 --- 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 407030c25ac41c46f2091f0fe6619dc0ba5869a7..0000000000000000000000000000000000000000 --- 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 787fe939765d16ed650281f12eacc63898ca07d8..0000000000000000000000000000000000000000 --- 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 407030c25ac41c46f2091f0fe6619dc0ba5869a7..0000000000000000000000000000000000000000 --- a/src/tests/FunctionalTests/WebAssembly/TopLevel/NormalInterp/WebAssembly.TopLevel.NormalInterp.Test.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - false - true - 42 - - - - -