Skip to content

Commit 8c01165

Browse files
committed
Derive PHPUnit pass/fail from JUnit XML, not process exit status
Since PHP hangs during shutdown after every test run (Turso deadlock), the process is killed by `timeout` and we can't rely on PHPUnit's own exit code. Write a JUnit XML log and parse it to decide the step's status — any <error> or <failure> element fails the step, with a summary printed as a workflow notice.
1 parent e91c99a commit 8c01165

1 file changed

Lines changed: 24 additions & 11 deletions

File tree

.github/workflows/phpunit-tests-turso.yml

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -596,18 +596,31 @@ jobs:
596596
working-directory: packages/mysql-on-sqlite
597597
# PHPUnit's own run completes in ~2 minutes, but PHP then hangs inside
598598
# zend_gc_collect_cycles → pdo_sqlite → Turso's sqlite3_finalize, which
599-
# deadlocks on the sqlite3Inner mutex during process shutdown. Wrap
600-
# the command in `timeout` so we bound process lifetime: once the test
601-
# summary is printed, the process is killed and the step exits cleanly.
602-
# The pass/fail signal comes from the summary, not the exit status.
599+
# deadlocks on the sqlite3Inner mutex during process shutdown. We can't
600+
# trust the process's exit status, so we derive pass/fail from a JUnit
601+
# XML file written incrementally during the run: if the file records
602+
# any <error> or <failure>, the step fails.
603603
run: |
604604
set +e
605-
timeout --preserve-status --kill-after=10 180 \
606-
php ./vendor/bin/phpunit -c ./phpunit.xml.dist
605+
timeout --kill-after=10 180 \
606+
php ./vendor/bin/phpunit -c ./phpunit.xml.dist \
607+
--log-junit /tmp/phpunit-turso.xml
607608
ec=$?
608-
# Exit 124 means timeout fired; anything else is PHPUnit's own status.
609-
if [ "$ec" = "124" ] || [ "$ec" = "137" ]; then
610-
echo "::notice::PHPUnit completed; process was killed during shutdown (Turso finalize deadlock)."
611-
exit 0
609+
if [ ! -s /tmp/phpunit-turso.xml ]; then
610+
echo "::error::JUnit report not written — PHPUnit likely crashed before any tests ran."
611+
exit "$ec"
612612
fi
613-
exit "$ec"
613+
python3 <<'PY'
614+
import sys, xml.etree.ElementTree as ET
615+
cases = list(ET.parse('/tmp/phpunit-turso.xml').iter('testcase'))
616+
errors = sum(1 for c in cases if c.find('error') is not None)
617+
failures = sum(1 for c in cases if c.find('failure') is not None)
618+
skipped = sum(1 for c in cases if c.find('skipped') is not None)
619+
assertions = sum(int(c.get('assertions', 0) or 0) for c in cases)
620+
total = len(cases)
621+
passing = total - errors - failures - skipped
622+
print(f"::notice::Turso DB: {passing}/{total} passing "
623+
f"(errors={errors}, failures={failures}, skipped={skipped}, "
624+
f"assertions={assertions})")
625+
sys.exit(1 if errors or failures else 0)
626+
PY

0 commit comments

Comments
 (0)