mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Use ephemeral port in more server tests
Port the main php_cli_server.inc to use ephemeral ports, thus allowing CLI server tests to be parallelized. A complication here is that we also need to give each test a separate doc root, to avoid index.php files writing over each other. Closes GH-6375.
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
--TEST--
|
||||
Bug #73037 SoapServer reports Bad Request when gzipped, var 0
|
||||
--CONFLICTS--
|
||||
server
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
|
||||
@@ -8,8 +8,6 @@ SOAP customized Content-Type, eg. SwA use case
|
||||
echo "skip sapi/cli/tests/php_cli_server.inc required but not found";
|
||||
}
|
||||
?>
|
||||
--CONFLICTS--
|
||||
server
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ if(!$res) {
|
||||
die("skip could not open cli server script");
|
||||
}
|
||||
?>
|
||||
--CONFLICTS--
|
||||
server
|
||||
--FILE--
|
||||
<?php
|
||||
include __DIR__."/../../../../sapi/cli/tests/php_cli_server.inc";
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
--TEST--
|
||||
Test get_headers() function : test with context
|
||||
--CONFLICTS--
|
||||
server
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
server
|
||||
@@ -7,7 +7,7 @@ include "skipif.inc";
|
||||
--FILE--
|
||||
<?php
|
||||
include "php_cli_server.inc";
|
||||
php_cli_server_start('<?php ?>', null);
|
||||
$doc_root = php_cli_server_start('<?php ?>', null)->docRoot;
|
||||
|
||||
/*
|
||||
* If a Mime Type is added in php_cli_server.c, add it to this array and update
|
||||
@@ -15,32 +15,29 @@ php_cli_server_start('<?php ?>', null);
|
||||
*/
|
||||
$mimetypes = ['html', 'htm', 'svg', 'css', 'js', 'png', 'webm', 'ogv', 'ogg'];
|
||||
|
||||
function test_mimetypes($mimetypes) {
|
||||
foreach ($mimetypes as $mimetype) {
|
||||
$host = PHP_CLI_SERVER_HOSTNAME;
|
||||
$fp = php_cli_server_connect();
|
||||
if (!$fp) die('Connect failed');
|
||||
file_put_contents(__DIR__ . "/foo.{$mimetype}", '');
|
||||
$header = <<<HEADER
|
||||
foreach ($mimetypes as $mimetype) {
|
||||
$host = PHP_CLI_SERVER_HOSTNAME;
|
||||
$fp = php_cli_server_connect();
|
||||
if (!$fp) die('Connect failed');
|
||||
file_put_contents($doc_root . "/foo.{$mimetype}", '');
|
||||
$header = <<<HEADER
|
||||
GET /foo.{$mimetype} HTTP/1.1
|
||||
Host: {$host}
|
||||
|
||||
|
||||
HEADER;
|
||||
if (fwrite($fp, $header)) {
|
||||
while (!feof($fp)) {
|
||||
$text = fgets($fp);
|
||||
if (strncasecmp("Content-type:", $text, 13) == 0) {
|
||||
echo "foo.{$mimetype} => ", $text;
|
||||
}
|
||||
if (fwrite($fp, $header)) {
|
||||
while (!feof($fp)) {
|
||||
$text = fgets($fp);
|
||||
if (strncasecmp("Content-type:", $text, 13) == 0) {
|
||||
echo "foo.{$mimetype} => ", $text;
|
||||
}
|
||||
@unlink(__DIR__ . "/foo.{$mimetype}");
|
||||
fclose($fp);
|
||||
}
|
||||
@unlink($doc_root . "/foo.{$mimetype}");
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
|
||||
test_mimetypes($mimetypes);
|
||||
?>
|
||||
--EXPECT--
|
||||
foo.html => Content-Type: text/html; charset=UTF-8
|
||||
|
||||
@@ -8,7 +8,7 @@ include "skipif.inc";
|
||||
<?php
|
||||
include "php_cli_server.inc";
|
||||
|
||||
$proc_handle = php_cli_server_start(<<<PHP
|
||||
php_cli_server_start(<<<PHP
|
||||
http_response_code(308);
|
||||
PHP
|
||||
);
|
||||
|
||||
@@ -8,7 +8,7 @@ include "skipif.inc";
|
||||
<?php
|
||||
include "php_cli_server.inc";
|
||||
|
||||
$proc_handle = php_cli_server_start(<<<PHP
|
||||
php_cli_server_start(<<<PHP
|
||||
http_response_code(426);
|
||||
PHP
|
||||
);
|
||||
|
||||
@@ -9,13 +9,10 @@ include "skipif.inc";
|
||||
--FILE--
|
||||
<?php
|
||||
include "php_cli_server.inc";
|
||||
file_put_contents(__DIR__ . '/bug68291+test.html', 'Found');
|
||||
php_cli_server_start(NULL, NULL);
|
||||
$docRoot = php_cli_server_start(NULL, NULL)->docRoot;
|
||||
file_put_contents($docRoot . '/bug68291+test.html', 'Found');
|
||||
echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/bug68291+test.html');
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
@unlink(__DIR__ . '/bug68291+test.html');
|
||||
@unlink($docRoot . '/bug68291+test.html');
|
||||
?>
|
||||
--EXPECT--
|
||||
Found
|
||||
|
||||
@@ -17,11 +17,11 @@ foreach (['MKCO', 'MKCOLL', 'M'] as $method) {
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: file_get_contents(http://localhost:8964): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented
|
||||
Warning: file_get_contents(http://localhost:%d): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented
|
||||
in %s on line %d
|
||||
|
||||
Warning: file_get_contents(http://localhost:8964): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented
|
||||
Warning: file_get_contents(http://localhost:%d): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented
|
||||
in %s on line %d
|
||||
|
||||
Warning: file_get_contents(http://localhost:8964): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented
|
||||
Warning: file_get_contents(http://localhost:%d): Failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented
|
||||
in %s on line %d
|
||||
|
||||
@@ -1,22 +1,29 @@
|
||||
<?php
|
||||
define("PHP_CLI_SERVER_HOSTNAME", "localhost");
|
||||
define("PHP_CLI_SERVER_PORT", 8964);
|
||||
define("PHP_CLI_SERVER_ADDRESS", PHP_CLI_SERVER_HOSTNAME.":".PHP_CLI_SERVER_PORT);
|
||||
|
||||
// TODO: Move address/port info in here?
|
||||
class CliServerInfo {
|
||||
public function __construct(
|
||||
public string $docRoot,
|
||||
) {}
|
||||
}
|
||||
|
||||
function php_cli_server_start(
|
||||
?string $code = 'echo "Hello world";',
|
||||
?string $router = 'index.php',
|
||||
array $cmd_args = []
|
||||
) {
|
||||
): CliServerInfo {
|
||||
$php_executable = getenv('TEST_PHP_EXECUTABLE');
|
||||
$doc_root = __DIR__;
|
||||
$error = null;
|
||||
|
||||
// Create dedicated doc root to avoid index.php clashes between tests.
|
||||
$doc_root = __DIR__ . '/' . basename($_SERVER['PHP_SELF'], '.php');
|
||||
@mkdir($doc_root);
|
||||
|
||||
if ($code) {
|
||||
file_put_contents($doc_root . '/' . ($router ?: 'index.php'), '<?php ' . $code . ' ?>');
|
||||
}
|
||||
|
||||
$cmd = [$php_executable, '-t', $doc_root, '-n', ...$cmd_args, '-S', PHP_CLI_SERVER_ADDRESS];
|
||||
$cmd = [$php_executable, '-t', $doc_root, '-n', ...$cmd_args, '-S', 'localhost:0'];
|
||||
if (!is_null($router)) {
|
||||
$cmd[] = $router;
|
||||
}
|
||||
@@ -24,62 +31,58 @@ function php_cli_server_start(
|
||||
$descriptorspec = array(
|
||||
0 => STDIN,
|
||||
1 => STDOUT,
|
||||
2 => array("null"),
|
||||
2 => ['pipe', 'w'],
|
||||
);
|
||||
$handle = proc_open($cmd, $descriptorspec, $pipes, $doc_root, null, array("suppress_errors" => true));
|
||||
|
||||
// note: here we check the process is running
|
||||
for ($i=0; $i < 120; $i++) {
|
||||
// First, wait for the dev server to declare itself ready.
|
||||
$bound = null;
|
||||
stream_set_blocking($pipes[2], false);
|
||||
for ($i = 0; $i < 60; $i++) {
|
||||
usleep(50000); // 50ms per try
|
||||
$status = proc_get_status($handle);
|
||||
|
||||
if (!$status || !$status['running']) {
|
||||
if ($status &&
|
||||
($status['running'] == false && $status['exitcode'] != 0)) {
|
||||
$error =
|
||||
"Server could not be started\n";
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(50000); // 50ms per try
|
||||
continue;
|
||||
if (empty($status['running'])) {
|
||||
echo "Server is not running\n";
|
||||
proc_terminate($handle);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ($status['signaled']) {
|
||||
$error =
|
||||
"Server was terminated with {$status['termsig']}\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if ($status['stopped']) {
|
||||
$error =
|
||||
"Server was stopped with {$status['stopsig']}\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// note: here we check the server is listening, even when the server prints
|
||||
// listening on %s:%d
|
||||
// it may not be ready to accept connections
|
||||
$start = time();
|
||||
|
||||
for ($try = 0; $try < 120; $try++) {
|
||||
$error = @fsockopen(
|
||||
PHP_CLI_SERVER_HOSTNAME, PHP_CLI_SERVER_PORT) ?
|
||||
null :
|
||||
sprintf(
|
||||
"Server is not accepting connections after %d seconds\n",
|
||||
time() - $start);
|
||||
|
||||
if (!$error) {
|
||||
while (($line = fgets($pipes[2])) !== false) {
|
||||
if (preg_match('@PHP \S* Development Server \(https?://(.*?:\d+)\) started@', $line, $matches)) {
|
||||
$bound = $matches[1];
|
||||
// Now that we've identified the listen address, close STDERR.
|
||||
// Otherwise the pipe may clog up with unread log messages.
|
||||
fclose($pipes[2]);
|
||||
break 2;
|
||||
}
|
||||
|
||||
usleep(50000);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if ($bound === null) {
|
||||
echo "Server did not output startup message";
|
||||
proc_terminate($handle);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Now wait for a connection to succeed.
|
||||
// note: even when server prints 'Listening on localhost:8964...Press Ctrl-C to quit.'
|
||||
// it might not be listening yet...need to wait until fsockopen() call returns
|
||||
$error = "Unable to connect to server\n";
|
||||
for ($i=0; $i < 60; $i++) {
|
||||
usleep(50000); // 50ms per try
|
||||
$status = proc_get_status($handle);
|
||||
$fp = @fsockopen("tcp://$bound");
|
||||
// Failure, the server is no longer running
|
||||
if (!($status && $status['running'])) {
|
||||
$error = "Server is not running\n";
|
||||
break;
|
||||
}
|
||||
// Success, Connected to servers
|
||||
if ($fp) {
|
||||
$error = '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
php_cli_server_start_error:
|
||||
if ($error) {
|
||||
echo $error;
|
||||
proc_terminate($handle);
|
||||
@@ -87,14 +90,21 @@ php_cli_server_start_error:
|
||||
}
|
||||
|
||||
register_shutdown_function(
|
||||
function($handle) use($router) {
|
||||
function($handle) use($router, $doc_root) {
|
||||
proc_terminate($handle);
|
||||
@unlink(__DIR__ . "/{$router}");
|
||||
@rmdir($doc_root);
|
||||
},
|
||||
$handle
|
||||
);
|
||||
|
||||
return $handle;
|
||||
// Define the same "constants" we previously did.
|
||||
$port = (int) substr($bound, strrpos($bound, ':') + 1);
|
||||
define("PHP_CLI_SERVER_HOSTNAME", "localhost");
|
||||
define("PHP_CLI_SERVER_PORT", $port);
|
||||
define("PHP_CLI_SERVER_ADDRESS", PHP_CLI_SERVER_HOSTNAME.":".PHP_CLI_SERVER_PORT);
|
||||
|
||||
return new CliServerInfo($doc_root);
|
||||
}
|
||||
|
||||
function php_cli_server_connect() {
|
||||
|
||||
@@ -13,8 +13,8 @@ php_cli_server_start('var_dump($_SERVER["DOCUMENT_ROOT"], $_SERVER["SERVER_SOFTW
|
||||
var_dump(file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS));
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(%d) "string(%d) "%stests"
|
||||
string(%d) "string(%d) "%sphp_cli_server_002"
|
||||
string(%d) "PHP %s Development Server"
|
||||
string(%d) "localhost"
|
||||
string(%d) "8964"
|
||||
string(%d) "%s"
|
||||
"
|
||||
|
||||
@@ -7,8 +7,8 @@ include "skipif.inc";
|
||||
--FILE--
|
||||
<?php
|
||||
include "php_cli_server.inc";
|
||||
php_cli_server_start('print_r($_REQUEST); $_REQUEST["foo"] = "bar"; return FALSE;');
|
||||
$doc_root = __DIR__;
|
||||
$info = php_cli_server_start('print_r($_REQUEST); $_REQUEST["foo"] = "bar"; return FALSE;');
|
||||
$doc_root = $info->docRoot;
|
||||
file_put_contents($doc_root . '/request.php', '<?php print_r($_REQUEST); ?>');
|
||||
|
||||
$host = PHP_CLI_SERVER_HOSTNAME;
|
||||
|
||||
@@ -9,10 +9,9 @@ display_errors=1
|
||||
--FILE--
|
||||
<?php
|
||||
include "php_cli_server.inc";
|
||||
php_cli_server_start('require("syntax_error.php");');
|
||||
$dir = realpath(__DIR__);
|
||||
$doc_root = php_cli_server_start('require("syntax_error.php");')->docRoot;
|
||||
|
||||
file_put_contents($dir . "/syntax_error.php", "<?php non_exists_function(); ?>");
|
||||
file_put_contents($doc_root . "/syntax_error.php", "<?php non_exists_function(); ?>");
|
||||
|
||||
$output = '';
|
||||
$host = PHP_CLI_SERVER_HOSTNAME;
|
||||
@@ -30,7 +29,7 @@ HEADER
|
||||
}
|
||||
}
|
||||
echo $output;
|
||||
@unlink($dir . "/syntax_error.php");
|
||||
@unlink($doc_root . "/syntax_error.php");
|
||||
fclose($fp);
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
php://input is empty when enable_post_data_reading=Off
|
||||
--INI--
|
||||
allow_url_fopen=1
|
||||
--CONFLICTS--
|
||||
server
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include __DIR__."/../../sapi/cli/tests/skipif.inc";
|
||||
|
||||
Reference in New Issue
Block a user