1--TEST-- 2FPM: bug76601 children should not ignore signals during concurrent reloads 3--SKIPIF-- 4<?php 5include "skipif.inc"; 6if (getenv("SKIP_SLOW_TESTS")) die("skip slow test"); 7?> 8--FILE-- 9<?php 10 11require_once "tester.inc"; 12 13$cfg = <<<EOT 14[global] 15error_log = {{FILE:LOG}} 16pid = {{FILE:PID}} 17; some value twice greater than tester->getLogLines() timeout 18process_control_timeout=10 19[unconfined] 20listen = {{ADDR}} 21; spawn children immediately after reload 22pm = static 23pm.max_children = 10 24EOT; 25 26$code = <<<EOT 27<?php 28/* empty */ 29EOT; 30 31/* 32 * If a child miss SIGQUIT then reload process should stuck 33 * for at least process_control_timeout that is set greater 34 * than timout in log reading functions. 35 * 36 * Alternative way is to set log_level=debug and filter result of 37 * $tester->getLogLines(2000) for lines containing SIGKILL 38 * 39 * [22-Oct-2019 03:28:19.532703] DEBUG: pid 21315, fpm_pctl_kill_all(), line 161: [pool unconfined] sending signal 9 SIGKILL to child 21337 40 * [22-Oct-2019 03:28:19.533471] DEBUG: pid 21315, fpm_children_bury(), line 259: [pool unconfined] child 21337 exited on signal 9 (SIGKILL) after 1.003055 seconds from start 41 * 42 * but it has less probability of failure detection. Additionally it requires more 43 * $tester->expectLogNotice() around last reload due to presence of debug messages. 44 */ 45 46$tester = new FPM\Tester($cfg, $code); 47$tester->start(); 48$tester->expectLogStartNotices(); 49 50/* Vary interval between concurrent reload requests 51 since performance of test instance is not known in advance */ 52$max_interval = 25000; 53$step = 1000; 54$pid = $tester->getPid(); 55for ($interval = 0; $interval < $max_interval; $interval += $step) { 56 exec("kill -USR2 $pid", $out, $killExitCode); 57 if ($killExitCode) { 58 echo "ERROR: master process is dead\n"; 59 break; 60 } 61 usleep($interval); 62} 63echo "Reached interval $interval us with $step us steps\n"; 64$tester->expectLogNotice('Reloading in progress ...'); 65/* Consume mix of 'Reloading in progress ...' and 'reloading: .*' */ 66$skipped = $tester->getLogLines(2000); 67 68$tester->signal('USR2'); 69$tester->expectLogNotice('Reloading in progress ...'); 70/* When a child ignores SIGQUIT, the following expectation fails due to timeout. */ 71if (!$tester->expectLogNotice('reloading: .*')) { 72 /* for troubleshooting */ 73 echo "Skipped messages\n"; 74 echo implode('', $skipped); 75} 76$tester->expectLogNotice('using inherited socket fd=\d+, "127.0.0.1:\d+"'); 77$tester->expectLogStartNotices(); 78 79$tester->terminate(); 80$tester->expectLogTerminatingNotices(); 81$tester->close(); 82 83?> 84Done 85--EXPECT-- 86Reached interval 25000 us with 1000 us steps 87Done 88--CLEAN-- 89<?php 90require_once "tester.inc"; 91FPM\Tester::clean(); 92?> 93