mirror of
https://github.com/php/php-src.git
synced 2024-09-23 10:57:26 +00:00
Merge branch 'PHP-7.1' into PHP-7.2
This commit is contained in:
commit
bc58ba750f
@ -1,51 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Startup and connect
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = 127.0.0.1:$port
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
$i = 0;
|
||||
while (($i++ < 60) && !($fp = @fsockopen('127.0.0.1', $port))) {
|
||||
usleep(50000);
|
||||
}
|
||||
if ($fp) {
|
||||
echo "Done\n";
|
||||
fclose($fp);
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,54 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test IPv6 support
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc";
|
||||
@stream_socket_client('tcp://[::1]:0', $errno);
|
||||
if ($errno != 111) die('skip IPv6 not supported.');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = [::1]:$port
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
$i = 0;
|
||||
while (($i++ < 60) && !($fp = fsockopen('[::1]', $port))) {
|
||||
usleep(50000);
|
||||
}
|
||||
if ($fp) {
|
||||
echo "Done\n";
|
||||
fclose($fp);
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,62 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test IPv4/IPv6 support
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc";
|
||||
@stream_socket_client('tcp://[::1]:0', $errno);
|
||||
if ($errno != 111) die('skip IPv6 not supported.');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = [::]:$port
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
$i = 0;
|
||||
while (($i++ < 60) && !($fp = @fsockopen('127.0.0.1', $port))) {
|
||||
usleep(50000);
|
||||
}
|
||||
if ($fp) {
|
||||
echo "Done IPv4\n";
|
||||
fclose($fp);
|
||||
}
|
||||
while (($i++ < 60) && !($fp = @fsockopen('[::1]', $port))) {
|
||||
usleep(50000);
|
||||
}
|
||||
if ($fp) {
|
||||
echo "Done IPv6\n";
|
||||
fclose($fp);
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
Done IPv4
|
||||
Done IPv6
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,60 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test IPv4 allowed clients
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc";
|
||||
@stream_socket_client('tcp://[::1]:0', $errno);
|
||||
if ($errno != 111) die('skip IPv6 not supported.');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = [::]:$port
|
||||
listen.allowed_clients = 127.0.0.1
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
run_request('127.0.0.1', $port);
|
||||
echo "IPv4 ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "IPv4 error\n";
|
||||
}
|
||||
try {
|
||||
run_request('[::1]', $port);
|
||||
echo "IPv6 ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "IPv6 error\n";
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
IPv4 ok
|
||||
IPv6 error
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,60 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test IPv6 allowed clients (bug #68428)
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc";
|
||||
@stream_socket_client('tcp://[::1]:0', $errno);
|
||||
if ($errno != 111) die('skip IPv6 not supported.');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = [::]:$port
|
||||
listen.allowed_clients = ::1
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
run_request('127.0.0.1', $port);
|
||||
echo "IPv4 ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "IPv4 error\n";
|
||||
}
|
||||
try {
|
||||
run_request('[::1]', $port);
|
||||
echo "IPv6 ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "IPv6 error\n";
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
IPv4 error
|
||||
IPv6 ok
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,71 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test IPv6 all addresses and access_log (bug #68421)
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc";
|
||||
@stream_socket_client('tcp://[::1]:0', $errno);
|
||||
if ($errno != 111) die('skip IPv6 not supported.');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$accfile = dirname(__FILE__).'/php-fpm.acc.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = [::]:$port
|
||||
access.log = $accfile
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
var_dump(strpos(run_request('127.0.0.1', $port), 'pong'));
|
||||
echo "IPv4 ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "IPv4 error\n";
|
||||
}
|
||||
try {
|
||||
var_dump(strpos(run_request('[::1]', $port), 'pong'));
|
||||
echo "IPv6 ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "IPv6 error\n";
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
|
||||
echo file_get_contents($accfile);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
int(%d)
|
||||
IPv4 ok
|
||||
int(%d)
|
||||
IPv6 ok
|
||||
127.0.0.1 %s "GET /ping" 200
|
||||
::1 %s "GET /ping" 200
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
$accfile = dirname(__FILE__).'/php-fpm.acc.tmp';
|
||||
@unlink($accfile);
|
||||
?>
|
@ -1,100 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test multi pool (dynamic + ondemand + static) (bug #68423)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = /dev/null
|
||||
[poold_ondemand]
|
||||
listen=127.0.0.1:9000
|
||||
pm = ondemand
|
||||
pm.max_children = 2
|
||||
pm.process_idle_timeout = 10
|
||||
EOT;
|
||||
|
||||
if (test_fpm_conf($cfg, $msg) == false) {
|
||||
die("skip " . $msg);
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port1 = 9000+PHP_INT_SIZE;
|
||||
$port2 = 9001+PHP_INT_SIZE;
|
||||
$port3 = 9002+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[pool_dynamic]
|
||||
listen = 127.0.0.1:$port1
|
||||
ping.path = /ping
|
||||
ping.response = pong-dynamic
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
[poold_ondemand]
|
||||
listen = 127.0.0.1:$port2
|
||||
ping.path = /ping
|
||||
ping.response = pong-on-demand
|
||||
pm = ondemand
|
||||
pm.max_children = 2
|
||||
pm.process_idle_timeout = 10
|
||||
[pool_static]
|
||||
listen = 127.0.0.1:$port3
|
||||
ping.path = /ping
|
||||
ping.response = pong-static
|
||||
pm = static
|
||||
pm.max_children = 2
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
var_dump(strpos(run_request('127.0.0.1', $port1), 'pong-dynamic'));
|
||||
echo "Dynamic ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Dynamic error\n";
|
||||
}
|
||||
try {
|
||||
var_dump(strpos(run_request('127.0.0.1', $port2), 'pong-on-demand'));
|
||||
echo "OnDemand ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "OnDemand error\n";
|
||||
}
|
||||
try {
|
||||
var_dump(strpos(run_request('127.0.0.1', $port3), 'pong-static'));
|
||||
echo "Static ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Static error\n";
|
||||
}
|
||||
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
int(%d)
|
||||
Dynamic ok
|
||||
int(%d)
|
||||
OnDemand ok
|
||||
int(%d)
|
||||
Static ok
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,53 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test Unix Domain Socket
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$socket = dirname(__FILE__).'/php-fpm.sock';
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = $socket
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
var_dump(strpos(run_request('unix://'.$socket, -1), 'pong'));
|
||||
echo "UDS ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "UDS error\n";
|
||||
}
|
||||
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
int(%d)
|
||||
UDS ok
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,87 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test status page
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--XFAIL--
|
||||
randomly intermittently failing all the time in CI, with diff:
|
||||
017+ active processes: 0
|
||||
018+ total processes: 1
|
||||
017- active processes: 1
|
||||
018- total processes: 2
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = 127.0.0.1:$port
|
||||
pm.status_path = /status
|
||||
pm = static
|
||||
pm.max_children = 1
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
echo run_request('127.0.0.1', $port, '/status');
|
||||
|
||||
$html = run_request('127.0.0.1', $port, '/status', 'html');
|
||||
var_dump(strpos($html, 'text/html') && strpos($html, 'DOCTYPE') && strpos($html, 'PHP-FPM Status Page'));
|
||||
|
||||
$json = run_request('127.0.0.1', $port, '/status', 'json');
|
||||
var_dump(strpos($json, 'application/json') && strpos($json, '"pool":"unconfined"'));
|
||||
|
||||
$xml = run_request('127.0.0.1', $port, '/status', 'xml');
|
||||
var_dump(strpos($xml, 'text/xml') && strpos($xml, '<?xml'));
|
||||
|
||||
echo "IPv4 ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "IPv4 error\n";
|
||||
}
|
||||
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
X-Powered-By: PHP/%s
|
||||
Expires: %s
|
||||
Cache-Control: %s
|
||||
Content-type: text/plain%s
|
||||
|
||||
pool: unconfined
|
||||
process manager: static
|
||||
start time: %s
|
||||
start since: %d
|
||||
accepted conn: 1
|
||||
listen queue: 0
|
||||
max listen queue: 0
|
||||
listen queue len: %d
|
||||
idle processes: 0
|
||||
active processes: 1
|
||||
total processes: 1
|
||||
max active processes: 1
|
||||
max children reached: 0
|
||||
slow requests: 0
|
||||
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
IPv4 ok
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,53 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test IPv4 all addresses (bug #68420)
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = $port
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
var_dump(strpos(run_request('127.0.0.1', $port), 'pong'));
|
||||
echo "IPv4 ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "IPv4 error\n";
|
||||
}
|
||||
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
int(%d)
|
||||
IPv4 ok
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,79 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test reload configuration (bug #68442)
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$pidfile = dirname(__FILE__).'/php-fpm.pid';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
pid = $pidfile
|
||||
[unconfined]
|
||||
listen = 127.0.0.1:$port
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
var_dump(strpos(run_request('127.0.0.1', $port), 'pong'));
|
||||
echo "IPv4 ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "IPv4 error\n";
|
||||
}
|
||||
|
||||
$pid=file_get_contents($pidfile);
|
||||
if ($pid) {
|
||||
exec("kill -USR2 $pid");
|
||||
} else {
|
||||
die("PID not found\n");
|
||||
}
|
||||
fpm_display_log($tail, 5);
|
||||
|
||||
try {
|
||||
var_dump(strpos(run_request('127.0.0.1', $port), 'pong'));
|
||||
echo "IPv4 ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "IPv4 error\n";
|
||||
}
|
||||
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
int(%d)
|
||||
IPv4 ok
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: Reloading in progress ...
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: reloading: %s
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: using inherited socket fd=%d, "127.0.0.1:%d"
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
|
||||
[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
|
||||
int(%d)
|
||||
IPv4 ok
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
$pidfile = dirname(__FILE__).'/php-fpm.pid';
|
||||
@unlink($pidfile);
|
||||
?>
|
@ -1,53 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test for log_level in fpm_unix_init_main #68381
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
log_level = warning
|
||||
[unconfined]
|
||||
listen = 127.0.0.1:$port
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
$i = 0;
|
||||
while (($i++ < 60) && !($fp = @fsockopen('127.0.0.1', $port))) {
|
||||
usleep(50000);
|
||||
}
|
||||
if ($fp) {
|
||||
echo "Started\n";
|
||||
fclose($fp);
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
if (!feof($tail)) {
|
||||
echo stream_get_contents($tail);
|
||||
}
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
Started
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,53 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test for pm.start_servers default calculation message being a notice and not a warning #68458
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
log_level = warning
|
||||
[unconfined]
|
||||
listen = 127.0.0.1:$port
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
;pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
$i = 0;
|
||||
while (($i++ < 60) && !($fp = @fsockopen('127.0.0.1', $port))) {
|
||||
usleep(50000);
|
||||
}
|
||||
if ($fp) {
|
||||
echo "Started\n";
|
||||
fclose($fp);
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
if (!feof($tail)) {
|
||||
echo stream_get_contents($tail);
|
||||
}
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
Started
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,89 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test various messages on start, from master and childs
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--XFAIL--
|
||||
randomly intermittently failing all the time in CI,
|
||||
ERROR: unable to read what child say: Bad file descriptor (9)
|
||||
catch_workers_output = yes seems not reliable
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$port1 = 9000+PHP_INT_SIZE;
|
||||
$port2 = 9001+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
log_level = notice
|
||||
[pool1]
|
||||
listen = 127.0.0.1:$port1
|
||||
listen.allowed_clients=127.0.0.1
|
||||
user = foo
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
catch_workers_output = yes
|
||||
[pool2]
|
||||
listen = 127.0.0.1:$port2
|
||||
listen.allowed_clients=xxx
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 1
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
catch_workers_output = yes
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
$i = 0;
|
||||
while (($i++ < 60) && !($fp = @fsockopen('127.0.0.1', $port1))) {
|
||||
usleep(50000);
|
||||
}
|
||||
if ($fp) {
|
||||
echo "Started\n";
|
||||
fclose($fp);
|
||||
}
|
||||
for ($i=0 ; $i<10 ; $i++) {
|
||||
try {
|
||||
run_request('127.0.0.1', $port1);
|
||||
} catch (Exception $e) {
|
||||
echo "Error 1\n";
|
||||
}
|
||||
}
|
||||
try {
|
||||
run_request('127.0.0.1', $port2);
|
||||
} catch (Exception $e) {
|
||||
echo "Error 2\n";
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
fpm_display_log($tail, -1);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
Started
|
||||
Error 2
|
||||
[%s] NOTICE: [pool pool1] pm.start_servers is not set. It's been set to 2.
|
||||
[%s] NOTICE: [pool pool1] 'user' directive is ignored when FPM is not running as root
|
||||
[%s] NOTICE: fpm is running, pid %d
|
||||
[%s] NOTICE: ready to handle connections
|
||||
[%s] WARNING: [pool pool2] child %d said into stderr: "ERROR: Wrong IP address 'xxx' in listen.allowed_clients"
|
||||
[%s] WARNING: [pool pool2] child %d said into stderr: "ERROR: There are no allowed %s"
|
||||
[%s] WARNING: [pool pool2] child %d said into stderr: "ERROR: Connection disallowed: IP address '127.0.0.1' has been dropped."
|
||||
[%s] NOTICE: Terminating ...
|
||||
[%s] NOTICE: exiting, bye-bye!
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,101 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test splited configuration and load order #68391
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = /dev/null
|
||||
[poold_ondemand]
|
||||
listen=127.0.0.1:9000
|
||||
pm = ondemand
|
||||
pm.max_children = 2
|
||||
pm.process_idle_timeout = 10
|
||||
EOT;
|
||||
|
||||
if (test_fpm_conf($cfg, $msg) == false) {
|
||||
die("skip " . $msg);
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = __DIR__.'/php-fpm.log.tmp';
|
||||
$logdir = __DIR__.'/conf.d';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
// Main configuration
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
log_level = notice
|
||||
include = $logdir/*.conf
|
||||
EOT;
|
||||
|
||||
// Splited configuration
|
||||
@mkdir($logdir);
|
||||
$i=$port;
|
||||
$names = ['cccc', 'aaaa', 'eeee', 'dddd', 'bbbb'];
|
||||
foreach($names as $name) {
|
||||
$poolcfg = <<<EOT
|
||||
[$name]
|
||||
listen = 127.0.0.1:$i
|
||||
listen.allowed_clients=127.0.0.1
|
||||
user = foo
|
||||
pm = ondemand
|
||||
pm.max_children = 5
|
||||
EOT;
|
||||
file_put_contents("$logdir/$name.conf", $poolcfg);
|
||||
$i++;
|
||||
}
|
||||
|
||||
// Test
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, count($names)+2);
|
||||
$i=$port;
|
||||
foreach($names as $name) {
|
||||
try {
|
||||
run_request('127.0.0.1', $i++);
|
||||
echo "OK $name\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Error 1\n";
|
||||
}
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
fpm_display_log($tail, -1);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
[%s] NOTICE: [pool aaaa] 'user' directive is ignored when FPM is not running as root
|
||||
[%s] NOTICE: [pool bbbb] 'user' directive is ignored when FPM is not running as root
|
||||
[%s] NOTICE: [pool cccc] 'user' directive is ignored when FPM is not running as root
|
||||
[%s] NOTICE: [pool dddd] 'user' directive is ignored when FPM is not running as root
|
||||
[%s] NOTICE: [pool eeee] 'user' directive is ignored when FPM is not running as root
|
||||
[%s] NOTICE: fpm is running, pid %d
|
||||
[%s] NOTICE: ready to handle connections
|
||||
OK cccc
|
||||
OK aaaa
|
||||
OK eeee
|
||||
OK dddd
|
||||
OK bbbb
|
||||
[%s] NOTICE: Terminating ...
|
||||
[%s] NOTICE: exiting, bye-bye!
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = __DIR__.'/php-fpm.log.tmp';
|
||||
$logdir = __DIR__.'/conf.d';
|
||||
@unlink($logfile);
|
||||
foreach(glob("$logdir/*.conf") as $name) {
|
||||
unlink($name);
|
||||
}
|
||||
@rmdir($logdir);
|
||||
?>
|
@ -1,67 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test fastcgi_finish_request function
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = __DIR__.'/php-fpm.log.tmp';
|
||||
$srcfile = __DIR__.'/php-fpm.tmp.php';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = 127.0.0.1:$port
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 1
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$code = <<<EOT
|
||||
<?php
|
||||
echo "Test Start\n";
|
||||
fastcgi_finish_request();
|
||||
echo "Test End\n";
|
||||
EOT;
|
||||
file_put_contents($srcfile, $code);
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
$req = run_request('127.0.0.1', $port, $srcfile);
|
||||
echo strstr($req, "Test Start");
|
||||
echo "Request ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Request error\n";
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
fpm_display_log($tail, -1);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
[%s] NOTICE: fpm is running, pid %d
|
||||
[%s] NOTICE: ready to handle connections
|
||||
Test Start
|
||||
|
||||
Request ok
|
||||
[%s] NOTICE: Terminating ...
|
||||
[%s] NOTICE: exiting, bye-bye!
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = __DIR__.'/php-fpm.log.tmp';
|
||||
$srcfile = __DIR__.'/php-fpm.tmp.php';
|
||||
@unlink($logfile);
|
||||
@unlink($srcfile);
|
||||
?>
|
@ -1,79 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test global prefix
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = 'php-fpm.log.tmp';
|
||||
$accfile = 'php-fpm.acc.tmp';
|
||||
$slwfile = 'php-fpm.slw.tmp';
|
||||
$pidfile = 'php-fpm.pid.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
pid = $pidfile
|
||||
[test]
|
||||
listen = 127.0.0.1:$port
|
||||
access.log = $accfile
|
||||
slowlog = $slwfile;
|
||||
request_slowlog_timeout = 1
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail, '--prefix '.__DIR__);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
run_request('127.0.0.1', $port);
|
||||
echo "Ping ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Ping error\n";
|
||||
}
|
||||
printf("File %s %s\n", $logfile, (file_exists(__DIR__.'/'.$logfile) ? "exists" : "missing"));
|
||||
printf("File %s %s\n", $accfile, (file_exists(__DIR__.'/'.$accfile) ? "exists" : "missing"));
|
||||
printf("File %s %s\n", $slwfile, (file_exists(__DIR__.'/'.$slwfile) ? "exists" : "missing"));
|
||||
printf("File %s %s\n", $pidfile, (file_exists(__DIR__.'/'.$pidfile) ? "exists" : "missing"));
|
||||
|
||||
proc_terminate($fpm);
|
||||
fpm_display_log($tail, -1);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
printf("File %s %s\n", $pidfile, (file_exists(__DIR__.'/'.$pidfile) ? "still exists" : "removed"));
|
||||
readfile(__DIR__.'/'.$accfile);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%s] NOTICE: fpm is running, pid %d
|
||||
[%s] NOTICE: ready to handle connections
|
||||
Ping ok
|
||||
File php-fpm.log.tmp exists
|
||||
File php-fpm.acc.tmp exists
|
||||
File php-fpm.slw.tmp exists
|
||||
File php-fpm.pid.tmp exists
|
||||
[%s] NOTICE: Terminating ...
|
||||
[%s] NOTICE: exiting, bye-bye!
|
||||
File php-fpm.pid.tmp removed
|
||||
127.0.0.1 - %s "GET /ping" 200
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = __DIR__.'/php-fpm.log.tmp';
|
||||
$accfile = __DIR__.'/php-fpm.acc.tmp';
|
||||
$slwfile = __DIR__.'/php-fpm.slw.tmp';
|
||||
$pidfile = __DIR__.'/php-fpm.pid.tmp';
|
||||
@unlink($logfile);
|
||||
@unlink($accfile);
|
||||
@unlink($slwfile);
|
||||
@unlink($pidfile);
|
||||
?>
|
@ -1,75 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test pool prefix
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$prefix = __DIR__;
|
||||
$logfile = __DIR__.'/php-fpm.log.tmp';
|
||||
$accfile = 'php-fpm.acc.tmp';
|
||||
$slwfile = 'php-fpm.slw.tmp';
|
||||
$pidfile = __DIR__.'/php-fpm.pid.tmp';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
$cfg = <<<EOT
|
||||
|
||||
[global]
|
||||
error_log = $logfile
|
||||
pid = $pidfile
|
||||
[test]
|
||||
prefix = $prefix;
|
||||
listen = 127.0.0.1:$port
|
||||
access.log = $accfile
|
||||
slowlog = $slwfile;
|
||||
request_slowlog_timeout = 1
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
run_request('127.0.0.1', $port);
|
||||
echo "Ping ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Ping error\n";
|
||||
}
|
||||
printf("File %s %s\n", $accfile, (file_exists(__DIR__.'/'.$accfile) ? "exists" : "missing"));
|
||||
printf("File %s %s\n", $slwfile, (file_exists(__DIR__.'/'.$slwfile) ? "exists" : "missing"));
|
||||
|
||||
proc_terminate($fpm);
|
||||
fpm_display_log($tail, -1);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
readfile(__DIR__.'/'.$accfile);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%s] NOTICE: fpm is running, pid %d
|
||||
[%s] NOTICE: ready to handle connections
|
||||
Ping ok
|
||||
File php-fpm.acc.tmp exists
|
||||
File php-fpm.slw.tmp exists
|
||||
[%s] NOTICE: Terminating ...
|
||||
[%s] NOTICE: exiting, bye-bye!
|
||||
127.0.0.1 - %s "GET /ping" 200
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = __DIR__.'/php-fpm.log.tmp';
|
||||
$accfile = __DIR__.'/php-fpm.acc.tmp';
|
||||
$slwfile = __DIR__.'/php-fpm.slw.tmp';
|
||||
$pidfile = __DIR__.'/php-fpm.pid.tmp';
|
||||
@unlink($logfile);
|
||||
@unlink($accfile);
|
||||
@unlink($slwfile);
|
||||
@unlink($pidfile);
|
||||
?>
|
@ -1,102 +0,0 @@
|
||||
--TEST--
|
||||
FPM: Test Unix Domain Socket with Posix ACL
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
if (!(file_exists('/usr/bin/getfacl') && file_exists('/etc/passwd') && file_exists('/etc/group'))) die ("skip missing getfacl command");
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = /dev/null
|
||||
[unconfined]
|
||||
listen = 127.0.0.1:9999
|
||||
listen.acl_users = nobody
|
||||
listen.acl_groups = nobody
|
||||
listen.mode = 0600
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
if (test_fpm_conf($cfg, $msg) == false) { die("skip " . $msg); }
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$socket = dirname(__FILE__).'/php-fpm.sock';
|
||||
|
||||
// Select 3 users and 2 groups known by system (avoid root)
|
||||
$users = $groups = [];
|
||||
$tmp = file('/etc/passwd');
|
||||
for ($i=1 ; $i<=3 ; $i++) {
|
||||
$tab = explode(':', $tmp[$i]);
|
||||
$users[] = $tab[0];
|
||||
}
|
||||
$users = implode(',', $users);
|
||||
$tmp = file('/etc/group');
|
||||
for ($i=1 ; $i<=2 ; $i++) {
|
||||
$tab = explode(':', $tmp[$i]);
|
||||
$groups[] = $tab[0];
|
||||
}
|
||||
$groups = implode(',', $groups);
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = $socket
|
||||
listen.acl_users = $users
|
||||
listen.acl_groups = $groups
|
||||
listen.mode = 0600
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
var_dump(strpos(run_request('unix://'.$socket, -1), 'pong'));
|
||||
echo "UDS ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "UDS error\n";
|
||||
}
|
||||
passthru("/usr/bin/getfacl -cp $socket");
|
||||
|
||||
proc_terminate($fpm);
|
||||
fpm_display_log($tail, -1);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
[%s] NOTICE: fpm is running, pid %d
|
||||
[%s] NOTICE: ready to handle connections
|
||||
int(%d)
|
||||
UDS ok
|
||||
user::rw-
|
||||
user:%s:rw-
|
||||
user:%s:rw-
|
||||
user:%s:rw-
|
||||
group::---
|
||||
group:%s:rw-
|
||||
group:%s:rw-
|
||||
mask::rw-
|
||||
other::---
|
||||
|
||||
[%s] NOTICE: Terminating ...
|
||||
[%s] NOTICE: exiting, bye-bye!
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
@ -1,81 +0,0 @@
|
||||
--TEST--
|
||||
FPM: HTTP_PROXY - CVE-2016-5385
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = __DIR__.'/php-fpm.log.tmp';
|
||||
$srcfile = __DIR__.'/php-fpm.tmp.php';
|
||||
$port = 9000+PHP_INT_SIZE;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[unconfined]
|
||||
listen = 127.0.0.1:$port
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 1
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$code = <<<EOT
|
||||
<?php
|
||||
echo "Test Start\n";
|
||||
var_dump(
|
||||
@\$_SERVER["HTTP_PROXY"],
|
||||
\$_SERVER["HTTP_FOO"],
|
||||
getenv("HTTP_PROXY"),
|
||||
getenv("HTTP_FOO")
|
||||
);
|
||||
echo "Test End\n";
|
||||
EOT;
|
||||
file_put_contents($srcfile, $code);
|
||||
|
||||
$fpm = run_fpm($cfg, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
fpm_display_log($tail, 2);
|
||||
try {
|
||||
$headers = [
|
||||
'HTTP_FOO' => 'BAR',
|
||||
'HTTP_PROXY' => 'BADPROXY',
|
||||
];
|
||||
$req = run_request('127.0.0.1', $port, $srcfile, '', $headers);
|
||||
echo strstr($req, "Test Start");
|
||||
echo "Request ok\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Request error\n";
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
fpm_display_log($tail, -1);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
[%s] NOTICE: fpm is running, pid %d
|
||||
[%s] NOTICE: ready to handle connections
|
||||
Test Start
|
||||
NULL
|
||||
string(3) "BAR"
|
||||
bool(false)
|
||||
string(3) "BAR"
|
||||
Test End
|
||||
|
||||
Request ok
|
||||
[%s] NOTICE: Terminating ...
|
||||
[%s] NOTICE: exiting, bye-bye!
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = __DIR__.'/php-fpm.log.tmp';
|
||||
$srcfile = __DIR__.'/php-fpm.tmp.php';
|
||||
@unlink($logfile);
|
||||
@unlink($srcfile);
|
||||
?>
|
40
sapi/fpm/tests/bug68381-log-level-warning.phpt
Normal file
40
sapi/fpm/tests/bug68381-log-level-warning.phpt
Normal file
@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
FPM: bug68381 - Log messages with warning level only
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
log_level = warning
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->checkConnection();
|
||||
$tester->terminate();
|
||||
$tester->expectNoLogMessages();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
53
sapi/fpm/tests/bug68391-conf-include-order.phpt
Normal file
53
sapi/fpm/tests/bug68391-conf-include-order.phpt
Normal file
@ -0,0 +1,53 @@
|
||||
--TEST--
|
||||
FPM: bug68391 - Configuration inclusion in alphabetical order
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg['main'] = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
log_level = notice
|
||||
include = {{INCLUDE:CONF}}
|
||||
EOT;
|
||||
|
||||
$cfgPoolTemplate = <<<EOT
|
||||
[%name%]
|
||||
listen = {{ADDR[%name%]}}
|
||||
user = foo
|
||||
pm = ondemand
|
||||
pm.max_children = 5
|
||||
EOT;
|
||||
|
||||
$names = ['cccc', 'aaaa', 'eeee', 'dddd', 'bbbb'];
|
||||
foreach($names as $name) {
|
||||
$cfg[$name] = str_replace('%name%', $name, $cfgPoolTemplate);
|
||||
}
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$userMessage = "'user' directive is ignored when FPM is not running as root";
|
||||
$tester->expectLogNotice($userMessage, 'aaaa');
|
||||
$tester->expectLogNotice($userMessage, 'bbbb');
|
||||
$tester->expectLogNotice($userMessage, 'cccc');
|
||||
$tester->expectLogNotice($userMessage, 'dddd');
|
||||
$tester->expectLogNotice($userMessage, 'eeee');
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
42
sapi/fpm/tests/bug68420-ipv4-all-addresses.phpt
Normal file
42
sapi/fpm/tests/bug68420-ipv4-all-addresses.phpt
Normal file
@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
FPM: bug68420 - IPv4 all addresses
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{PORT}}
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->ping('127.0.0.1');
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
47
sapi/fpm/tests/bug68421-ipv6-access-log.phpt
Normal file
47
sapi/fpm/tests/bug68421-ipv6-access-log.phpt
Normal file
@ -0,0 +1,47 @@
|
||||
--TEST--
|
||||
FPM: bug68421 - IPv6 all addresses and access_log
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
FPM\Tester::skipIfIPv6IsNotSupported();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG:ERR}}
|
||||
[unconfined]
|
||||
listen = {{ADDR:IPv6:ANY}}
|
||||
access.log = {{FILE:LOG:ACC}}
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->ping('127.0.0.1');
|
||||
$tester->ping('[::1]');
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
$tester->printAccessLog();
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
127.0.0.1 %s "GET /ping" 200
|
||||
::1 %s "GET /ping" 200
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
55
sapi/fpm/tests/bug68423-multi-pool-all-pms.phpt
Normal file
55
sapi/fpm/tests/bug68423-multi-pool-all-pms.phpt
Normal file
@ -0,0 +1,55 @@
|
||||
--TEST--
|
||||
FPM: bug68423 - Multiple pools with different PMs (dynamic + ondemand + static)
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[pool_dynamic]
|
||||
listen = {{ADDR[dynamic]}}
|
||||
ping.path = /ping
|
||||
ping.response = pong-dynamic
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
[pool_ondemand]
|
||||
listen = {{ADDR[ondemand]}}
|
||||
ping.path = /ping
|
||||
ping.response = pong-on-demand
|
||||
pm = ondemand
|
||||
pm.max_children = 2
|
||||
pm.process_idle_timeout = 10
|
||||
[pool_static]
|
||||
listen = {{ADDR[static]}}
|
||||
ping.path = /ping
|
||||
ping.response = pong-static
|
||||
pm = static
|
||||
pm.max_children = 2
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->ping('{{ADDR[dynamic]}}', 'pong-dynamic');
|
||||
$tester->ping('{{ADDR[ondemand]}}', 'pong-on-demand');
|
||||
$tester->ping('{{ADDR[static]}}', 'pong-static');
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
45
sapi/fpm/tests/bug68428-ipv6-allowed-clients.phpt
Normal file
45
sapi/fpm/tests/bug68428-ipv6-allowed-clients.phpt
Normal file
@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
FPM: bug68428 - IPv6 allowed client only
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
FPM\Tester::skipIfIPv6IsNotSupported();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR:IPv6:ANY}}
|
||||
listen.allowed_clients = ::1
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->checkRequest('127.0.0.1', 'IPv4: ok', 'IPv4: error');
|
||||
$tester->checkRequest('[::1]', 'IPv6: ok', 'IPv6: error');
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
IPv4: error
|
||||
IPv6: ok
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
47
sapi/fpm/tests/bug68442-signal-reload.phpt
Normal file
47
sapi/fpm/tests/bug68442-signal-reload.phpt
Normal file
@ -0,0 +1,47 @@
|
||||
--TEST--
|
||||
FPM: bug68442 - Signal reload
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
pid = {{FILE:PID}}
|
||||
[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 = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->ping('{{ADDR}}');
|
||||
$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--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
42
sapi/fpm/tests/bug68458-pm-no-start-server.phpt
Normal file
42
sapi/fpm/tests/bug68458-pm-no-start-server.phpt
Normal file
@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
FPM: bug68458 - Missing pm.start_servers should emit notice instead of warning
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
log_level = warning
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
;pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->checkConnection();
|
||||
$tester->terminate();
|
||||
$tester->expectNoLogMessages();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
66
sapi/fpm/tests/bug72573-http-proxy.phpt
Normal file
66
sapi/fpm/tests/bug72573-http-proxy.phpt
Normal file
@ -0,0 +1,66 @@
|
||||
--TEST--
|
||||
FPM: bug72573 - HTTP_PROXY - CVE-2016-5385
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 1
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$code = <<<EOT
|
||||
<?php
|
||||
echo "Test Start\n";
|
||||
var_dump(
|
||||
@\$_SERVER["HTTP_PROXY"],
|
||||
\$_SERVER["HTTP_FOO"],
|
||||
getenv("HTTP_PROXY"),
|
||||
getenv("HTTP_FOO")
|
||||
);
|
||||
echo "Test End\n";
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg, $code);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester
|
||||
->request(
|
||||
'',
|
||||
[
|
||||
'HTTP_FOO' => 'BAR',
|
||||
'HTTP_PROXY' => 'BADPROXY',
|
||||
]
|
||||
)
|
||||
->expectBody(
|
||||
[
|
||||
'Test Start',
|
||||
'NULL',
|
||||
'string(3) "BAR"',
|
||||
'bool(false)',
|
||||
'string(3) "BAR"',
|
||||
'Test End'
|
||||
]
|
||||
);
|
||||
$tester->terminate();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
45
sapi/fpm/tests/fastcgi_finish_request_basic.phpt
Normal file
45
sapi/fpm/tests/fastcgi_finish_request_basic.phpt
Normal file
@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
FPM: Function fastcgi_finish_request basic test
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 1
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$code = <<<EOT
|
||||
<?php
|
||||
echo "Test Start\n";
|
||||
fastcgi_finish_request();
|
||||
echo "Test End\n";
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg, $code);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->request()->expectBody("Test Start");
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
@ -72,25 +72,25 @@ class Client
|
||||
|
||||
/**
|
||||
* Socket
|
||||
* @var Resource
|
||||
* @var resource
|
||||
*/
|
||||
private $_sock = null;
|
||||
|
||||
/**
|
||||
* Host
|
||||
* @var String
|
||||
* @var string
|
||||
*/
|
||||
private $_host = null;
|
||||
|
||||
/**
|
||||
* Port
|
||||
* @var Integer
|
||||
* @var int
|
||||
*/
|
||||
private $_port = null;
|
||||
|
||||
/**
|
||||
* Keep Alive
|
||||
* @var Boolean
|
||||
* @var bool
|
||||
*/
|
||||
private $_keepAlive = false;
|
||||
|
||||
@ -110,27 +110,27 @@ class Client
|
||||
|
||||
/**
|
||||
* Use persistent sockets to connect to backend
|
||||
* @var Boolean
|
||||
* @var bool
|
||||
*/
|
||||
private $_persistentSocket = false;
|
||||
|
||||
/**
|
||||
* Connect timeout in milliseconds
|
||||
* @var Integer
|
||||
* @var int
|
||||
*/
|
||||
private $_connectTimeout = 5000;
|
||||
|
||||
/**
|
||||
* Read/Write timeout in milliseconds
|
||||
* @var Integer
|
||||
* @var int
|
||||
*/
|
||||
private $_readWriteTimeout = 5000;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param String $host Host of the FastCGI application
|
||||
* @param Integer $port Port of the FastCGI application
|
||||
* @param string $host Host of the FastCGI application
|
||||
* @param int $port Port of the FastCGI application
|
||||
*/
|
||||
public function __construct($host, $port)
|
||||
{
|
||||
@ -138,15 +138,25 @@ class Client
|
||||
$this->_port = $port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get host.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
return $this->_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define whether or not the FastCGI application should keep the connection
|
||||
* alive at the end of a request
|
||||
*
|
||||
* @param Boolean $b true if the connection should stay alive, false otherwise
|
||||
* @param bool $b true if the connection should stay alive, false otherwise
|
||||
*/
|
||||
public function setKeepAlive($b)
|
||||
{
|
||||
$this->_keepAlive = (boolean)$b;
|
||||
$this->_keepAlive = (bool)$b;
|
||||
if (!$this->_keepAlive && $this->_sock) {
|
||||
fclose($this->_sock);
|
||||
}
|
||||
@ -155,7 +165,7 @@ class Client
|
||||
/**
|
||||
* Get the keep alive status
|
||||
*
|
||||
* @return Boolean true if the connection should stay alive, false otherwise
|
||||
* @return bool true if the connection should stay alive, false otherwise
|
||||
*/
|
||||
public function getKeepAlive()
|
||||
{
|
||||
@ -166,12 +176,12 @@ class Client
|
||||
* Define whether or not PHP should attempt to re-use sockets opened by previous
|
||||
* request for efficiency
|
||||
*
|
||||
* @param Boolean $b true if persistent socket should be used, false otherwise
|
||||
* @param bool $b true if persistent socket should be used, false otherwise
|
||||
*/
|
||||
public function setPersistentSocket($b)
|
||||
{
|
||||
$was_persistent = ($this->_sock && $this->_persistentSocket);
|
||||
$this->_persistentSocket = (boolean)$b;
|
||||
$this->_persistentSocket = (bool)$b;
|
||||
if (!$this->_persistentSocket && $was_persistent) {
|
||||
fclose($this->_sock);
|
||||
}
|
||||
@ -180,7 +190,7 @@ class Client
|
||||
/**
|
||||
* Get the pesistent socket status
|
||||
*
|
||||
* @return Boolean true if the socket should be persistent, false otherwise
|
||||
* @return bool true if the socket should be persistent, false otherwise
|
||||
*/
|
||||
public function getPersistentSocket()
|
||||
{
|
||||
@ -191,7 +201,7 @@ class Client
|
||||
/**
|
||||
* Set the connect timeout
|
||||
*
|
||||
* @param Integer number of milliseconds before connect will timeout
|
||||
* @param int number of milliseconds before connect will timeout
|
||||
*/
|
||||
public function setConnectTimeout($timeoutMs)
|
||||
{
|
||||
@ -201,7 +211,7 @@ class Client
|
||||
/**
|
||||
* Get the connect timeout
|
||||
*
|
||||
* @return Integer number of milliseconds before connect will timeout
|
||||
* @return int number of milliseconds before connect will timeout
|
||||
*/
|
||||
public function getConnectTimeout()
|
||||
{
|
||||
@ -211,7 +221,7 @@ class Client
|
||||
/**
|
||||
* Set the read/write timeout
|
||||
*
|
||||
* @param Integer number of milliseconds before read or write call will timeout
|
||||
* @param int number of milliseconds before read or write call will timeout
|
||||
*/
|
||||
public function setReadWriteTimeout($timeoutMs)
|
||||
{
|
||||
@ -222,7 +232,7 @@ class Client
|
||||
/**
|
||||
* Get the read timeout
|
||||
*
|
||||
* @return Integer number of milliseconds before read will timeout
|
||||
* @return int number of milliseconds before read will timeout
|
||||
*/
|
||||
public function getReadWriteTimeout()
|
||||
{
|
||||
@ -232,14 +242,18 @@ class Client
|
||||
/**
|
||||
* Helper to avoid duplicating milliseconds to secs/usecs in a few places
|
||||
*
|
||||
* @param Integer millisecond timeout
|
||||
* @return Boolean
|
||||
* @param int millisecond timeout
|
||||
* @return bool
|
||||
*/
|
||||
private function set_ms_timeout($timeoutMs) {
|
||||
if (!$this->_sock) {
|
||||
return false;
|
||||
}
|
||||
return stream_set_timeout($this->_sock, floor($timeoutMs / 1000), ($timeoutMs % 1000) * 1000);
|
||||
return stream_set_timeout(
|
||||
$this->_sock,
|
||||
floor($timeoutMs / 1000),
|
||||
($timeoutMs % 1000) * 1000
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -250,9 +264,21 @@ class Client
|
||||
{
|
||||
if (!$this->_sock) {
|
||||
if ($this->_persistentSocket) {
|
||||
$this->_sock = pfsockopen($this->_host, $this->_port, $errno, $errstr, $this->_connectTimeout/1000);
|
||||
$this->_sock = pfsockopen(
|
||||
$this->_host,
|
||||
$this->_port,
|
||||
$errno,
|
||||
$errstr,
|
||||
$this->_connectTimeout/1000
|
||||
);
|
||||
} else {
|
||||
$this->_sock = fsockopen($this->_host, $this->_port, $errno, $errstr, $this->_connectTimeout/1000);
|
||||
$this->_sock = fsockopen(
|
||||
$this->_host,
|
||||
$this->_port,
|
||||
$errno,
|
||||
$errstr,
|
||||
$this->_connectTimeout/1000
|
||||
);
|
||||
}
|
||||
|
||||
if (!$this->_sock) {
|
||||
@ -268,9 +294,10 @@ class Client
|
||||
/**
|
||||
* Build a FastCGI packet
|
||||
*
|
||||
* @param Integer $type Type of the packet
|
||||
* @param String $content Content of the packet
|
||||
* @param Integer $requestId RequestId
|
||||
* @param int $type Type of the packet
|
||||
* @param string $content Content of the packet
|
||||
* @param int $requestId RequestId
|
||||
* @return string
|
||||
*/
|
||||
private function buildPacket($type, $content, $requestId = 1)
|
||||
{
|
||||
@ -289,9 +316,9 @@ class Client
|
||||
/**
|
||||
* Build an FastCGI Name value pair
|
||||
*
|
||||
* @param String $name Name
|
||||
* @param String $value Value
|
||||
* @return String FastCGI Name value pair
|
||||
* @param string $name Name
|
||||
* @param string $value Value
|
||||
* @return string FastCGI Name value pair
|
||||
*/
|
||||
private function buildNvpair($name, $value)
|
||||
{
|
||||
@ -302,14 +329,16 @@ class Client
|
||||
$nvpair = chr($nlen);
|
||||
} else {
|
||||
/* nameLengthB3 & nameLengthB2 & nameLengthB1 & nameLengthB0 */
|
||||
$nvpair = chr(($nlen >> 24) | 0x80) . chr(($nlen >> 16) & 0xFF) . chr(($nlen >> 8) & 0xFF) . chr($nlen & 0xFF);
|
||||
$nvpair = chr(($nlen >> 24) | 0x80) . chr(($nlen >> 16) & 0xFF)
|
||||
. chr(($nlen >> 8) & 0xFF) . chr($nlen & 0xFF);
|
||||
}
|
||||
if ($vlen < 128) {
|
||||
/* valueLengthB0 */
|
||||
$nvpair .= chr($vlen);
|
||||
} else {
|
||||
/* valueLengthB3 & valueLengthB2 & valueLengthB1 & valueLengthB0 */
|
||||
$nvpair .= chr(($vlen >> 24) | 0x80) . chr(($vlen >> 16) & 0xFF) . chr(($vlen >> 8) & 0xFF) . chr($vlen & 0xFF);
|
||||
$nvpair .= chr(($vlen >> 24) | 0x80) . chr(($vlen >> 16) & 0xFF)
|
||||
. chr(($vlen >> 8) & 0xFF) . chr($vlen & 0xFF);
|
||||
}
|
||||
/* nameData & valueData */
|
||||
return $nvpair . $name . $value;
|
||||
@ -318,7 +347,7 @@ class Client
|
||||
/**
|
||||
* Read a set of FastCGI Name value pairs
|
||||
*
|
||||
* @param String $data Data containing the set of FastCGI NVPair
|
||||
* @param string $data Data containing the set of FastCGI NVPair
|
||||
* @return array of NVPair
|
||||
*/
|
||||
private function readNvpair($data, $length = null)
|
||||
@ -357,7 +386,7 @@ class Client
|
||||
/**
|
||||
* Decode a FastCGI Packet
|
||||
*
|
||||
* @param String $data String containing all the packet
|
||||
* @param string $data string containing all the packet
|
||||
* @return array
|
||||
*/
|
||||
private function decodePacketHeader($data)
|
||||
@ -403,6 +432,7 @@ class Client
|
||||
*
|
||||
* @param array $requestedInfo information to retrieve
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getValues(array $requestedInfo)
|
||||
{
|
||||
@ -423,11 +453,14 @@ class Client
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a request to the FastCGI application
|
||||
* Execute a request to the FastCGI application and return response body
|
||||
*
|
||||
* @param array $params Array of parameters
|
||||
* @param String $stdin Content
|
||||
* @return String
|
||||
* @param string $stdin Content
|
||||
* @return string
|
||||
* @throws ForbiddenException
|
||||
* @throws TimedOutException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function request(array $params, $stdin)
|
||||
{
|
||||
@ -435,20 +468,38 @@ class Client
|
||||
return $this->wait_for_response($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a request to the FastCGI application and return request data
|
||||
*
|
||||
* @param array $params Array of parameters
|
||||
* @param string $stdin Content
|
||||
* @return array
|
||||
* @throws ForbiddenException
|
||||
* @throws TimedOutException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function request_data(array $params, $stdin)
|
||||
{
|
||||
$id = $this->async_request($params, $stdin);
|
||||
return $this->wait_for_response_data($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a request to the FastCGI application asyncronously
|
||||
*
|
||||
*
|
||||
* This sends request to application and returns the assigned ID for that request.
|
||||
*
|
||||
* You should keep this id for later use with wait_for_response(). Ids are chosen randomly
|
||||
* rather than seqentially to guard against false-positives when using persistent sockets.
|
||||
* In that case it is possible that a delayed response to a request made by a previous script
|
||||
* invocation comes back on this socket and is mistaken for response to request made with same ID
|
||||
* during this request.
|
||||
* rather than sequentially to guard against false-positives when using persistent sockets.
|
||||
* In that case it is possible that a delayed response to a request made by a previous script
|
||||
* invocation comes back on this socket and is mistaken for response to request made with same
|
||||
* ID during this request.
|
||||
*
|
||||
* @param array $params Array of parameters
|
||||
* @param String $stdin Content
|
||||
* @return Integer
|
||||
* @param string $stdin Content
|
||||
* @return int
|
||||
* @throws TimedOutException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function async_request(array $params, $stdin)
|
||||
{
|
||||
@ -460,10 +511,12 @@ class Client
|
||||
// Using persistent sockets implies you want them keept alive by server!
|
||||
$keepAlive = intval($this->_keepAlive || $this->_persistentSocket);
|
||||
|
||||
$request = $this->buildPacket(self::BEGIN_REQUEST
|
||||
,chr(0) . chr(self::RESPONDER) . chr($keepAlive) . str_repeat(chr(0), 5)
|
||||
,$id
|
||||
);
|
||||
$request = $this->buildPacket(
|
||||
self::BEGIN_REQUEST,
|
||||
chr(0) . chr(self::RESPONDER) . chr($keepAlive)
|
||||
. str_repeat(chr(0), 5),
|
||||
$id
|
||||
);
|
||||
|
||||
$paramsRequest = '';
|
||||
foreach ($params as $key => $value) {
|
||||
@ -494,21 +547,26 @@ class Client
|
||||
|
||||
$this->_requests[$id] = array(
|
||||
'state' => self::REQ_STATE_WRITTEN,
|
||||
'response' => null
|
||||
'response' => null,
|
||||
'err_response' => null,
|
||||
'out_response' => null,
|
||||
);
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocking call that waits for response to specific request
|
||||
*
|
||||
* @param Integer $requestId
|
||||
* @param Integer $timeoutMs [optional] the number of milliseconds to wait. Defaults to the ReadWriteTimeout value set.
|
||||
* @return string response body
|
||||
* Blocking call that waits for response data of the specific request
|
||||
*
|
||||
* @param int $requestId
|
||||
* @param int $timeoutMs [optional] the number of milliseconds to wait.
|
||||
* @return array response data
|
||||
* @throws ForbiddenException
|
||||
* @throws TimedOutException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function wait_for_response($requestId, $timeoutMs = 0) {
|
||||
|
||||
public function wait_for_response_data($requestId, $timeoutMs = 0)
|
||||
{
|
||||
if (!isset($this->_requests[$requestId])) {
|
||||
throw new \Exception('Invalid request id given');
|
||||
}
|
||||
@ -537,6 +595,9 @@ class Client
|
||||
if ($resp['type'] == self::STDOUT || $resp['type'] == self::STDERR) {
|
||||
if ($resp['type'] == self::STDERR) {
|
||||
$this->_requests[$resp['requestId']]['state'] = self::REQ_STATE_ERR;
|
||||
$this->_requests[$resp['requestId']]['err_response'] .= $resp['content'];
|
||||
} else {
|
||||
$this->_requests[$resp['requestId']]['out_response'] .= $resp['content'];
|
||||
}
|
||||
$this->_requests[$resp['requestId']]['response'] .= $resp['content'];
|
||||
}
|
||||
@ -586,7 +647,22 @@ class Client
|
||||
throw new \Exception('Role value not known [UNKNOWN_ROLE]');
|
||||
break;
|
||||
case self::REQUEST_COMPLETE:
|
||||
return $this->_requests[$requestId]['response'];
|
||||
return $this->_requests[$requestId];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocking call that waits for response to specific request
|
||||
*
|
||||
* @param int $requestId
|
||||
* @param int $timeoutMs [optional] the number of milliseconds to wait.
|
||||
* @return string The response content.
|
||||
* @throws ForbiddenException
|
||||
* @throws TimedOutException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function wait_for_response($requestId, $timeoutMs = 0)
|
||||
{
|
||||
return $this->wait_for_response_data($requestId, $timeoutMs)['response'];
|
||||
}
|
||||
}
|
||||
|
@ -1,135 +0,0 @@
|
||||
<?php
|
||||
|
||||
function get_fpm_path() /* {{{ */
|
||||
{
|
||||
$php_path = getenv("TEST_PHP_EXECUTABLE");
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$slash_pos = strrpos($php_path, "/");
|
||||
if ($slash_pos) {
|
||||
$php_path = substr($php_path, 0, $slash_pos);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($php_path && is_dir($php_path)) {
|
||||
if (file_exists($php_path."/fpm/php-fpm") && is_executable($php_path."/fpm/php-fpm")) {
|
||||
/* gotcha */
|
||||
return $php_path."/fpm/php-fpm";
|
||||
}
|
||||
$php_sbin_fpm = $php_path."/sbin/php-fpm";
|
||||
if (file_exists($php_sbin_fpm) && is_executable($php_sbin_fpm)) {
|
||||
return $php_sbin_fpm;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
function run_fpm($config, &$out = false, $extra_args = '') /* {{{ */
|
||||
{
|
||||
$cfg = dirname(__FILE__).'/test-fpm-config.tmp';
|
||||
file_put_contents($cfg, $config);
|
||||
$desc = [];
|
||||
if ($out !== false) {
|
||||
$desc = [1 => array('pipe', 'w')];
|
||||
}
|
||||
/* Since it's not possible to spawn a process under linux without using a
|
||||
* shell in php (why?!?) we need a little shell trickery, so that we can
|
||||
* actually kill php-fpm */
|
||||
$asroot = getenv('TEST_FPM_RUN_AS_ROOT') ? '--allow-to-run-as-root' : '';
|
||||
$cmd = get_fpm_path()." $asroot -F -O -y $cfg $extra_args";
|
||||
$fpm = proc_open("killit () { kill \$child; }; trap killit TERM; $cmd 2>&1 & child=\$!; wait",
|
||||
$desc, $pipes);
|
||||
register_shutdown_function(
|
||||
function($fpm) use($cfg) {
|
||||
@unlink($cfg);
|
||||
if (is_resource($fpm)) {
|
||||
@proc_terminate($fpm);
|
||||
while (proc_get_status($fpm)['running']) {
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
},
|
||||
$fpm
|
||||
);
|
||||
if ($out !== false) {
|
||||
$out = $pipes[1];
|
||||
}
|
||||
return $fpm;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
function test_fpm_conf($config, &$msg = NULL) { /* {{{ */
|
||||
$cfg = dirname(__FILE__).'/test-fpm-config.tmp';
|
||||
file_put_contents($cfg, $config);
|
||||
exec(get_fpm_path() . ' -t -y ' . $cfg . ' 2>&1', $output, $code);
|
||||
if ($code) {
|
||||
$msg = preg_replace("/\[.+?\]/", "", $output[0]);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
function run_fpm_till($needle, $config, $max = 10) /* {{{ */
|
||||
{
|
||||
$i = 0;
|
||||
$fpm = run_fpm($config, $tail);
|
||||
if (is_resource($fpm)) {
|
||||
while($i < $max) {
|
||||
$i++;
|
||||
$line = fgets($tail);
|
||||
if(preg_match($needle, $line) === 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($i >= $max) {
|
||||
$line = false;
|
||||
}
|
||||
proc_terminate($fpm);
|
||||
stream_get_contents($tail);
|
||||
fclose($tail);
|
||||
proc_close($fpm);
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
function fpm_display_log($tail, $n=1, $ignore='systemd') { /* {{{ */
|
||||
/* Read $n lines or until EOF */
|
||||
while ($n>0 || ($n<0 && !feof($tail))) {
|
||||
$a = fgets($tail);
|
||||
if (empty($ignore) || !strpos($a, $ignore)) {
|
||||
echo $a;
|
||||
$n--;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function run_request($host, $port, $uri='/ping', $query='', $headers=array()) { /* {{{ */
|
||||
require_once 'fcgi.inc';
|
||||
$client = new Adoy\FastCGI\Client($host, $port);
|
||||
$params = array_merge(array(
|
||||
'GATEWAY_INTERFACE' => 'FastCGI/1.0',
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'SCRIPT_FILENAME' => $uri,
|
||||
'SCRIPT_NAME' => $uri,
|
||||
'QUERY_STRING' => $query,
|
||||
'REQUEST_URI' => $uri . ($query ? '?'.$query : ""),
|
||||
'DOCUMENT_URI' => $uri,
|
||||
'SERVER_SOFTWARE' => 'php/fcgiclient',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'REMOTE_PORT' => '9985',
|
||||
'SERVER_ADDR' => '127.0.0.1',
|
||||
'SERVER_PORT' => '80',
|
||||
'SERVER_NAME' => php_uname('n'),
|
||||
'SERVER_PROTOCOL' => 'HTTP/1.1',
|
||||
'CONTENT_TYPE' => '',
|
||||
'DOCUMENT_ROOT' => __DIR__,
|
||||
'CONTENT_LENGTH' => 0
|
||||
), $headers);
|
||||
return $client->request($params, false)."\n";
|
||||
}
|
||||
/* }}} */
|
476
sapi/fpm/tests/logtool.inc
Normal file
476
sapi/fpm/tests/logtool.inc
Normal file
@ -0,0 +1,476 @@
|
||||
<?php
|
||||
|
||||
namespace FPM;
|
||||
|
||||
class LogTool
|
||||
{
|
||||
const P_TIME = '\[\d\d-\w\w\w-\d{4} \d\d:\d\d:\d\d\]';
|
||||
const P_PREFIX = '\[pool unconfined\] child \d+ said into stderr: ';
|
||||
const FINAL_SUFFIX = ', pipe is closed';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $message;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $level;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $position;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $suffixPosition;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $limit;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $pattern;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $error;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param int $limit
|
||||
* @param int $repeat
|
||||
*/
|
||||
public function setExpectedMessage(string $message, int $limit, int $repeat = 0)
|
||||
{
|
||||
$this->message = ($repeat > 0) ? str_repeat($message, $repeat) : $message;
|
||||
$this->limit = $limit;
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $level
|
||||
* @return int
|
||||
*/
|
||||
public function setExpectedLevel(string $level)
|
||||
{
|
||||
return $this->level = $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getExpectedLevel(): string
|
||||
{
|
||||
return $this->level ?: 'WARNING';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @return bool
|
||||
*/
|
||||
public function checkTruncatedMessage(string $line)
|
||||
{
|
||||
if ($this->message === null) {
|
||||
throw new \LogicException('The message has not been set');
|
||||
}
|
||||
$lineLen = strlen($line);
|
||||
if (!$this->checkLineLength($line)) {
|
||||
return false;
|
||||
}
|
||||
$this->pattern = '/^PHP message: (.*?)(\.\.\.)?$/';
|
||||
if (preg_match($this->pattern, $line, $matches) === 0) {
|
||||
return $this->error("Unexpected truncated message: {$line}");
|
||||
}
|
||||
|
||||
if ($lineLen === $this->limit) {
|
||||
if (!isset($matches[2])) {
|
||||
return $this->error("The truncated line is not ended with '...'");
|
||||
}
|
||||
if (!$this->checkMessage($matches[1])) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (isset($matches[2])) {
|
||||
// this is expecting that the expected message does not end with '...'
|
||||
// which should not be an issue for the test purpose.
|
||||
return $this->error("The line is complete and should not end with '...'");
|
||||
}
|
||||
if (!$this->checkMessage($matches[1], -1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $lines
|
||||
* @param bool $terminated
|
||||
* @param bool $decorated
|
||||
* @return bool
|
||||
*/
|
||||
public function checkWrappedMessage(array $lines, bool $terminated = true, bool $decorated = true)
|
||||
{
|
||||
if ($this->message === null) {
|
||||
throw new \LogicException('The message has not been set');
|
||||
}
|
||||
if ($decorated) {
|
||||
$this->pattern = sprintf(
|
||||
'/^(%s %s: %s)"([^"]*)"(.*)?$/',
|
||||
self::P_TIME,
|
||||
$this->getExpectedLevel(),
|
||||
self::P_PREFIX
|
||||
);
|
||||
} else {
|
||||
$this->pattern = null;
|
||||
}
|
||||
|
||||
$idx = 0;
|
||||
foreach ($lines as $idx => $line) {
|
||||
if (!$this->checkLine($line)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->suffixPosition > 0) {
|
||||
$suffixPattern = sprintf(
|
||||
'/^%s %s: %s(.*)$/',
|
||||
self::P_TIME, $this->getExpectedLevel(),
|
||||
self::P_PREFIX
|
||||
);
|
||||
$line = $lines[++$idx];
|
||||
if (preg_match($suffixPattern, $line, $matches) === 0) {
|
||||
return $this->error("Unexpected line: $line");
|
||||
}
|
||||
if ($matches[1] !== substr(self::FINAL_SUFFIX, $this->suffixPosition)) {
|
||||
return $this->error(
|
||||
"The suffix has not been finished from position $this->suffixPosition in line: $line"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($terminated) {
|
||||
return $this->expectTerminatorLines($lines, $idx);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @return bool
|
||||
*/
|
||||
private function checkLine(string $line)
|
||||
{
|
||||
if ($this->pattern === null) {
|
||||
// plain (not decorated) output
|
||||
$out = rtrim($line);
|
||||
$finalSuffix = null;
|
||||
} elseif (($res = preg_match($this->pattern, $line, $matches)) > 0) {
|
||||
$out = $matches[2];
|
||||
$finalSuffix = $matches[3] ?? false;
|
||||
} else {
|
||||
return $this->error("Unexpected line: $line");
|
||||
}
|
||||
|
||||
$rem = strlen($this->message) - $this->position;
|
||||
$lineLen = strlen($line);
|
||||
if (!$this->checkLineLength($line, $lineLen)) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->checkMessage($out, $this->position)) {
|
||||
return false;
|
||||
}
|
||||
$outLen = strlen($out);
|
||||
if ($rem > $outLen) { // continuous line
|
||||
if ($lineLen !== $this->limit) {
|
||||
if ($lineLen + ($rem - $outLen) < $this->limit) {
|
||||
return $this->error("Printed less than the message len");
|
||||
}
|
||||
return $this->error(
|
||||
"The continuous line length is $lineLen but it should equal to limit $this->limit"
|
||||
);
|
||||
}
|
||||
$this->position += $outLen;
|
||||
return true;
|
||||
}
|
||||
if ($rem !== $outLen) {
|
||||
return $this->error("Printed more than the message len");
|
||||
}
|
||||
if ($finalSuffix === null || $finalSuffix === "") {
|
||||
return false;
|
||||
}
|
||||
if ($finalSuffix === false) {
|
||||
return $this->error("No final suffix");
|
||||
}
|
||||
if (strpos(self::FINAL_SUFFIX, $finalSuffix) === false) {
|
||||
return $this->error("The final suffix has to be equal to ', pipe is closed'");
|
||||
}
|
||||
if (self::FINAL_SUFFIX !== $finalSuffix) {
|
||||
$this->suffixPosition = strlen($finalSuffix);
|
||||
}
|
||||
// complete final suffix printed
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @param int $lineLen
|
||||
* @return bool
|
||||
*/
|
||||
private function checkLineLength(string $line, $lineLen = null) {
|
||||
$lineLen = $lineLen ?: strlen($line);
|
||||
if ($lineLen > $this->limit) {
|
||||
return $this->error(
|
||||
"The line length is $lineLen which is higher than limit $this->limit"
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $matchedMessage
|
||||
* @param int $expectedMessageStart
|
||||
* @return bool
|
||||
*/
|
||||
private function checkMessage(string $matchedMessage, int $expectedMessageStart = 0)
|
||||
{
|
||||
if ($expectedMessageStart < 0) {
|
||||
$expectedMessage = $this->message;
|
||||
} else {
|
||||
$expectedMessage = substr($this->message, $expectedMessageStart, strlen($matchedMessage));
|
||||
}
|
||||
if ($expectedMessage !== $matchedMessage) {
|
||||
return $this->error(
|
||||
sprintf(
|
||||
"The actual string(%d) does not match expected string(%d):\n",
|
||||
strlen($matchedMessage),
|
||||
strlen($expectedMessage)
|
||||
) .
|
||||
"- EXPECT: '$expectedMessage'\n" .
|
||||
"- ACTUAL: '$matchedMessage'"
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $lines
|
||||
* @return bool
|
||||
*/
|
||||
public function expectStartingLines(array $lines)
|
||||
{
|
||||
if ($this->getError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($lines) < 2) {
|
||||
return $this->error("No starting lines");
|
||||
}
|
||||
|
||||
return (
|
||||
$this->expectNotice($lines[0], 'fpm is running, pid \d+') &&
|
||||
$this->expectNotice($lines[1], 'ready to handle connections')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $lines
|
||||
* @param int $idx
|
||||
* @return bool
|
||||
*/
|
||||
public function expectTerminatorLines(array $lines, int $idx = -1)
|
||||
{
|
||||
if ($this->getError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($lines) - $idx < 3) {
|
||||
return $this->error("No terminating lines");
|
||||
}
|
||||
|
||||
return (
|
||||
$this->expectNotice($lines[++$idx], 'Terminating ...') &&
|
||||
$this->expectNotice($lines[++$idx], 'exiting, bye-bye!')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param string $line
|
||||
* @param string $expectedMessage
|
||||
* @param string|null $pool
|
||||
* @return bool
|
||||
*/
|
||||
public function expectEntry(string $type, string $line, string $expectedMessage, $pool = null)
|
||||
{
|
||||
if ($this->getError()) {
|
||||
return false;
|
||||
}
|
||||
if ($pool !== null) {
|
||||
$expectedMessage = '\[pool ' . $pool . '\] ' . $expectedMessage;
|
||||
}
|
||||
|
||||
$line = rtrim($line);
|
||||
$pattern = sprintf('/^%s %s: %s$/', self::P_TIME, $type, $expectedMessage);
|
||||
|
||||
if (preg_match($pattern, $line, $matches) === 0) {
|
||||
return $this->error(
|
||||
"The $type does not match expected message:\n" .
|
||||
"- PATTERN: $pattern\n" .
|
||||
"- MESSAGE: $line\n" .
|
||||
"- EXPECT: '$expectedMessage'\n" .
|
||||
"- ACTUAL: '" . substr($line, strpos($line, $type) + strlen($type) + 2) . "'"
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @param string $expectedMessage
|
||||
* @param string|null $pool
|
||||
* @return bool
|
||||
*/
|
||||
public function expectDebug(string $line, string $expectedMessage, $pool = null)
|
||||
{
|
||||
return $this->expectEntry('DEBUG', $line, $expectedMessage, $pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @param string $expectedMessage
|
||||
* @param string|null $pool
|
||||
* @return bool
|
||||
*/
|
||||
public function expectNotice(string $line, string $expectedMessage, $pool = null)
|
||||
{
|
||||
return $this->expectEntry('NOTICE', $line, $expectedMessage, $pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @param string $expectedMessage
|
||||
* @param string|null $pool
|
||||
* @return bool
|
||||
*/
|
||||
public function expectWarning(string $line, string $expectedMessage, $pool = null)
|
||||
{
|
||||
return $this->expectEntry('WARNING', $line, $expectedMessage, $pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @param string $expectedMessage
|
||||
* @param string|null $pool
|
||||
* @return bool
|
||||
*/
|
||||
public function expectError(string $line, string $expectedMessage, $pool = null)
|
||||
{
|
||||
return $this->expectEntry('ERROR', $line, $expectedMessage, $pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $line
|
||||
* @param string $expectedMessage
|
||||
* @param string|null $pool
|
||||
* @return bool
|
||||
*/
|
||||
public function expectAlert(string $line, string $expectedMessage, $pool = null)
|
||||
{
|
||||
return $this->expectEntry('ALERT', $line, $expectedMessage, $pool);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $msg
|
||||
* @return bool
|
||||
*/
|
||||
private function error(string $msg)
|
||||
{
|
||||
$this->error = $msg;
|
||||
echo "ERROR: $msg\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($argv[1]) && $argv[1] === 'logtool-selftest') {
|
||||
$cases = [
|
||||
[
|
||||
'limit' => 1050,
|
||||
'lines' => [
|
||||
'[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' .
|
||||
str_repeat('a', 968) . '"',
|
||||
'[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' .
|
||||
str_repeat('a', 968) . '"',
|
||||
'[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' .
|
||||
str_repeat('a', 112) . '", pipe is closed',
|
||||
'[08-Oct-2017 19:53:55] NOTICE: Terminating ...',
|
||||
'[08-Oct-2017 19:53:55] NOTICE: exiting, bye-bye!',
|
||||
],
|
||||
'message' => str_repeat('a', 2048),
|
||||
'type' => 'stdio',
|
||||
],
|
||||
[
|
||||
'limit' => 1050,
|
||||
'lines' => [
|
||||
'[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' .
|
||||
str_repeat('a', 968) . '"',
|
||||
'[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' .
|
||||
str_repeat('a', 968) . '"',
|
||||
'[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: "' .
|
||||
str_repeat('a', 964) . '", pi',
|
||||
'[08-Oct-2017 19:53:50] WARNING: [pool unconfined] child 23183 said into stderr: pe is closed',
|
||||
'[08-Oct-2017 19:53:55] NOTICE: Terminating ...',
|
||||
'[08-Oct-2017 19:53:55] NOTICE: exiting, bye-bye!',
|
||||
],
|
||||
'message' => str_repeat('a', 2900),
|
||||
'type' => 'stdio',
|
||||
],
|
||||
[
|
||||
'limit' => 1024,
|
||||
'line' => '[08-Oct-2017 19:53:50] WARNING: ' . str_repeat('a',989) . '...',
|
||||
'message' => str_repeat('a', 2900),
|
||||
'type' => 'message',
|
||||
],
|
||||
[
|
||||
'limit' => 1024,
|
||||
'line' => '[08-Oct-2017 19:53:50] WARNING: ' . str_repeat('a',20),
|
||||
'message' => str_repeat('a', 20),
|
||||
'type' => 'message',
|
||||
],
|
||||
];
|
||||
foreach ($cases as $case) {
|
||||
printf("Test message with len %d and limit %d: ", strlen($case['message']), $case['limit']);
|
||||
$logTool = new LogTool();
|
||||
$logTool->setExpectedMessage($case['message'], $case['limit']);
|
||||
if ($case['type'] === 'stdio') {
|
||||
$logTool->checkWrappedMessage($case['lines']);
|
||||
} else {
|
||||
$logTool->checkTruncatedMessage($case['line']);
|
||||
}
|
||||
if (!$logTool->getError()) {
|
||||
echo "OK\n";
|
||||
}
|
||||
}
|
||||
echo "Done\n";
|
||||
}
|
50
sapi/fpm/tests/main-global-prefix.phpt
Normal file
50
sapi/fpm/tests/main-global-prefix.phpt
Normal file
@ -0,0 +1,50 @@
|
||||
--TEST--
|
||||
FPM: Main invocation with prefix
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{RFILE:LOG:ERR}}
|
||||
pid = {{RFILE:PID}}
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
access.log = {{RFILE:LOG:ACC}}
|
||||
slowlog = {{RFILE:LOG:SLOW}}
|
||||
request_slowlog_timeout = 1
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$prefix = __DIR__;
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start('--prefix ' . $prefix);
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->expectFile(FPM\Tester::FILE_EXT_LOG_ACC, $prefix);
|
||||
$tester->expectFile(FPM\Tester::FILE_EXT_LOG_ERR, $prefix);
|
||||
$tester->expectFile(FPM\Tester::FILE_EXT_LOG_SLOW, $prefix);
|
||||
$tester->expectFile(FPM\Tester::FILE_EXT_PID, $prefix);
|
||||
$tester->ping();
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
$tester->expectNoFile(FPM\Tester::FILE_EXT_PID, $prefix);
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
@ -5,9 +5,9 @@ FPM: version string
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
require_once "tester.inc";
|
||||
|
||||
$php = get_fpm_path();
|
||||
$php = \FPM\Tester::findExecutable();
|
||||
|
||||
var_dump(`$php -n -v`);
|
||||
|
@ -1,27 +1,32 @@
|
||||
--TEST--
|
||||
FPM: Apparmor Test
|
||||
--DESCRIPTION--
|
||||
This test tries to launches a pool which tries to change to non existing
|
||||
apparmor hat a. Test succeeds if apparmor is not running or hat is non
|
||||
existent.
|
||||
FPM: AppArmor basic test
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
include "skipapparmor.inc";
|
||||
|
||||
$config = <<<EOT
|
||||
[global]
|
||||
error_log = /dev/null
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
apparmor_hat = a
|
||||
EOT;
|
||||
FPM\Tester::skipIfConfigFails($config);
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "include.inc";
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[a]
|
||||
listen = 127.0.0.1:9001
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR:UDS}}
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
@ -30,6 +35,7 @@ pm.max_spare_servers = 3
|
||||
apparmor_hat = a
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
/* libapparmor has a bug which can cause SIGSEGV till Version 2.8.0-0ubuntu28
|
||||
See https://bugs.launchpad.net/apparmor/+bug/1196880
|
||||
Possible outcomes:
|
||||
@ -41,14 +47,17 @@ EOT;
|
||||
- exited with code 70
|
||||
Change to successful; Hat not existent (Process gets killed by apparmor)
|
||||
*/
|
||||
var_dump(run_fpm_till('/(SIGSEGV|failed to query apparmor confinement|failed to change to new confinement|exited with code 70)/', $cfg));
|
||||
$tester->runTill(
|
||||
'/(SIGSEGV|failed to query apparmor confinement|' .
|
||||
'failed to change to new confinement|exited with code 70)/'
|
||||
);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(%d) "%s
|
||||
"
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
@unlink($logfile);
|
||||
?>
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
54
sapi/fpm/tests/pool-prefix.phpt
Normal file
54
sapi/fpm/tests/pool-prefix.phpt
Normal file
@ -0,0 +1,54 @@
|
||||
--TEST--
|
||||
FPM: Pool prefix
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$prefix = __DIR__;
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
pid = {{FILE:PID}}
|
||||
[unconfined]
|
||||
prefix = $prefix
|
||||
listen = {{ADDR}}
|
||||
access.log = {{RFILE:LOG:ACC}}
|
||||
slowlog = {{RFILE:LOG:SLOW}}
|
||||
request_slowlog_timeout = 1
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->ping();
|
||||
$tester->expectFile(FPM\Tester::FILE_EXT_LOG_ACC, $prefix);
|
||||
$tester->expectFile(FPM\Tester::FILE_EXT_LOG_ERR);
|
||||
$tester->expectFile(FPM\Tester::FILE_EXT_LOG_SLOW, $prefix);
|
||||
$tester->expectFile(FPM\Tester::FILE_EXT_PID);
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
$tester->expectNoFile(FPM\Tester::FILE_EXT_PID);
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
45
sapi/fpm/tests/proc-no-start-server.phpt
Normal file
45
sapi/fpm/tests/proc-no-start-server.phpt
Normal file
@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
FPM: Process manager config option pm.start_servers missing
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
;pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogNotice(
|
||||
"pm.start_servers is not set. It's been set to 2.",
|
||||
'unconfined'
|
||||
);
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
46
sapi/fpm/tests/proc-user-ignored.phpt
Normal file
46
sapi/fpm/tests/proc-user-ignored.phpt
Normal file
@ -0,0 +1,46 @@
|
||||
--TEST--
|
||||
FPM: Process user setting ignored when FPM is not running as root
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
user = foo
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogNotice(
|
||||
"'user' directive is ignored when FPM is not running as root",
|
||||
'unconfined'
|
||||
);
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
281
sapi/fpm/tests/response.inc
Normal file
281
sapi/fpm/tests/response.inc
Normal file
@ -0,0 +1,281 @@
|
||||
<?php
|
||||
|
||||
namespace FPM;
|
||||
|
||||
class Response
|
||||
{
|
||||
const HEADER_SEPARATOR = "\r\n\r\n";
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $rawData;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $rawHeaders;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $rawBody;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $headers;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $valid;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $expectInvalid;
|
||||
|
||||
/**
|
||||
* @param string|array|null $data
|
||||
* @param bool $expectInvalid
|
||||
*/
|
||||
public function __construct($data = null, $expectInvalid = false)
|
||||
{
|
||||
if (!is_array($data)) {
|
||||
$data = [
|
||||
'response' => $data,
|
||||
'err_response' => null,
|
||||
'out_response' => $data,
|
||||
];
|
||||
}
|
||||
|
||||
$this->data = $data;
|
||||
$this->expectInvalid = $expectInvalid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $body
|
||||
* @param string $contentType
|
||||
* @return Response
|
||||
*/
|
||||
public function expectBody($body, $contentType = 'text/html')
|
||||
{
|
||||
if ($multiLine = is_array($body)) {
|
||||
$body = implode("\n", $body);
|
||||
}
|
||||
|
||||
if (
|
||||
$this->checkIfValid() &&
|
||||
$this->checkDefaultHeaders($contentType) &&
|
||||
$body !== $this->rawBody
|
||||
) {
|
||||
if ($multiLine) {
|
||||
$this->error(
|
||||
"==> The expected body:\n$body\n" .
|
||||
"==> does not match the actual body:\n$this->rawBody"
|
||||
);
|
||||
} else {
|
||||
$this->error(
|
||||
"The expected body '$body' does not match actual body '$this->rawBody'"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Response
|
||||
*/
|
||||
public function expectEmptyBody()
|
||||
{
|
||||
return $this->expectBody('');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $contentType
|
||||
* @return string|null
|
||||
*/
|
||||
public function getBody($contentType = 'text/html')
|
||||
{
|
||||
if ($this->checkIfValid() && $this->checkDefaultHeaders($contentType)) {
|
||||
return $this->rawBody;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print raw body
|
||||
*/
|
||||
public function dumpBody()
|
||||
{
|
||||
var_dump($this->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Print raw body
|
||||
*/
|
||||
public function printBody()
|
||||
{
|
||||
echo $this->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug response output
|
||||
*/
|
||||
public function debugOutput()
|
||||
{
|
||||
echo "-------------- RESPONSE: --------------\n";
|
||||
echo "OUT:\n";
|
||||
echo $this->data['out_response'];
|
||||
echo "ERR:\n";
|
||||
echo $this->data['err_response'];
|
||||
echo "---------------------------------------\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getErrorData()
|
||||
{
|
||||
return $this->data['err_response'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the response is valid and if not emit error message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkIfValid()
|
||||
{
|
||||
if ($this->isValid()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$this->expectInvalid) {
|
||||
$this->error("The response is invalid: $this->rawData");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $contentType
|
||||
* @return bool
|
||||
*/
|
||||
private function checkDefaultHeaders($contentType)
|
||||
{
|
||||
// check default headers
|
||||
return (
|
||||
$this->checkHeader('X-Powered-By', '|^PHP/7|', true) &&
|
||||
$this->checkHeader('Content-type', '|^' . $contentType . '(;\s?charset=\w+)?|', true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param bool $useRegex
|
||||
* @return bool
|
||||
*/
|
||||
private function checkHeader(string $name, string $value, $useRegex = false)
|
||||
{
|
||||
$lcName = strtolower($name);
|
||||
$headers = $this->getHeaders();
|
||||
if (!isset($headers[$lcName])) {
|
||||
return $this->error("The header $name is not present");
|
||||
}
|
||||
$header = $headers[$lcName];
|
||||
|
||||
if (!$useRegex) {
|
||||
if ($header === $value) {
|
||||
return true;
|
||||
}
|
||||
return $this->error("The header $name value '$header' is not the same as '$value'");
|
||||
}
|
||||
|
||||
if (!preg_match($value, $header)) {
|
||||
return $this->error("The header $name value '$header' does not match RegExp '$value'");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
private function getHeaders()
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_array($this->headers)) {
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
$headerRows = explode("\r\n", $this->rawHeaders);
|
||||
$headers = [];
|
||||
foreach ($headerRows as $headerRow) {
|
||||
$colonPosition = strpos($headerRow, ':');
|
||||
if ($colonPosition === false) {
|
||||
$this->error("Invalid header row (no colon): $headerRow");
|
||||
}
|
||||
$headers[strtolower(substr($headerRow, 0, $colonPosition))] = trim(
|
||||
substr($headerRow, $colonPosition + 1)
|
||||
);
|
||||
}
|
||||
|
||||
return ($this->headers = $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function isValid()
|
||||
{
|
||||
if ($this->valid === null) {
|
||||
$this->processData();
|
||||
}
|
||||
|
||||
return $this->valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process data and set validity and raw data
|
||||
*/
|
||||
private function processData()
|
||||
{
|
||||
$this->rawData = $this->data['out_response'];
|
||||
$this->valid = (
|
||||
!is_null($this->rawData) &&
|
||||
strpos($this->rawData, self::HEADER_SEPARATOR)
|
||||
);
|
||||
if ($this->valid) {
|
||||
list ($this->rawHeaders, $this->rawBody) = array_map(
|
||||
'trim',
|
||||
explode(self::HEADER_SEPARATOR, $this->rawData)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit error message
|
||||
*
|
||||
* @param string $message
|
||||
* @return bool
|
||||
*/
|
||||
private function error($message)
|
||||
{
|
||||
echo "ERROR: $message\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = $logfile
|
||||
[a]
|
||||
listen = 127.0.0.1:9001
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
apparmor_hat = a
|
||||
EOT;
|
||||
|
||||
$fpm = run_fpm($cfg, $out, '-t');
|
||||
$ok = false;
|
||||
if (is_resource($fpm)) {
|
||||
if (strpos(stream_get_contents($out), "test is successful") !== FALSE) {
|
||||
$ok = true;
|
||||
}
|
||||
fclose($out);
|
||||
proc_close($fpm);
|
||||
}
|
||||
if (!$ok) {
|
||||
die("skip No apparmor support built in");
|
||||
}
|
||||
|
||||
?>
|
@ -1,17 +1,15 @@
|
||||
<?php
|
||||
|
||||
// Do not run on Windows
|
||||
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||
die ("skip not for Windows");
|
||||
die("skip not for Windows");
|
||||
}
|
||||
|
||||
|
||||
// Running as root is not allowed without TEST_FPM_RUN_AS_ROOT env
|
||||
if (!getmyuid() && !getenv('TEST_FPM_RUN_AS_ROOT')) {
|
||||
die('Refusing to run as root');
|
||||
die('skip Refusing to run as root');
|
||||
}
|
||||
|
||||
include dirname(__FILE__)."/include.inc";
|
||||
require_once "tester.inc";
|
||||
|
||||
if (!get_fpm_path()) {
|
||||
die("skip FPM not found");
|
||||
}
|
||||
?>
|
||||
if (!FPM\Tester::findExecutable()) {
|
||||
die("skip php-fpm binary not found");
|
||||
}
|
48
sapi/fpm/tests/socket-invalid-allowed-clients.phpt
Normal file
48
sapi/fpm/tests/socket-invalid-allowed-clients.phpt
Normal file
@ -0,0 +1,48 @@
|
||||
--TEST--
|
||||
FPM: Socket for invalid allowed client only
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
listen.allowed_clients = xxx
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 1
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
catch_workers_output = yes
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->checkRequest('127.0.0.1', 'Req: ok', 'Req: error');
|
||||
$tester->terminate();
|
||||
// this is from child when starting
|
||||
$tester->expectLogLine("ERROR: Wrong IP address 'xxx' in listen.allowed_clients");
|
||||
$tester->expectLogLine("ERROR: There are no allowed addresses");
|
||||
// this is from the request
|
||||
$tester->expectLogLine("ERROR: Connection disallowed: IP address '127.0.0.1' has been dropped.");
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Req: error
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
45
sapi/fpm/tests/socket-ipv4-allowed-clients.phpt
Normal file
45
sapi/fpm/tests/socket-ipv4-allowed-clients.phpt
Normal file
@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
FPM: Socket for IPv4 allowed client only
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
FPM\Tester::skipIfIPv6IsNotSupported();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR:IPv6:ANY}}
|
||||
listen.allowed_clients = 127.0.0.1
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->checkRequest('127.0.0.1', 'IPv4: ok', 'IPv4: error');
|
||||
$tester->checkRequest('[::1]', 'IPv6: ok', 'IPv6: error');
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
IPv4: ok
|
||||
IPv6: error
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
37
sapi/fpm/tests/socket-ipv4-basic.phpt
Normal file
37
sapi/fpm/tests/socket-ipv4-basic.phpt
Normal file
@ -0,0 +1,37 @@
|
||||
--TEST--
|
||||
FPM: Socket for IPv4 connection
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR:IPv4}}
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
44
sapi/fpm/tests/socket-ipv6-any.phpt
Normal file
44
sapi/fpm/tests/socket-ipv6-any.phpt
Normal file
@ -0,0 +1,44 @@
|
||||
--TEST--
|
||||
FPM: Socket for IPv6 any address connection
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
FPM\Tester::skipIfIPv6IsNotSupported();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR:IPv6:ANY}}
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->checkConnection('127.0.0.1', 'IPv4: ok');
|
||||
$tester->checkConnection('[::1]', 'IPv6: ok');
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
IPv4: ok
|
||||
IPv6: ok
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
40
sapi/fpm/tests/socket-ipv6-basic.phpt
Normal file
40
sapi/fpm/tests/socket-ipv6-basic.phpt
Normal file
@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
FPM: Socket for IPv6 connection
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
FPM\Tester::skipIfIPv6IsNotSupported();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR:IPv6}}
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
87
sapi/fpm/tests/socket-uds-acl.phpt
Normal file
87
sapi/fpm/tests/socket-uds-acl.phpt
Normal file
@ -0,0 +1,87 @@
|
||||
--TEST--
|
||||
FPM: Unix Domain Socket with Posix ACL
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include "skipif.inc";
|
||||
FPM\Tester::skipIfAnyFileDoesNotExist(['/usr/bin/getfacl', '/etc/passwd', '/etc/group']);
|
||||
$config = <<<EOT
|
||||
[global]
|
||||
error_log = /dev/null
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
listen.acl_users = nobody
|
||||
listen.acl_groups = nobody
|
||||
listen.mode = 0600
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
FPM\Tester::skipIfConfigFails($config);
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
// Select 3 users and 2 groups known by system (avoid root)
|
||||
$users = $groups = [];
|
||||
$tmp = file('/etc/passwd');
|
||||
for ($i=1 ; $i <= 3 ; $i++) {
|
||||
$tab = explode(':', $tmp[$i]);
|
||||
$users[] = $tab[0];
|
||||
}
|
||||
$users = implode(',', $users);
|
||||
$tmp = file('/etc/group');
|
||||
for ($i=1 ; $i <= 2 ; $i++) {
|
||||
$tab = explode(':', $tmp[$i]);
|
||||
$groups[] = $tab[0];
|
||||
}
|
||||
$groups = implode(',', $groups);
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR:UDS}}
|
||||
listen.acl_users = $users
|
||||
listen.acl_groups = $groups
|
||||
listen.mode = 0600
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->ping('{{ADDR:UDS}}');
|
||||
passthru("/usr/bin/getfacl -cp " . $tester->getListen('{{ADDR:UDS}}'));
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
user::rw-
|
||||
user:%s:rw-
|
||||
user:%s:rw-
|
||||
user:%s:rw-
|
||||
group::---
|
||||
group:%s:rw-
|
||||
group:%s:rw-
|
||||
mask::rw-
|
||||
other::---
|
||||
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
40
sapi/fpm/tests/socket-uds-basic.phpt
Normal file
40
sapi/fpm/tests/socket-uds-basic.phpt
Normal file
@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
FPM: Unix Domain Socket connection
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR:UDS}}
|
||||
ping.path = /ping
|
||||
ping.response = pong
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
EOT;
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->ping('{{ADDR:UDS}}');
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
50
sapi/fpm/tests/status-basic.phpt
Normal file
50
sapi/fpm/tests/status-basic.phpt
Normal file
@ -0,0 +1,50 @@
|
||||
--TEST--
|
||||
FPM: Status basic test
|
||||
--SKIPIF--
|
||||
<?php include "skipif.inc"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once "tester.inc";
|
||||
|
||||
$cfg = <<<EOT
|
||||
[global]
|
||||
error_log = {{FILE:LOG}}
|
||||
[unconfined]
|
||||
listen = {{ADDR}}
|
||||
pm = static
|
||||
pm.max_children = 1
|
||||
pm.status_path = /status
|
||||
EOT;
|
||||
|
||||
$expectedStatusData = [
|
||||
'pool' => 'unconfined',
|
||||
'process manager' => 'static',
|
||||
'listen queue' => 0,
|
||||
'max listen queue' => 0,
|
||||
'idle processes' => 0,
|
||||
'active processes' => 1,
|
||||
'total processes' => 1,
|
||||
'max active processes' => 1,
|
||||
'max children reached' => 0,
|
||||
'slow requests' => 0,
|
||||
];
|
||||
|
||||
$tester = new FPM\Tester($cfg);
|
||||
$tester->start();
|
||||
$tester->expectLogStartNotices();
|
||||
$tester->request()->expectEmptyBody();
|
||||
$tester->status($expectedStatusData);
|
||||
$tester->terminate();
|
||||
$tester->expectLogTerminatingNotices();
|
||||
$tester->close();
|
||||
|
||||
?>
|
||||
Done
|
||||
--EXPECT--
|
||||
Done
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "tester.inc";
|
||||
FPM\Tester::clean();
|
||||
?>
|
199
sapi/fpm/tests/status.inc
Normal file
199
sapi/fpm/tests/status.inc
Normal file
@ -0,0 +1,199 @@
|
||||
<?php
|
||||
|
||||
namespace FPM;
|
||||
|
||||
class Status
|
||||
{
|
||||
const HTML_TITLE = 'PHP-FPM Status Page';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $contentTypes = [
|
||||
'plain' => 'text/plain',
|
||||
'html' => 'text/html',
|
||||
'xml' => 'text/xml',
|
||||
'json' => 'application/json',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $defaultFields = [
|
||||
'pool' => '\w+',
|
||||
'process manager' => '(static|dynamic|ondemand)',
|
||||
'start time' => '\d+\/\w{3}\/\d{4}:\d{2}:\d{2}:\d{2}\s[+-]\d{4}',
|
||||
'start since' => '\d+',
|
||||
'accepted conn' => '\d+',
|
||||
'listen queue' => '\d+',
|
||||
'max listen queue' => '\d+',
|
||||
'listen queue len' => '\d+',
|
||||
'idle processes' => '\d+',
|
||||
'active processes' => '\d+',
|
||||
'total processes' => '\d+',
|
||||
'max active processes' => '\d+',
|
||||
'max children reached' => '\d+',
|
||||
'slow requests' => '\d+',
|
||||
];
|
||||
|
||||
/**
|
||||
* Check status page.
|
||||
*
|
||||
* @param Response $response
|
||||
* @param array $fields
|
||||
* @param string $type
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function checkStatus(Response $response, array $fields, string $type)
|
||||
{
|
||||
if (!isset($this->contentTypes[$type])) {
|
||||
throw new \Exception('Invalid content type ' . $type);
|
||||
}
|
||||
|
||||
$body = $response->getBody($this->contentTypes[$type]);
|
||||
if ($body === null) {
|
||||
return;
|
||||
}
|
||||
$method = "checkStatus" . ucfirst($type);
|
||||
|
||||
$this->$method($body, array_merge($this->defaultFields, $fields));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make status check for status page.
|
||||
*
|
||||
* @param string $body
|
||||
* @param array $fields
|
||||
* @param string $rowPattern
|
||||
* @param string $header
|
||||
* @param string $footer
|
||||
* @param null|callable $nameTransformer
|
||||
* @param null|callable $valueTransformer
|
||||
* @param bool $startTimeTimestamp
|
||||
* @param bool $closingName
|
||||
*/
|
||||
private function makeStatusCheck(
|
||||
string $body,
|
||||
array $fields,
|
||||
string $rowPattern,
|
||||
string $header = '',
|
||||
string $footer = '',
|
||||
$nameTransformer = null,
|
||||
$valueTransformer = null,
|
||||
bool $startTimeTimestamp = false,
|
||||
bool $closingName = false
|
||||
) {
|
||||
|
||||
if ($startTimeTimestamp && $fields['start time'][0] === '\\') {
|
||||
$fields['start time'] = '\d+';
|
||||
}
|
||||
$pattern = '|' . $header;
|
||||
foreach ($fields as $name => $value) {
|
||||
if ($nameTransformer) {
|
||||
$name = call_user_func($nameTransformer, $name);
|
||||
}
|
||||
if ($valueTransformer) {
|
||||
$value = call_user_func($valueTransformer, $value);
|
||||
}
|
||||
if ($closingName) {
|
||||
$pattern .= sprintf($rowPattern, $name, $value, $name);
|
||||
} else {
|
||||
$pattern .= sprintf($rowPattern, $name, $value);
|
||||
}
|
||||
}
|
||||
$pattern = rtrim($pattern, $rowPattern[strlen($rowPattern) - 1]);
|
||||
$pattern .= $footer . '|';
|
||||
|
||||
if (!preg_match($pattern, $body)) {
|
||||
echo "ERROR: Expected body does not match pattern\n";
|
||||
echo "BODY:\n";
|
||||
var_dump($body);
|
||||
echo "PATTERN:\n";
|
||||
var_dump($pattern);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check plain status page.
|
||||
*
|
||||
* @param string $body
|
||||
* @param array $fields
|
||||
*/
|
||||
protected function checkStatusPlain(string $body, array $fields)
|
||||
{
|
||||
$this->makeStatusCheck($body, $fields, "%s:\s+%s\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check html status page.
|
||||
*
|
||||
* @param string $body
|
||||
* @param array $fields
|
||||
*/
|
||||
protected function checkStatusHtml(string $body, array $fields)
|
||||
{
|
||||
$header = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " .
|
||||
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" .
|
||||
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" .
|
||||
"<head><title>" . self::HTML_TITLE . "</title></head>\n" .
|
||||
"<body>\n<table>\n";
|
||||
$footer = "\n</table>\n</body></html>";
|
||||
|
||||
$this->makeStatusCheck(
|
||||
$body,
|
||||
$fields,
|
||||
"<tr><th>%s</th><td>%s</td></tr>\n",
|
||||
$header,
|
||||
$footer
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check xml status page.
|
||||
*
|
||||
* @param string $body
|
||||
* @param array $fields
|
||||
*/
|
||||
protected function checkStatusXml(string $body, array $fields)
|
||||
{
|
||||
$this->makeStatusCheck(
|
||||
$body,
|
||||
$fields,
|
||||
"<%s>%s</%s>\n",
|
||||
"<\?xml version=\"1.0\" \?>\n<status>\n",
|
||||
"\n</status>",
|
||||
function ($name) {
|
||||
return str_replace(' ', '-', $name);
|
||||
},
|
||||
null,
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check json status page.
|
||||
*
|
||||
* @param string $body
|
||||
* @param array $fields
|
||||
*/
|
||||
protected function checkStatusJson(string $body, array $fields)
|
||||
{
|
||||
$this->makeStatusCheck(
|
||||
$body,
|
||||
$fields,
|
||||
'"%s":%s,',
|
||||
'{',
|
||||
'}',
|
||||
null,
|
||||
function ($value) {
|
||||
if (is_numeric($value) || $value === '\d+') {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return '"' . $value . '"';
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
1183
sapi/fpm/tests/tester.inc
Normal file
1183
sapi/fpm/tests/tester.inc
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user