Skip to content

Commit 99755dd

Browse files
committed
Split server.php test functionality out
Now a helper class that better encapuslates things and prepares for its use in other tests.
1 parent e73f8cf commit 99755dd

File tree

2 files changed

+161
-111
lines changed

2 files changed

+161
-111
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<?php
2+
3+
namespace Wrench\Tests;
4+
5+
/**
6+
* In conjunction with server.php, provides a listening server
7+
* against which tests can be run.
8+
*/
9+
class ServerTestHelper
10+
{
11+
const TEST_SERVER_PORT_MIN = 16666;
12+
const TEST_SERVER_PORT_MAX = 52222;
13+
14+
public static $nextPort = null;
15+
16+
protected $port = null;
17+
protected $process = null;
18+
protected $pipes = array();
19+
20+
/**
21+
* Gets the next available port number to start a server on
22+
*/
23+
public static function getNextPort()
24+
{
25+
if (self::$nextPort === null) {
26+
self::$nextPort = mt_rand(self::TEST_SERVER_PORT_MIN, self::TEST_SERVER_PORT_MAX);
27+
}
28+
return self::$nextPort++;
29+
}
30+
31+
/**
32+
* Destructor
33+
*/
34+
public function __destruct()
35+
{
36+
$this->tearDown();
37+
}
38+
39+
/**
40+
* @return string
41+
*/
42+
public function getConnectionString()
43+
{
44+
return 'ws://localhost:' . $this->port;
45+
}
46+
47+
/**
48+
* @return string
49+
*/
50+
public function getEchoConnectionString()
51+
{
52+
return $this->getConnectionString() . '/echo';
53+
}
54+
55+
/**
56+
* Sets up the server process and sleeps for a few seconds while
57+
* it wakes up
58+
*/
59+
public function setUp()
60+
{
61+
$this->port = self::getNextPort();
62+
63+
$this->process = proc_open(
64+
$this->getCommand(),
65+
array(
66+
0 => array('file', '/dev/null', 'r'),
67+
1 => array('file', __DIR__ . '/../../../build/server.log', 'a+'),
68+
2 => array('file', __DIR__ . '/../../../build/server.err.log', 'a+')
69+
),
70+
$this->pipes,
71+
__DIR__ . '../'
72+
);
73+
74+
sleep(3);
75+
}
76+
77+
/**
78+
* Tears down the server process
79+
*
80+
* This method *must* be called
81+
*/
82+
public function tearDown()
83+
{
84+
if ($this->process) {
85+
foreach ($this->pipes as &$pipe) {
86+
fclose($pipe);
87+
}
88+
$this->pipes = null;
89+
90+
// Sigh
91+
$status = proc_get_status($this->process);
92+
93+
if ($status && isset($status['pid']) && $status['pid']) {
94+
// More sigh, this is the pid of the parent sh process, we want
95+
// to terminate the server directly
96+
$this->log('Command: /bin/ps -ao pid,ppid | /usr/bin/col | /usr/bin/tail -n +2 | /bin/grep \' ' . $status['pid'] . "'", 'info');
97+
exec('/bin/ps -ao pid,ppid | /usr/bin/col | /usr/bin/tail -n +2 | /bin/grep \' ' . $status['pid'] . "'", $processes, $return);
98+
99+
if ($return === 0) {
100+
foreach ($processes as $process) {
101+
list($pid, $ppid) = explode(' ', str_replace(' ', ' ', $process));
102+
if ($pid) {
103+
$this->log('Killing ' . $pid, 'info');
104+
exec('/bin/kill ' . $pid . ' > /dev/null 2>&1');
105+
}
106+
}
107+
} else {
108+
$this->log('Unable to find child processes', 'warning');
109+
}
110+
111+
sleep(1);
112+
113+
$this->log('Killing ' . $status['pid'], 'info');
114+
exec('/bin/kill ' . $status['pid'] . ' > /dev/null 2>&1');
115+
116+
sleep(1);
117+
}
118+
119+
proc_close($this->process);
120+
$this->process = null;
121+
}
122+
}
123+
124+
/**
125+
* Gets the server command
126+
*
127+
* @return string
128+
*/
129+
protected function getCommand()
130+
{
131+
return sprintf('/usr/bin/env php %s/server.php %d', __DIR__, $this->port);
132+
}
133+
134+
/**
135+
* Logs a message
136+
*
137+
* @param string $message
138+
* @param string $priority
139+
*/
140+
public function log($message, $priority = 'info')
141+
{
142+
//echo $message . "\n";
143+
}
144+
}

lib/Wrench/Tests/Socket/ClientSocketTest.php

Lines changed: 17 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,12 @@
44

55
use Wrench\Protocol\Rfc6455Protocol;
66
use Wrench\Socket\ClientSocket;
7+
use Wrench\Tests\ServerTestHelper;
78
use \Exception;
89
use \stdClass;
910

