From 2f9f40915606f34b177b722d50a7ed4ce43adfc7 Mon Sep 17 00:00:00 2001
From: Maksim Nikulin <mnikulin@plesk.com>
Date: Thu, 25 Jul 2019 11:41:36 +0700
Subject: [PATCH] Add (slow) test for fpm concurrent reloads #74083

---
 .../fpm/tests/bug74083-concurrent-reload.phpt | 76 +++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 sapi/fpm/tests/bug74083-concurrent-reload.phpt

diff --git a/sapi/fpm/tests/bug74083-concurrent-reload.phpt b/sapi/fpm/tests/bug74083-concurrent-reload.phpt
new file mode 100644
index 0000000000..532c3b10bf
--- /dev/null
+++ b/sapi/fpm/tests/bug74083-concurrent-reload.phpt
@@ -0,0 +1,76 @@
+--TEST--
+Concurrent reload signals should not kill PHP-FPM master process. (Bug: #74083)
+--SKIPIF--
+<?php
+if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
+?>
+--FILE--
+<?php
+
+require_once "tester.inc";
+
+$cfg = <<<EOT
+[global]
+error_log = {{FILE:LOG}}
+pid = {{FILE:PID}}
+process_control_timeout=1
+[unconfined]
+listen = {{ADDR}}
+ping.path = /ping
+ping.response = pong
+pm = dynamic
+pm.max_children = 5
+pm.start_servers = 1
+pm.min_spare_servers = 1
+pm.max_spare_servers = 1
+EOT;
+
+$code = <<<EOT
+<?php
+/* empty */
+EOT;
+
+$tester = new FPM\Tester($cfg, $code);
+$tester->start();
+$tester->expectLogStartNotices();
+$tester->ping('{{ADDR}}');
+
+/* Vary interval between concurrent reload requests
+    since performance of test instance is not known in advance */
+$max_interval = 25000;
+$step = 1000;
+$pid = $tester->getPid();
+for ($interval = 0; $interval < $max_interval; $interval += $step) {
+    exec("kill -USR2 $pid", $out, $killExitCode);
+    if ($killExitCode) {
+        echo "ERROR: master process is dead\n";
+        break;
+    }
+    usleep($interval);
+}
+echo "Reached interval $interval us with $step us steps\n";
+$tester->expectLogNotice('Reloading in progress ...');
+/* Consume mix of 'Reloading in progress ...' and 'reloading: .*' */
+$tester->getLogLines(2000);
+
+$tester->signal('USR2');
+$tester->expectLogNotice('Reloading in progress ...');
+$tester->expectLogNotice('reloading: .*');
+$tester->expectLogNotice('using inherited socket fd=\d+, "127.0.0.1:\d+"');
+$tester->expectLogStartNotices();
+$tester->ping('{{ADDR}}');
+
+$tester->terminate();
+$tester->expectLogTerminatingNotices();
+$tester->close();
+
+?>
+Done
+--EXPECT--
+Reached interval 25000 us with 1000 us steps
+Done
+--CLEAN--
+<?php
+require_once "tester.inc";
+FPM\Tester::clean();
+?>
-- 
2.40.0