Skip to content

Commit f95f8a3

Browse files
committed
Add simple Firebird payload fake server to test suite
This is meant to test against certain fixed responses of Firebird servers. For now we add just a most basic test which verifies a connection attempt. Closes GH-6940.
1 parent 178bbe3 commit f95f8a3

File tree

4 files changed

+127
-0
lines changed

4 files changed

+127
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
function run_server(string $payloadFile): string {
4+
$cmd = [getenv("TEST_PHP_EXECUTABLE"), "-n", __DIR__ . "/payload_server.php", $payloadFile];
5+
$descriptorspec = array(
6+
0 => STDIN,
7+
1 => STDOUT,
8+
2 => ['pipe', 'w'],
9+
);
10+
$proc = proc_open($cmd, $descriptorspec, $pipes);
11+
12+
// First, wait for the payload server to declare itself ready.
13+
$bound = null;
14+
stream_set_blocking($pipes[2], false);
15+
for ($i = 0; $i < 60; $i++) {
16+
usleep(50000); // 50ms per try
17+
$status = proc_get_status($proc);
18+
if (empty($status['running'])) {
19+
echo "Server is not running\n";
20+
proc_terminate($proc);
21+
exit(1);
22+
}
23+
while (($line = fgets($pipes[2])) !== false) {
24+
if (preg_match('/FB payload server listening on (.+)/', $line, $matches)) {
25+
$bound = $matches[1];
26+
// Now that we've identified the listen address, close STDERR.
27+
// Otherwise the pipe may clog up with unread log messages.
28+
fclose($pipes[2]);
29+
break 2;
30+
}
31+
}
32+
}
33+
34+
if ($bound === null) {
35+
echo "Server did not output startup message";
36+
proc_terminate($proc);
37+
exit(1);
38+
}
39+
40+
// Now wait for a connection to succeed.
41+
// note: even when server prints 'FB payload server listening on localhost:12345'
42+
// it might not be listening yet...need to wait until fsockopen() call returns
43+
$error = "Unable to connect to server\n";
44+
for ($i=0; $i < 60; $i++) {
45+
usleep(50000); // 50ms per try
46+
$status = proc_get_status($proc);
47+
$fp = fsockopen("tcp://$bound");
48+
// Failure, the server is no longer running
49+
if (!($status && $status['running'])) {
50+
$error = "Server is not running\n";
51+
break;
52+
}
53+
// Success, Connected to servers
54+
if ($fp) {
55+
$error = '';
56+
break;
57+
}
58+
}
59+
60+
if ($fp) {
61+
fclose($fp);
62+
}
63+
64+
if ($error) {
65+
echo $error;
66+
proc_terminate($proc);
67+
exit(1);
68+
}
69+
70+
register_shutdown_function(
71+
function($proc) {
72+
proc_terminate($proc);
73+
/* Wait for server to shutdown */
74+
for ($i = 0; $i < 60; $i++) {
75+
$status = proc_get_status($proc);
76+
if (!($status && $status['running'])) {
77+
break;
78+
}
79+
usleep(50000);
80+
}
81+
},
82+
$proc
83+
);
84+
85+
return $bound;
86+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
$socket = stream_socket_server("tcp://localhost:0", $errno, $errstr);
4+
if (!$socket) {
5+
echo "Can't start server: $errstr ($errno)\n";
6+
exit(1);
7+
}
8+
9+
$filename = $argv[1];
10+
$payload = file_get_contents($filename);
11+
if ($payload === false) {
12+
echo "Can't read $filename\n";
13+
exit(1);
14+
}
15+
16+
fputs(STDERR, "FB payload server listening on " . stream_socket_get_name($socket, false) . "\n");
17+
18+
while ($conn = stream_socket_accept($socket)) {
19+
fwrite($conn, $payload);
20+
}
424 Bytes
Binary file not shown.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
FB payload server satisfies connection attempt
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('pdo_firebird')) die("skip pdo_firebird extension not available");
6+
if (!extension_loaded('sockets')) die("skip sockets extension not available");
7+
?>
8+
--FILE--
9+
<?php
10+
require_once "payload_server.inc";
11+
12+
$address = run_server(__DIR__ . "/payload_test.data");
13+
14+
// no need to change the credentials; we're running against a fake server
15+
$dsn = "firebird:dbname=inet://$address/test";
16+
$username = 'SYSDBA';
17+
$password = 'masterkey';
18+
19+
new PDO($dsn, $username, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
20+
?>
21+
--EXPECT--

0 commit comments

Comments
 (0)