Skip to content

Commit cc130df

Browse files
committed
Fix flaky tests: use deterministic waits and sorted output
- 013: Replace usleep with stream_get_contents to wait for child EOF, fixing race under ASAN where child exit takes longer than 200ms - 014: Collect coroutine results in array with ksort instead of echo, fixing non-deterministic scheduling order
1 parent ee10c37 commit cc130df

2 files changed

Lines changed: 16 additions & 19 deletions

File tree

tests/exec/013-proc_close_child_already_reaped.phpt

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ if (!function_exists("proc_open")) echo "skip proc_open() is not available";
66
if (DIRECTORY_SEPARATOR === '\\') die('skip Unix-only test');
77
$php = getenv('TEST_PHP_EXECUTABLE');
88
if ($php === false) echo "skip no php executable defined";
9-
// Under ASAN, child process exit(42) takes much longer due to leak checking,
10-
// so usleep(200ms) is not enough for the child to become a zombie.
11-
// pcntl_waitpid returns 0 (still running) and the external reap never happens.
12-
if (getenv('USE_ZEND_ALLOC') === '0') die('skip ASAN slows child exit, making race condition unreliable');
139
?>
1410
--FILE--
1511
<?php
@@ -36,20 +32,15 @@ $c = spawn(function() use ($php) {
3632
$status = proc_get_status($process);
3733
$pid = $status['pid'];
3834

39-
// Wait for child to exit
40-
usleep(200000);
35+
// Wait for child to actually exit by reading stdout until EOF.
36+
// This is deterministic regardless of ASAN/valgrind slowdown.
37+
stream_get_contents($pipes[1]);
4138

4239
// Simulate external reaping (like Go runtime doing waitpid(-1))
4340
// This steals the zombie before proc_close can get it.
4441
$reap_status = 0;
4542
$reaped = pcntl_waitpid($pid, $reap_status, WNOHANG);
46-
if ($reaped == $pid) {
47-
echo "Zombie reaped externally, exit=" . pcntl_wexitstatus($reap_status) . "\n";
48-
} else {
49-
echo "Could not reap (result=$reaped), trying waitpid(-1)\n";
50-
$reaped = pcntl_waitpid(-1, $reap_status, WNOHANG);
51-
echo "waitpid(-1) result: $reaped\n";
52-
}
43+
echo "Zombie reaped externally, exit=" . pcntl_wexitstatus($reap_status) . "\n";
5344

5445
fclose($pipes[0]);
5546
fclose($pipes[1]);

tests/pdo_pgsql/014-pdo_pgsql_pool_stmt_cross_coroutine.phpt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ $pdo = AsyncPDOPgSQLTest::poolFactory();
2121
$pdo->exec("DROP TABLE IF EXISTS test_pgsql_pool_cross");
2222
$pdo->exec("CREATE TABLE test_pgsql_pool_cross (id SERIAL PRIMARY KEY, val VARCHAR(50))");
2323

24-
$coro1 = spawn(function() use ($pdo) {
24+
$results = [];
25+
26+
$coro1 = spawn(function() use ($pdo, &$results) {
2527
$stmtA = $pdo->query("SELECT pg_backend_pid() as pid");
2628
$pid = $stmtA->fetch()['pid'];
2729

@@ -33,12 +35,12 @@ $coro1 = spawn(function() use ($pdo) {
3335

3436
$stmtC = $pdo->query("SELECT pg_backend_pid() as pid");
3537
$check = $stmtC->fetch()['pid'];
36-
echo "Coro1 same conn: " . ($pid === $check ? "yes" : "no") . "\n";
38+
$results['coro1'] = ($pid === $check ? "yes" : "no");
3739

3840
return $pid;
3941
});
4042

41-
$coro2 = spawn(function() use ($pdo) {
43+
$coro2 = spawn(function() use ($pdo, &$results) {
4244
$stmtA = $pdo->query("SELECT pg_backend_pid() as pid");
4345
$pid = $stmtA->fetch()['pid'];
4446

@@ -50,14 +52,18 @@ $coro2 = spawn(function() use ($pdo) {
5052

5153
$stmtC = $pdo->query("SELECT pg_backend_pid() as pid");
5254
$check = $stmtC->fetch()['pid'];
53-
echo "Coro2 same conn: " . ($pid === $check ? "yes" : "no") . "\n";
55+
$results['coro2'] = ($pid === $check ? "yes" : "no");
5456

5557
return $pid;
5658
});
5759

5860
$pid1 = await($coro1);
5961
$pid2 = await($coro2);
6062

63+
ksort($results);
64+
foreach ($results as $name => $same) {
65+
echo "$name same conn: $same\n";
66+
}
6167
echo "Different connections across coroutines: " . ($pid1 !== $pid2 ? "yes" : "no") . "\n";
6268

6369
$stmt = $pdo->query("SELECT val FROM test_pgsql_pool_cross ORDER BY id");
@@ -69,8 +75,8 @@ $pdo->exec("DROP TABLE IF EXISTS test_pgsql_pool_cross");
6975
echo "Done\n";
7076
?>
7177
--EXPECT--
72-
Coro1 same conn: yes
73-
Coro2 same conn: yes
78+
coro1 same conn: yes
79+
coro2 same conn: yes
7480
Different connections across coroutines: yes
7581
Rows: coro1, coro2
7682
Done

0 commit comments

Comments
 (0)