1011
class ClientSocketTest extends UriSocketTest
1112
{
12-
const TEST_SERVER_PORT_MIN = 16666;
13-
const TEST_SERVER_PORT_MAX = 52222;
14-
15-
public static $nextPort = null;
16-
17-
protected $port = null;
18-
protected $process = null;
19-
protected $pipes = array();
20-
21-
/**
22-
* Gets the next available port number to start a server on
23-
*/
24-
public static function getNextPort()
25-
{
26-
if (self::$nextPort === null) {
27-
self::$nextPort = mt_rand(self::TEST_SERVER_PORT_MIN, self::TEST_SERVER_PORT_MAX);
28-
}
29-
return self::$nextPort++;
30-
}
31-
3213
/**
3314
* @see Wrench\Tests.Test::getClass()
3415
*/
@@ -37,87 +18,6 @@ public function getClass()
3718
return 'Wrench\Socket\ClientSocket';
3819
}
3920

40-
/**
41-
* Gets the server command
42-
*
43-
* @return string
44-
*/
45-
protected function getCommand()
46-
{
47-
return sprintf('/usr/bin/env php %s/../server.php %d', __DIR__, $this->port);
48-
}
49-
50-
/**
51-
* Starts a listening server
52-
*/
53-
protected function startProcess()
54-
{
55-
$this->port = self::getNextPort();
56-
57-
$this->process = proc_open(
58-
$this->getCommand(),
59-
array(
60-
0 => array('file', '/dev/null', 'r'),
61-
1 => array('file', __DIR__ . '/../../../../build/server.log', 'a+'),
62-
2 => array('file', __DIR__ . '/../../../../build/server.err.log', 'a+')
63-
),
64-
$this->pipes,
65-
__DIR__ . '../'
66-
);
67-
68-
sleep(3);
69-
}
70-
71-
/**
72-
* Stops the listening server
73-
*/
74-
protected function stopProcess()
75-
{
76-
if ($this->process) {
77-
foreach ($this->pipes as &$pipe) {
78-
fclose($pipe);
79-
}
80-
$this->pipes = null;
81-
82-
// Sigh
83-
$status = proc_get_status($this->process);
84-
85-
if ($status && isset($status['pid']) && $status['pid']) {
86-
// More sigh, this is the pid of the parent sh process, we want
87-
// to terminate the server directly
88-
$this->log('Command: /bin/ps -ao pid,ppid | /usr/bin/col | /usr/bin/tail -n +2 | /bin/grep \' ' . $status['pid'] . "'", 'info');
89-
exec('/bin/ps -ao pid,ppid | /usr/bin/col | /usr/bin/tail -n +2 | /bin/grep \' ' . $status['pid'] . "'", $processes, $return);
90-
91-
if ($return === 0) {
92-
foreach ($processes as $process) {
93-
list($pid, $ppid) = explode(' ', str_replace(' ', ' ', $process));
94-
if ($pid) {
95-
$this->log('Killing ' . $pid, 'info');
96-
exec('/bin/kill ' . $pid . ' > /dev/null 2>&1');
97-
}
98-
}
99-
} else {
100-
$this->log('Unable to find child processes', 'warning');
101-
}
102-
103-
sleep(1);
104-
105-
$this->log('Killing ' . $status['pid'], 'info');
106-
exec('/bin/kill ' . $status['pid'] . ' > /dev/null 2>&1');
107-
108-
sleep(1);
109-
}
110-
111-
proc_close($this->process);
112-
unset($this->process);
113-
}
114-
}
115-
116-
public function log($message, $priority = 'info')
117-
{
118-
//echo $message . "\n";
119-
}
120-
12121
/**
12222
* Overriden to use with the depends annotation
12323
*
@@ -236,26 +136,32 @@ public function testSendTooEarly($instance)
236136
*/
237137
public function testConnect()
238138
{
239-
$this->startProcess();
139+
try {
140+
$helper = new ServerTestHelper();
141+
$helper->setUp();
240142

241-
// Wait for server to come up
242-
$instance = $this->getInstance('ws://localhost:' . $this->port);
243-
$success = $instance->connect();
143+
$instance = $this->getInstance($helper->getConnectionString());
144+
$success = $instance->connect();
244145

245-
$this->assertTrue($success, 'Client socket can connect to test server');
146+
$this->assertTrue($success, 'Client socket can connect to test server');
246147

247-
$sent = $instance->send("GET /echo HTTP/1.1\r
148+
$sent = $instance->send("GET /echo HTTP/1.1\r
248149
Host: localhost\r
249150
Upgrade: websocket\r
250151
Connection: Upgrade\r
251152
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r
252153
Origin: http://localhost\r
253154
Sec-WebSocket-Version: 13\r\n\r\n");
254-
$this->assertNotEquals(false, $sent, 'Client socket can send to test server');
155+
$this->assertNotEquals(false, $sent, 'Client socket can send to test server');
255156

256-
$response = $instance->receive();
257-
$this->assertStringStartsWith('HTTP', $response, 'Response looks like HTTP handshake response');
157+
$response = $instance->receive();
158+
$this->assertStringStartsWith('HTTP', $response, 'Response looks like HTTP handshake response');
159+
160+
} catch (\Exception $e) {
161+
$helper->tearDown();
162+
throw $e;
163+
}
258164

259-
$this->stopProcess();
165+
$helper->tearDown();
260166
}
261167
}

0 commit comments

Comments
 (0)