Skip to content

Commit ce22919

Browse files
committed
Extend columnN probe + parse stdout when JUnit not flushed
Two diagnostic improvements following the most recent CI run: - Probe extension: the previous probe used single-column VALUES and every case passed, even though the failing tests report "no such column: column17" / "column5" / "column1". The driver emits multi-column VALUES for INSERT-from-VALUES with multiple values; cover 2-, 3-, 5-column shapes and the SELECT-AS-alias and CTE-alias rewrites at the same arity. - Test runner: PHPUnit was completing the full run (596 tests, 8 errors, 2 failures => 582 passing) but Turso's shutdown SIGSEGV in sqlite3_finalize raced PHPUnit's --log-junit flush, so the XML was empty and the harness returned "crashed before any tests ran". Tee stdout, prefer JUnit when present, fall back to parsing PHPUnit's "Tests: N, ... Errors: E ..." summary line. Drop --debug since per-test logging is no longer needed for diagnostics.
1 parent c138e01 commit ce22919

1 file changed

Lines changed: 59 additions & 35 deletions

File tree

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

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -910,29 +910,32 @@ jobs:
910910
$pdo->exec('CREATE TABLE t (v INTEGER)');
911911
912912
$cases = [
913-
'top-level SELECT column1 FROM (VALUES)' =>
913+
'top-level SELECT column1 FROM (VALUES) (1 col)' =>
914914
'SELECT column1 FROM (VALUES (5))',
915-
'top-level SELECT `column1` FROM (VALUES)' =>
916-
'SELECT `column1` FROM (VALUES (5))',
917-
'top-level SELECT CAST(`column1`) FROM (VALUES)' =>
918-
'SELECT CAST(`column1` AS INTEGER) FROM (VALUES (5))',
919-
'top-level SELECT CAST(`column1`) FROM (VALUES) WHERE true' =>
915+
'top-level SELECT CAST(`column1`) FROM (VALUES) WHERE true (1 col)' =>
920916
'SELECT CAST(`column1` AS INTEGER) FROM (VALUES (5)) WHERE true',
921-
'INSERT...SELECT column1 FROM (VALUES)' =>
922-
'INSERT INTO t (v) SELECT column1 FROM (VALUES (5))',
923-
'INSERT...SELECT `column1` FROM (VALUES)' =>
924-
'INSERT INTO t (v) SELECT `column1` FROM (VALUES (5))',
925-
'INSERT...SELECT CAST(`column1`) FROM (VALUES)' =>
926-
'INSERT INTO t (v) SELECT CAST(`column1` AS INTEGER) FROM (VALUES (5))',
927-
'INSERT...SELECT CAST(`column1`) FROM (VALUES) WHERE true' =>
917+
'INSERT...SELECT CAST(`column1`) FROM (VALUES) WHERE true (1 col)' =>
928918
'INSERT INTO t (v) SELECT CAST(`column1` AS INTEGER) FROM (VALUES (5)) WHERE true',
929-
'INSERT...SELECT CAST(column1) FROM (VALUES) WHERE true (no backticks)' =>
930-
'INSERT INTO t (v) SELECT CAST(column1 AS INTEGER) FROM (VALUES (5)) WHERE true',
931-
'INSERT...SELECT CAST(`column1`) FROM (SELECT...)' =>
932-
'INSERT INTO t (v) SELECT CAST(`column1` AS INTEGER) FROM (SELECT 5 AS `column1`) WHERE true',
933-
'INSERT...SELECT CAST(`column1`) FROM CTE(VALUES)' =>
934-
"INSERT INTO t (v) WITH src(`column1`) AS (VALUES (5)) SELECT CAST(`column1` AS INTEGER) FROM src WHERE true",
919+
'top-level SELECT column1, column2 FROM (VALUES) (2 cols)' =>
920+
'SELECT column1, column2 FROM (VALUES (5, 6))',
921+
'INSERT...SELECT CAST(`column1`), CAST(`column2`) FROM (VALUES) WHERE true (2 cols)' =>
922+
'INSERT INTO t2 (a, b) SELECT CAST(`column1` AS INTEGER), CAST(`column2` AS INTEGER) FROM (VALUES (5, 6)) WHERE true',
923+
'INSERT (3 cols)' =>
924+
'INSERT INTO t3 (a, b, c) SELECT CAST(`column1` AS INTEGER), CAST(`column2` AS INTEGER), CAST(`column3` AS INTEGER) FROM (VALUES (5, 6, 7)) WHERE true',
925+
'INSERT (5 cols, refer column5)' =>
926+
'INSERT INTO t5 (a, b, c, d, e) SELECT CAST(`column1` AS INTEGER), CAST(`column2` AS INTEGER), CAST(`column3` AS INTEGER), CAST(`column4` AS INTEGER), CAST(`column5` AS INTEGER) FROM (VALUES (1, 2, 3, 4, 5)) WHERE true',
927+
'INSERT (3 cols, no backticks)' =>
928+
'INSERT INTO t3 (a, b, c) SELECT CAST(column1 AS INTEGER), CAST(column2 AS INTEGER), CAST(column3 AS INTEGER) FROM (VALUES (5, 6, 7)) WHERE true',
929+
'top-level SELECT column1, column2 FROM (SELECT...)' =>
930+
'SELECT column1, column2 FROM (SELECT 5 AS column1, 6 AS column2)',
931+
'INSERT (3 cols) FROM (SELECT…AS column1)' =>
932+
'INSERT INTO t3 (a, b, c) SELECT CAST(column1 AS INTEGER), CAST(column2 AS INTEGER), CAST(column3 AS INTEGER) FROM (SELECT 5 AS column1, 6 AS column2, 7 AS column3) WHERE true',
933+
'INSERT (3 cols) CTE(VALUES) AS src(c1, c2, c3)' =>
934+
"INSERT INTO t3 (a, b, c) WITH src(column1, column2, column3) AS (VALUES (5, 6, 7)) SELECT CAST(column1 AS INTEGER), CAST(column2 AS INTEGER), CAST(column3 AS INTEGER) FROM src WHERE true",
935935
];
936+
$pdo->exec('CREATE TABLE t2 (a INTEGER, b INTEGER)');
937+
$pdo->exec('CREATE TABLE t3 (a INTEGER, b INTEGER, c INTEGER)');
938+
$pdo->exec('CREATE TABLE t5 (a INTEGER, b INTEGER, c INTEGER, d INTEGER, e INTEGER)');
936939
foreach ($cases as $label => $sql) {
937940
try {
938941
$stmt = $pdo->query($sql);
@@ -943,7 +946,9 @@ jobs:
943946
} catch (Throwable $e) {
944947
echo "FAIL $label -> " . $e->getMessage() . "\n";
945948
}
946-
try { $pdo->exec('DELETE FROM t'); } catch (Throwable $_) {}
949+
foreach (['t', 't2', 't3', 't5'] as $tbl) {
950+
try { $pdo->exec("DELETE FROM $tbl"); } catch (Throwable $_) {}
951+
}
947952
}
948953
949954
- name: Install Composer dependencies (root)
@@ -1677,25 +1682,44 @@ jobs:
16771682
skip_regex='^(?!WP_MySQL_Server_Suite_).+'
16781683
timeout --kill-after=10 600 \
16791684
php ./vendor/bin/phpunit -c ./phpunit.xml.dist \
1680-
--debug \
16811685
--filter "$skip_regex" \
1682-
--log-junit /tmp/phpunit-turso.xml
1683-
ec=$?
1684-
if [ ! -s /tmp/phpunit-turso.xml ]; then
1685-
echo "::error::JUnit report not written — PHPUnit likely crashed before any tests ran."
1686-
exit "$ec"
1687-
fi
1686+
--log-junit /tmp/phpunit-turso.xml \
1687+
| tee /tmp/phpunit-turso.stdout
1688+
ec=${PIPESTATUS[0]}
1689+
# If JUnit was flushed, prefer it. Otherwise (Turso's shutdown
1690+
# SIGSEGV in sqlite3_finalize can race PHPUnit's logger flush),
1691+
# fall back to parsing PHPUnit's stdout summary.
16881692
python3 <<'PY'
1689-
import sys, xml.etree.ElementTree as ET
1690-
cases = list(ET.parse('/tmp/phpunit-turso.xml').iter('testcase'))
1691-
errors = sum(1 for c in cases if c.find('error') is not None)
1692-
failures = sum(1 for c in cases if c.find('failure') is not None)
1693-
skipped = sum(1 for c in cases if c.find('skipped') is not None)
1694-
assertions = sum(int(c.get('assertions', 0) or 0) for c in cases)
1695-
total = len(cases)
1693+
import os, re, sys
1694+
junit = '/tmp/phpunit-turso.xml'
1695+
if os.path.getsize(junit) > 0:
1696+
import xml.etree.ElementTree as ET
1697+
cases = list(ET.parse(junit).iter('testcase'))
1698+
errors = sum(1 for c in cases if c.find('error') is not None)
1699+
failures = sum(1 for c in cases if c.find('failure') is not None)
1700+
skipped = sum(1 for c in cases if c.find('skipped') is not None)
1701+
assertions = sum(int(c.get('assertions', 0) or 0) for c in cases)
1702+
total = len(cases)
1703+
source = 'junit'
1704+
else:
1705+
# PHPUnit summary line: "Tests: N, Assertions: A, Errors: E, Failures: F, Skipped: S, Incomplete: I."
1706+
text = open('/tmp/phpunit-turso.stdout').read()
1707+
m = re.search(r'Tests:\s*(\d+)(?:,\s*Assertions:\s*(\d+))?'
1708+
r'(?:,\s*Errors:\s*(\d+))?(?:,\s*Failures:\s*(\d+))?'
1709+
r'(?:,\s*Skipped:\s*(\d+))?(?:,\s*Incomplete:\s*(\d+))?',
1710+
text)
1711+
if not m:
1712+
print('::error::Neither JUnit nor PHPUnit summary parseable.')
1713+
sys.exit(1)
1714+
total = int(m.group(1))
1715+
assertions = int(m.group(2) or 0)
1716+
errors = int(m.group(3) or 0)
1717+
failures = int(m.group(4) or 0)
1718+
skipped = int(m.group(5) or 0)
1719+
source = 'stdout'
16961720
passing = total - errors - failures - skipped
16971721
print(f"::notice::Turso DB: {passing}/{total} passing "
16981722
f"(errors={errors}, failures={failures}, skipped={skipped}, "
1699-
f"assertions={assertions})")
1723+
f"assertions={assertions}, source={source})")
17001724
sys.exit(1 if errors or failures else 0)
17011725
PY

0 commit comments

Comments
 (0)