From cd6273eb3e212319ee590d22bd43432211faf296 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Mon, 20 Jul 2026 23:19:41 +0200 Subject: [PATCH 01/30] Enable OOP tests in CoreCLR WASM runners Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Common/CLRTest.Execute.Bash.targets | 107 +++++++++++++-- .../Common/CLRTest.Execute.Batch.targets | 58 ++++++++- .../CoreCLRTestLibrary/OutOfProcessTest.cs | 86 +++++++++++- .../Common/XUnitWrapperGenerator/ITestInfo.cs | 123 +++++++++++------- .../XUnitWrapperGenerator.cs | 118 +++++++++-------- .../XUnitWrapperGenerator.props | 20 +++ 6 files changed, 400 insertions(+), 112 deletions(-) diff --git a/src/tests/Common/CLRTest.Execute.Bash.targets b/src/tests/Common/CLRTest.Execute.Bash.targets index be824d9285214a..d2924848cfc63e 100644 --- a/src/tests/Common/CLRTest.Execute.Bash.targets +++ b/src/tests/Common/CLRTest.Execute.Bash.targets @@ -465,15 +465,16 @@ run_with_timeout() { fi } -if [ ! -z ${RunCrossGen2+x} ]%3B then - TakeLock -fi - -if [ -z ${RunWithNodeJS+x} ] ; then - cd WasmApp - ./run-v8.sh -else - if [ -z ${__TestTimeout+x} ]; then +run_browser_test() { + if [ -z ${RunWithNodeJS+x} ] + then + ( + cd WasmApp + ./run-v8.sh + ) + else + if [ -z ${__TestTimeout+x} ] + then __TestTimeout=300000 fi @@ -486,6 +487,94 @@ else cmd=( node --experimental-wasm-exnref --stack-size=8192 "${CORE_ROOT}/corerun.js" -c "${CORE_ROOT}" "${PWD}/${ExePath}" "${CLRTestExecutionArguments[@]}" ) echo Running: "${cmd[@]}" run_with_timeout $__TestTimeout "${cmd[@]}" + fi +} + +run_out_of_process_tests() { + local oop_plan_file="${PWD}/$(AssemblyName).outofprocess-plan" + local oop_result_token="$$-${RANDOM}-%24(date +%s)" + local -a oop_merged_execution_arguments=("${CLRTestExecutionArguments[@]}") + local oop_test_harness_stripe="${TEST_HARNESS_STRIPE_TO_EXECUTE-}" + local oop_test_harness_stripe_was_set="${TEST_HARNESS_STRIPE_TO_EXECUTE+x}" + local oop_plan_exit + + rm -f "$oop_plan_file" + export __TestOutOfProcessPlanFile="$oop_plan_file" + run_browser_test + oop_plan_exit=$? + unset __TestOutOfProcessPlanFile + + if [ "$oop_plan_exit" -ne "$CLRTestExpectedExitCode" ] + then + echo "Out-of-process test planning failed with exit code $oop_plan_exit." + return "$oop_plan_exit" + fi + + if [ ! -f "$oop_plan_file" ] + then + echo "Out-of-process test planning did not create '$oop_plan_file'." + return 1 + fi + + unset CLRTestExecutionArguments + unset TEST_HARNESS_STRIPE_TO_EXECUTE + while IFS= read -r oop_assembly + do + if [ -z "$oop_assembly" ] + then + continue + fi + + oop_assembly="${oop_assembly//%5C%5C//}" + local oop_wrapper="${oop_assembly%.*}.sh" + local oop_result="${oop_assembly}.outofprocess-result" + local oop_output="${oop_result}.output.$$" + local oop_result_tmp="${oop_result}.tmp.$$" + local oop_exit + + rm -f "$oop_result" "$oop_output" "$oop_result_tmp" + /usr/bin/env bash "$oop_wrapper" < /dev/null > "$oop_output" 2>&1 + oop_exit=$? + + { + echo 1 + echo "$oop_result_token" + echo "$oop_exit" + cat "$oop_output" + } > "$oop_result_tmp" + + if [ $? -eq 0 ] + then + mv -f "$oop_result_tmp" "$oop_result" + else + echo "Failed to write out-of-process result '$oop_result'." + rm -f "$oop_result_tmp" + fi + rm -f "$oop_output" + done < "$oop_plan_file" + + CLRTestExecutionArguments=("${oop_merged_execution_arguments[@]}") + if [ -n "$oop_test_harness_stripe_was_set" ] + then + export TEST_HARNESS_STRIPE_TO_EXECUTE="$oop_test_harness_stripe" + fi + + export __TestOutOfProcessResultToken="$oop_result_token" + run_browser_test + local oop_test_exit=$? + unset __TestOutOfProcessResultToken + return "$oop_test_exit" +} + +if [ ! -z ${RunCrossGen2+x} ]%3B then + TakeLock +fi + +if [ -f "$(AssemblyName).HasOutOfProcessTests" ] +then + run_out_of_process_tests +else + run_browser_test fi CLRTestExitCode=$? diff --git a/src/tests/Common/CLRTest.Execute.Batch.targets b/src/tests/Common/CLRTest.Execute.Batch.targets index 920f29593849eb..18c3a0476afe90 100644 --- a/src/tests/Common/CLRTest.Execute.Batch.targets +++ b/src/tests/Common/CLRTest.Execute.Batch.targets @@ -366,8 +366,62 @@ IF NOT DEFINED RunWithNodeJS ( set "__RunCmd=node --experimental-wasm-exnref --stack-size=8192 "!__CoreRootWin!\corerun.js" -c "!__CoreRootUnix!" "!__ExePathUnix!" %CLRTestExecutionArguments%" ECHO Running: !__RunCmd! - call :RunWithTimeout !__TestTimeout! - set CLRTestExitCode=!ERRORLEVEL! + + IF EXIST "$(AssemblyName).HasOutOfProcessTests" ( + set "__OopPlanFile=$(AssemblyName).outofprocess-plan" + set "__OopResultToken=!RANDOM!-!RANDOM!-!RANDOM!" + del /q "!__OopPlanFile!" 2>NUL + + set "__TestOutOfProcessPlanFile=!__OopPlanFile!" + call :RunWithTimeout !__TestTimeout! + set "__OopPlanExit=!ERRORLEVEL!" + set "__TestOutOfProcessPlanFile=" + + IF NOT "!__OopPlanExit!"=="!CLRTestExpectedExitCode!" ( + ECHO Out-of-process test planning failed with exit code !__OopPlanExit!. + set CLRTestExitCode=!__OopPlanExit! + ) ELSE IF NOT EXIST "!__OopPlanFile!" ( + ECHO Out-of-process test planning did not create "!__OopPlanFile!". + set CLRTestExitCode=1 + ) ELSE ( + set "__OopMergedExecutionArguments=!CLRTestExecutionArguments!" + set "__OopMergedTestHarnessStripe=!TEST_HARNESS_STRIPE_TO_EXECUTE!" + set "CLRTestExecutionArguments=" + set "TEST_HARNESS_STRIPE_TO_EXECUTE=" + + for /F "usebackq delims=" %%P in ("!__OopPlanFile!") do ( + for %%F in ("%%P") do set "__OopWrapper=%%~dpnF.cmd" + set "__OopResult=%%P.outofprocess-result" + set "__OopOutput=!__OopResult!.output.!RANDOM!" + set "__OopResultTemp=!__OopResult!.tmp.!RANDOM!" + del /q "!__OopResult!" "!__OopOutput!" "!__OopResultTemp!" 2>NUL + + set "CORE_ROOT=!__CoreRootWin!" + "%ComSpec%" /D /S /C call "!__OopWrapper!" > "!__OopOutput!" 2>&1 + set "__OopExit=!ERRORLEVEL!" + set "CORE_ROOT=!__CoreRootUnix!" + + ( + ECHO 1 + ECHO !__OopResultToken! + ECHO !__OopExit! + TYPE "!__OopOutput!" + ) > "!__OopResultTemp!" + move /Y "!__OopResultTemp!" "!__OopResult!" >NUL + del /q "!__OopOutput!" 2>NUL + ) + + set "CLRTestExecutionArguments=!__OopMergedExecutionArguments!" + set "TEST_HARNESS_STRIPE_TO_EXECUTE=!__OopMergedTestHarnessStripe!" + set "__TestOutOfProcessResultToken=!__OopResultToken!" + call :RunWithTimeout !__TestTimeout! + set CLRTestExitCode=!ERRORLEVEL! + set "__TestOutOfProcessResultToken=" + ) + ) ELSE ( + call :RunWithTimeout !__TestTimeout! + set CLRTestExitCode=!ERRORLEVEL! + ) ) if defined RunCrossGen2 ( diff --git a/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs b/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs index e08088951f19bd..0bb46aba78daf6 100644 --- a/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs +++ b/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs @@ -16,6 +16,11 @@ namespace TestLibrary { public static class OutOfProcessTest { + private const string OutOfProcessPlanFileEnvironmentVariable = "__TestOutOfProcessPlanFile"; + private const string OutOfProcessResultFileSuffix = ".outofprocess-result"; + private const string OutOfProcessResultFormatVersion = "1"; + private const string OutOfProcessResultTokenEnvironmentVariable = "__TestOutOfProcessResultToken"; + internal static bool runningInWindows; internal static string reportBase; internal static string testBinaryBase; @@ -41,15 +46,28 @@ static OutOfProcessTest() } } + public static string OutOfProcessPlanFile => + Environment.GetEnvironmentVariable(OutOfProcessPlanFileEnvironmentVariable); + + public static bool IsUsingPrecomputedResults => + !String.IsNullOrEmpty(Environment.GetEnvironmentVariable(OutOfProcessResultTokenEnvironmentVariable)); + public static bool OutOfProcessTestsSupported => - !OperatingSystem.IsIOS() - && !OperatingSystem.IsTvOS() - && !OperatingSystem.IsAndroid() - && !OperatingSystem.IsBrowser() - && !OperatingSystem.IsWasi(); + IsUsingPrecomputedResults + || (!OperatingSystem.IsIOS() + && !OperatingSystem.IsTvOS() + && !OperatingSystem.IsAndroid() + && !OperatingSystem.IsBrowser() + && !OperatingSystem.IsWasi()); public static void RunOutOfProcessTest(string assemblyPath, string testPathPrefix) { + if (IsUsingPrecomputedResults) + { + ImportPrecomputedResult(assemblyPath, testPathPrefix); + return; + } + int ret = -100; string baseDir = AppContext.BaseDirectory; string outputDir = System.IO.Path.GetFullPath(Path.Combine(reportBase, Path.GetDirectoryName(assemblyPath))); @@ -147,5 +165,63 @@ public static void RunOutOfProcessTest(string assemblyPath, string testPathPrefi Assert.True(ret == CoreclrTestWrapperLib.EXIT_SUCCESS_CODE, string.Join(Environment.NewLine, testOutput)); } } + + private static void ImportPrecomputedResult(string assemblyPath, string testPathPrefix) + { + string resultToken = Environment.GetEnvironmentVariable(OutOfProcessResultTokenEnvironmentVariable); + if (String.IsNullOrEmpty(resultToken)) + { + Assert.Fail($"Test Infrastructure Failure: Environment variable '{OutOfProcessResultTokenEnvironmentVariable}' is not set."); + } + + string testAssemblyPath = assemblyPath; + if (testPathPrefix != null) + { + testAssemblyPath = Path.Combine(testPathPrefix, testAssemblyPath); + } + + if (!OperatingSystem.IsWindows()) + { + testAssemblyPath = testAssemblyPath.Replace("\\", "/"); + } + + string resultFile = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), testAssemblyPath)) + OutOfProcessResultFileSuffix; + if (!File.Exists(resultFile)) + { + Assert.Fail($"Test Infrastructure Failure: Out-of-process result file '{resultFile}' was not found."); + } + + using StreamReader resultReader = File.OpenText(resultFile); + string formatVersion = resultReader.ReadLine(); + string actualResultToken = resultReader.ReadLine(); + string exitCodeText = resultReader.ReadLine(); + string output = resultReader.ReadToEnd(); + + if (!String.Equals(formatVersion, OutOfProcessResultFormatVersion, StringComparison.Ordinal)) + { + Assert.Fail($"Test Infrastructure Failure: Out-of-process result file '{resultFile}' has unsupported format version '{formatVersion}'."); + } + + if (!String.Equals(actualResultToken, resultToken, StringComparison.Ordinal)) + { + Assert.Fail($"Test Infrastructure Failure: Out-of-process result file '{resultFile}' is stale or belongs to another run."); + } + + if (!Int32.TryParse(exitCodeText, out int exitCode)) + { + Assert.Fail($"Test Infrastructure Failure: Out-of-process result file '{resultFile}' contains invalid exit code '{exitCodeText}'."); + } + + Console.WriteLine($"Out-of-process result file: {resultFile}"); + Console.Write(output); + if (output.Length != 0 && output[output.Length - 1] != '\n') + { + Console.WriteLine(); + } + Console.WriteLine($"Return code: {exitCode}"); + + Assert.True(exitCode == CoreclrTestWrapperLib.EXIT_SUCCESS_CODE, + $"Out-of-process wrapper failed with exit code {exitCode}.{Environment.NewLine}{output}"); + } } } diff --git a/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs b/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs index d0474f5d8f9066..4741dd1b8a0982 100644 --- a/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs +++ b/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs @@ -376,7 +376,7 @@ public sealed class OutOfProcessTest : ITestInfo public string ContainingType => "OutOfProcessTest"; private CodeBuilder _executionStatement { get; } - private string RelativeAssemblyPath { get; } + public string RelativeAssemblyPath { get; } public OutOfProcessTest(string displayName, string relativeAssemblyPath, string? testBuildMode) { @@ -555,14 +555,17 @@ public sealed class WrapperLibraryTestSummaryReporting : ITestReporterWrapper private readonly string _summaryLocalIdentifier; private readonly string _filterLocalIdentifier; private readonly string _outputRecorderIdentifier; + private readonly string? _outOfProcessPlanWriterIdentifier; public WrapperLibraryTestSummaryReporting(string summaryLocalIdentifier, string filterLocalIdentifier, - string outputRecorderIdentifier) + string outputRecorderIdentifier, + string? outOfProcessPlanWriterIdentifier = null) { _summaryLocalIdentifier = summaryLocalIdentifier; _filterLocalIdentifier = filterLocalIdentifier; _outputRecorderIdentifier = outputRecorderIdentifier; + _outOfProcessPlanWriterIdentifier = outOfProcessPlanWriterIdentifier; } public CodeBuilder WrapTestExecutionWithReporting(CodeBuilder testExecutionExpression, @@ -576,43 +579,27 @@ public CodeBuilder WrapTestExecutionWithReporting(CodeBuilder testExecutionExpre using (builder.NewBracesScope()) { - builder.AppendLine($"System.TimeSpan testStart = stopwatch.Elapsed;"); - builder.AppendLine("try"); - - using (builder.NewBracesScope()) + if (_outOfProcessPlanWriterIdentifier is not null) { - builder.AppendLine($"{_summaryLocalIdentifier}.ReportStartingTest(" - + $"{test.TestNameExpression}," - + $" System.Console.Out);"); - - builder.AppendLine($"{_outputRecorderIdentifier}.ResetTestOutput();"); - builder.Append(testExecutionExpression); - - builder.AppendLine($"{_summaryLocalIdentifier}.ReportPassedTest(" - + $"{test.TestNameExpression}," - + $" \"{test.ContainingType}\"," - + $" @\"{test.Method}\"," - + $" stopwatch.Elapsed - testStart," - + $" {_outputRecorderIdentifier}.GetTestOutput()," - + $" System.Console.Out," - + $" tempLogSw," - + $" statsCsvSw);"); + builder.AppendLine($"if ({_outOfProcessPlanWriterIdentifier} is not null)"); + using (builder.NewBracesScope()) + { + if (test is OutOfProcessTest outOfProcessTest) + { + string relativeAssemblyPath = outOfProcessTest.RelativeAssemblyPath.Replace("\"", "\"\""); + builder.AppendLine($@"{_outOfProcessPlanWriterIdentifier}.WriteLine(@""{relativeAssemblyPath}"");"); + } + } + + builder.AppendLine("else"); + using (builder.NewBracesScope()) + { + AppendTestExecutionWithReporting(builder, testExecutionExpression, test); + } } - - builder.AppendLine("catch (System.Exception ex)"); - - using (builder.NewBracesScope()) + else { - builder.AppendLine($"{_summaryLocalIdentifier}.ReportFailedTest(" - + $"{test.TestNameExpression}," - + $" \"{test.ContainingType}\"," - + $" @\"{test.Method}\"," - + $" stopwatch.Elapsed - testStart," - + $" ex," - + $" {_outputRecorderIdentifier}.GetTestOutput()," - + $" System.Console.Out," - + $" tempLogSw," - + $" statsCsvSw);"); + AppendTestExecutionWithReporting(builder, testExecutionExpression, test); } } @@ -625,19 +612,67 @@ public CodeBuilder WrapTestExecutionWithReporting(CodeBuilder testExecutionExpre return builder; } + private void AppendTestExecutionWithReporting(CodeBuilder builder, + CodeBuilder testExecutionExpression, + ITestInfo test) + { + builder.AppendLine("System.TimeSpan testStart = stopwatch.Elapsed;"); + builder.AppendLine("try"); + + using (builder.NewBracesScope()) + { + builder.AppendLine($"{_summaryLocalIdentifier}.ReportStartingTest(" + + $"{test.TestNameExpression}," + + $" System.Console.Out);"); + + builder.AppendLine($"{_outputRecorderIdentifier}.ResetTestOutput();"); + builder.Append(testExecutionExpression); + + builder.AppendLine($"{_summaryLocalIdentifier}.ReportPassedTest(" + + $"{test.TestNameExpression}," + + $" \"{test.ContainingType}\"," + + $" @\"{test.Method}\"," + + $" stopwatch.Elapsed - testStart," + + $" {_outputRecorderIdentifier}.GetTestOutput()," + + $" System.Console.Out," + + $" tempLogSw," + + $" statsCsvSw);"); + } + + builder.AppendLine("catch (System.Exception ex)"); + + using (builder.NewBracesScope()) + { + builder.AppendLine($"{_summaryLocalIdentifier}.ReportFailedTest(" + + $"{test.TestNameExpression}," + + $" \"{test.ContainingType}\"," + + $" @\"{test.Method}\"," + + $" stopwatch.Elapsed - testStart," + + $" ex," + + $" {_outputRecorderIdentifier}.GetTestOutput()," + + $" System.Console.Out," + + $" tempLogSw," + + $" statsCsvSw);"); + } + } + public string GenerateSkippedTestReporting(ITestInfo skippedTest, string? skipReason = null) { string reasonExpression = skipReason != null ? $"@\"{skipReason.Replace("\r", "").Replace("\n", " ").Replace("\"", "\"\"")}\"" : "string.Empty"; - return $"{_summaryLocalIdentifier}.ReportSkippedTest(" - + $"{skippedTest.TestNameExpression}," - + $" \"{skippedTest.ContainingType}\"," - + $" @\"{skippedTest.Method}\"," - + $" System.TimeSpan.Zero," - + $" {reasonExpression}," - + $" tempLogSw," - + $" statsCsvSw);"; + string reportSkippedTest = $"{_summaryLocalIdentifier}.ReportSkippedTest(" + + $"{skippedTest.TestNameExpression}," + + $" \"{skippedTest.ContainingType}\"," + + $" @\"{skippedTest.Method}\"," + + $" System.TimeSpan.Zero," + + $" {reasonExpression}," + + $" tempLogSw," + + $" statsCsvSw);"; + + return _outOfProcessPlanWriterIdentifier is null + ? reportSkippedTest + : $"if ({_outOfProcessPlanWriterIdentifier} is null) {reportSkippedTest}"; } } diff --git a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs index 85de9ae0ef5795..8e7db7d7fa1860 100644 --- a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs +++ b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs @@ -302,6 +302,41 @@ private static string GenerateFullTestRunner(ImmutableArray testInfos CodeBuilder builder = new(); AppendAliasMap(builder, aliasMap); + CodeBuilder testExecutorBuilder = new(); + int outOfProcessTestCount = testInfos.Count(static test => test is OutOfProcessTest); + ITestReporterWrapper reporter = + new WrapperLibraryTestSummaryReporting( + "summary", + "filter", + "outputRecorder", + outOfProcessTestCount != 0 ? "outOfProcessPlanWriter" : null); + int currentTestExecutor = 0; + + // This code breaks the tests into groups called by helper methods. + // + // Reasonably large methods are known to take a long time to compile, and use excessive stack + // leading to test failures. Groups of 50 were sufficient to avoid this problem. + // + // However, large methods also appear to causes problems when the tests are run in gcstress + // modes. Groups of 1 appear to help with this. It hasn't been directly measured but + // experimentally has improved gcstress testing. + foreach (ITestInfo test in testInfos) + { + currentTestExecutor++; + testExecutorBuilder.AppendLine($"void TestExecutor{currentTestExecutor}(" + + "System.IO.StreamWriter tempLogSw, " + + "System.IO.StreamWriter statsCsvSw" + + (outOfProcessTestCount != 0 + ? ", System.IO.StreamWriter outOfProcessPlanWriter)" + : ")")); + testExecutorBuilder.AppendLine("{"); + testExecutorBuilder.PushIndent(); + testExecutorBuilder.Append(test.GenerateTestExecution(reporter)); + testExecutorBuilder.PopIndent(); + testExecutorBuilder.AppendLine("}"); + testExecutorBuilder.AppendLine(); + } + builder.AppendLine("XUnitWrapperLibrary.TestFilter filter;"); builder.AppendLine("XUnitWrapperLibrary.TestSummary summary;"); builder.AppendLine("System.Diagnostics.Stopwatch stopwatch;"); @@ -341,11 +376,35 @@ private static string GenerateFullTestRunner(ImmutableArray testInfos builder.AppendLine("Initialize();"); + if (outOfProcessTestCount != 0) + { + builder.AppendLine("string outOfProcessPlanFile = TestLibrary.OutOfProcessTest.OutOfProcessPlanFile;"); + builder.AppendLine("if (outOfProcessPlanFile is not null)"); + using (builder.NewBracesScope()) + { + builder.AppendLine("using (System.IO.StreamWriter unusedWriter = new(System.IO.Stream.Null))"); + builder.AppendLine("using (System.IO.StreamWriter outOfProcessPlanWriter = System.IO.File.CreateText(outOfProcessPlanFile))"); + using (builder.NewBracesScope()) + { + for (int i = 1; i <= currentTestExecutor; i++) + { + builder.AppendLine($"TestExecutor{i}(unusedWriter, unusedWriter, outOfProcessPlanWriter);"); + } + } + builder.AppendLine("return 100;"); + } + + builder.AppendLine("if (System.OperatingSystem.IsBrowser() && !TestLibrary.OutOfProcessTest.IsUsingPrecomputedResults)"); + using (builder.NewBracesScope()) + { + builder.AppendLine(@"System.Console.Error.WriteLine(""Out-of-process tests require host-side orchestration on Browser."");"); + builder.AppendLine("return 1;"); + } + } + // Open the stream writer for the temp log. builder.AppendLine($@"using (System.IO.StreamWriter tempLogSw = System.IO.File.AppendText(""{assemblyName}.tempLog.xml""))"); builder.AppendLine($@"using (System.IO.StreamWriter statsCsvSw = System.IO.File.AppendText(""{assemblyName}.testStats.csv""))"); - CodeBuilder testExecutorBuilder = new(); - int totalTestsEmitted = 0; using (builder.NewBracesScope()) { @@ -355,56 +414,11 @@ private static string GenerateFullTestRunner(ImmutableArray testInfos // Otherwise, it's going to fail when attempting to find dumps. builder.AppendLine($@"summary.WriteHeaderToTempLog(""{assemblyName}"", tempLogSw);"); - ITestReporterWrapper reporter = - new WrapperLibraryTestSummaryReporting("summary", "filter", "outputRecorder"); - - int testsLeftInCurrentTestExecutor = 0; - int currentTestExecutor = 0; - - if (testInfos.Length > 0) + for (int i = 1; i <= currentTestExecutor; i++) { - // This code breaks the tests into groups called by helper methods. - // - // Reasonably large methods are known to take a long time to compile, and use excessive stack - // leading to test failures. Groups of 50 were sufficient to avoid this problem. - // - // However, large methods also appear to causes problems when the tests are run in gcstress - // modes. Groups of 1 appear to help with this. It hasn't been directly measured but - // experimentally has improved gcstress testing. - foreach (ITestInfo test in testInfos) - { - if (testsLeftInCurrentTestExecutor == 0) - { - if (currentTestExecutor != 0) - { - testExecutorBuilder.PopIndent(); - testExecutorBuilder.AppendLine("}"); - testExecutorBuilder.AppendLine(); - } - - currentTestExecutor++; - testExecutorBuilder.AppendLine($"void TestExecutor{currentTestExecutor}(" - + "System.IO.StreamWriter tempLogSw, " - + "System.IO.StreamWriter statsCsvSw)"); - testExecutorBuilder.AppendLine("{"); - testExecutorBuilder.PushIndent(); - - builder.AppendLine($"TestExecutor{currentTestExecutor}(tempLogSw, statsCsvSw);"); - testsLeftInCurrentTestExecutor = 1; // Break test executors into groups of 1, which empirically seems to work well - } - else - { - testExecutorBuilder.AppendLine(); - } - - testExecutorBuilder.Append(test.GenerateTestExecution(reporter)); - totalTestsEmitted++; - testsLeftInCurrentTestExecutor--; - } - - testExecutorBuilder.PopIndent(); - testExecutorBuilder.AppendLine("}"); - testExecutorBuilder.AppendLine(); + builder.AppendLine(outOfProcessTestCount != 0 + ? $"TestExecutor{i}(tempLogSw, statsCsvSw, null);" + : $"TestExecutor{i}(tempLogSw, statsCsvSw);"); } builder.AppendLine("summary.WriteFooterToTempLog(tempLogSw);"); @@ -432,7 +446,7 @@ private static string GenerateFullTestRunner(ImmutableArray testInfos builder.AppendLine(); builder.Append(testExecutorBuilder); - builder.AppendLine("public static class TestCount { public const int Count = " + totalTestsEmitted.ToString() + "; }"); + builder.AppendLine("public static class TestCount { public const int Count = " + testInfos.Length.ToString() + "; }"); return builder.GetCode(); } diff --git a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props index ec37dd9be0e252..52468282a6c4be 100644 --- a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props +++ b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props @@ -26,4 +26,24 @@ + + + + <_HasOutOfProcessTestsMarker>$(OutputPath)$(AssemblyName).HasOutOfProcessTests + <_ShouldWriteHasOutOfProcessTestsMarker + Condition="'$(IsMergedTestRunnerAssembly)' == 'true' and '@(OutOfProcessTests)' != '' and '$(RuntimeFlavor)' == 'coreclr' and '$(TargetOS)' == 'browser'">true + + + + + + + From 426baacf0cb5963dd90159d0671bda9eae44e152 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 12:10:06 +0200 Subject: [PATCH 02/30] Filter non-runnable tests from OOP discovery Merged runners query each project reference for process isolation. Matching tests are moved into host-side OOP scheduling. Only return projects that generate a run script and are enabled for the current target. This prevents BuildOnly and SharedLibrary helpers, as well as disabled or unsupported projects, from producing OOP entries without runnable wrappers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Directory.Build.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/Directory.Build.targets b/src/tests/Directory.Build.targets index 0dd84e05865a14..f006b1b4efe233 100644 --- a/src/tests/Directory.Build.targets +++ b/src/tests/Directory.Build.targets @@ -495,7 +495,7 @@ - + From e327ee098faa75d5fe01abc81b9f730a3d4b7802 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 12:10:12 +0200 Subject: [PATCH 03/30] Run InterpreterTester OOP on browser WASM InterpreterTester normally uses Process.Start to launch Interpreter.dll under corerun. Browser WASM cannot create that child process. Keep the test enabled for CoreCLR browser WASM and make its generated wrapper launch Interpreter.dll directly. Enable interpreter mode and disable tiering so the payload remains interpreted, while preserving the existing desktop path. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- .../JIT/interpreter/InterpreterTester.csproj | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/tests/JIT/interpreter/InterpreterTester.csproj b/src/tests/JIT/interpreter/InterpreterTester.csproj index 5e0641be74dc2b..03d6b7b8f6a8ed 100644 --- a/src/tests/JIT/interpreter/InterpreterTester.csproj +++ b/src/tests/JIT/interpreter/InterpreterTester.csproj @@ -1,14 +1,29 @@ + <_RunInterpreterDirectly Condition="'$(RuntimeFlavor)' == 'CoreCLR' and '$(TargetOS)' == 'browser' and '$(TargetArchitecture)' == 'wasm'">true true true - true + true true true - true + true + + + + + + + + From 30f2056e4a33c82f4f3ef869d13b500060552120 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 12:10:17 +0200 Subject: [PATCH 04/30] Exclude unsupported CoreCLR browser OOP tests Enabling OOP execution exposes tests that either cannot exercise their scenario in a browser or block the merged runner. These include NoGCRegion callbacks, the Android/Java GC bridge, Mono embedding APIs, and Windows-only PDB, APC, and type-equivalence tests. Mark these tests unsupported only for CoreCLR browser runs. Desktop CoreCLR, WASI, and Mono configurations remain unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/GC/API/NoGCRegion/Callback.csproj | 1 + src/tests/GC/API/NoGCRegion/Callback_Svr.csproj | 1 + src/tests/Interop/GCBridge/BridgeTest.csproj | 1 + src/tests/Interop/MonoAPI/MonoMono/Directory.Build.props | 4 ++++ .../exceptions/fullpdbstacktrace/FullPdbThrower.csproj | 1 + .../baseservices/threading/regressions/115178/115178.csproj | 1 + .../baseservices/typeequivalence/TypeEquivalence.targets | 4 ++++ 7 files changed, 13 insertions(+) diff --git a/src/tests/GC/API/NoGCRegion/Callback.csproj b/src/tests/GC/API/NoGCRegion/Callback.csproj index 1b821c52b41f7a..6d0fc33a9ac036 100644 --- a/src/tests/GC/API/NoGCRegion/Callback.csproj +++ b/src/tests/GC/API/NoGCRegion/Callback.csproj @@ -7,6 +7,7 @@ true + true true diff --git a/src/tests/GC/API/NoGCRegion/Callback_Svr.csproj b/src/tests/GC/API/NoGCRegion/Callback_Svr.csproj index a9211df29c62cd..99a6a771baed94 100644 --- a/src/tests/GC/API/NoGCRegion/Callback_Svr.csproj +++ b/src/tests/GC/API/NoGCRegion/Callback_Svr.csproj @@ -7,6 +7,7 @@ true + true true diff --git a/src/tests/Interop/GCBridge/BridgeTest.csproj b/src/tests/Interop/GCBridge/BridgeTest.csproj index 965f8371061bb7..31e90c8ea510f9 100644 --- a/src/tests/Interop/GCBridge/BridgeTest.csproj +++ b/src/tests/Interop/GCBridge/BridgeTest.csproj @@ -3,6 +3,7 @@ true true + true true true diff --git a/src/tests/Interop/MonoAPI/MonoMono/Directory.Build.props b/src/tests/Interop/MonoAPI/MonoMono/Directory.Build.props index 8e2d1cb9dc4fa4..e857662a73d3f4 100644 --- a/src/tests/Interop/MonoAPI/MonoMono/Directory.Build.props +++ b/src/tests/Interop/MonoAPI/MonoMono/Directory.Build.props @@ -1,6 +1,10 @@ + + true + + diff --git a/src/tests/baseservices/exceptions/fullpdbstacktrace/FullPdbThrower.csproj b/src/tests/baseservices/exceptions/fullpdbstacktrace/FullPdbThrower.csproj index bfee69c12f84ef..28f9b354943567 100644 --- a/src/tests/baseservices/exceptions/fullpdbstacktrace/FullPdbThrower.csproj +++ b/src/tests/baseservices/exceptions/fullpdbstacktrace/FullPdbThrower.csproj @@ -5,6 +5,7 @@ Full true false + true true @@ -530,16 +530,27 @@ run_out_of_process_tests() { local oop_result="${oop_assembly}.outofprocess-result" local oop_output="${oop_result}.output.$$" local oop_result_tmp="${oop_result}.tmp.$$" + local oop_status="${PWD}/${oop_result}.status.$$" local oop_exit - rm -f "$oop_result" "$oop_output" "$oop_result_tmp" + rm -f "$oop_result" "$oop_output" "$oop_result_tmp" "$oop_status" + export __TestOutOfProcessStatusFile="$oop_status" /usr/bin/env bash "$oop_wrapper" < /dev/null > "$oop_output" 2>&1 oop_exit=$? + unset __TestOutOfProcessStatusFile { - echo 1 + echo 2 echo "$oop_result_token" echo "$oop_exit" + if [ -f "$oop_status" ] + then + echo Skip + cat "$oop_status" + else + echo Pass + echo + fi cat "$oop_output" } > "$oop_result_tmp" @@ -550,7 +561,7 @@ run_out_of_process_tests() { echo "Failed to write out-of-process result '$oop_result'." rm -f "$oop_result_tmp" fi - rm -f "$oop_output" + rm -f "$oop_output" "$oop_status" done < "$oop_plan_file" CLRTestExecutionArguments=("${oop_merged_execution_arguments[@]}") diff --git a/src/tests/Common/CLRTest.Execute.Batch.targets b/src/tests/Common/CLRTest.Execute.Batch.targets index 18c3a0476afe90..12dcf2b0ea292c 100644 --- a/src/tests/Common/CLRTest.Execute.Batch.targets +++ b/src/tests/Common/CLRTest.Execute.Batch.targets @@ -50,7 +50,7 @@ WARNING: When setting properties based on their current state (for example: Note also that this means it will run after the first of such targets. --> @@ -394,21 +394,31 @@ IF NOT DEFINED RunWithNodeJS ( set "__OopResult=%%P.outofprocess-result" set "__OopOutput=!__OopResult!.output.!RANDOM!" set "__OopResultTemp=!__OopResult!.tmp.!RANDOM!" - del /q "!__OopResult!" "!__OopOutput!" "!__OopResultTemp!" 2>NUL + set "__OopStatus=!__OopResult!.status.!RANDOM!" + del /q "!__OopResult!" "!__OopOutput!" "!__OopResultTemp!" "!__OopStatus!" 2>NUL set "CORE_ROOT=!__CoreRootWin!" + for %%S in ("!__OopStatus!") do set "__TestOutOfProcessStatusFile=%%~fS" "%ComSpec%" /D /S /C call "!__OopWrapper!" > "!__OopOutput!" 2>&1 set "__OopExit=!ERRORLEVEL!" + set "__TestOutOfProcessStatusFile=" set "CORE_ROOT=!__CoreRootUnix!" ( - ECHO 1 + ECHO 2 ECHO !__OopResultToken! ECHO !__OopExit! + IF EXIST "!__OopStatus!" ( + ECHO Skip + TYPE "!__OopStatus!" + ) ELSE ( + ECHO Pass + ECHO. + ) TYPE "!__OopOutput!" ) > "!__OopResultTemp!" move /Y "!__OopResultTemp!" "!__OopResult!" >NUL - del /q "!__OopOutput!" 2>NUL + del /q "!__OopOutput!" "!__OopStatus!" 2>NUL ) set "CLRTestExecutionArguments=!__OopMergedExecutionArguments!" diff --git a/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs b/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs index 0bb46aba78daf6..66e999e93b2bd8 100644 --- a/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs +++ b/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs @@ -14,12 +14,23 @@ namespace TestLibrary { + public sealed class OutOfProcessTestSkippedException : Exception + { + public OutOfProcessTestSkippedException(string message) + : base(message) + { + } + } + public static class OutOfProcessTest { private const string OutOfProcessPlanFileEnvironmentVariable = "__TestOutOfProcessPlanFile"; private const string OutOfProcessResultFileSuffix = ".outofprocess-result"; - private const string OutOfProcessResultFormatVersion = "1"; + private const string OutOfProcessResultFormatVersion = "2"; + private const string OutOfProcessResultPassed = "Pass"; + private const string OutOfProcessResultSkipped = "Skip"; private const string OutOfProcessResultTokenEnvironmentVariable = "__TestOutOfProcessResultToken"; + private const string OutOfProcessStatusFileEnvironmentVariable = "__TestOutOfProcessStatusFile"; internal static bool runningInWindows; internal static string reportBase; @@ -73,7 +84,9 @@ public static void RunOutOfProcessTest(string assemblyPath, string testPathPrefi string outputDir = System.IO.Path.GetFullPath(Path.Combine(reportBase, Path.GetDirectoryName(assemblyPath))); string outputFile = Path.Combine(outputDir, "output.txt"); string errorFile = Path.Combine(outputDir, "error.txt"); + string statusFile = Path.Combine(outputDir, Path.GetFileName(assemblyPath) + ".outofprocess-status"); string testExecutable = null; + string skipReason = null; Exception infraEx = null; try @@ -95,15 +108,33 @@ public static void RunOutOfProcessTest(string assemblyPath, string testPathPrefi if (!File.Exists(testExecutable)) { - Console.WriteLine($"Test executable '{testExecutable}' not found, skipping."); - - // Skip platform-specific test when running on the excluded platform - return; + throw new OutOfProcessTestSkippedException( + $"Test executable '{testExecutable}' was not found on this platform."); } System.IO.Directory.CreateDirectory(outputDir); + File.Delete(statusFile); + + string previousStatusFile = Environment.GetEnvironmentVariable(OutOfProcessStatusFileEnvironmentVariable); + try + { + Environment.SetEnvironmentVariable(OutOfProcessStatusFileEnvironmentVariable, statusFile); + ret = wrapper.RunTest(testExecutable, outputFile, errorFile, Assembly.GetEntryAssembly()!.FullName!, testBinaryBase, outputDir); + } + finally + { + Environment.SetEnvironmentVariable(OutOfProcessStatusFileEnvironmentVariable, previousStatusFile); + } - ret = wrapper.RunTest(testExecutable, outputFile, errorFile, Assembly.GetEntryAssembly()!.FullName!, testBinaryBase, outputDir); + if (File.Exists(statusFile)) + { + skipReason = File.ReadAllText(statusFile).TrimEnd('\r', '\n'); + File.Delete(statusFile); + } + } + catch (OutOfProcessTestSkippedException) + { + throw; } catch (Exception ex) { @@ -163,6 +194,12 @@ public static void RunOutOfProcessTest(string assemblyPath, string testPathPrefi } Assert.True(ret == CoreclrTestWrapperLib.EXIT_SUCCESS_CODE, string.Join(Environment.NewLine, testOutput)); + + if (skipReason is not null) + { + throw new OutOfProcessTestSkippedException( + skipReason.Length != 0 ? skipReason : "Out-of-process test was skipped."); + } } } @@ -195,6 +232,8 @@ private static void ImportPrecomputedResult(string assemblyPath, string testPath string formatVersion = resultReader.ReadLine(); string actualResultToken = resultReader.ReadLine(); string exitCodeText = resultReader.ReadLine(); + string resultStatus = resultReader.ReadLine(); + string skipReason = resultReader.ReadLine(); string output = resultReader.ReadToEnd(); if (!String.Equals(formatVersion, OutOfProcessResultFormatVersion, StringComparison.Ordinal)) @@ -212,6 +251,23 @@ private static void ImportPrecomputedResult(string assemblyPath, string testPath Assert.Fail($"Test Infrastructure Failure: Out-of-process result file '{resultFile}' contains invalid exit code '{exitCodeText}'."); } + if (!String.Equals(resultStatus, OutOfProcessResultPassed, StringComparison.Ordinal) + && !String.Equals(resultStatus, OutOfProcessResultSkipped, StringComparison.Ordinal)) + { + Assert.Fail($"Test Infrastructure Failure: Out-of-process result file '{resultFile}' contains invalid result status '{resultStatus}'."); + } + + if (skipReason is null) + { + Assert.Fail($"Test Infrastructure Failure: Out-of-process result file '{resultFile}' does not contain a skip reason line."); + } + + if (String.Equals(resultStatus, OutOfProcessResultPassed, StringComparison.Ordinal) + && skipReason.Length != 0) + { + Assert.Fail($"Test Infrastructure Failure: Out-of-process result file '{resultFile}' contains a skip reason for a passing test."); + } + Console.WriteLine($"Out-of-process result file: {resultFile}"); Console.Write(output); if (output.Length != 0 && output[output.Length - 1] != '\n') @@ -222,6 +278,12 @@ private static void ImportPrecomputedResult(string assemblyPath, string testPath Assert.True(exitCode == CoreclrTestWrapperLib.EXIT_SUCCESS_CODE, $"Out-of-process wrapper failed with exit code {exitCode}.{Environment.NewLine}{output}"); + + if (String.Equals(resultStatus, OutOfProcessResultSkipped, StringComparison.Ordinal)) + { + throw new OutOfProcessTestSkippedException( + skipReason.Length != 0 ? skipReason : "Out-of-process test was skipped."); + } } } } diff --git a/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs b/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs index 4741dd1b8a0982..79bffca94d6b53 100644 --- a/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs +++ b/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs @@ -23,6 +23,8 @@ public interface ITestInfo public interface ITestReporterWrapper { + bool ShouldReturnAfterSkipReporting { get; } + CodeBuilder WrapTestExecutionWithReporting(CodeBuilder testExecution, ITestInfo test); string GenerateSkippedTestReporting(ITestInfo skippedTest, string? skipReason = null); @@ -187,9 +189,12 @@ public CodeBuilder GenerateTestExecution(ITestReporterWrapper testReporterWrappe if (skipReporting.Length > 0) { builder.AppendLine(skipReporting); - // Return so a skipped test isn't also reported as passed by the trailing - // ReportPassedTest. Safe because each executor holds a single test. - builder.AppendLine("return;"); + if (testReporterWrapper.ShouldReturnAfterSkipReporting) + { + // Return so a skipped test isn't also reported as passed by the trailing + // ReportPassedTest. Safe because each executor holds a single test. + builder.AppendLine("return;"); + } } } return builder; @@ -491,9 +496,12 @@ public CodeBuilder GenerateTestExecution(ITestReporterWrapper testReporterWrappe if (skipReporting.Length > 0) { builder.AppendLine(skipReporting); - // Return so a skipped test isn't also reported as passed by the trailing - // ReportPassedTest. Safe because each executor holds a single test. - builder.AppendLine("return;"); + if (testReporterWrapper.ShouldReturnAfterSkipReporting) + { + // Return so a skipped test isn't also reported as passed by the trailing + // ReportPassedTest. Safe because each executor holds a single test. + builder.AppendLine("return;"); + } } return builder; } @@ -522,11 +530,44 @@ public override int GetHashCode() public sealed class NoTestReporting : ITestReporterWrapper { + public bool ShouldReturnAfterSkipReporting => false; + public CodeBuilder WrapTestExecutionWithReporting(CodeBuilder testExecution, ITestInfo test) => testExecution; public string GenerateSkippedTestReporting(ITestInfo skippedTest, string? skipReason = null) => string.Empty; } +public sealed class StandaloneTestReporting : ITestReporterWrapper +{ + private readonly string _testExecutedLocalIdentifier; + private readonly string _skipReasonLocalIdentifier; + + public StandaloneTestReporting(string testExecutedLocalIdentifier, string skipReasonLocalIdentifier) + { + _testExecutedLocalIdentifier = testExecutedLocalIdentifier; + _skipReasonLocalIdentifier = skipReasonLocalIdentifier; + } + + public bool ShouldReturnAfterSkipReporting => false; + + public CodeBuilder WrapTestExecutionWithReporting(CodeBuilder testExecution, ITestInfo test) + { + CodeBuilder builder = new(); + builder.AppendLine($"{_testExecutedLocalIdentifier} = true;"); + builder.Append(testExecution); + return builder; + } + + public string GenerateSkippedTestReporting(ITestInfo skippedTest, string? skipReason = null) + { + string reasonExpression = skipReason is not null + ? $"@\"{skipReason.Replace("\r", "").Replace("\n", " ").Replace("\"", "\"\"")}\"" + : "string.Empty"; + + return $"{_skipReasonLocalIdentifier} ??= {reasonExpression};"; + } +} + /// /// A wrapper that suppresses (to avoid double-wrapping) /// but forwards to the outer reporter using a fixed @@ -544,6 +585,8 @@ public SkipReportingPassthrough(ITestReporterWrapper outer, ITestInfo displayNam _displayNameSource = displayNameSource; } + public bool ShouldReturnAfterSkipReporting => _outer.ShouldReturnAfterSkipReporting; + public CodeBuilder WrapTestExecutionWithReporting(CodeBuilder testExecution, ITestInfo test) => testExecution; public string GenerateSkippedTestReporting(ITestInfo skippedTest, string? skipReason = null) @@ -568,6 +611,8 @@ public WrapperLibraryTestSummaryReporting(string summaryLocalIdentifier, _outOfProcessPlanWriterIdentifier = outOfProcessPlanWriterIdentifier; } + public bool ShouldReturnAfterSkipReporting => true; + public CodeBuilder WrapTestExecutionWithReporting(CodeBuilder testExecutionExpression, ITestInfo test) { @@ -639,6 +684,16 @@ private void AppendTestExecutionWithReporting(CodeBuilder builder, + $" statsCsvSw);"); } + if (test is OutOfProcessTest) + { + builder.AppendLine("catch (TestLibrary.OutOfProcessTestSkippedException ex)"); + + using (builder.NewBracesScope()) + { + builder.AppendLine(GenerateSkippedTestReporting(test, "ex.Message", skipReasonIsExpression: true)); + } + } + builder.AppendLine("catch (System.Exception ex)"); using (builder.NewBracesScope()) @@ -657,8 +712,13 @@ private void AppendTestExecutionWithReporting(CodeBuilder builder, } public string GenerateSkippedTestReporting(ITestInfo skippedTest, string? skipReason = null) + => GenerateSkippedTestReporting(skippedTest, skipReason, skipReasonIsExpression: false); + + private string GenerateSkippedTestReporting(ITestInfo skippedTest, string? skipReason, bool skipReasonIsExpression) { - string reasonExpression = skipReason != null + string reasonExpression = skipReasonIsExpression + ? skipReason! + : skipReason != null ? $"@\"{skipReason.Replace("\r", "").Replace("\n", " ").Replace("\"", "\"\"")}\"" : "string.Empty"; diff --git a/src/tests/Common/XUnitWrapperGenerator/OptionsHelper.cs b/src/tests/Common/XUnitWrapperGenerator/OptionsHelper.cs index c1cb445218062f..75f4d34cac9014 100644 --- a/src/tests/Common/XUnitWrapperGenerator/OptionsHelper.cs +++ b/src/tests/Common/XUnitWrapperGenerator/OptionsHelper.cs @@ -12,6 +12,7 @@ public static class OptionsHelper private const string CLRTestPriorityToBuildOption = "build_property.CLRTestPriorityToBuild"; private const string TestBuildModeOption = "build_property.TestBuildMode"; private const string RuntimeFlavorOption = "build_property.RuntimeFlavor"; + private const string RequiresProcessIsolationOption = "build_property.RequiresProcessIsolation"; private const string IsOutOfProcessTestAssemblyOption = "build_metadata.AdditionalFiles.IsOutOfProcessTestAssembly"; private const string TestFilterOption = "build_property.TestFilter"; private const string TestAssemblyRelativePathOption = "build_metadata.AdditionalFiles.TestAssemblyRelativePath"; @@ -42,6 +43,8 @@ private static bool GetBoolOption(this AnalyzerConfigOptions options, string key internal static string RuntimeFlavor(this AnalyzerConfigOptions options) => options.TryGetValue(RuntimeFlavorOption, out string? flavor) ? flavor : "CoreCLR"; + internal static bool RequiresProcessIsolation(this AnalyzerConfigOptions options) => options.GetBoolOption(RequiresProcessIsolationOption); + internal static string? TestBuildMode(this AnalyzerConfigOptions options) => options.TryGetValue(TestBuildModeOption, out string? option) ? option : null; internal static bool IsOutOfProcessTestAssembly(this AnalyzerConfigOptions options) => options.GetBoolOption(IsOutOfProcessTestAssemblyOption); diff --git a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs index 8e7db7d7fa1860..8702a22558755a 100644 --- a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs +++ b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs @@ -270,7 +270,12 @@ private static void AddRunnerSource(SourceProductionContext context, ImmutableAr } else { - context.AddSource("SimpleRunner.g.cs", GenerateStandaloneSimpleTestRunner(methods, aliasMap)); + context.AddSource( + "SimpleRunner.g.cs", + GenerateStandaloneSimpleTestRunner( + methods, + aliasMap, + configOptions.GlobalOptions.RequiresProcessIsolation())); } } @@ -590,9 +595,16 @@ private static string GenerateXHarnessTestRunner(ImmutableArray testI return builder.GetCode(); } - private static string GenerateStandaloneSimpleTestRunner(ImmutableArray testInfos, ImmutableDictionary aliasMap) + private static string GenerateStandaloneSimpleTestRunner( + ImmutableArray testInfos, + ImmutableDictionary aliasMap, + bool reportOutOfProcessStatus) { - ITestReporterWrapper reporter = new NoTestReporting(); + const string testExecutedIdentifier = "outOfProcessTestExecuted"; + const string skipReasonIdentifier = "outOfProcessSkipReason"; + ITestReporterWrapper reporter = reportOutOfProcessStatus + ? new StandaloneTestReporting(testExecutedIdentifier, skipReasonIdentifier) + : new NoTestReporting(); CodeBuilder builder = new(); AppendAliasMap(builder, aliasMap); builder.AppendLine("class __GeneratedMainWrapper"); @@ -601,6 +613,12 @@ private static string GenerateStandaloneSimpleTestRunner(ImmutableArray + From 8814530942a73fc1046fc3b2e489851b192a3348 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 14:36:05 +0200 Subject: [PATCH 06/30] Skip browser OOP tests requiring native relinking CoreCLR browser runtime test payloads do not yet relink per-test native assets, and UCO thunk relinking is tracked separately. OOP execution exposes tests that were previously absent and lets those paths fail at runtime. Apply the existing tracking issues to xUnit entry points so merged results retain ActiveIssue attribution. Mark the two non-xUnit projects unsupported on WASM, where no attribute-based skip can be generated. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Interop/PInvoke/CriticalHandles/Test/Test.cs | 1 + src/tests/JIT/Directed/StructABI/EmptyStructs.cs | 2 ++ src/tests/JIT/Directed/StructABI/EmptyStructs.csproj | 1 + src/tests/JIT/Directed/StructABI/StructABI.cs | 1 + src/tests/JIT/Directed/aliasing_retbuf/aliasing_retbuf.cs | 1 + src/tests/JIT/Directed/callconv/ThisCall/EmptyThisCallTest.cs | 1 + src/tests/JIT/Directed/pinvoke/tail_pinvoke.ilproj | 2 ++ src/tests/JIT/Directed/tls/TestTLSWithLoadedDlls.csproj | 2 ++ .../JIT/Regression/JitBlue/Runtime_101046/Runtime_101046.cs | 2 ++ .../JIT/Regression/JitBlue/Runtime_101046/Runtime_101046.csproj | 1 + src/tests/JIT/SIMD/Vector3Interop.cs | 1 + src/tests/baseservices/callconvs/TestCallingConventions.cs | 1 + 12 files changed, 16 insertions(+) diff --git a/src/tests/Interop/PInvoke/CriticalHandles/Test/Test.cs b/src/tests/Interop/PInvoke/CriticalHandles/Test/Test.cs index 04ad51fe52a66e..94cd710daaca9d 100644 --- a/src/tests/Interop/PInvoke/CriticalHandles/Test/Test.cs +++ b/src/tests/Interop/PInvoke/CriticalHandles/Test/Test.cs @@ -361,6 +361,7 @@ public class Test { [ActiveIssue("https://github.com/dotnet/runtimelab/issues/173", typeof(Utilities), nameof(Utilities.IsNativeAot))] [ActiveIssue("needs triage", TestRuntimes.Mono)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/123946", typeof(PlatformDetection), nameof(PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] [Fact] public static int TestEntryPoint() { diff --git a/src/tests/JIT/Directed/StructABI/EmptyStructs.cs b/src/tests/JIT/Directed/StructABI/EmptyStructs.cs index 6be88b68dea71e..138b80184e5d0f 100644 --- a/src/tests/JIT/Directed/StructABI/EmptyStructs.cs +++ b/src/tests/JIT/Directed/StructABI/EmptyStructs.cs @@ -10,8 +10,10 @@ using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; +using TestLibrary; using Xunit; +[ActiveIssue("https://github.com/dotnet/runtime/issues/123946", typeof(PlatformDetection), nameof(PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] public static class Program { public static bool IsSystemV => diff --git a/src/tests/JIT/Directed/StructABI/EmptyStructs.csproj b/src/tests/JIT/Directed/StructABI/EmptyStructs.csproj index 95383a1bffc1f0..87be306136ff86 100644 --- a/src/tests/JIT/Directed/StructABI/EmptyStructs.csproj +++ b/src/tests/JIT/Directed/StructABI/EmptyStructs.csproj @@ -17,5 +17,6 @@ + diff --git a/src/tests/JIT/Directed/StructABI/StructABI.cs b/src/tests/JIT/Directed/StructABI/StructABI.cs index 432a667e6eab2e..0ec1f52e6c029f 100644 --- a/src/tests/JIT/Directed/StructABI/StructABI.cs +++ b/src/tests/JIT/Directed/StructABI/StructABI.cs @@ -2190,6 +2190,7 @@ static bool Issue80393Wrapper() [ActiveIssue("Doesn't pass after LLVM AOT compilation.", TestRuntimes.Mono)] [ActiveIssue("needs triage", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoMiniJIT), nameof(PlatformDetection.IsArm64Process), nameof(PlatformDetection.IsNotWindows))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/123946", typeof(PlatformDetection), nameof(PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] [Fact] public static int TestEntryPoint() { diff --git a/src/tests/JIT/Directed/aliasing_retbuf/aliasing_retbuf.cs b/src/tests/JIT/Directed/aliasing_retbuf/aliasing_retbuf.cs index d4a54e1269a36d..3572a20a865cfe 100644 --- a/src/tests/JIT/Directed/aliasing_retbuf/aliasing_retbuf.cs +++ b/src/tests/JIT/Directed/aliasing_retbuf/aliasing_retbuf.cs @@ -11,6 +11,7 @@ public unsafe class AliasingRetBuf { [ActiveIssue("Fails after removing patching step: https://github.com/dotnet/runtime/pull/62863", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoAnyAOT))] [ActiveIssue("needs triage", TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/123946", typeof(PlatformDetection), nameof(PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] [Fact] public static int TestEntryPoint() { diff --git a/src/tests/JIT/Directed/callconv/ThisCall/EmptyThisCallTest.cs b/src/tests/JIT/Directed/callconv/ThisCall/EmptyThisCallTest.cs index 6682ae8500328e..39d700bd2e1938 100644 --- a/src/tests/JIT/Directed/callconv/ThisCall/EmptyThisCallTest.cs +++ b/src/tests/JIT/Directed/callconv/ThisCall/EmptyThisCallTest.cs @@ -18,6 +18,7 @@ unsafe class ThisCallNative public unsafe class EmptyThisCallTest { [ActiveIssue("Tests that 'thiscall' with an empty signature results in InvalidProgramException", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoFULLAOT))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/124219", typeof(PlatformDetection), nameof(PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] [Fact] public static int TestEntryPoint() { diff --git a/src/tests/JIT/Directed/pinvoke/tail_pinvoke.ilproj b/src/tests/JIT/Directed/pinvoke/tail_pinvoke.ilproj index f762903556d80c..c9fc351e06b07d 100644 --- a/src/tests/JIT/Directed/pinvoke/tail_pinvoke.ilproj +++ b/src/tests/JIT/Directed/pinvoke/tail_pinvoke.ilproj @@ -3,6 +3,8 @@ true true + + true PdbOnly diff --git a/src/tests/JIT/Directed/tls/TestTLSWithLoadedDlls.csproj b/src/tests/JIT/Directed/tls/TestTLSWithLoadedDlls.csproj index ac1a042106e22d..8084339c83744c 100644 --- a/src/tests/JIT/Directed/tls/TestTLSWithLoadedDlls.csproj +++ b/src/tests/JIT/Directed/tls/TestTLSWithLoadedDlls.csproj @@ -6,6 +6,8 @@ true true + + true PdbOnly diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_101046/Runtime_101046.cs b/src/tests/JIT/Regression/JitBlue/Runtime_101046/Runtime_101046.cs index 9fefb59913fea7..798635eab474cb 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_101046/Runtime_101046.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_101046/Runtime_101046.cs @@ -6,12 +6,14 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using TestLibrary; using Xunit; public unsafe class Runtime_101046 { [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/106393", TestRuntimes.Mono)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/123946", typeof(PlatformDetection), nameof(PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] public static int TestEntryPoint() { ushort value = unchecked((ushort)-123); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_101046/Runtime_101046.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_101046/Runtime_101046.csproj index e343dad23f5e50..90a617ea476013 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_101046/Runtime_101046.csproj +++ b/src/tests/JIT/Regression/JitBlue/Runtime_101046/Runtime_101046.csproj @@ -8,5 +8,6 @@ + \ No newline at end of file diff --git a/src/tests/JIT/SIMD/Vector3Interop.cs b/src/tests/JIT/SIMD/Vector3Interop.cs index c9cc3d0e9d9215..5d7c16ed555fe3 100644 --- a/src/tests/JIT/SIMD/Vector3Interop.cs +++ b/src/tests/JIT/SIMD/Vector3Interop.cs @@ -558,6 +558,7 @@ public class Test_Vector3Interop [ActiveIssue("https://github.com/dotnet/runtime/issues/96051", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoInterpreter), nameof(PlatformDetection.IsArm64Process), nameof(PlatformDetection.IsOSX))] [ActiveIssue("https://github.com/dotnet/runtime/issues/92129", TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst)] [ActiveIssue("https://github.com/dotnet/runtime/issues/127827", typeof(TestLibrary.CoreClrConfigurationDetection), nameof(TestLibrary.CoreClrConfigurationDetection.IsGCStressC))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/123946", typeof(PlatformDetection), nameof(PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] [Fact] public static int TestEntryPoint() { diff --git a/src/tests/baseservices/callconvs/TestCallingConventions.cs b/src/tests/baseservices/callconvs/TestCallingConventions.cs index d64e7dbef78b4c..bae160692548ca 100644 --- a/src/tests/baseservices/callconvs/TestCallingConventions.cs +++ b/src/tests/baseservices/callconvs/TestCallingConventions.cs @@ -166,6 +166,7 @@ static void NonblittableFunctionPointers() } [ActiveIssue("needs triage", TestRuntimes.Mono)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/123946", typeof(PlatformDetection), nameof(PlatformDetection.PlatformDoesNotSupportNativeTestAssets))] [Fact] public static int TestEntryPoint() { From 5d2fe74be71ff22d7296e8a90430a09b3f9cf479 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 16:28:37 +0200 Subject: [PATCH 07/30] Pass host properties to browser CoreCLR tests CoreCLR's browser launcher invoked corerun.js without the -p arguments generated from RuntimeHostConfigurationOption. Tests using host properties therefore behaved differently from their native counterparts. Include the existing CoreRunArgs in the Node launch commands on Bash and Batch. This lets browser tests configure runtime properties such as the external type-map entry assembly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Common/CLRTest.Execute.Bash.targets | 2 +- src/tests/Common/CLRTest.Execute.Batch.targets | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/Common/CLRTest.Execute.Bash.targets b/src/tests/Common/CLRTest.Execute.Bash.targets index 86c6d661748f03..f976de3b54b635 100644 --- a/src/tests/Common/CLRTest.Execute.Bash.targets +++ b/src/tests/Common/CLRTest.Execute.Bash.targets @@ -484,7 +484,7 @@ run_browser_test() { echo CLRTestExecutionArguments: ${CLRTestExecutionArguments[@]} echo node version: `node -v` echo Timeout in ms: $__TestTimeout - cmd=( node --experimental-wasm-exnref --stack-size=8192 "${CORE_ROOT}/corerun.js" -c "${CORE_ROOT}" "${PWD}/${ExePath}" "${CLRTestExecutionArguments[@]}" ) + cmd=( node --experimental-wasm-exnref --stack-size=8192 "${CORE_ROOT}/corerun.js" -c "${CORE_ROOT}" $(CoreRunArgs) "${PWD}/${ExePath}" "${CLRTestExecutionArguments[@]}" ) echo Running: "${cmd[@]}" run_with_timeout $__TestTimeout "${cmd[@]}" fi diff --git a/src/tests/Common/CLRTest.Execute.Batch.targets b/src/tests/Common/CLRTest.Execute.Batch.targets index 12dcf2b0ea292c..c7330898b4882c 100644 --- a/src/tests/Common/CLRTest.Execute.Batch.targets +++ b/src/tests/Common/CLRTest.Execute.Batch.targets @@ -364,7 +364,7 @@ IF NOT DEFINED RunWithNodeJS ( ECHO CLRTestExecutionArguments: %CLRTestExecutionArguments% ECHO Timeout in ms: !__TestTimeout! - set "__RunCmd=node --experimental-wasm-exnref --stack-size=8192 "!__CoreRootWin!\corerun.js" -c "!__CoreRootUnix!" "!__ExePathUnix!" %CLRTestExecutionArguments%" + set "__RunCmd=node --experimental-wasm-exnref --stack-size=8192 "!__CoreRootWin!\corerun.js" -c "!__CoreRootUnix!" $(CoreRunArgs) "!__ExePathUnix!" %CLRTestExecutionArguments%" ECHO Running: !__RunCmd! IF EXIST "$(AssemblyName).HasOutOfProcessTests" ( From 537e3560e7c77207b5fa968167a31a776a224442 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 16:34:15 +0200 Subject: [PATCH 08/30] Skip host-only tests in browser CoreCLR OOP The AssemblyDependencyResolver test requires a native mock hostpolicy and the SuperPMI collection test launches host RyuJIT tools. Neither dependency is available inside the browser runtime, so exclude those projects from the CoreCLR browser target. SystemCoreLibDirectory also cannot validate a physical CoreLib path when System.Private.CoreLib has no Assembly.Location. Check that assembly directly so the generated standalone runner records the test as skipped. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/JIT/superpmi/superpmicollect.csproj | 1 + .../AssemblyDependencyResolverTests.csproj | 1 + .../Loader/SystemCoreLibDirectory/SystemCoreLibDirectory.cs | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tests/JIT/superpmi/superpmicollect.csproj b/src/tests/JIT/superpmi/superpmicollect.csproj index 64e029145a6108..06e7e698f208ea 100644 --- a/src/tests/JIT/superpmi/superpmicollect.csproj +++ b/src/tests/JIT/superpmi/superpmicollect.csproj @@ -25,6 +25,7 @@ true + true true true diff --git a/src/tests/Loader/AssemblyDependencyResolver/AssemblyDependencyResolverTests/AssemblyDependencyResolverTests.csproj b/src/tests/Loader/AssemblyDependencyResolver/AssemblyDependencyResolverTests/AssemblyDependencyResolverTests.csproj index 039d2ea2930b45..153d832f9185fb 100644 --- a/src/tests/Loader/AssemblyDependencyResolver/AssemblyDependencyResolverTests/AssemblyDependencyResolverTests.csproj +++ b/src/tests/Loader/AssemblyDependencyResolver/AssemblyDependencyResolverTests/AssemblyDependencyResolverTests.csproj @@ -3,6 +3,7 @@ true true + true true diff --git a/src/tests/Loader/SystemCoreLibDirectory/SystemCoreLibDirectory.cs b/src/tests/Loader/SystemCoreLibDirectory/SystemCoreLibDirectory.cs index 3d1e895b174c63..bf0be56550d02a 100644 --- a/src/tests/Loader/SystemCoreLibDirectory/SystemCoreLibDirectory.cs +++ b/src/tests/Loader/SystemCoreLibDirectory/SystemCoreLibDirectory.cs @@ -7,7 +7,9 @@ public class SystemCoreLibDirectory { - [ConditionalFact(typeof(TestLibrary.Utilities), nameof(TestLibrary.Utilities.HasAssemblyFiles))] + public static bool HasSystemCoreLibFile => !string.IsNullOrEmpty(typeof(object).Assembly.Location); + + [ConditionalFact(typeof(SystemCoreLibDirectory), nameof(HasSystemCoreLibFile))] public static void HostProvidedPath() { string configuredDirectory = AppContext.GetData("SYSTEM_CORELIB_DIRECTORY") as string; From d5cbbf9c56b37d90e143c7854a5758314703f112 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 16:36:24 +0200 Subject: [PATCH 09/30] Fix Crossgen2 smoke string comparison String.CompareTo guarantees a value less than zero when the first value sorts before the second, but it does not guarantee exactly -1. The browser runtime returns -15 for the smoke test inputs, which is valid behavior. Check the documented sign contract so the instance-method test remains portable while continuing to exercise the generic interface call. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/readytorun/crossgen2/Program.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tests/readytorun/crossgen2/Program.cs b/src/tests/readytorun/crossgen2/Program.cs index 8c7fefd81b4c24..aa7e87c6b8040f 100644 --- a/src/tests/readytorun/crossgen2/Program.cs +++ b/src/tests/readytorun/crossgen2/Program.cs @@ -770,10 +770,9 @@ private static bool InstanceMethodTest() Console.WriteLine("Int result: {0}, expected: {1}", intResult, ExpectedIntResult); int stringResult = InstanceMethodCaller.Compare("hello", "world"); - const int ExpectedStringResult = -1; - Console.WriteLine("String result: {0}, expected: {1}", stringResult, ExpectedStringResult); + Console.WriteLine("String result: {0}, expected: less than zero", stringResult); - return intResult == ExpectedIntResult && stringResult == ExpectedStringResult; + return intResult == ExpectedIntResult && stringResult < 0; } private static string GetTypeName() From b7a5529de537bafdb16ddf186024a4513678b015 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 16:41:14 +0200 Subject: [PATCH 10/30] Exclude browser OOP tests using unavailable APIs CoreCLR browser does not provide the COM ABI hooks, dynamic native library loading, diagnostics IPC, child process creation, host ReadyToRun tools, or FileVersionInfo support required by these tests. Running their newly enabled out-of-process wrappers therefore produces only platform-not-supported failures. Mark the projects unsupported only for CoreCLR browser so native CoreCLR and other runtime targets retain their existing coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj | 3 ++- .../ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj | 1 + .../COM/ComWrappers/WeakReference/WeakReferenceTest.csproj | 3 ++- src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj | 1 + .../AssemblyLoadContext/ResolveUnmanagedDllTests.csproj | 3 ++- .../MainProgramHandle/MainProgramHandleTests.csproj | 1 + src/tests/JIT/Directed/debugging/debuginfo/tester.csproj | 3 ++- .../baseservices/RuntimeConfiguration/TestConfigTester.csproj | 1 + .../exceptions/stackoverflow/stackoverflowtester.csproj | 3 ++- .../baseservices/exceptions/unhandled/unhandledTester.csproj | 3 ++- .../coreroot_determinism/coreroot_determinism.csproj | 1 + .../readytorun/r2rdump/FrameworkTests/R2RDumpTests.csproj | 1 + .../fileversionpreservation/fileversionpreservation.csproj | 3 ++- .../randomizedallocationsampling/allocationsampling.csproj | 3 ++- 14 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj b/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj index 5ff5257423c2ba..9ccad781cc094e 100644 --- a/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj +++ b/src/tests/Interop/COM/ComWrappers/API/ComWrappersTests.csproj @@ -1,7 +1,8 @@ - + true + true true diff --git a/src/tests/Interop/COM/ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj b/src/tests/Interop/COM/ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj index 512d0af1d1181a..ca7ef7f11ccce8 100644 --- a/src/tests/Interop/COM/ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj +++ b/src/tests/Interop/COM/ComWrappers/API/ComWrappersTestsBuiltInComDisabled.csproj @@ -3,6 +3,7 @@ true true + true diff --git a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj index 0e0683f43821dd..5c46109cb88245 100644 --- a/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj +++ b/src/tests/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj @@ -1,7 +1,8 @@ - + true + true true true diff --git a/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj b/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj index 2cf089e210b27c..ea02b39c029220 100644 --- a/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj +++ b/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj @@ -3,6 +3,7 @@ true + true true true diff --git a/src/tests/Interop/NativeLibrary/AssemblyLoadContext/ResolveUnmanagedDllTests.csproj b/src/tests/Interop/NativeLibrary/AssemblyLoadContext/ResolveUnmanagedDllTests.csproj index 39c41a61e38e1f..92fcea8b5f65b6 100644 --- a/src/tests/Interop/NativeLibrary/AssemblyLoadContext/ResolveUnmanagedDllTests.csproj +++ b/src/tests/Interop/NativeLibrary/AssemblyLoadContext/ResolveUnmanagedDllTests.csproj @@ -1,7 +1,8 @@ - + true + true true true diff --git a/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj b/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj index e76fe4100f97b0..520aac1014c2d5 100644 --- a/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj +++ b/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj @@ -4,6 +4,7 @@ true true true + true diff --git a/src/tests/JIT/Directed/debugging/debuginfo/tester.csproj b/src/tests/JIT/Directed/debugging/debuginfo/tester.csproj index 147ae9778d4013..002a9ccc94d389 100644 --- a/src/tests/JIT/Directed/debugging/debuginfo/tester.csproj +++ b/src/tests/JIT/Directed/debugging/debuginfo/tester.csproj @@ -1,7 +1,8 @@ - + true + true PdbOnly True True diff --git a/src/tests/baseservices/RuntimeConfiguration/TestConfigTester.csproj b/src/tests/baseservices/RuntimeConfiguration/TestConfigTester.csproj index acd5e84f77ef08..367924f78fc5a1 100644 --- a/src/tests/baseservices/RuntimeConfiguration/TestConfigTester.csproj +++ b/src/tests/baseservices/RuntimeConfiguration/TestConfigTester.csproj @@ -2,6 +2,7 @@ true + true true true diff --git a/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.csproj b/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.csproj index db14155f73a4d7..238f8756fc2885 100644 --- a/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.csproj +++ b/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.csproj @@ -1,7 +1,8 @@ - + true + true false true diff --git a/src/tests/baseservices/exceptions/unhandled/unhandledTester.csproj b/src/tests/baseservices/exceptions/unhandled/unhandledTester.csproj index 8933e2db0e6fa5..6c2ec6e540792e 100644 --- a/src/tests/baseservices/exceptions/unhandled/unhandledTester.csproj +++ b/src/tests/baseservices/exceptions/unhandled/unhandledTester.csproj @@ -1,7 +1,8 @@ - + true + true false diff --git a/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj b/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj index 2f637ddebbf28c..78b05acd247702 100644 --- a/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj +++ b/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj @@ -2,6 +2,7 @@ true + true true true diff --git a/src/tests/readytorun/r2rdump/FrameworkTests/R2RDumpTests.csproj b/src/tests/readytorun/r2rdump/FrameworkTests/R2RDumpTests.csproj index 2305c5721b219a..50e53e1c345bc7 100644 --- a/src/tests/readytorun/r2rdump/FrameworkTests/R2RDumpTests.csproj +++ b/src/tests/readytorun/r2rdump/FrameworkTests/R2RDumpTests.csproj @@ -1,6 +1,7 @@ true + true true diff --git a/src/tests/readytorun/tests/fileversionpreservation/fileversionpreservation.csproj b/src/tests/readytorun/tests/fileversionpreservation/fileversionpreservation.csproj index 252b576fa62866..c7f0b54dc1e683 100644 --- a/src/tests/readytorun/tests/fileversionpreservation/fileversionpreservation.csproj +++ b/src/tests/readytorun/tests/fileversionpreservation/fileversionpreservation.csproj @@ -1,7 +1,8 @@ - + true + true PdbOnly True true diff --git a/src/tests/tracing/eventpipe/randomizedallocationsampling/allocationsampling.csproj b/src/tests/tracing/eventpipe/randomizedallocationsampling/allocationsampling.csproj index a2944dc986a117..364cb9fd36182d 100644 --- a/src/tests/tracing/eventpipe/randomizedallocationsampling/allocationsampling.csproj +++ b/src/tests/tracing/eventpipe/randomizedallocationsampling/allocationsampling.csproj @@ -1,7 +1,8 @@ - + true + true .NETCoreApp true true From a18ac4f62817be4239ecaf012d8c9a7177a8dff5 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 16:56:01 +0200 Subject: [PATCH 11/30] Preserve browser coverage without multithreading CoreCLR browser-WASM does not support managed multithreading, but several newly enabled out-of-process tests also contain useful single-threaded coverage. Run the allocation and collectible-static checks that do not need worker threads, and condition only thread-dependent facts on the runtime capability. Use the writable temporary directory for the collectible assembly-on-disk test instead of the read-only browser application directory. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/GC/API/GC/GetTotalAllocatedBytes.cs | 5 +++++ src/tests/GC/Coverage/LargeObjectAlloc.cs | 9 ++++++++- .../CollectibleAssemblies/AssemblyOnDisk/Program.cs | 2 +- .../CollectibleAssemblies/Statics/CollectibleStatics.cs | 6 ++++++ .../Statics/CollectibleTLSStaticCollection.cs | 3 +-- .../UnhandledExceptionHandler/HandlerRefuses.cs | 2 +- .../UnhandledExceptionHandler/HandlerThrows.cs | 2 +- .../UnhandledExceptionHandler/UnhandledTrivial.cs | 8 ++++---- 8 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/tests/GC/API/GC/GetTotalAllocatedBytes.cs b/src/tests/GC/API/GC/GetTotalAllocatedBytes.cs index 13ef35dbf46742..ad1bc0d3b2d57e 100644 --- a/src/tests/GC/API/GC/GetTotalAllocatedBytes.cs +++ b/src/tests/GC/API/GC/GetTotalAllocatedBytes.cs @@ -185,6 +185,11 @@ public static void TestEntryPoint() { TestSingleThreaded(); TestSingleThreadedLOH(); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))] + public static void TestMultithreaded() + { TestAnotherThread(); TestLohSohConcurrently(); } diff --git a/src/tests/GC/Coverage/LargeObjectAlloc.cs b/src/tests/GC/Coverage/LargeObjectAlloc.cs index 76ab5b4a184925..f8b25ebac5d823 100644 --- a/src/tests/GC/Coverage/LargeObjectAlloc.cs +++ b/src/tests/GC/Coverage/LargeObjectAlloc.cs @@ -6,6 +6,7 @@ using System; using System.Threading; +using TestLibrary; internal class Mainy { @@ -43,6 +44,13 @@ public static int Main(String[] args) Console.WriteLine("LargeObjectAlloc started with {0} threads. Control-C to exit", Threads.ToString()); + if (!PlatformDetection.IsMultithreadingSupported) + { + Mainy.DoWork(); + Console.WriteLine("Test Passed"); + return 100; + } + Thread myThread = null; for (long i = 0; i < Threads; i++) { @@ -59,4 +67,3 @@ public static int Main(String[] args) return 100; } } - diff --git a/src/tests/Loader/CollectibleAssemblies/AssemblyOnDisk/Program.cs b/src/tests/Loader/CollectibleAssemblies/AssemblyOnDisk/Program.cs index 5dd8fd22c640df..770dc832f18f11 100644 --- a/src/tests/Loader/CollectibleAssemblies/AssemblyOnDisk/Program.cs +++ b/src/tests/Loader/CollectibleAssemblies/AssemblyOnDisk/Program.cs @@ -12,7 +12,7 @@ public class Program [Fact] public static void EntryPoint() { - string directoryPath = Path.Combine(AppContext.BaseDirectory, "ToDelete"); + string directoryPath = Path.Combine(Path.GetTempPath(), $"AssemblyOnDisk-{Guid.NewGuid():N}"); string originalAssemblyPath = typeof(Program).Assembly.Location; string newAssemblyPath = Path.Combine(directoryPath, Path.GetFileName(originalAssemblyPath)); diff --git a/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.cs b/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.cs index cf1d555fda2a4d..2d246a378c68ea 100644 --- a/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.cs +++ b/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleStatics.cs @@ -69,6 +69,12 @@ public static int TestEntryPoint() if (val5Obj != obj5) return 15; + if (!PlatformDetection.IsMultithreadingSupported) + { + GC.KeepAlive(accessor); + return 100; + } + int otherThreadResult = 0; Thread t = new ((ThreadStart)delegate { diff --git a/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleTLSStaticCollection.cs b/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleTLSStaticCollection.cs index 4f285d9e166fba..7f4df95c086e2f 100644 --- a/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleTLSStaticCollection.cs +++ b/src/tests/Loader/CollectibleAssemblies/Statics/CollectibleTLSStaticCollection.cs @@ -114,7 +114,7 @@ void ForceCollectibleTLSStaticToGoThroughThreadTermination() [ActiveIssue("https://github.com/dotnet/runtimelab/issues/155: Collectible assemblies", typeof(Utilities), nameof(Utilities.IsNativeAot))] [ActiveIssue("https://github.com/dotnet/runtime/issues/40394", TestRuntimes.Mono)] - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))] public static void TestEntryPoint() { s_getAnIntField = typeof(CollectibleThreadStaticShutdownRace).GetField("s_getAnInt"); @@ -124,4 +124,3 @@ public static void TestEntryPoint() } } } - diff --git a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/HandlerRefuses.cs b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/HandlerRefuses.cs index e59f6206bd2818..7ec58de9a3b858 100644 --- a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/HandlerRefuses.cs +++ b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/HandlerRefuses.cs @@ -44,7 +44,7 @@ static HandlerRefuses() SetHandler(); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))] public static void Test1() { shouldReturnFalseFromFilter = false; diff --git a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/HandlerThrows.cs b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/HandlerThrows.cs index 7ff082be0663e0..4d789731b9cc02 100644 --- a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/HandlerThrows.cs +++ b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/HandlerThrows.cs @@ -45,7 +45,7 @@ static HandlerThrows() } [ActiveIssue("https://github.com/dotnet/runtime/issues/47624", TestRuntimes.Mono)] - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))] public static void Test1() { shouldThrowFromFilter = false; diff --git a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/UnhandledTrivial.cs b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/UnhandledTrivial.cs index b7bb9cd5b65e63..520d1867f5081a 100644 --- a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/UnhandledTrivial.cs +++ b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/UnhandledTrivial.cs @@ -74,7 +74,7 @@ public static void SetNull() } } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))] public static void SetTwiceFailsUserThread() { // in a user thread @@ -96,7 +96,7 @@ public static void SetTwiceFailsUserThread() th.Join(); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))] public static void SetTwiceFailsTPWorkitem() { // in a threadpool workitem @@ -115,7 +115,7 @@ public static void SetTwiceFailsTPWorkitem() }); } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))] public static void SetTwiceFailsInTask() { // in a task @@ -161,7 +161,7 @@ class InFinalizer } } - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))] public static void SetTwiceFailsInFinalizer() { // in a finalizer From a0a339dc5abada769aa9304df478ec5009dc306d Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 17:00:40 +0200 Subject: [PATCH 12/30] Exclude thread-only tests from CoreCLR browser CoreCLR browser-WASM does not support managed multithreading. These tests exercise concurrent GC stress, JIT behavior under concurrent mutation, or unhandled-exception delivery from worker and native threads, so a single-threaded fallback would not preserve their purpose. Mark only the CoreCLR browser target unsupported. Native CoreCLR continues to build and run the existing thread coverage unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/GC/Scenarios/BinTree/thdtree.csproj | 3 ++- src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj | 3 ++- src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj | 3 ++- src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj | 3 ++- src/tests/GC/Scenarios/THDChaos/thdchaos.csproj | 3 ++- src/tests/GC/Scenarios/THDList/thdlist.csproj | 3 ++- .../Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj | 3 ++- .../UnhandledExceptionHandler/Foreign/ForeignUnhandled.csproj | 3 ++- .../UnhandledExceptionHandler/NoEffectInMainThread.csproj | 1 + .../UnhandledExceptionHandler/PInvoke/PInvokeUnhandled.csproj | 3 ++- 10 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/tests/GC/Scenarios/BinTree/thdtree.csproj b/src/tests/GC/Scenarios/BinTree/thdtree.csproj index b4c819075d1395..e2a57acbcbc312 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtree.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtree.csproj @@ -1,7 +1,8 @@ - + true + true false diff --git a/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj b/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj index 1d7e5ca906cd9d..0c7e72343ebfeb 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj @@ -1,7 +1,8 @@ - + true + true false diff --git a/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj b/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj index 738f99771e9dc6..d263b232db98d9 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj @@ -1,7 +1,8 @@ - + true + true false diff --git a/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj b/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj index e8441100974f70..f28b7ed7a93907 100644 --- a/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj +++ b/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj @@ -1,7 +1,8 @@ - + true + true false diff --git a/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj b/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj index 44fb000f056b36..ac13b1eeda753b 100644 --- a/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj +++ b/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj @@ -1,7 +1,8 @@ - + true + true false diff --git a/src/tests/GC/Scenarios/THDList/thdlist.csproj b/src/tests/GC/Scenarios/THDList/thdlist.csproj index 7be6faa3a2c6c2..2b8b9f63a086d9 100644 --- a/src/tests/GC/Scenarios/THDList/thdlist.csproj +++ b/src/tests/GC/Scenarios/THDList/thdlist.csproj @@ -1,7 +1,8 @@ - + true + true false diff --git a/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj b/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj index 74223a8413113b..df0983efe9d8c0 100644 --- a/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj +++ b/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj @@ -1,7 +1,8 @@ - + true + true true diff --git a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/Foreign/ForeignUnhandled.csproj b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/Foreign/ForeignUnhandled.csproj index 73a6546017f6c4..2f650e9acf2a66 100644 --- a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/Foreign/ForeignUnhandled.csproj +++ b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/Foreign/ForeignUnhandled.csproj @@ -1,7 +1,8 @@ - + true + true false 0 diff --git a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj index 7c1df14970dc13..0d94ded022a195 100644 --- a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj +++ b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj @@ -2,6 +2,7 @@ true + true false true diff --git a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/PInvoke/PInvokeUnhandled.csproj b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/PInvoke/PInvokeUnhandled.csproj index 6f554cba76aaa6..1255a382872216 100644 --- a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/PInvoke/PInvokeUnhandled.csproj +++ b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/PInvoke/PInvokeUnhandled.csproj @@ -1,7 +1,8 @@ - + true + true false 0 From fe7ea198402ac8be2e9e30ba6d4ea5d4870c3f68 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 17:17:12 +0200 Subject: [PATCH 13/30] Stage host Crossgen2 for cross-architecture tests Core_Root staging assumed every cross-architecture build ran on an x64 host. On macOS arm64, browser-WASM builds therefore omitted the host Crossgen2 executable and its WASM JIT libraries even though the build had produced them under the arm64 host-artifact directory. Resolve the fallback directory from BuildArchitecture so cross-targeting and sanitizer layouts use the tools built for their actual host architecture. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Common/CoreRootArtifacts.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/Common/CoreRootArtifacts.targets b/src/tests/Common/CoreRootArtifacts.targets index 3265c2d7d9f2ec..f4ae0e322d8015 100644 --- a/src/tests/Common/CoreRootArtifacts.targets +++ b/src/tests/Common/CoreRootArtifacts.targets @@ -129,7 +129,7 @@ - <_Crossgen2Dir Condition="('$(TargetArchitecture)' != 'x64' and '$(BuildArchitecture)' == 'x64') or '$(EnableNativeSanitizers)' != ''">$(CoreCLRArtifactsPath)x64/crossgen2 + <_Crossgen2Dir Condition="'$(TargetArchitecture)' != '$(BuildArchitecture)' or '$(EnableNativeSanitizers)' != ''">$(CoreCLRArtifactsPath)$(BuildArchitecture)/crossgen2 From f928c6c6b06de708cd6ebaf2699876e108c23245 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 17:17:31 +0200 Subject: [PATCH 14/30] Validate composite WASM ReadyToRun components Composite WASM Crossgen2 output contains a manifest plus one ReadyToRun image per input assembly. R2RDump rejected the manifest because it intentionally has no ReadyToRun header, causing otherwise successful browser-WASM compilations to fail before test execution. Validate each emitted component for composite WASM builds in both Bash and Batch scripts. Keep the existing single-output validation for other modes, and do not invoke R2RDump after a failed Crossgen2 command. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Common/CLRTest.CrossGen.targets | 54 ++++++++++++++++++----- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/src/tests/Common/CLRTest.CrossGen.targets b/src/tests/Common/CLRTest.CrossGen.targets index 52e28281a55059..a384bcb654a5ad 100644 --- a/src/tests/Common/CLRTest.CrossGen.targets +++ b/src/tests/Common/CLRTest.CrossGen.targets @@ -75,8 +75,10 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then rm IL-CG2/composite-r2r.* 2>/dev/null if [ ! -z ${CompositeBuildMode+x} ]%3B then - # HACK: copy native shared shim libraries. Not needed on Windows. - cp "$CORE_ROOT"/lib*.so "$CORE_ROOT"/lib*.dylib $(scriptPath) + if [ "$(CrossGen2OutputFormat)" != "wasm" ]; then + # HACK: copy native shared shim libraries. Not needed on Windows. + cp "$CORE_ROOT"/lib*.so "$CORE_ROOT"/lib*.dylib $(scriptPath) + fi ExtraCrossGen2Args+=" --composite" ExtraCrossGen2Args+=" $(CompositeCrossGen2TestExtraArguments)" @@ -109,7 +111,6 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then __R2RDumpCommand+=" dotnet" fi __R2RDumpCommand+=" $CORE_ROOT/R2RDump/R2RDump.dll" - __R2RDumpCommand+=" --header --sc --in $__OutputFileFinal --out $__OutputFileFinal.r2rdump --val --rp $CORE_ROOT" __Command="$_DebuggerFullPath $CORE_ROOT/crossgen2/crossgen2" __Command+=" @$__ResponseFile" @@ -175,9 +176,26 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then __linkExitCode=$? fi - echo "Running R2RDump: $__R2RDumpCommand" - $__R2RDumpCommand - __r2rDumpExitCode=$? + if [ $__cg2ExitCode -eq 0 ]; then + if [ "$(CrossGen2OutputFormat)" == "wasm" ] && [ ! -z ${CompositeBuildMode+x} ]; then + # The composite WASM output is a manifest; validate each emitted R2R component. + for dllFile in "${__InputFiles[@]}"; do + __R2RDumpInput="$PWD/${dllFile##*/}" + __R2RDumpInput="${__R2RDumpInput%.dll}.wasm" + __R2RDumpOutput="${__R2RDumpInput}.r2rdump" + echo "Running R2RDump: $__R2RDumpCommand --header --sc --in $__R2RDumpInput --out $__R2RDumpOutput --val --rp $CORE_ROOT" + $__R2RDumpCommand --header --sc --in "$__R2RDumpInput" --out "$__R2RDumpOutput" --val --rp "$CORE_ROOT" + __r2rDumpExitCode=$? + if [ $__r2rDumpExitCode -ne 0 ]; then + break + fi + done + else + echo "Running R2RDump: $__R2RDumpCommand --header --sc --in $__OutputFileFinal --out $__OutputFileFinal.r2rdump --val --rp $CORE_ROOT" + $__R2RDumpCommand --header --sc --in "$__OutputFileFinal" --out "$__OutputFileFinal.r2rdump" --val --rp "$CORE_ROOT" + __r2rDumpExitCode=$? + fi + fi export DOTNET_GCName DOTNET_GCStress DOTNET_HeapVerify DOTNET_ReadyToRun DOTNET_GCHeapAffinitizeRanges export DOTNET_TC_OnStackReplacement DOTNET_TC_PartialCompilation @@ -330,7 +348,6 @@ if defined RunCrossGen2 ( set __DotNet="dotnet" ) set __R2RDumpCommand=!_DebuggerFullPath! !__DotNet! "!CORE_ROOT!\r2rdump\r2rdump.dll" - set __R2RDumpCommand=!__R2RDumpCommand! --header --sc --in !__OutputFile! --out !__OutputFile!.r2rdump --val --rp "!CORE_ROOT!" set __Command=!_DebuggerFullPath! "!CORE_ROOT!\crossgen2\crossgen2.exe" set __Command=!__Command! @"!__ResponseFile!" @@ -390,10 +407,27 @@ if defined RunCrossGen2 ( IF NOT !CrossGen2Status!==0 goto :DoneR2RDumpOperations - echo "Running R2RDump: !__R2RDumpCommand!" - call !__R2RDumpCommand! + set __R2RDumpInput=!__OutputFile! + if "$(CrossGen2OutputFormat)"=="wasm" ( + REM The composite WASM output is a manifest; validate each emitted R2R component. + if defined CompositeBuildMode set __R2RDumpInput= + ) - set R2RDumpStatus=!ERRORLEVEL! + if defined __R2RDumpInput ( + set __R2RDumpArguments=--header --sc --in "!__R2RDumpInput!" --out "!__R2RDumpInput!.r2rdump" --val --rp "!CORE_ROOT!" + echo "Running R2RDump: !__R2RDumpCommand! !__R2RDumpArguments!" + call !__R2RDumpCommand! !__R2RDumpArguments! + set R2RDumpStatus=!ERRORLEVEL! + ) else ( + for %%I in (!scriptPath!IL-CG2\*.dll) do ( + set __R2RDumpInput=!scriptPath!%%~nI.wasm + set __R2RDumpArguments=--header --sc --in "!__R2RDumpInput!" --out "!__R2RDumpInput!.r2rdump" --val --rp "!CORE_ROOT!" + echo "Running R2RDump: !__R2RDumpCommand! !__R2RDumpArguments!" + call !__R2RDumpCommand! !__R2RDumpArguments! + set R2RDumpStatus=!ERRORLEVEL! + if not !R2RDumpStatus!==0 goto :DoneR2RDumpOperations + ) + ) :DoneR2RDumpOperations endlocal & set "R2RDumpStatus=%R2RDumpStatus%" &set "CrossGen2Status=%CrossGen2Status%" From 163f5cccfaca617b6b440e088fdea5225599fa0a Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 17:17:44 +0200 Subject: [PATCH 15/30] Handle locationless WASM ReadyToRun entry assemblies Composite WASM ReadyToRun execution does not populate Assembly.Location for the entry assembly. The smoke test used that value to reopen its IL image and failed before exercising its constrained-dispose check. Use argv[0] as the entry assembly path when Location is empty. Native and non-ReadyToRun execution continue to use Assembly.Location unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/readytorun/crossgen2/Program.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tests/readytorun/crossgen2/Program.cs b/src/tests/readytorun/crossgen2/Program.cs index aa7e87c6b8040f..97c6c832177193 100644 --- a/src/tests/readytorun/crossgen2/Program.cs +++ b/src/tests/readytorun/crossgen2/Program.cs @@ -571,7 +571,13 @@ private static bool DisposeEnumeratorTest() private static bool DisposeEnumeratorTestWithConstrainedCall() { - string thisAssembly = Assembly.GetExecutingAssembly().Location; + Assembly assembly = Assembly.GetExecutingAssembly(); + string thisAssembly = assembly.Location; + if (string.IsNullOrEmpty(thisAssembly)) + { + // Composite WASM R2R assemblies have no location, but the entry assembly remains argv[0]. + thisAssembly = Environment.GetCommandLineArgs()[0]; + } using (var fs = new FileStream(thisAssembly, FileMode.Open, FileAccess.Read)) { From b727d593c896b9c9db5b10360d99dec379db8acc Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 17:34:26 +0200 Subject: [PATCH 16/30] Return empty memory info when background GC is unavailable CoreCLR browser builds compile without BACKGROUND_GC, but GC.GetGCMemoryInfo(GCKind.Background) remains a valid API request. The native selector therefore fell through to the Any case and asserted in checked builds. Use a zero-initialized record for Background requests when background GC is not compiled. This preserves the documented Index == 0 result for a GC kind that has never occurred and leaves BACKGROUND_GC builds unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/coreclr/gc/interface.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/coreclr/gc/interface.cpp b/src/coreclr/gc/interface.cpp index 00d5f77f1a5e3f..40cb874de05aca 100644 --- a/src/coreclr/gc/interface.cpp +++ b/src/coreclr/gc/interface.cpp @@ -2226,12 +2226,15 @@ void GCHeap::GetMemoryInfo(uint64_t* highMemLoadThresholdBytes, { last_gc_info = &gc_heap::last_full_blocking_gc_info; } -#ifdef BACKGROUND_GC else if ((gc_kind)kind == gc_kind_background) { +#ifdef BACKGROUND_GC last_gc_info = gc_heap::get_completed_bgc_info(); - } +#else + static last_recorded_gc_info no_background_gc_info = {}; + last_gc_info = &no_background_gc_info; #endif //BACKGROUND_GC + } else { assert ((gc_kind)kind == gc_kind_any); From 8234f9edd839d08fcb22e229465e94b93c14983c Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 18:23:20 +0200 Subject: [PATCH 17/30] Skip NativeLibrary setup for unsupported targets NativeLibraryTests is excluded from CoreCLR browser-WASM builds, but its AfterTargets="Build" setup target still ran under nobuild.targets and tried to copy an assembly that was intentionally not produced. Stale output masked this during incremental builds and made clean builds fail. Run the managed subdirectory setup only when the project itself is built. The normal macOS build continues copying the suffixed test assembly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj b/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj index ea02b39c029220..e88b9311b1cfb1 100644 --- a/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj +++ b/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj @@ -35,7 +35,7 @@ - + From a77848fff528bdb72b0da7f101b48f8126a86eb3 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 18:39:51 +0200 Subject: [PATCH 18/30] Limit OOP assembly path visibility RelativeAssemblyPath is only consumed by wrappers within XUnitWrapperGenerator. Keep it internal instead of widening the public surface of the generator assembly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs b/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs index 79bffca94d6b53..0686aae5de3074 100644 --- a/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs +++ b/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs @@ -381,7 +381,7 @@ public sealed class OutOfProcessTest : ITestInfo public string ContainingType => "OutOfProcessTest"; private CodeBuilder _executionStatement { get; } - public string RelativeAssemblyPath { get; } + internal string RelativeAssemblyPath { get; } public OutOfProcessTest(string displayName, string relativeAssemblyPath, string? testBuildMode) { From 1721e4cfdf10bed86808e1d5d9278059a184d4bf Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 20:21:20 +0200 Subject: [PATCH 19/30] Preserve browser coverage in priority-one tests Avoid the unsupported Process lookup used only to format the GC Collect test's usage text. Keep the ReadyToRun generics coverage while skipping only its cross-thread field checks when multithreading is unavailable. The Emscripten 3.1.56 to 5.0.6 update included upstream change emscripten-core/emscripten#25093, which moved preInit processing before WASM module creation. At that point ___funcs_on_exit is only an early-access placeholder, and later export binding replaces the browser shutdown wrapper installed from preInit. Without the wrapper, Environment.Exit proceeds through Emscripten shutdown without BrowserHost_ShutdownDotnet. A finalization callback retains the runtime, and later host activity changes the requested exit code 100 into generic failure status 1. Install the wrapper from preRun, after WASM exports are assigned but before managed Main runs. This shuts CoreCLR down before Emscripten exit callbacks and lets b65423 keep its original Environment.Exit behavior and process-isolation coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/native/libs/System.Native.Browser/native/index.ts | 6 ++++-- src/tests/GC/API/GC/Collect_Forced.cs | 2 +- src/tests/readytorun/tests/generics.cs | 5 +++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/native/libs/System.Native.Browser/native/index.ts b/src/native/libs/System.Native.Browser/native/index.ts index d436df5b34a934..0a017810450e3a 100644 --- a/src/native/libs/System.Native.Browser/native/index.ts +++ b/src/native/libs/System.Native.Browser/native/index.ts @@ -61,7 +61,10 @@ export function dotnetInitializeModule(internals: InternalExchange): void { _ems_.FS.createPath("/", virtualWorkingDirectory!, true, true); _ems_.FS.chdir(virtualWorkingDirectory!); } + }, ...(_ems_.Module.preInit || [])]; + // preInit runs before Emscripten assigns the native WASM exports. + _ems_.Module.preRun = [() => { const orig_funcs_on_exit = _ems_.___funcs_on_exit; // it would be better to use addOnExit(), but it's called too late. // this can't be async @@ -77,7 +80,6 @@ export function dotnetInitializeModule(internals: InternalExchange): void { // silently ignore any error during shutdown } }; - - }, ...(_ems_.Module.preInit || [])]; + }, ...(_ems_.Module.preRun || [])]; } } diff --git a/src/tests/GC/API/GC/Collect_Forced.cs b/src/tests/GC/API/GC/Collect_Forced.cs index 75d47e62514dd1..9b2188cc9f7554 100644 --- a/src/tests/GC/API/GC/Collect_Forced.cs +++ b/src/tests/GC/API/GC/Collect_Forced.cs @@ -17,7 +17,7 @@ public static void Usage() public static int Main(string[] args ) { - ProcessName = Process.GetCurrentProcess().ProcessName; + ProcessName = OperatingSystem.IsBrowser() ? nameof(DefaultCollect) : Process.GetCurrentProcess().ProcessName; int gen = -1; if ( (args.Length!=1) || (!Int32.TryParse(args[0], out gen)) ) { diff --git a/src/tests/readytorun/tests/generics.cs b/src/tests/readytorun/tests/generics.cs index 63456c913abd91..102df0853a82a5 100644 --- a/src/tests/readytorun/tests/generics.cs +++ b/src/tests/readytorun/tests/generics.cs @@ -180,6 +180,11 @@ static void RunTest4() GenBase.GetFieldsTest(fobj1, "MyIdClass0=1", "MyIdClass0=2", "MyIdClass0=3", 1, 2, 3); GenBase.GetFieldsTest(fobj2, "MyIdClass1=1", "MyIdClass1=2", "MyIdClass1=3", 1, 2, 3); + if (!PlatformDetection.IsMultithreadingSupported) + { + return; + } + Thread t = new Thread(new ThreadStart(() => { GenBase.SetFieldsTest(fobj1, new MyIdClass0("11"), new MyIdClass0("22"), new MyIdClass0("33"), 11, 22, 33); From aa623d3386cbf597dab9ee4fc9ab51f1c0ceb443 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 21:22:40 +0200 Subject: [PATCH 20/30] Exclude thread-dependent priority-one browser tests CoreCLR browser-WASM is single-threaded and is built without background GC. Priority-one scenarios that require worker threads, finalizer threads, registered callbacks, or concurrent GC cannot exercise their intended behavior there. Mark only the CoreCLR browser target unsupported so these projects remain enabled on threaded runtimes and other WASM configurations. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/GC/Features/BackgroundGC/foregroundgc.csproj | 1 + src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj | 1 + src/tests/JIT/Methodical/Boxing/misc/concurgc_d.ilproj | 1 + src/tests/JIT/Methodical/Boxing/misc/concurgc_r.ilproj | 1 + src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj | 1 + src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj | 1 + src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj | 1 + src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj | 1 + .../baseservices/threading/regressions/576463/576463.csproj | 1 + src/tests/baseservices/threading/regressions/beta2/437017.csproj | 1 + src/tests/baseservices/threading/regressions/beta2/437044.csproj | 1 + 11 files changed, 11 insertions(+) diff --git a/src/tests/GC/Features/BackgroundGC/foregroundgc.csproj b/src/tests/GC/Features/BackgroundGC/foregroundgc.csproj index 91452ea777c135..bc69cde57e16b1 100644 --- a/src/tests/GC/Features/BackgroundGC/foregroundgc.csproj +++ b/src/tests/GC/Features/BackgroundGC/foregroundgc.csproj @@ -8,6 +8,7 @@ true 1 + true diff --git a/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj b/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj index aaf0f97f29a20f..18bce72f376faa 100644 --- a/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj +++ b/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj @@ -10,6 +10,7 @@ true 1 + true diff --git a/src/tests/JIT/Methodical/Boxing/misc/concurgc_d.ilproj b/src/tests/JIT/Methodical/Boxing/misc/concurgc_d.ilproj index 07f728396e5264..96075fcb3fd049 100644 --- a/src/tests/JIT/Methodical/Boxing/misc/concurgc_d.ilproj +++ b/src/tests/JIT/Methodical/Boxing/misc/concurgc_d.ilproj @@ -4,6 +4,7 @@ true true 1 + true Full diff --git a/src/tests/JIT/Methodical/Boxing/misc/concurgc_r.ilproj b/src/tests/JIT/Methodical/Boxing/misc/concurgc_r.ilproj index 2fc3c3b70758e1..27cb44a8888c13 100644 --- a/src/tests/JIT/Methodical/Boxing/misc/concurgc_r.ilproj +++ b/src/tests/JIT/Methodical/Boxing/misc/concurgc_r.ilproj @@ -4,6 +4,7 @@ true true 1 + true PdbOnly diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj index acf66f2eefba8e..7367ac4e3aa9c4 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj @@ -1,6 +1,7 @@ 1 + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj index 84a6a235f5fce4..db6533dbd56050 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj @@ -2,6 +2,7 @@ true 1 + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj index 469732170db55a..8b5ff3be46cf5a 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj @@ -1,6 +1,7 @@ 1 + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj index 82eb8ee9cd7215..c250030b414d68 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj @@ -1,6 +1,7 @@ 1 + true true diff --git a/src/tests/baseservices/threading/regressions/576463/576463.csproj b/src/tests/baseservices/threading/regressions/576463/576463.csproj index af9931808c36e9..5828abbf8ea95a 100644 --- a/src/tests/baseservices/threading/regressions/576463/576463.csproj +++ b/src/tests/baseservices/threading/regressions/576463/576463.csproj @@ -4,6 +4,7 @@ true true 1 + true true diff --git a/src/tests/baseservices/threading/regressions/beta2/437017.csproj b/src/tests/baseservices/threading/regressions/beta2/437017.csproj index 13e92e71289979..72c86d0e0bb22b 100644 --- a/src/tests/baseservices/threading/regressions/beta2/437017.csproj +++ b/src/tests/baseservices/threading/regressions/beta2/437017.csproj @@ -5,6 +5,7 @@ true 1 + true diff --git a/src/tests/baseservices/threading/regressions/beta2/437044.csproj b/src/tests/baseservices/threading/regressions/beta2/437044.csproj index 11e4aec55051ec..2be9e7282155d6 100644 --- a/src/tests/baseservices/threading/regressions/beta2/437044.csproj +++ b/src/tests/baseservices/threading/regressions/beta2/437044.csproj @@ -3,6 +3,7 @@ true 1 + true From 7993cf24eb56d49c9574fbb0692739f6c164d050 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 21:22:52 +0200 Subject: [PATCH 21/30] Exclude host-dependent priority-one browser tests These tests require child processes, native helper executables, COM behavior, or secondary threads to validate their exception and lifetime semantics. Browser-WASM cannot reproduce those host conditions without changing what the tests assert. Restrict the exclusion to CoreCLR browser so the existing coverage remains unchanged on supported targets. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- .../JitBlue/GitHub_23199/GitHub_23199_Target_32Bit.csproj | 1 + .../JitBlue/GitHub_23199/GitHub_23199_Target_64Bit.csproj | 1 + src/tests/Regressions/coreclr/GitHub_117393/test117393.csproj | 1 + src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj | 1 + .../regressions/Dev11/154243/dynamicmethodliveness.csproj | 1 + .../exceptions/regressions/V1/SEH/VJ/HandlerException.csproj | 1 + .../exceptions/regressions/V1/SEH/VJ/MultipleException.csproj | 1 + .../exceptions/regressions/V1/SEH/VJ/NestedException.csproj | 1 + .../exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj | 1 + .../baseservices/exceptions/simple/ParallelCrashTester.csproj | 1 + 10 files changed, 10 insertions(+) diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_32Bit.csproj b/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_32Bit.csproj index bc619c13f6146f..4ef450931f82de 100644 --- a/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_32Bit.csproj +++ b/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_32Bit.csproj @@ -3,6 +3,7 @@ true 1 + true None True diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_64Bit.csproj b/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_64Bit.csproj index bc619c13f6146f..4ef450931f82de 100644 --- a/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_64Bit.csproj +++ b/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_64Bit.csproj @@ -3,6 +3,7 @@ true 1 + true None True diff --git a/src/tests/Regressions/coreclr/GitHub_117393/test117393.csproj b/src/tests/Regressions/coreclr/GitHub_117393/test117393.csproj index 1eb37361a65be7..b46a964153f902 100644 --- a/src/tests/Regressions/coreclr/GitHub_117393/test117393.csproj +++ b/src/tests/Regressions/coreclr/GitHub_117393/test117393.csproj @@ -3,6 +3,7 @@ true 1 + true diff --git a/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj b/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj index e374cc1cdc1704..79b8cb540b2785 100644 --- a/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj +++ b/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj @@ -4,6 +4,7 @@ true true 1 + true true diff --git a/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj b/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj index 8f92451cf4f8fc..58b557e3d2dad4 100644 --- a/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj +++ b/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj @@ -4,6 +4,7 @@ true true 1 + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj index f791b036d1c3f3..8c9e6f0b628138 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj @@ -4,6 +4,7 @@ true true 1 + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj index 6fae86e42321f8..2de51d34c04080 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj @@ -4,6 +4,7 @@ true true 1 + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj index 49ae0ca6c0f14c..3e7b02a0af7027 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj @@ -4,6 +4,7 @@ true true 1 + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj index aa0ee8b679c196..fd953b5aa07921 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj @@ -4,6 +4,7 @@ true true 1 + true true diff --git a/src/tests/baseservices/exceptions/simple/ParallelCrashTester.csproj b/src/tests/baseservices/exceptions/simple/ParallelCrashTester.csproj index 6d7a397094b31a..ee7d1d4ca06d5b 100644 --- a/src/tests/baseservices/exceptions/simple/ParallelCrashTester.csproj +++ b/src/tests/baseservices/exceptions/simple/ParallelCrashTester.csproj @@ -1,6 +1,7 @@ 1 + true true From a423486aa9638297b064a747d8d16620c1b6e1a1 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 21:23:03 +0200 Subject: [PATCH 22/30] Defer priority-one browser native asset tests SuppressGCTransition, UnmanagedCallersOnly, pinning, native-library, and hostpolicy tests need native artifacts or host behavior that the CoreCLR browser payload does not provide. Their assertions cannot run meaningfully through the current OOP host path. Exclude only CoreCLR browser and leave relinking and UCO thunk support for the dedicated follow-up work. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- .../SuppressGCTransition/SuppressGCTransitionNegativeTest.csproj | 1 + .../UnmanagedCallersOnly/UnmanagedCallersOnlyNegativeTest.csproj | 1 + src/tests/JIT/Directed/pinning/object-pin/object-pin.ilproj | 1 + .../JIT/Regression/VS-ia64-JIT/V1.2-M02/b108129/b108129.csproj | 1 + .../MissingHostPolicyTests/MissingHostPolicyTests.csproj | 1 + src/tests/Loader/NativeLibs/FromNativePaths.csproj | 1 + 6 files changed, 6 insertions(+) diff --git a/src/tests/Interop/SuppressGCTransition/SuppressGCTransitionNegativeTest.csproj b/src/tests/Interop/SuppressGCTransition/SuppressGCTransitionNegativeTest.csproj index 27aecdb908a340..e9f6203e21821b 100644 --- a/src/tests/Interop/SuppressGCTransition/SuppressGCTransitionNegativeTest.csproj +++ b/src/tests/Interop/SuppressGCTransition/SuppressGCTransitionNegativeTest.csproj @@ -9,6 +9,7 @@ -2146233082 -1073740286 1 + true true diff --git a/src/tests/Interop/UnmanagedCallersOnly/UnmanagedCallersOnlyNegativeTest.csproj b/src/tests/Interop/UnmanagedCallersOnly/UnmanagedCallersOnlyNegativeTest.csproj index 16c925c64851ff..93854f98c72085 100644 --- a/src/tests/Interop/UnmanagedCallersOnly/UnmanagedCallersOnlyNegativeTest.csproj +++ b/src/tests/Interop/UnmanagedCallersOnly/UnmanagedCallersOnlyNegativeTest.csproj @@ -8,6 +8,7 @@ 134 -2146233082 1 + true false true diff --git a/src/tests/JIT/Directed/pinning/object-pin/object-pin.ilproj b/src/tests/JIT/Directed/pinning/object-pin/object-pin.ilproj index 983a979a2ea864..a4a2a5fb9ce0a1 100644 --- a/src/tests/JIT/Directed/pinning/object-pin/object-pin.ilproj +++ b/src/tests/JIT/Directed/pinning/object-pin/object-pin.ilproj @@ -3,6 +3,7 @@ true 1 + true PdbOnly diff --git a/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b108129/b108129.csproj b/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b108129/b108129.csproj index f8901585d65c21..44452b338e3140 100644 --- a/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b108129/b108129.csproj +++ b/src/tests/JIT/Regression/VS-ia64-JIT/V1.2-M02/b108129/b108129.csproj @@ -3,6 +3,7 @@ true 1 + true PdbOnly diff --git a/src/tests/Loader/AssemblyDependencyResolver/MissingHostPolicyTests/MissingHostPolicyTests.csproj b/src/tests/Loader/AssemblyDependencyResolver/MissingHostPolicyTests/MissingHostPolicyTests.csproj index 761c55abb1129d..f6c2568f9b5cea 100644 --- a/src/tests/Loader/AssemblyDependencyResolver/MissingHostPolicyTests/MissingHostPolicyTests.csproj +++ b/src/tests/Loader/AssemblyDependencyResolver/MissingHostPolicyTests/MissingHostPolicyTests.csproj @@ -3,6 +3,7 @@ true 1 + true true diff --git a/src/tests/Loader/NativeLibs/FromNativePaths.csproj b/src/tests/Loader/NativeLibs/FromNativePaths.csproj index e782c5209916a6..158423689ad3bf 100644 --- a/src/tests/Loader/NativeLibs/FromNativePaths.csproj +++ b/src/tests/Loader/NativeLibs/FromNativePaths.csproj @@ -3,6 +3,7 @@ true 1 + true true true From d2e47ff64837a3c01d422ccd9929e376bed1464b Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 22 Jul 2026 21:23:13 +0200 Subject: [PATCH 23/30] Exclude impractical priority-one browser JIT tests TripCountOverflow intentionally runs beyond Int32.MaxValue, while LotsOfInlines performs roughly one billion calls. CoreCLR browser-WASM lacks the optimizing JIT behavior that makes these workloads practical, so both prevent the merged JIT.opt payload from completing. Gate only CoreCLR browser rather than weakening either regression test's workload. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/JIT/opt/Inline/tests/LotsOfInlines.csproj | 1 + src/tests/JIT/opt/Loops/TripCountOverflow.csproj | 1 + 2 files changed, 2 insertions(+) diff --git a/src/tests/JIT/opt/Inline/tests/LotsOfInlines.csproj b/src/tests/JIT/opt/Inline/tests/LotsOfInlines.csproj index 9b7067377ef3ab..04cda9cac0ec45 100644 --- a/src/tests/JIT/opt/Inline/tests/LotsOfInlines.csproj +++ b/src/tests/JIT/opt/Inline/tests/LotsOfInlines.csproj @@ -1,6 +1,7 @@ 1 + true None diff --git a/src/tests/JIT/opt/Loops/TripCountOverflow.csproj b/src/tests/JIT/opt/Loops/TripCountOverflow.csproj index 4ee2e5892f2252..a7eef83a08f724 100644 --- a/src/tests/JIT/opt/Loops/TripCountOverflow.csproj +++ b/src/tests/JIT/opt/Loops/TripCountOverflow.csproj @@ -1,6 +1,7 @@ 1 + true PdbOnly From 48c2a34bf6fbea5d2c0341d6fbe105a142390cb6 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 23 Jul 2026 22:28:24 +0200 Subject: [PATCH 24/30] Gate CoreCLR browser tests on multithreading Allow tests whose only missing browser capability is managed multithreading to build when WasmEnableThreads is enabled. Preserve the default single-threaded exclusions and the exclusions for tests that need other unsupported capabilities. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/GC/API/NoGCRegion/Callback.csproj | 2 +- src/tests/GC/Scenarios/BinTree/thdtree.csproj | 2 +- src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj | 2 +- src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj | 2 +- src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj | 2 +- src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj | 2 +- src/tests/GC/Scenarios/THDChaos/thdchaos.csproj | 2 +- src/tests/GC/Scenarios/THDList/thdlist.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj | 2 +- .../Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj | 2 +- src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj | 2 +- .../UnhandledExceptionHandler/NoEffectInMainThread.csproj | 2 +- .../regressions/Dev11/154243/dynamicmethodliveness.csproj | 2 +- .../exceptions/regressions/V1/SEH/VJ/HandlerException.csproj | 2 +- .../exceptions/regressions/V1/SEH/VJ/MultipleException.csproj | 2 +- .../exceptions/regressions/V1/SEH/VJ/NestedException.csproj | 2 +- .../exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj | 2 +- .../baseservices/threading/regressions/576463/576463.csproj | 2 +- .../baseservices/threading/regressions/beta2/437017.csproj | 2 +- .../baseservices/threading/regressions/beta2/437044.csproj | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/tests/GC/API/NoGCRegion/Callback.csproj b/src/tests/GC/API/NoGCRegion/Callback.csproj index 6d0fc33a9ac036..4e149f9b2cb244 100644 --- a/src/tests/GC/API/NoGCRegion/Callback.csproj +++ b/src/tests/GC/API/NoGCRegion/Callback.csproj @@ -7,7 +7,7 @@ true - true + true true diff --git a/src/tests/GC/Scenarios/BinTree/thdtree.csproj b/src/tests/GC/Scenarios/BinTree/thdtree.csproj index e2a57acbcbc312..59bece174c67fc 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtree.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtree.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj b/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj index 0c7e72343ebfeb..46351859f150f5 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj b/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj index d263b232db98d9..05d7c83a2d23f3 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj b/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj index f28b7ed7a93907..460039c28a7625 100644 --- a/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj +++ b/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj b/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj index 18bce72f376faa..6da59324e2f843 100644 --- a/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj +++ b/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj @@ -10,7 +10,7 @@ true 1 - true + true diff --git a/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj b/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj index ac13b1eeda753b..08f0b125b487f4 100644 --- a/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj +++ b/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/THDList/thdlist.csproj b/src/tests/GC/Scenarios/THDList/thdlist.csproj index 2b8b9f63a086d9..ed0d012fd3652c 100644 --- a/src/tests/GC/Scenarios/THDList/thdlist.csproj +++ b/src/tests/GC/Scenarios/THDList/thdlist.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj index 7367ac4e3aa9c4..c4854bbb6fc4c5 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj @@ -1,7 +1,7 @@ 1 - true + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj index db6533dbd56050..242d57c3c1a3cb 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj @@ -2,7 +2,7 @@ true 1 - true + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj index 8b5ff3be46cf5a..4db0a7c1d948b7 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj @@ -1,7 +1,7 @@ 1 - true + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj index c250030b414d68..b6ddfbf03b0966 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj @@ -1,7 +1,7 @@ 1 - true + true true diff --git a/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj b/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj index df0983efe9d8c0..d212fb0385b6ec 100644 --- a/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj +++ b/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj @@ -2,7 +2,7 @@ true - true + true true diff --git a/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj b/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj index 79b8cb540b2785..18fcde01089df2 100644 --- a/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj +++ b/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj index 0d94ded022a195..78f5f6e56ff179 100644 --- a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj +++ b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj @@ -2,7 +2,7 @@ true - true + true false true diff --git a/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj b/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj index 58b557e3d2dad4..4599c0b7fe9df7 100644 --- a/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj +++ b/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj index 8c9e6f0b628138..eb437dd1975d56 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj index 2de51d34c04080..07df7bead8e63e 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj index 3e7b02a0af7027..6767454dd98235 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj index fd953b5aa07921..aa0265463d41eb 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/threading/regressions/576463/576463.csproj b/src/tests/baseservices/threading/regressions/576463/576463.csproj index 5828abbf8ea95a..049d11e6c078a4 100644 --- a/src/tests/baseservices/threading/regressions/576463/576463.csproj +++ b/src/tests/baseservices/threading/regressions/576463/576463.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/threading/regressions/beta2/437017.csproj b/src/tests/baseservices/threading/regressions/beta2/437017.csproj index 72c86d0e0bb22b..e4d3901619fa98 100644 --- a/src/tests/baseservices/threading/regressions/beta2/437017.csproj +++ b/src/tests/baseservices/threading/regressions/beta2/437017.csproj @@ -5,7 +5,7 @@ true 1 - true + true diff --git a/src/tests/baseservices/threading/regressions/beta2/437044.csproj b/src/tests/baseservices/threading/regressions/beta2/437044.csproj index 2be9e7282155d6..b5ec7dbee15135 100644 --- a/src/tests/baseservices/threading/regressions/beta2/437044.csproj +++ b/src/tests/baseservices/threading/regressions/beta2/437044.csproj @@ -3,7 +3,7 @@ true 1 - true + true From e3ff5914c3141a70f1ed20c51f58b92bc17c9519 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Fri, 24 Jul 2026 13:42:43 +0200 Subject: [PATCH 25/30] Expose multithreading feature to runtime tests Runtime test project exclusions are evaluated before the complete CoreCLR feature definitions are imported. Extract FeatureMultithreading into a small props file and import it during test project evaluation. Use the feature property for browser test gates so they follow the runtime capability rather than the underlying WasmEnableThreads build switch. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/coreclr/clr.featuredefines.props | 3 ++- src/coreclr/clr.featuremultithreading.props | 6 ++++++ src/tests/Directory.Build.props | 1 + src/tests/GC/API/NoGCRegion/Callback.csproj | 2 +- src/tests/GC/Scenarios/BinTree/thdtree.csproj | 2 +- src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj | 2 +- src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj | 2 +- src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj | 2 +- src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj | 2 +- src/tests/GC/Scenarios/THDChaos/thdchaos.csproj | 2 +- src/tests/GC/Scenarios/THDList/thdlist.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj | 2 +- .../CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj | 2 +- src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj | 2 +- .../UnhandledExceptionHandler/NoEffectInMainThread.csproj | 2 +- .../regressions/Dev11/154243/dynamicmethodliveness.csproj | 2 +- .../regressions/V1/SEH/VJ/HandlerException.csproj | 2 +- .../regressions/V1/SEH/VJ/MultipleException.csproj | 2 +- .../exceptions/regressions/V1/SEH/VJ/NestedException.csproj | 2 +- .../regressions/V1/SEH/VJ/RecursiveException.csproj | 2 +- .../baseservices/threading/regressions/576463/576463.csproj | 2 +- .../baseservices/threading/regressions/beta2/437017.csproj | 2 +- .../baseservices/threading/regressions/beta2/437044.csproj | 2 +- 26 files changed, 32 insertions(+), 24 deletions(-) create mode 100644 src/coreclr/clr.featuremultithreading.props diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props index a37bacbfd1807b..32a91b8e93a6be 100644 --- a/src/coreclr/clr.featuredefines.props +++ b/src/coreclr/clr.featuredefines.props @@ -1,4 +1,6 @@ + + true true @@ -7,7 +9,6 @@ true true true - true diff --git a/src/coreclr/clr.featuremultithreading.props b/src/coreclr/clr.featuremultithreading.props new file mode 100644 index 00000000000000..558751c555fd2e --- /dev/null +++ b/src/coreclr/clr.featuremultithreading.props @@ -0,0 +1,6 @@ + + + true + <_ClrFeatureMultithreadingPropsImported>true + + diff --git a/src/tests/Directory.Build.props b/src/tests/Directory.Build.props index 66f9d1fe232e6d..ffae1fd13a6e9c 100644 --- a/src/tests/Directory.Build.props +++ b/src/tests/Directory.Build.props @@ -244,6 +244,7 @@ true + diff --git a/src/tests/GC/API/NoGCRegion/Callback.csproj b/src/tests/GC/API/NoGCRegion/Callback.csproj index 4e149f9b2cb244..c54f6906c3d7ac 100644 --- a/src/tests/GC/API/NoGCRegion/Callback.csproj +++ b/src/tests/GC/API/NoGCRegion/Callback.csproj @@ -7,7 +7,7 @@ true - true + true true diff --git a/src/tests/GC/Scenarios/BinTree/thdtree.csproj b/src/tests/GC/Scenarios/BinTree/thdtree.csproj index 59bece174c67fc..44e6860a02d12c 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtree.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtree.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj b/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj index 46351859f150f5..e5b0f873fe883f 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj b/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj index 05d7c83a2d23f3..813f4ca038bf9b 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj b/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj index 460039c28a7625..e720f94aac6a11 100644 --- a/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj +++ b/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj b/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj index 6da59324e2f843..234daeaf7ab044 100644 --- a/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj +++ b/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj @@ -10,7 +10,7 @@ true 1 - true + true diff --git a/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj b/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj index 08f0b125b487f4..2aa4e0d8df65b1 100644 --- a/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj +++ b/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/THDList/thdlist.csproj b/src/tests/GC/Scenarios/THDList/thdlist.csproj index ed0d012fd3652c..4f187b9f99564f 100644 --- a/src/tests/GC/Scenarios/THDList/thdlist.csproj +++ b/src/tests/GC/Scenarios/THDList/thdlist.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj index c4854bbb6fc4c5..7a73c1066a6412 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj @@ -1,7 +1,7 @@ 1 - true + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj index 242d57c3c1a3cb..b87426557eda9f 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj @@ -2,7 +2,7 @@ true 1 - true + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj index 4db0a7c1d948b7..c0b6bf1fd2621f 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj @@ -1,7 +1,7 @@ 1 - true + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj index b6ddfbf03b0966..cf1b77e247f85c 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj @@ -1,7 +1,7 @@ 1 - true + true true diff --git a/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj b/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj index d212fb0385b6ec..7e1aa9bd51f23c 100644 --- a/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj +++ b/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj @@ -2,7 +2,7 @@ true - true + true true diff --git a/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj b/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj index 18fcde01089df2..397575352fe068 100644 --- a/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj +++ b/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj index 78f5f6e56ff179..42aac9d55febda 100644 --- a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj +++ b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj @@ -2,7 +2,7 @@ true - true + true false true diff --git a/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj b/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj index 4599c0b7fe9df7..e98cf92a73b083 100644 --- a/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj +++ b/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj index eb437dd1975d56..6b2b0150794477 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj index 07df7bead8e63e..5dcf3f174274b8 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj index 6767454dd98235..c9221a0df2fe5b 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj index aa0265463d41eb..2f7be2de78b132 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/threading/regressions/576463/576463.csproj b/src/tests/baseservices/threading/regressions/576463/576463.csproj index 049d11e6c078a4..e404611a9b24eb 100644 --- a/src/tests/baseservices/threading/regressions/576463/576463.csproj +++ b/src/tests/baseservices/threading/regressions/576463/576463.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/threading/regressions/beta2/437017.csproj b/src/tests/baseservices/threading/regressions/beta2/437017.csproj index e4d3901619fa98..2e319814331cd1 100644 --- a/src/tests/baseservices/threading/regressions/beta2/437017.csproj +++ b/src/tests/baseservices/threading/regressions/beta2/437017.csproj @@ -5,7 +5,7 @@ true 1 - true + true diff --git a/src/tests/baseservices/threading/regressions/beta2/437044.csproj b/src/tests/baseservices/threading/regressions/beta2/437044.csproj index b5ec7dbee15135..01aef24f840de0 100644 --- a/src/tests/baseservices/threading/regressions/beta2/437044.csproj +++ b/src/tests/baseservices/threading/regressions/beta2/437044.csproj @@ -3,7 +3,7 @@ true 1 - true + true From ca321583583cb387125f2f0d8aa4b87604f173b7 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Fri, 24 Jul 2026 14:44:17 +0200 Subject: [PATCH 26/30] Use global multithreading capability for runtime tests FeatureMultithreading describes threading support across runtimes and platforms. Gate multithreading-dependent tests directly on that capability instead of limiting the exclusion to CoreCLR browser builds. This also excludes the tests from single-threaded WASI and Mono browser configurations while preserving desktop and threaded WebAssembly coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/GC/API/NoGCRegion/Callback.csproj | 2 +- src/tests/GC/Scenarios/BinTree/thdtree.csproj | 2 +- src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj | 2 +- src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj | 2 +- src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj | 2 +- src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj | 2 +- src/tests/GC/Scenarios/THDChaos/thdchaos.csproj | 2 +- src/tests/GC/Scenarios/THDList/thdlist.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj | 2 +- src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj | 2 +- .../Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj | 2 +- src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj | 2 +- .../UnhandledExceptionHandler/NoEffectInMainThread.csproj | 2 +- .../regressions/Dev11/154243/dynamicmethodliveness.csproj | 2 +- .../exceptions/regressions/V1/SEH/VJ/HandlerException.csproj | 2 +- .../exceptions/regressions/V1/SEH/VJ/MultipleException.csproj | 2 +- .../exceptions/regressions/V1/SEH/VJ/NestedException.csproj | 2 +- .../exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj | 2 +- .../baseservices/threading/regressions/576463/576463.csproj | 2 +- .../baseservices/threading/regressions/beta2/437017.csproj | 2 +- .../baseservices/threading/regressions/beta2/437044.csproj | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/tests/GC/API/NoGCRegion/Callback.csproj b/src/tests/GC/API/NoGCRegion/Callback.csproj index c54f6906c3d7ac..32834e6ff2b0ab 100644 --- a/src/tests/GC/API/NoGCRegion/Callback.csproj +++ b/src/tests/GC/API/NoGCRegion/Callback.csproj @@ -7,7 +7,7 @@ true - true + true true diff --git a/src/tests/GC/Scenarios/BinTree/thdtree.csproj b/src/tests/GC/Scenarios/BinTree/thdtree.csproj index 44e6860a02d12c..62a72356bc8769 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtree.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtree.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj b/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj index e5b0f873fe883f..efa5a87a669260 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtreegrowingobj.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj b/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj index 813f4ca038bf9b..ff1c3236e011f8 100644 --- a/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj +++ b/src/tests/GC/Scenarios/BinTree/thdtreelivingobj.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj b/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj index e720f94aac6a11..e6cd223932f465 100644 --- a/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj +++ b/src/tests/GC/Scenarios/DoublinkList/dlbigleakthd.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj b/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj index 234daeaf7ab044..e266e23d4cc129 100644 --- a/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj +++ b/src/tests/GC/Scenarios/LeakGen/leakgenthrd.csproj @@ -10,7 +10,7 @@ true 1 - true + true diff --git a/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj b/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj index 2aa4e0d8df65b1..610573192d0382 100644 --- a/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj +++ b/src/tests/GC/Scenarios/THDChaos/thdchaos.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/GC/Scenarios/THDList/thdlist.csproj b/src/tests/GC/Scenarios/THDList/thdlist.csproj index 4f187b9f99564f..8626d6ca996384 100644 --- a/src/tests/GC/Scenarios/THDList/thdlist.csproj +++ b/src/tests/GC/Scenarios/THDList/thdlist.csproj @@ -2,7 +2,7 @@ true - true + true false diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj index 7a73c1066a6412..a7eb41e296bd87 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_d.csproj @@ -1,7 +1,7 @@ 1 - true + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj index b87426557eda9f..89c1f9b9f3ddde 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_do.csproj @@ -2,7 +2,7 @@ true 1 - true + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj index c0b6bf1fd2621f..42a6033076252d 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_r.csproj @@ -1,7 +1,7 @@ 1 - true + true true diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj index cf1b77e247f85c..f0cfb9a6ff0d92 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj +++ b/src/tests/JIT/Methodical/cctor/misc/threads2_cs_ro.csproj @@ -1,7 +1,7 @@ 1 - true + true true diff --git a/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj b/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj index 7e1aa9bd51f23c..68fe00a6fab515 100644 --- a/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj +++ b/src/tests/JIT/Regression/CLR-x86-JIT/V2.0-Beta2/b426654/b426654.ilproj @@ -2,7 +2,7 @@ true - true + true true diff --git a/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj b/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj index 397575352fe068..0e4daab1df6c30 100644 --- a/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj +++ b/src/tests/Regressions/coreclr/GitHub_12224/Test12224.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj index 42aac9d55febda..7cbe7fab8ad97b 100644 --- a/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj +++ b/src/tests/baseservices/exceptions/UnhandledExceptionHandler/NoEffectInMainThread.csproj @@ -2,7 +2,7 @@ true - true + true false true diff --git a/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj b/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj index e98cf92a73b083..b6393f1b0f7732 100644 --- a/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj +++ b/src/tests/baseservices/exceptions/regressions/Dev11/154243/dynamicmethodliveness.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj index 6b2b0150794477..acc8aff37bd64d 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/HandlerException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj index 5dcf3f174274b8..055426dcaca4d3 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/MultipleException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj index c9221a0df2fe5b..d63d53eebb67ce 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/NestedException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj index 2f7be2de78b132..8eb21849202a52 100644 --- a/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj +++ b/src/tests/baseservices/exceptions/regressions/V1/SEH/VJ/RecursiveException.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/threading/regressions/576463/576463.csproj b/src/tests/baseservices/threading/regressions/576463/576463.csproj index e404611a9b24eb..f15d101fca4979 100644 --- a/src/tests/baseservices/threading/regressions/576463/576463.csproj +++ b/src/tests/baseservices/threading/regressions/576463/576463.csproj @@ -4,7 +4,7 @@ true true 1 - true + true true diff --git a/src/tests/baseservices/threading/regressions/beta2/437017.csproj b/src/tests/baseservices/threading/regressions/beta2/437017.csproj index 2e319814331cd1..8f5d32c1430958 100644 --- a/src/tests/baseservices/threading/regressions/beta2/437017.csproj +++ b/src/tests/baseservices/threading/regressions/beta2/437017.csproj @@ -5,7 +5,7 @@ true 1 - true + true diff --git a/src/tests/baseservices/threading/regressions/beta2/437044.csproj b/src/tests/baseservices/threading/regressions/beta2/437044.csproj index 01aef24f840de0..bc77f9cc0d8ed9 100644 --- a/src/tests/baseservices/threading/regressions/beta2/437044.csproj +++ b/src/tests/baseservices/threading/regressions/beta2/437044.csproj @@ -3,7 +3,7 @@ true 1 - true + true From a955d8f0882a255962e43d855cddd63f49a0490c Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Fri, 24 Jul 2026 17:45:40 +0200 Subject: [PATCH 27/30] Document deferred CoreCLR browser tests Link browser-specific runtime test exclusions that can be re-enabled after missing capabilities or test adaptations are available. Describe the prerequisite for each exclusion at its source. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/GC/API/NoGCRegion/Callback_Svr.csproj | 2 ++ src/tests/GC/Features/BackgroundGC/foregroundgc.csproj | 2 ++ src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj | 2 ++ .../AssemblyLoadContext/ResolveUnmanagedDllTests.csproj | 2 ++ .../MainProgramHandle/MainProgramHandleTests.csproj | 2 ++ src/tests/JIT/Directed/debugging/debuginfo/tester.csproj | 2 ++ src/tests/JIT/Methodical/Boxing/misc/concurgc_d.ilproj | 2 ++ src/tests/JIT/Methodical/Boxing/misc/concurgc_r.ilproj | 2 ++ .../JitBlue/GitHub_23199/GitHub_23199_Target_32Bit.csproj | 3 +++ .../JitBlue/GitHub_23199/GitHub_23199_Target_64Bit.csproj | 3 +++ src/tests/JIT/opt/Inline/tests/LotsOfInlines.csproj | 2 ++ src/tests/JIT/opt/Loops/TripCountOverflow.csproj | 2 ++ src/tests/Loader/NativeLibs/FromNativePaths.csproj | 2 ++ .../baseservices/RuntimeConfiguration/TestConfigTester.csproj | 2 ++ .../baseservices/exceptions/simple/ParallelCrashTester.csproj | 2 ++ .../exceptions/stackoverflow/stackoverflowtester.csproj | 2 ++ .../baseservices/exceptions/unhandled/unhandledTester.csproj | 2 ++ .../coreroot_determinism/coreroot_determinism.csproj | 2 ++ .../readytorun/r2rdump/FrameworkTests/R2RDumpTests.csproj | 2 ++ .../randomizedallocationsampling/allocationsampling.csproj | 2 ++ 20 files changed, 42 insertions(+) diff --git a/src/tests/GC/API/NoGCRegion/Callback_Svr.csproj b/src/tests/GC/API/NoGCRegion/Callback_Svr.csproj index 99a6a771baed94..eed8fb3f10a204 100644 --- a/src/tests/GC/API/NoGCRegion/Callback_Svr.csproj +++ b/src/tests/GC/API/NoGCRegion/Callback_Svr.csproj @@ -7,6 +7,8 @@ true + true true diff --git a/src/tests/GC/Features/BackgroundGC/foregroundgc.csproj b/src/tests/GC/Features/BackgroundGC/foregroundgc.csproj index bc69cde57e16b1..1f2e89a6ae4188 100644 --- a/src/tests/GC/Features/BackgroundGC/foregroundgc.csproj +++ b/src/tests/GC/Features/BackgroundGC/foregroundgc.csproj @@ -8,6 +8,8 @@ true 1 + true diff --git a/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj b/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj index e88b9311b1cfb1..1ccfd6b222bc92 100644 --- a/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj +++ b/src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj @@ -3,6 +3,8 @@ true + true true diff --git a/src/tests/Interop/NativeLibrary/AssemblyLoadContext/ResolveUnmanagedDllTests.csproj b/src/tests/Interop/NativeLibrary/AssemblyLoadContext/ResolveUnmanagedDllTests.csproj index 92fcea8b5f65b6..6f1068c8544060 100644 --- a/src/tests/Interop/NativeLibrary/AssemblyLoadContext/ResolveUnmanagedDllTests.csproj +++ b/src/tests/Interop/NativeLibrary/AssemblyLoadContext/ResolveUnmanagedDllTests.csproj @@ -2,6 +2,8 @@ true + true true diff --git a/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj b/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj index 520aac1014c2d5..87d694f0416463 100644 --- a/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj +++ b/src/tests/Interop/NativeLibrary/MainProgramHandle/MainProgramHandleTests.csproj @@ -4,6 +4,8 @@ true true true + true diff --git a/src/tests/JIT/Directed/debugging/debuginfo/tester.csproj b/src/tests/JIT/Directed/debugging/debuginfo/tester.csproj index 002a9ccc94d389..590387389b4cba 100644 --- a/src/tests/JIT/Directed/debugging/debuginfo/tester.csproj +++ b/src/tests/JIT/Directed/debugging/debuginfo/tester.csproj @@ -2,6 +2,8 @@ true + true PdbOnly True diff --git a/src/tests/JIT/Methodical/Boxing/misc/concurgc_d.ilproj b/src/tests/JIT/Methodical/Boxing/misc/concurgc_d.ilproj index 96075fcb3fd049..b4310bd38304f0 100644 --- a/src/tests/JIT/Methodical/Boxing/misc/concurgc_d.ilproj +++ b/src/tests/JIT/Methodical/Boxing/misc/concurgc_d.ilproj @@ -4,6 +4,8 @@ true true 1 + true diff --git a/src/tests/JIT/Methodical/Boxing/misc/concurgc_r.ilproj b/src/tests/JIT/Methodical/Boxing/misc/concurgc_r.ilproj index 27cb44a8888c13..9e20147f7c1a2c 100644 --- a/src/tests/JIT/Methodical/Boxing/misc/concurgc_r.ilproj +++ b/src/tests/JIT/Methodical/Boxing/misc/concurgc_r.ilproj @@ -4,6 +4,8 @@ true true 1 + true diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_32Bit.csproj b/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_32Bit.csproj index 4ef450931f82de..f2728f313e65e3 100644 --- a/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_32Bit.csproj +++ b/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_32Bit.csproj @@ -3,6 +3,9 @@ true 1 + true None True diff --git a/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_64Bit.csproj b/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_64Bit.csproj index 4ef450931f82de..f2728f313e65e3 100644 --- a/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_64Bit.csproj +++ b/src/tests/JIT/Regression/JitBlue/GitHub_23199/GitHub_23199_Target_64Bit.csproj @@ -3,6 +3,9 @@ true 1 + true None True diff --git a/src/tests/JIT/opt/Inline/tests/LotsOfInlines.csproj b/src/tests/JIT/opt/Inline/tests/LotsOfInlines.csproj index 04cda9cac0ec45..ac866c26b29217 100644 --- a/src/tests/JIT/opt/Inline/tests/LotsOfInlines.csproj +++ b/src/tests/JIT/opt/Inline/tests/LotsOfInlines.csproj @@ -1,6 +1,8 @@ 1 + true diff --git a/src/tests/JIT/opt/Loops/TripCountOverflow.csproj b/src/tests/JIT/opt/Loops/TripCountOverflow.csproj index a7eef83a08f724..e15c730de0a9af 100644 --- a/src/tests/JIT/opt/Loops/TripCountOverflow.csproj +++ b/src/tests/JIT/opt/Loops/TripCountOverflow.csproj @@ -1,6 +1,8 @@ 1 + true diff --git a/src/tests/Loader/NativeLibs/FromNativePaths.csproj b/src/tests/Loader/NativeLibs/FromNativePaths.csproj index 158423689ad3bf..63bb78a989572a 100644 --- a/src/tests/Loader/NativeLibs/FromNativePaths.csproj +++ b/src/tests/Loader/NativeLibs/FromNativePaths.csproj @@ -3,6 +3,8 @@ true 1 + true true diff --git a/src/tests/baseservices/RuntimeConfiguration/TestConfigTester.csproj b/src/tests/baseservices/RuntimeConfiguration/TestConfigTester.csproj index 367924f78fc5a1..5be4cf05f06288 100644 --- a/src/tests/baseservices/RuntimeConfiguration/TestConfigTester.csproj +++ b/src/tests/baseservices/RuntimeConfiguration/TestConfigTester.csproj @@ -2,6 +2,8 @@ true + true true diff --git a/src/tests/baseservices/exceptions/simple/ParallelCrashTester.csproj b/src/tests/baseservices/exceptions/simple/ParallelCrashTester.csproj index ee7d1d4ca06d5b..f4ada846d05f2c 100644 --- a/src/tests/baseservices/exceptions/simple/ParallelCrashTester.csproj +++ b/src/tests/baseservices/exceptions/simple/ParallelCrashTester.csproj @@ -1,6 +1,8 @@ 1 + true true diff --git a/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.csproj b/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.csproj index 238f8756fc2885..c7cc82c6a4b175 100644 --- a/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.csproj +++ b/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.csproj @@ -2,6 +2,8 @@ true + true false diff --git a/src/tests/baseservices/exceptions/unhandled/unhandledTester.csproj b/src/tests/baseservices/exceptions/unhandled/unhandledTester.csproj index 6c2ec6e540792e..04d3ad017f7366 100644 --- a/src/tests/baseservices/exceptions/unhandled/unhandledTester.csproj +++ b/src/tests/baseservices/exceptions/unhandled/unhandledTester.csproj @@ -2,6 +2,8 @@ true + true false diff --git a/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj b/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj index 78b05acd247702..851bb2ade97145 100644 --- a/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj +++ b/src/tests/readytorun/coreroot_determinism/coreroot_determinism.csproj @@ -2,6 +2,8 @@ true + true true diff --git a/src/tests/readytorun/r2rdump/FrameworkTests/R2RDumpTests.csproj b/src/tests/readytorun/r2rdump/FrameworkTests/R2RDumpTests.csproj index 50e53e1c345bc7..297e787f3ad124 100644 --- a/src/tests/readytorun/r2rdump/FrameworkTests/R2RDumpTests.csproj +++ b/src/tests/readytorun/r2rdump/FrameworkTests/R2RDumpTests.csproj @@ -1,6 +1,8 @@ true + true true diff --git a/src/tests/tracing/eventpipe/randomizedallocationsampling/allocationsampling.csproj b/src/tests/tracing/eventpipe/randomizedallocationsampling/allocationsampling.csproj index 364cb9fd36182d..833974a9ce4904 100644 --- a/src/tests/tracing/eventpipe/randomizedallocationsampling/allocationsampling.csproj +++ b/src/tests/tracing/eventpipe/randomizedallocationsampling/allocationsampling.csproj @@ -2,6 +2,8 @@ true + true .NETCoreApp true From f9b60d053c925c2ad0a07581a013e92d0b8dcd42 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Fri, 24 Jul 2026 21:06:14 +0200 Subject: [PATCH 28/30] Fix browser OOP platform handling Preserve the Mono active issue after splitting the allocation test. Convert the Batch status-file path to browser Unix syntax before exposing it to managed code. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Common/CLRTest.Execute.Batch.targets | 5 ++++- src/tests/GC/API/GC/GetTotalAllocatedBytes.cs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tests/Common/CLRTest.Execute.Batch.targets b/src/tests/Common/CLRTest.Execute.Batch.targets index c7330898b4882c..51cc92d51c6e69 100644 --- a/src/tests/Common/CLRTest.Execute.Batch.targets +++ b/src/tests/Common/CLRTest.Execute.Batch.targets @@ -398,7 +398,10 @@ IF NOT DEFINED RunWithNodeJS ( del /q "!__OopResult!" "!__OopOutput!" "!__OopResultTemp!" "!__OopStatus!" 2>NUL set "CORE_ROOT=!__CoreRootWin!" - for %%S in ("!__OopStatus!") do set "__TestOutOfProcessStatusFile=%%~fS" + for %%S in ("!__OopStatus!") do set "__OopStatusUnix=%%~fS" + set "__OopStatusUnix=!__OopStatusUnix:\=/!" + if "!__OopStatusUnix:~1,1!"==":" set "__OopStatusUnix=/!__OopStatusUnix:~3!" + set "__TestOutOfProcessStatusFile=!__OopStatusUnix!" "%ComSpec%" /D /S /C call "!__OopWrapper!" > "!__OopOutput!" 2>&1 set "__OopExit=!ERRORLEVEL!" set "__TestOutOfProcessStatusFile=" diff --git a/src/tests/GC/API/GC/GetTotalAllocatedBytes.cs b/src/tests/GC/API/GC/GetTotalAllocatedBytes.cs index ad1bc0d3b2d57e..f665a34a9b78f3 100644 --- a/src/tests/GC/API/GC/GetTotalAllocatedBytes.cs +++ b/src/tests/GC/API/GC/GetTotalAllocatedBytes.cs @@ -187,6 +187,7 @@ public static void TestEntryPoint() TestSingleThreadedLOH(); } + [ActiveIssue("needs triage", TestRuntimes.Mono)] [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))] public static void TestMultithreaded() { From 27a17dc3998db8626e1e2cf8af25ef2e23ac1f4b Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Fri, 24 Jul 2026 21:33:18 +0200 Subject: [PATCH 29/30] Handle empty OOP plan file settings Normalize empty plan-file environment values to null and pattern-bind the generated runner plan path before opening it. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- .../Common/CoreCLRTestLibrary/OutOfProcessTest.cs | 10 ++++++++-- .../XUnitWrapperGenerator/XUnitWrapperGenerator.cs | 3 +-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs b/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs index 66e999e93b2bd8..fe7b815d92939f 100644 --- a/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs +++ b/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs @@ -57,8 +57,14 @@ static OutOfProcessTest() } } - public static string OutOfProcessPlanFile => - Environment.GetEnvironmentVariable(OutOfProcessPlanFileEnvironmentVariable); + public static string? OutOfProcessPlanFile + { + get + { + string? planFile = Environment.GetEnvironmentVariable(OutOfProcessPlanFileEnvironmentVariable); + return String.IsNullOrEmpty(planFile) ? null : planFile; + } + } public static bool IsUsingPrecomputedResults => !String.IsNullOrEmpty(Environment.GetEnvironmentVariable(OutOfProcessResultTokenEnvironmentVariable)); diff --git a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs index 8ea0df0e60b217..2aa25c19e9af7f 100644 --- a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs +++ b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs @@ -383,8 +383,7 @@ private static string GenerateFullTestRunner(ImmutableArray testInfos if (outOfProcessTestCount != 0) { - builder.AppendLine("string outOfProcessPlanFile = TestLibrary.OutOfProcessTest.OutOfProcessPlanFile;"); - builder.AppendLine("if (outOfProcessPlanFile is not null)"); + builder.AppendLine("if (TestLibrary.OutOfProcessTest.OutOfProcessPlanFile is string outOfProcessPlanFile)"); using (builder.NewBracesScope()) { builder.AppendLine("using (System.IO.StreamWriter unusedWriter = new(System.IO.Stream.Null))"); From 995f6361a62e485fc1b0fc0730a3985e321e0f52 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Fri, 24 Jul 2026 21:42:25 +0200 Subject: [PATCH 30/30] Harden browser OOP environment handling Ignore empty status-file settings in generated child runners and align the interpreter runtime-flavor check with the lowercase test default. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9 --- src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs | 2 +- src/tests/JIT/interpreter/InterpreterTester.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs index 2aa25c19e9af7f..a60570faa3a671 100644 --- a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs +++ b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs @@ -636,7 +636,7 @@ private static string GenerateStandaloneSimpleTestRunner( { builder.AppendLine(); builder.AppendLine(@"string outOfProcessStatusFile = System.Environment.GetEnvironmentVariable(""__TestOutOfProcessStatusFile"");"); - builder.AppendLine($"if (outOfProcessStatusFile is not null && !{testExecutedIdentifier} && {skipReasonIdentifier} is not null)"); + builder.AppendLine($"if (!System.String.IsNullOrEmpty(outOfProcessStatusFile) && !{testExecutedIdentifier} && {skipReasonIdentifier} is not null)"); using (builder.NewBracesScope()) { builder.AppendLine($"System.IO.File.WriteAllText(outOfProcessStatusFile, {skipReasonIdentifier} + System.Environment.NewLine);"); diff --git a/src/tests/JIT/interpreter/InterpreterTester.csproj b/src/tests/JIT/interpreter/InterpreterTester.csproj index 03d6b7b8f6a8ed..1df9573c0d5b8b 100644 --- a/src/tests/JIT/interpreter/InterpreterTester.csproj +++ b/src/tests/JIT/interpreter/InterpreterTester.csproj @@ -1,6 +1,6 @@ - <_RunInterpreterDirectly Condition="'$(RuntimeFlavor)' == 'CoreCLR' and '$(TargetOS)' == 'browser' and '$(TargetArchitecture)' == 'wasm'">true + <_RunInterpreterDirectly Condition="'$(RuntimeFlavor)' == 'coreclr' and '$(TargetOS)' == 'browser' and '$(TargetArchitecture)' == 'wasm'">true true true true