[gcc r17-3319] testsuite: Fix instability in pytest-based tests
Lewis Hyatt via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:a3df0c3c54c61cc0fc4b1e5f7bbb29050f1ea7e2 commit r17-3319-ga3df0c3c54c61cc0fc4b1e5f7bbb29050f1ea7e2 Author: Lewis Hyatt <[email protected]> Date: Thu Aug 13 22:07:01 2026 -0400 testsuite: Fix instability in pytest-based tests The python-based tests using the pytest library all call "expect" with the default timeout, which is not always long enough for python to finish importing everything and scanning the file system, especially on a slower NFS mount. When the timeout is hit, it results in silently dropping the test outputs. Resolve that by increasing the timeout and by reporting a FAIL upon timeout to clarify what happened. Additionally, in a frequently-used setup where the build directory and the source directory are both contained in a common parent directory, pytest ends up choosing that parent directory as its "root dir", and writes some things there including a pytest_cache directory. When testing in parallel, all parallel invocations use that same cache directory. I have not directly seen it lead to an issue so far, but it is potentially problematic and it is also surprising for users that pytest writes to a location outside of the build directory. Address that as well by specifying the root dir to be inside the test base_dir and disabling the cache, which is not needed in any case. gcc/testsuite/ChangeLog: * lib/target-supports.exp (pytest_invoke): New function. (check_effective_target_pytest3): Use pytest_invoke to add some additional arguments to the pytest invocation. * lib/gcov.exp (run-gcov-pytest): Set timeout to 300 seconds, report test failure upon timeout, and use new pytest_invoke helper. * lib/scanhtml.exp (run-html-pytest): Likewise. * lib/scansarif.exp (run-sarif-pytest): Likewise. Diff: --- gcc/testsuite/lib/gcov.exp | 6 +++++- gcc/testsuite/lib/scanhtml.exp | 7 +++++-- gcc/testsuite/lib/scansarif.exp | 7 +++++-- gcc/testsuite/lib/target-supports.exp | 9 ++++++++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/gcc/testsuite/lib/gcov.exp b/gcc/testsuite/lib/gcov.exp index e62a39e7ed57..94a734817b1b 100644 --- a/gcc/testsuite/lib/gcov.exp +++ b/gcc/testsuite/lib/gcov.exp @@ -694,9 +694,10 @@ proc run-gcov-pytest { args } { } setenv GCOV_PATH $testcase - spawn -noecho python3 -m pytest --color=no -rap -s --tb=no $srcdir/$subdir/$pytest_script + spawn -noecho {*}[pytest_invoke] $srcdir/$subdir/$pytest_script set prefix "\[^\r\n\]*" + set timeout 300 expect { -re "FAILED($prefix)\[^\r\n\]+\r\n" { set output [gcov-pytest-format-line $testcase $pytest_script $expect_out(1,string)] @@ -713,6 +714,9 @@ proc run-gcov-pytest { args } { pass $output exp_continue } + timeout { + fail "$subdir/$testcase $pytest_script timed out" + } } clean-gcov $testcase diff --git a/gcc/testsuite/lib/scanhtml.exp b/gcc/testsuite/lib/scanhtml.exp index 9f2996c55306..d5aa20a2e1ca 100644 --- a/gcc/testsuite/lib/scanhtml.exp +++ b/gcc/testsuite/lib/scanhtml.exp @@ -62,13 +62,14 @@ proc run-html-pytest { args } { verbose "PYTHONPATH=[getenv PYTHONPATH]" 2 - spawn -noecho python3 -m pytest --color=no -rap -s --tb=no $srcdir/$subdir/$pytest_script + spawn -noecho {*}[pytest_invoke] $srcdir/$subdir/$pytest_script if [info exists old_PYTHONPATH] { setenv PYTHONPATH ${old_PYTHONPATH} } set prefix "\[^\r\n\]*" + set timeout 300 expect { -re "FAILED($prefix)\[^\r\n\]+\r\n" { set output [html-pytest-format-line $testcase $pytest_script $expect_out(1,string)] @@ -85,6 +86,8 @@ proc run-html-pytest { args } { pass $output exp_continue } + timeout { + fail "$subdir/$testcase $pytest_script timed out" + } } } - diff --git a/gcc/testsuite/lib/scansarif.exp b/gcc/testsuite/lib/scansarif.exp index 03014cd73088..b96458e398fd 100644 --- a/gcc/testsuite/lib/scansarif.exp +++ b/gcc/testsuite/lib/scansarif.exp @@ -173,13 +173,14 @@ proc run-sarif-pytest { args } { verbose "PYTHONPATH=[getenv PYTHONPATH]" 2 - spawn -noecho python3 -m pytest --color=no -rap -s --tb=no $srcdir/$subdir/$pytest_script + spawn -noecho {*}[pytest_invoke] $srcdir/$subdir/$pytest_script if [info exists old_PYTHONPATH] { setenv PYTHONPATH ${old_PYTHONPATH} } set prefix "\[^\r\n\]*" + set timeout 300 expect { -re "FAILED($prefix)\[^\r\n\]+\r\n" { set output [sarif-pytest-format-line $testcase $pytest_script $expect_out(1,string)] @@ -196,6 +197,8 @@ proc run-sarif-pytest { args } { pass $output exp_continue } + timeout { + fail "$subdir/$testcase $pytest_script timed out" + } } } - diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index eb2444204a0d..bf49da5513a3 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -14402,11 +14402,18 @@ proc check_effective_target_python3_module { module } { }] } +# Helper to return the common pytest arguments +proc pytest_invoke { } { + return [list python3 -m pytest --color=no -rap -s --tb=no \ + --rootdir . --basetemp pytest-tmp \ + -p no:cacheprovider] +} + # Return 1 if pytest module is available for python3. proc check_effective_target_pytest3 { } { return [check_cached_effective_target pytest3 { - set result [remote_exec host "python3 -m pytest --color=no -rap -s --tb=no --version"] + set result [remote_exec host "[pytest_invoke] --version"] set status [lindex $result 0] if { $status == 0 } then { return 1;