mirror of
https://github.com/php/php-src.git
synced 2025-08-19 17:04:47 +02:00
Merge branch 'PHP-7.1' into PHP-7.2
This commit is contained in:
commit
bc58ba750f
52 changed files with 3379 additions and 1684 deletions
|
@ -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
|
* Socket
|
||||||
* @var Resource
|
* @var resource
|
||||||
*/
|
*/
|
||||||
private $_sock = null;
|
private $_sock = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Host
|
* Host
|
||||||
* @var String
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $_host = null;
|
private $_host = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Port
|
* Port
|
||||||
* @var Integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $_port = null;
|
private $_port = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep Alive
|
* Keep Alive
|
||||||
* @var Boolean
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private $_keepAlive = false;
|
private $_keepAlive = false;
|
||||||
|
|
||||||
|
@ -110,27 +110,27 @@ class Client
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use persistent sockets to connect to backend
|
* Use persistent sockets to connect to backend
|
||||||
* @var Boolean
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private $_persistentSocket = false;
|
private $_persistentSocket = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect timeout in milliseconds
|
* Connect timeout in milliseconds
|
||||||
* @var Integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $_connectTimeout = 5000;
|
private $_connectTimeout = 5000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read/Write timeout in milliseconds
|
* Read/Write timeout in milliseconds
|
||||||
* @var Integer
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $_readWriteTimeout = 5000;
|
private $_readWriteTimeout = 5000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param String $host Host of the FastCGI application
|
* @param string $host Host of the FastCGI application
|
||||||
* @param Integer $port Port of the FastCGI application
|
* @param int $port Port of the FastCGI application
|
||||||
*/
|
*/
|
||||||
public function __construct($host, $port)
|
public function __construct($host, $port)
|
||||||
{
|
{
|
||||||
|
@ -138,15 +138,25 @@ class Client
|
||||||
$this->_port = $port;
|
$this->_port = $port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get host.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getHost()
|
||||||
|
{
|
||||||
|
return $this->_host;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define whether or not the FastCGI application should keep the connection
|
* Define whether or not the FastCGI application should keep the connection
|
||||||
* alive at the end of a request
|
* 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)
|
public function setKeepAlive($b)
|
||||||
{
|
{
|
||||||
$this->_keepAlive = (boolean)$b;
|
$this->_keepAlive = (bool)$b;
|
||||||
if (!$this->_keepAlive && $this->_sock) {
|
if (!$this->_keepAlive && $this->_sock) {
|
||||||
fclose($this->_sock);
|
fclose($this->_sock);
|
||||||
}
|
}
|
||||||
|
@ -155,7 +165,7 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Get the keep alive status
|
* 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()
|
public function getKeepAlive()
|
||||||
{
|
{
|
||||||
|
@ -166,12 +176,12 @@ class Client
|
||||||
* Define whether or not PHP should attempt to re-use sockets opened by previous
|
* Define whether or not PHP should attempt to re-use sockets opened by previous
|
||||||
* request for efficiency
|
* 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)
|
public function setPersistentSocket($b)
|
||||||
{
|
{
|
||||||
$was_persistent = ($this->_sock && $this->_persistentSocket);
|
$was_persistent = ($this->_sock && $this->_persistentSocket);
|
||||||
$this->_persistentSocket = (boolean)$b;
|
$this->_persistentSocket = (bool)$b;
|
||||||
if (!$this->_persistentSocket && $was_persistent) {
|
if (!$this->_persistentSocket && $was_persistent) {
|
||||||
fclose($this->_sock);
|
fclose($this->_sock);
|
||||||
}
|
}
|
||||||
|
@ -180,7 +190,7 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Get the pesistent socket status
|
* 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()
|
public function getPersistentSocket()
|
||||||
{
|
{
|
||||||
|
@ -191,7 +201,7 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Set the connect timeout
|
* 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)
|
public function setConnectTimeout($timeoutMs)
|
||||||
{
|
{
|
||||||
|
@ -201,7 +211,7 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Get the connect timeout
|
* 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()
|
public function getConnectTimeout()
|
||||||
{
|
{
|
||||||
|
@ -211,7 +221,7 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Set the read/write timeout
|
* 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)
|
public function setReadWriteTimeout($timeoutMs)
|
||||||
{
|
{
|
||||||
|
@ -222,7 +232,7 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Get the read timeout
|
* 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()
|
public function getReadWriteTimeout()
|
||||||
{
|
{
|
||||||
|
@ -232,14 +242,18 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Helper to avoid duplicating milliseconds to secs/usecs in a few places
|
* Helper to avoid duplicating milliseconds to secs/usecs in a few places
|
||||||
*
|
*
|
||||||
* @param Integer millisecond timeout
|
* @param int millisecond timeout
|
||||||
* @return Boolean
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function set_ms_timeout($timeoutMs) {
|
private function set_ms_timeout($timeoutMs) {
|
||||||
if (!$this->_sock) {
|
if (!$this->_sock) {
|
||||||
return false;
|
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->_sock) {
|
||||||
if ($this->_persistentSocket) {
|
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 {
|
} 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) {
|
if (!$this->_sock) {
|
||||||
|
@ -268,9 +294,10 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Build a FastCGI packet
|
* Build a FastCGI packet
|
||||||
*
|
*
|
||||||
* @param Integer $type Type of the packet
|
* @param int $type Type of the packet
|
||||||
* @param String $content Content of the packet
|
* @param string $content Content of the packet
|
||||||
* @param Integer $requestId RequestId
|
* @param int $requestId RequestId
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function buildPacket($type, $content, $requestId = 1)
|
private function buildPacket($type, $content, $requestId = 1)
|
||||||
{
|
{
|
||||||
|
@ -289,9 +316,9 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Build an FastCGI Name value pair
|
* Build an FastCGI Name value pair
|
||||||
*
|
*
|
||||||
* @param String $name Name
|
* @param string $name Name
|
||||||
* @param String $value Value
|
* @param string $value Value
|
||||||
* @return String FastCGI Name value pair
|
* @return string FastCGI Name value pair
|
||||||
*/
|
*/
|
||||||
private function buildNvpair($name, $value)
|
private function buildNvpair($name, $value)
|
||||||
{
|
{
|
||||||
|
@ -302,14 +329,16 @@ class Client
|
||||||
$nvpair = chr($nlen);
|
$nvpair = chr($nlen);
|
||||||
} else {
|
} else {
|
||||||
/* nameLengthB3 & nameLengthB2 & nameLengthB1 & nameLengthB0 */
|
/* 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) {
|
if ($vlen < 128) {
|
||||||
/* valueLengthB0 */
|
/* valueLengthB0 */
|
||||||
$nvpair .= chr($vlen);
|
$nvpair .= chr($vlen);
|
||||||
} else {
|
} else {
|
||||||
/* valueLengthB3 & valueLengthB2 & valueLengthB1 & valueLengthB0 */
|
/* 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 */
|
/* nameData & valueData */
|
||||||
return $nvpair . $name . $value;
|
return $nvpair . $name . $value;
|
||||||
|
@ -318,7 +347,7 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Read a set of FastCGI Name value pairs
|
* 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
|
* @return array of NVPair
|
||||||
*/
|
*/
|
||||||
private function readNvpair($data, $length = null)
|
private function readNvpair($data, $length = null)
|
||||||
|
@ -357,7 +386,7 @@ class Client
|
||||||
/**
|
/**
|
||||||
* Decode a FastCGI Packet
|
* Decode a FastCGI Packet
|
||||||
*
|
*
|
||||||
* @param String $data String containing all the packet
|
* @param string $data string containing all the packet
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function decodePacketHeader($data)
|
private function decodePacketHeader($data)
|
||||||
|
@ -403,6 +432,7 @@ class Client
|
||||||
*
|
*
|
||||||
* @param array $requestedInfo information to retrieve
|
* @param array $requestedInfo information to retrieve
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function getValues(array $requestedInfo)
|
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 array $params Array of parameters
|
||||||
* @param String $stdin Content
|
* @param string $stdin Content
|
||||||
* @return String
|
* @return string
|
||||||
|
* @throws ForbiddenException
|
||||||
|
* @throws TimedOutException
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function request(array $params, $stdin)
|
public function request(array $params, $stdin)
|
||||||
{
|
{
|
||||||
|
@ -435,20 +468,38 @@ class Client
|
||||||
return $this->wait_for_response($id);
|
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
|
* Execute a request to the FastCGI application asyncronously
|
||||||
*
|
*
|
||||||
* This sends request to application and returns the assigned ID for that request.
|
* 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
|
* 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.
|
* 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
|
* 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
|
* invocation comes back on this socket and is mistaken for response to request made with same
|
||||||
* during this request.
|
* ID during this request.
|
||||||
*
|
*
|
||||||
* @param array $params Array of parameters
|
* @param array $params Array of parameters
|
||||||
* @param String $stdin Content
|
* @param string $stdin Content
|
||||||
* @return Integer
|
* @return int
|
||||||
|
* @throws TimedOutException
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function async_request(array $params, $stdin)
|
public function async_request(array $params, $stdin)
|
||||||
{
|
{
|
||||||
|
@ -460,10 +511,12 @@ class Client
|
||||||
// Using persistent sockets implies you want them keept alive by server!
|
// Using persistent sockets implies you want them keept alive by server!
|
||||||
$keepAlive = intval($this->_keepAlive || $this->_persistentSocket);
|
$keepAlive = intval($this->_keepAlive || $this->_persistentSocket);
|
||||||
|
|
||||||
$request = $this->buildPacket(self::BEGIN_REQUEST
|
$request = $this->buildPacket(
|
||||||
,chr(0) . chr(self::RESPONDER) . chr($keepAlive) . str_repeat(chr(0), 5)
|
self::BEGIN_REQUEST,
|
||||||
,$id
|
chr(0) . chr(self::RESPONDER) . chr($keepAlive)
|
||||||
);
|
. str_repeat(chr(0), 5),
|
||||||
|
$id
|
||||||
|
);
|
||||||
|
|
||||||
$paramsRequest = '';
|
$paramsRequest = '';
|
||||||
foreach ($params as $key => $value) {
|
foreach ($params as $key => $value) {
|
||||||
|
@ -494,21 +547,26 @@ class Client
|
||||||
|
|
||||||
$this->_requests[$id] = array(
|
$this->_requests[$id] = array(
|
||||||
'state' => self::REQ_STATE_WRITTEN,
|
'state' => self::REQ_STATE_WRITTEN,
|
||||||
'response' => null
|
'response' => null,
|
||||||
|
'err_response' => null,
|
||||||
|
'out_response' => null,
|
||||||
);
|
);
|
||||||
|
|
||||||
return $id;
|
return $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blocking call that waits for response to specific request
|
* Blocking call that waits for response data of the specific request
|
||||||
*
|
*
|
||||||
* @param Integer $requestId
|
* @param int $requestId
|
||||||
* @param Integer $timeoutMs [optional] the number of milliseconds to wait. Defaults to the ReadWriteTimeout value set.
|
* @param int $timeoutMs [optional] the number of milliseconds to wait.
|
||||||
* @return string response body
|
* @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])) {
|
if (!isset($this->_requests[$requestId])) {
|
||||||
throw new \Exception('Invalid request id given');
|
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::STDOUT || $resp['type'] == self::STDERR) {
|
||||||
if ($resp['type'] == self::STDERR) {
|
if ($resp['type'] == self::STDERR) {
|
||||||
$this->_requests[$resp['requestId']]['state'] = self::REQ_STATE_ERR;
|
$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'];
|
$this->_requests[$resp['requestId']]['response'] .= $resp['content'];
|
||||||
}
|
}
|
||||||
|
@ -586,7 +647,22 @@ class Client
|
||||||
throw new \Exception('Role value not known [UNKNOWN_ROLE]');
|
throw new \Exception('Role value not known [UNKNOWN_ROLE]');
|
||||||
break;
|
break;
|
||||||
case self::REQUEST_COMPLETE:
|
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--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
include "include.inc";
|
require_once "tester.inc";
|
||||||
|
|
||||||
$php = get_fpm_path();
|
$php = \FPM\Tester::findExecutable();
|
||||||
|
|
||||||
var_dump(`$php -n -v`);
|
var_dump(`$php -n -v`);
|
||||||
|
|
|
@ -1,27 +1,32 @@
|
||||||
--TEST--
|
--TEST--
|
||||||
FPM: Apparmor Test
|
FPM: AppArmor basic 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.
|
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php
|
||||||
include "skipif.inc";
|
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--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
include "include.inc";
|
require_once "tester.inc";
|
||||||
|
|
||||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
|
||||||
|
|
||||||
$cfg = <<<EOT
|
$cfg = <<<EOT
|
||||||
[global]
|
[global]
|
||||||
error_log = $logfile
|
error_log = {{FILE:LOG}}
|
||||||
[a]
|
[unconfined]
|
||||||
listen = 127.0.0.1:9001
|
listen = {{ADDR:UDS}}
|
||||||
pm = dynamic
|
pm = dynamic
|
||||||
pm.max_children = 5
|
pm.max_children = 5
|
||||||
pm.start_servers = 2
|
pm.start_servers = 2
|
||||||
|
@ -30,6 +35,7 @@ pm.max_spare_servers = 3
|
||||||
apparmor_hat = a
|
apparmor_hat = a
|
||||||
EOT;
|
EOT;
|
||||||
|
|
||||||
|
$tester = new FPM\Tester($cfg);
|
||||||
/* libapparmor has a bug which can cause SIGSEGV till Version 2.8.0-0ubuntu28
|
/* libapparmor has a bug which can cause SIGSEGV till Version 2.8.0-0ubuntu28
|
||||||
See https://bugs.launchpad.net/apparmor/+bug/1196880
|
See https://bugs.launchpad.net/apparmor/+bug/1196880
|
||||||
Possible outcomes:
|
Possible outcomes:
|
||||||
|
@ -41,14 +47,17 @@ EOT;
|
||||||
- exited with code 70
|
- exited with code 70
|
||||||
Change to successful; Hat not existent (Process gets killed by apparmor)
|
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--
|
Done
|
||||||
string(%d) "%s
|
--EXPECT--
|
||||||
"
|
Done
|
||||||
--CLEAN--
|
--CLEAN--
|
||||||
<?php
|
<?php
|
||||||
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
|
require_once "tester.inc";
|
||||||
@unlink($logfile);
|
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
|
<?php
|
||||||
|
// Do not run on Windows
|
||||||
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
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')) {
|
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()) {
|
if (!FPM\Tester::findExecutable()) {
|
||||||
die("skip FPM not found");
|
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…
Add table
Add a link
Reference in a new issue