bug76601-reload-child-signals.phpt 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. --TEST--
  2. FPM: bug76601 children should not ignore signals during concurrent reloads
  3. --SKIPIF--
  4. <?php
  5. include "skipif.inc";
  6. if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
  7. ?>
  8. --FILE--
  9. <?php
  10. require_once "tester.inc";
  11. $cfg = <<<EOT
  12. [global]
  13. error_log = {{FILE:LOG}}
  14. pid = {{FILE:PID}}
  15. ; some value twice greater than tester->getLogLines() timeout
  16. process_control_timeout=10
  17. [unconfined]
  18. listen = {{ADDR}}
  19. ; spawn children immediately after reload
  20. pm = static
  21. pm.max_children = 10
  22. EOT;
  23. $code = <<<EOT
  24. <?php
  25. /* empty */
  26. EOT;
  27. /*
  28. * If a child miss SIGQUIT then reload process should stuck
  29. * for at least process_control_timeout that is set greater
  30. * than timeout in log reading functions.
  31. *
  32. * Alternative way is to set log_level=debug and filter result of
  33. * $tester->getLogLines(2000) for lines containing SIGKILL
  34. *
  35. * [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
  36. * [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
  37. *
  38. * but it has less probability of failure detection. Additionally it requires more
  39. * $tester->expectLogNotice() around last reload due to presence of debug messages.
  40. */
  41. $tester = new FPM\Tester($cfg, $code);
  42. $tester->start();
  43. $tester->expectLogStartNotices();
  44. /* Vary interval between concurrent reload requests
  45. since performance of test instance is not known in advance */
  46. $max_interval = 25000;
  47. $step = 1000;
  48. $pid = $tester->getPid();
  49. for ($interval = 0; $interval < $max_interval; $interval += $step) {
  50. exec("kill -USR2 $pid", $out, $killExitCode);
  51. if ($killExitCode) {
  52. echo "ERROR: master process is dead\n";
  53. break;
  54. }
  55. usleep($interval);
  56. }
  57. echo "Reached interval $interval us with $step us steps\n";
  58. $tester->expectLogNotice('Reloading in progress ...');
  59. /* Consume mix of 'Reloading in progress ...' and 'reloading: .*' */
  60. $tester->readAllLogNotices('Reloading in progress ...');
  61. $tester->reload();
  62. $tester->expectLogReloadingNotices();
  63. $tester->terminate();
  64. $tester->expectLogTerminatingNotices();
  65. $tester->close();
  66. ?>
  67. Done
  68. --EXPECT--
  69. Reached interval 25000 us with 1000 us steps
  70. Done
  71. --CLEAN--
  72. <?php
  73. require_once "tester.inc";
  74. FPM\Tester::clean();
  75. ?>