Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 98 additions & 9 deletions src/tests/Common/CLRTest.Execute.Bash.targets
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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=$?

Expand Down
58 changes: 56 additions & 2 deletions src/tests/Common/CLRTest.Execute.Batch.targets
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
86 changes: 81 additions & 5 deletions src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)));
Expand Down Expand Up @@ -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}");
}
}
}
Loading
Loading