diff --git a/composer.json b/composer.json index 44805eac..ec50942e 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ "react/stream": "^1.2" }, "require-dev": { - "clue/block-react": "^1.2", + "clue/block-react": "^1.5", "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", "react/promise-stream": "^1.2" }, diff --git a/tests/FdServerTest.php b/tests/FdServerTest.php index 3df1b296..e7ba55d0 100644 --- a/tests/FdServerTest.php +++ b/tests/FdServerTest.php @@ -3,8 +3,8 @@ namespace React\Tests\Socket; use Clue\React\Block; -use React\EventLoop\Loop; use React\Promise\Promise; +use React\Socket\ConnectionInterface; use React\Socket\FdServer; class FdServerTest extends TestCase @@ -302,16 +302,21 @@ public function testServerEmitsConnectionEventForNewConnection() $client = stream_socket_client('tcp://' . stream_socket_get_name($socket, false)); - $server = new FdServer($fd, Loop::get()); + $server = new FdServer($fd); $promise = new Promise(function ($resolve) use ($server) { $server->on('connection', $resolve); }); - $connection = Block\await($promise, Loop::get(), 1.0); + $connection = Block\await($promise, null, 1.0); + /** + * @var ConnectionInterface $connection + */ $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); fclose($client); + $connection->close(); + $server->close(); } public function testEmitsErrorWhenAcceptListenerFails() diff --git a/tests/FunctionalConnectorTest.php b/tests/FunctionalConnectorTest.php index 0ece63ae..767b92f0 100644 --- a/tests/FunctionalConnectorTest.php +++ b/tests/FunctionalConnectorTest.php @@ -3,7 +3,7 @@ namespace React\Tests\Socket; use Clue\React\Block; -use React\EventLoop\Factory; +use React\EventLoop\Loop; use React\Promise\Deferred; use React\Socket\ConnectionInterface; use React\Socket\Connector; @@ -20,13 +20,11 @@ class FunctionalConnectorTest extends TestCase /** @test */ public function connectionToTcpServerShouldSucceedWithLocalhost() { - $loop = Factory::create(); + $server = new TcpServer(9998); - $server = new TcpServer(9998, $loop); + $connector = new Connector(array()); - $connector = new Connector(array(), $loop); - - $connection = Block\await($connector->connect('localhost:9998'), $loop, self::TIMEOUT); + $connection = Block\await($connector->connect('localhost:9998'), null, self::TIMEOUT); $server->close(); @@ -44,18 +42,16 @@ public function testConnectTwiceWithoutHappyEyeBallsOnlySendsSingleDnsQueryDueTo $this->markTestSkipped('Not supported on Windows for PHP versions < 7.0 and legacy HHVM'); } - $loop = Factory::create(); - $socket = stream_socket_server('udp://127.0.0.1:0', $errno, $errstr, STREAM_SERVER_BIND); $connector = new Connector(array( 'dns' => 'udp://' . stream_socket_get_name($socket, false), 'happy_eyeballs' => false - ), $loop); + )); // minimal DNS proxy stub which forwards DNS messages to actual DNS server $received = 0; - $loop->addReadStream($socket, function ($socket) use (&$received) { + Loop::addReadStream($socket, function ($socket) use (&$received) { $request = stream_socket_recvfrom($socket, 65536, 0, $peer); $client = stream_socket_client('udp://8.8.8.8:53'); @@ -64,15 +60,18 @@ public function testConnectTwiceWithoutHappyEyeBallsOnlySendsSingleDnsQueryDueTo stream_socket_sendto($socket, $response, 0, $peer); ++$received; + fclose($client); }); - $connection = Block\await($connector->connect('example.com:80'), $loop); + $connection = Block\await($connector->connect('example.com:80')); $connection->close(); $this->assertEquals(1, $received); - $connection = Block\await($connector->connect('example.com:80'), $loop); + $connection = Block\await($connector->connect('example.com:80')); $connection->close(); $this->assertEquals(1, $received); + + Loop::removeReadStream($socket); } /** @@ -84,11 +83,9 @@ public function connectionToRemoteTCP4n6ServerShouldResultInOurIP() // max_nesting_level was set to 100 for PHP Versions < 5.4 which resulted in failing test for legacy PHP ini_set('xdebug.max_nesting_level', 256); - $loop = Factory::create(); - - $connector = new Connector(array('happy_eyeballs' => true), $loop); + $connector = new Connector(array('happy_eyeballs' => true)); - $ip = Block\await($this->request('dual.tlund.se', $connector), $loop, self::TIMEOUT); + $ip = Block\await($this->request('dual.tlund.se', $connector), null, self::TIMEOUT); $this->assertNotFalse(inet_pton($ip)); } @@ -99,12 +96,10 @@ public function connectionToRemoteTCP4n6ServerShouldResultInOurIP() */ public function connectionToRemoteTCP4ServerShouldResultInOurIP() { - $loop = Factory::create(); - - $connector = new Connector(array('happy_eyeballs' => true), $loop); + $connector = new Connector(array('happy_eyeballs' => true)); try { - $ip = Block\await($this->request('ipv4.tlund.se', $connector), $loop, self::TIMEOUT); + $ip = Block\await($this->request('ipv4.tlund.se', $connector), null, self::TIMEOUT); } catch (\Exception $e) { $this->checkIpv4(); throw $e; @@ -120,12 +115,10 @@ public function connectionToRemoteTCP4ServerShouldResultInOurIP() */ public function connectionToRemoteTCP6ServerShouldResultInOurIP() { - $loop = Factory::create(); - - $connector = new Connector(array('happy_eyeballs' => true), $loop); + $connector = new Connector(array('happy_eyeballs' => true)); try { - $ip = Block\await($this->request('ipv6.tlund.se', $connector), $loop, self::TIMEOUT); + $ip = Block\await($this->request('ipv6.tlund.se', $connector), null, self::TIMEOUT); } catch (\Exception $e) { $this->checkIpv6(); throw $e; @@ -141,30 +134,28 @@ public function testCancelPendingTlsConnectionDuringTlsHandshakeShouldCloseTcpCo $this->markTestSkipped('Not supported on legacy HHVM'); } - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $uri = str_replace('tcp://', 'tls://', $server->getAddress()); - $connector = new Connector(array(), $loop); + $connector = new Connector(array()); $promise = $connector->connect($uri); $deferred = new Deferred(); - $server->on('connection', function (ConnectionInterface $connection) use ($promise, $deferred, $loop) { + $server->on('connection', function (ConnectionInterface $connection) use ($promise, $deferred) { $connection->on('close', function () use ($deferred) { $deferred->resolve(); }); - $loop->futureTick(function () use ($promise) { + Loop::futureTick(function () use ($promise) { $promise->cancel(); }); }); - Block\await($deferred->promise(), $loop, self::TIMEOUT); + Block\await($deferred->promise(), null, self::TIMEOUT); $server->close(); try { - Block\await($promise, $loop, self::TIMEOUT); + Block\await($promise, null, self::TIMEOUT); $this->fail(); } catch (\Exception $e) { $this->assertInstanceOf('RuntimeException', $e); diff --git a/tests/FunctionalSecureServerTest.php b/tests/FunctionalSecureServerTest.php index 2dfe955b..d81040e6 100644 --- a/tests/FunctionalSecureServerTest.php +++ b/tests/FunctionalSecureServerTest.php @@ -4,7 +4,6 @@ use Clue\React\Block; use Evenement\EventEmitterInterface; -use React\EventLoop\Factory; use React\Promise\Promise; use React\Socket\ConnectionInterface; use React\Socket\SecureConnector; @@ -29,20 +28,18 @@ public function setUpSkipTest() public function testClientCanConnectToServer() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); $promise = $connector->connect($server->getAddress()); /* @var ConnectionInterface $client */ - $client = Block\await($promise, $loop, self::TIMEOUT); + $client = Block\await($promise, null, self::TIMEOUT); $this->assertInstanceOf('React\Socket\ConnectionInterface', $client); $this->assertEquals($server->getAddress(), $client->getRemoteAddress()); @@ -60,20 +57,18 @@ public function testClientUsesTls13ByDefaultWhenSupportedByOpenSSL() $this->markTestSkipped('Test requires PHP 7+ for crypto meta data (but excludes PHP 7.3 because it implicitly limits to TLS 1.2) and OpenSSL 1.1.1+ for TLS 1.3'); } - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); $promise = $connector->connect($server->getAddress()); /* @var ConnectionInterface $client */ - $client = Block\await($promise, $loop, self::TIMEOUT); + $client = Block\await($promise, null, self::TIMEOUT); $this->assertInstanceOf('React\Socket\Connection', $client); $this->assertTrue(isset($client->stream)); @@ -89,6 +84,9 @@ public function testClientUsesTls13ByDefaultWhenSupportedByOpenSSL() } else { $this->assertEquals('TLSv1.3', $meta['crypto']['protocol']); } + + $client->close(); + $server->close(); } public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByClient() @@ -97,21 +95,19 @@ public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByClien $this->markTestSkipped('Test requires PHP 7+ for crypto meta data'); } - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT )); $promise = $connector->connect($server->getAddress()); /* @var ConnectionInterface $client */ - $client = Block\await($promise, $loop, self::TIMEOUT); + $client = Block\await($promise, null, self::TIMEOUT); $this->assertInstanceOf('React\Socket\Connection', $client); $this->assertTrue(isset($client->stream)); @@ -119,6 +115,9 @@ public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByClien $meta = stream_get_meta_data($client->stream); $this->assertTrue(isset($meta['crypto']['protocol'])); $this->assertEquals('TLSv1.2', $meta['crypto']['protocol']); + + $client->close(); + $server->close(); } public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByServer() @@ -127,21 +126,19 @@ public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByServe $this->markTestSkipped('Test requires PHP 7+ for crypto meta data'); } - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem', 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER )); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); $promise = $connector->connect($server->getAddress()); /* @var ConnectionInterface $client */ - $client = Block\await($promise, $loop, self::TIMEOUT); + $client = Block\await($promise, null, self::TIMEOUT); $this->assertInstanceOf('React\Socket\Connection', $client); $this->assertTrue(isset($client->stream)); @@ -149,6 +146,9 @@ public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByServe $meta = stream_get_meta_data($client->stream); $this->assertTrue(isset($meta['crypto']['protocol'])); $this->assertEquals('TLSv1.2', $meta['crypto']['protocol']); + + $client->close(); + $server->close(); } public function testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClient() @@ -157,14 +157,12 @@ public function testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClien $this->markTestSkipped('Test requires PHP 7+ for crypto meta data'); } - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT )); @@ -172,7 +170,7 @@ public function testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClien /* @var ConnectionInterface $client */ try { - $client = Block\await($promise, $loop, self::TIMEOUT); + $client = Block\await($promise, null, self::TIMEOUT); } catch (\RuntimeException $e) { // legacy TLS 1.0 would be considered insecure by today's standards, so skip test if connection fails // OpenSSL error messages are version/platform specific @@ -180,6 +178,7 @@ public function testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClien // […] routines:state_machine:internal error // SSL operation failed with code 1. OpenSSL Error messages: error:0A000438:SSL routines::tlsv1 alert internal error // Connection lost during TLS handshake (ECONNRESET) + $server->close(); $this->markTestSkipped('TLS 1.0 not available on this system (' . $e->getMessage() . ')'); } @@ -189,14 +188,15 @@ public function testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClien $meta = stream_get_meta_data($client->stream); $this->assertTrue(isset($meta['crypto']['protocol'])); $this->assertEquals('TLSv1', $meta['crypto']['protocol']); + + $client->close(); + $server->close(); } public function testServerEmitsConnectionForClientConnection() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); @@ -205,14 +205,14 @@ public function testServerEmitsConnectionForClientConnection() $server->on('error', $reject); }); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); $client = $connector->connect($server->getAddress()); // await both client and server side end of connection /* @var ConnectionInterface[] $both */ - $both = Block\awaitAll(array($peer, $client), $loop, self::TIMEOUT); + $both = Block\awaitAll(array($peer, $client), null, self::TIMEOUT); // both ends of the connection are represented by different instances of ConnectionInterface $this->assertCount(2, $both); @@ -232,10 +232,8 @@ public function testServerEmitsConnectionForClientConnection() public function testClientEmitsDataEventOnceForDataWrittenFromServer() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); @@ -243,28 +241,32 @@ public function testClientEmitsDataEventOnceForDataWrittenFromServer() $conn->write('foo'); }); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); - $promise = $connector->connect($server->getAddress()); + $connecting = $connector->connect($server->getAddress()); - $promise = new Promise(function ($resolve, $reject) use ($promise) { - $promise->then(function (ConnectionInterface $connection) use ($resolve) { + $promise = new Promise(function ($resolve, $reject) use ($connecting) { + $connecting->then(function (ConnectionInterface $connection) use ($resolve) { $connection->on('data', $resolve); }, $reject); }); - $data = Block\await($promise, $loop, self::TIMEOUT); + $data = Block\await($promise, null, self::TIMEOUT); $this->assertEquals('foo', $data); + + $server->close(); + + $connecting->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testWritesDataInMultipleChunksToConnection() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableOnce()); @@ -273,15 +275,15 @@ public function testWritesDataInMultipleChunksToConnection() $conn->write(str_repeat('*', 400000)); }); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); - $promise = $connector->connect($server->getAddress()); + $connecting = $connector->connect($server->getAddress()); - $promise = new Promise(function ($resolve, $reject) use ($promise) { - $promise->then(function (ConnectionInterface $connection) use ($resolve) { + $promise = new Promise(function ($resolve, $reject) use ($connecting) { + $connecting->then(function (ConnectionInterface $connection) use ($resolve) { $received = 0; - $connection->on('data', function ($chunk) use (&$received, $resolve) { + $connection->on('data', function ($chunk) use (&$received, $resolve, $connection) { $received += strlen($chunk); if ($received >= 400000) { @@ -291,17 +293,21 @@ public function testWritesDataInMultipleChunksToConnection() }, $reject); }); - $received = Block\await($promise, $loop, self::TIMEOUT); + $received = Block\await($promise, null, self::TIMEOUT); $this->assertEquals(400000, $received); + + $server->close(); + + $connecting->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testWritesMoreDataInMultipleChunksToConnection() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableOnce()); @@ -310,13 +316,13 @@ public function testWritesMoreDataInMultipleChunksToConnection() $conn->write(str_repeat('*', 2000000)); }); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); - $promise = $connector->connect($server->getAddress()); + $connecting = $connector->connect($server->getAddress()); - $promise = new Promise(function ($resolve, $reject) use ($promise) { - $promise->then(function (ConnectionInterface $connection) use ($resolve) { + $promise = new Promise(function ($resolve, $reject) use ($connecting) { + $connecting->then(function (ConnectionInterface $connection) use ($resolve) { $received = 0; $connection->on('data', function ($chunk) use (&$received, $resolve) { $received += strlen($chunk); @@ -328,17 +334,21 @@ public function testWritesMoreDataInMultipleChunksToConnection() }, $reject); }); - $received = Block\await($promise, $loop, self::TIMEOUT); + $received = Block\await($promise, null, self::TIMEOUT); $this->assertEquals(2000000, $received); + + $server->close(); + + $connecting->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testEmitsDataFromConnection() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableOnce()); @@ -349,24 +359,29 @@ public function testEmitsDataFromConnection() }); }); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); - $connector->connect($server->getAddress())->then(function (ConnectionInterface $connection) { + $connecting = $connector->connect($server->getAddress()); + $connecting->then(function (ConnectionInterface $connection) { $connection->write('foo'); }); - $data = Block\await($promise, $loop, self::TIMEOUT); + $data = Block\await($promise, null, self::TIMEOUT); $this->assertEquals('foo', $data); + + $server->close(); + + $connecting->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testEmitsDataInMultipleChunksFromConnection() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableOnce()); @@ -384,24 +399,29 @@ public function testEmitsDataInMultipleChunksFromConnection() }); }); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); - $connector->connect($server->getAddress())->then(function (ConnectionInterface $connection) { + $connecting = $connector->connect($server->getAddress()); + $connecting->then(function (ConnectionInterface $connection) { $connection->write(str_repeat('*', 400000)); }); - $received = Block\await($promise, $loop, self::TIMEOUT); + $received = Block\await($promise, null, self::TIMEOUT); $this->assertEquals(400000, $received); + + $server->close(); + + $connecting->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testPipesDataBackInMultipleChunksFromConnection() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableOnce()); @@ -410,13 +430,13 @@ public function testPipesDataBackInMultipleChunksFromConnection() $conn->pipe($conn); }); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); - $promise = $connector->connect($server->getAddress()); + $connecting = $connector->connect($server->getAddress()); - $promise = new Promise(function ($resolve, $reject) use ($promise) { - $promise->then(function (ConnectionInterface $connection) use ($resolve) { + $promise = new Promise(function ($resolve, $reject) use ($connecting) { + $connecting->then(function (ConnectionInterface $connection) use ($resolve) { $received = 0; $connection->on('data', function ($chunk) use (&$received, $resolve) { $received += strlen($chunk); @@ -429,9 +449,15 @@ public function testPipesDataBackInMultipleChunksFromConnection() }, $reject); }); - $received = Block\await($promise, $loop, self::TIMEOUT); + $received = Block\await($promise, null, self::TIMEOUT); $this->assertEquals(400000, $received); + + $server->close(); + + $connecting->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } /** @@ -440,22 +466,25 @@ public function testPipesDataBackInMultipleChunksFromConnection() */ public function testEmitsConnectionForNewTlsv11Connection() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem', 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER )); $server->on('connection', $this->expectCallableOnce()); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT )); $promise = $connector->connect($server->getAddress()); - Block\await($promise, $loop, self::TIMEOUT); + Block\await($promise, null, self::TIMEOUT); + + $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } /** @@ -464,32 +493,35 @@ public function testEmitsConnectionForNewTlsv11Connection() */ public function testEmitsErrorForClientWithTlsVersionMismatch() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem', 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER|STREAM_CRYPTO_METHOD_TLSv1_2_SERVER )); $server->on('connection', $this->expectCallableNever()); $server->on('error', $this->expectCallableOnce()); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT )); $promise = $connector->connect($server->getAddress()); $this->setExpectedException('RuntimeException', 'handshake'); - Block\await($promise, $loop, self::TIMEOUT); + + try { + Block\await($promise, null, self::TIMEOUT); + } catch (\Exception $e) { + $server->close(); + + throw $e; + } } public function testServerEmitsConnectionForNewConnectionWithEncryptedCertificate() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem', 'passphrase' => 'swordfish' )); @@ -499,40 +531,46 @@ public function testServerEmitsConnectionForNewConnectionWithEncryptedCertificat $server->on('error', $reject); }); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); $connector->connect($server->getAddress()); - $connection = Block\await($peer, $loop, self::TIMEOUT); + $connection = Block\await($peer, null, self::TIMEOUT); $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); + + $server->close(); + $connection->close(); } public function testClientRejectsWithErrorForServerWithInvalidCertificate() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => 'invalid.pem' )); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); $promise = $connector->connect($server->getAddress()); $this->setExpectedException('RuntimeException', 'handshake'); - Block\await($promise, $loop, self::TIMEOUT); + + try { + Block\await($promise, null, self::TIMEOUT); + } catch (\Exception $e) { + $server->close(); + + throw $e; + } } public function testServerEmitsErrorForClientWithInvalidCertificate() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => 'invalid.pem' )); @@ -543,13 +581,20 @@ public function testServerEmitsErrorForClientWithInvalidCertificate() $server->on('error', $reject); }); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); $connector->connect($server->getAddress()); $this->setExpectedException('RuntimeException', 'handshake'); - Block\await($peer, $loop, self::TIMEOUT); + + try { + Block\await($peer, null, self::TIMEOUT); + } catch (\Exception $e) { + $server->close(); + + throw $e; + } } public function testEmitsErrorForServerWithEncryptedCertificateMissingPassphrase() @@ -558,22 +603,27 @@ public function testEmitsErrorForServerWithEncryptedCertificateMissingPassphrase $this->markTestSkipped('Not supported on Windows'); } - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem' )); $server->on('connection', $this->expectCallableNever()); $server->on('error', $this->expectCallableOnce()); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); $promise = $connector->connect($server->getAddress()); $this->setExpectedException('RuntimeException', 'handshake'); - Block\await($promise, $loop, self::TIMEOUT); + + try { + Block\await($promise, null, self::TIMEOUT); + } catch (\Exception $e) { + $server->close(); + + throw $e; + } } public function testEmitsErrorForServerWithEncryptedCertificateWithInvalidPassphrase() @@ -582,43 +632,48 @@ public function testEmitsErrorForServerWithEncryptedCertificateWithInvalidPassph $this->markTestSkipped('Not supported on Windows'); } - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem', 'passphrase' => 'nope' )); $server->on('connection', $this->expectCallableNever()); $server->on('error', $this->expectCallableOnce()); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); $promise = $connector->connect($server->getAddress()); $this->setExpectedException('RuntimeException', 'handshake'); - Block\await($promise, $loop, self::TIMEOUT); + + try { + Block\await($promise, null, self::TIMEOUT); + } catch (\Exception $e) { + $server->close(); + + throw $e; + } } public function testEmitsErrorForConnectionWithPeerVerification() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => true )); $promise = $connector->connect($server->getAddress()); $promise->then(null, $this->expectCallableOnce()); - Block\await($errorEvent, $loop, self::TIMEOUT); + Block\await($errorEvent, null, self::TIMEOUT); + + $server->close(); } public function testEmitsErrorIfConnectionIsCancelled() @@ -627,44 +682,42 @@ public function testEmitsErrorIfConnectionIsCancelled() $this->markTestSkipped('Linux only (OS is ' . PHP_OS . ')'); } - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); - $connector = new SecureConnector(new TcpConnector($loop), $loop, array( + $connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false )); $promise = $connector->connect($server->getAddress()); $promise->cancel(); $promise->then(null, $this->expectCallableOnce()); - Block\await($errorEvent, $loop, self::TIMEOUT); + Block\await($errorEvent, null, self::TIMEOUT); + + $server->close(); } public function testEmitsErrorIfConnectionIsClosedBeforeHandshake() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect(str_replace('tls://', '', $server->getAddress())); $promise->then(function (ConnectionInterface $stream) { $stream->close(); }); - $error = Block\await($errorEvent, $loop, self::TIMEOUT); + $error = Block\await($errorEvent, null, self::TIMEOUT); // Connection from tcp://127.0.0.1:39528 failed during TLS handshake: Connection lost during TLS handshake (ECONNRESET) $this->assertInstanceOf('RuntimeException', $error); @@ -672,27 +725,27 @@ public function testEmitsErrorIfConnectionIsClosedBeforeHandshake() $this->assertStringEndsWith('failed during TLS handshake: Connection lost during TLS handshake (ECONNRESET)', $error->getMessage()); $this->assertEquals(defined('SOCKET_ECONNRESET') ? SOCKET_ECONNRESET : 104, $error->getCode()); $this->assertNull($error->getPrevious()); + + $server->close(); } public function testEmitsErrorIfConnectionIsClosedWithIncompleteHandshake() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect(str_replace('tls://', '', $server->getAddress())); $promise->then(function (ConnectionInterface $stream) { $stream->end("\x1e"); }); - $error = Block\await($errorEvent, $loop, self::TIMEOUT); + $error = Block\await($errorEvent, null, self::TIMEOUT); // Connection from tcp://127.0.0.1:39528 failed during TLS handshake: Connection lost during TLS handshake (ECONNRESET) $this->assertInstanceOf('RuntimeException', $error); @@ -700,45 +753,48 @@ public function testEmitsErrorIfConnectionIsClosedWithIncompleteHandshake() $this->assertStringEndsWith('failed during TLS handshake: Connection lost during TLS handshake (ECONNRESET)', $error->getMessage()); $this->assertEquals(defined('SOCKET_ECONNRESET') ? SOCKET_ECONNRESET : 104, $error->getCode()); $this->assertNull($error->getPrevious()); + + $server->close(); } public function testEmitsNothingIfPlaintextConnectionIsIdle() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableNever()); $server->on('error', $this->expectCallableNever()); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect(str_replace('tls://', '', $server->getAddress())); - $connection = Block\await($promise, $loop, self::TIMEOUT); + $connection = Block\await($promise, null, self::TIMEOUT); $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); + + $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testEmitsErrorIfConnectionIsHttpInsteadOfSecureHandshake() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect(str_replace('tls://', '', $server->getAddress())); $promise->then(function (ConnectionInterface $stream) { $stream->write("GET / HTTP/1.0\r\n\r\n"); }); - $error = Block\await($errorEvent, $loop, self::TIMEOUT); + $error = Block\await($errorEvent, null, self::TIMEOUT); $this->assertInstanceOf('RuntimeException', $error); @@ -747,27 +803,27 @@ public function testEmitsErrorIfConnectionIsHttpInsteadOfSecureHandshake() // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:ssl3_get_record:wrong version number // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:func(143):reason(267) // Unable to complete TLS handshake: Failed setting RSA key + + $server->close(); } public function testEmitsErrorIfConnectionIsUnknownProtocolInsteadOfSecureHandshake() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); - $server = new SecureServer($server, $loop, array( + $server = new TcpServer(0); + $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect(str_replace('tls://', '', $server->getAddress())); $promise->then(function (ConnectionInterface $stream) { $stream->write("Hello world!\n"); }); - $error = Block\await($errorEvent, $loop, self::TIMEOUT); + $error = Block\await($errorEvent, null, self::TIMEOUT); $this->assertInstanceOf('RuntimeException', $error); @@ -776,6 +832,8 @@ public function testEmitsErrorIfConnectionIsUnknownProtocolInsteadOfSecureHandsh // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:ssl3_get_record:wrong version number // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:func(143):reason(267) // Unable to complete TLS handshake: Failed setting RSA key + + $server->close(); } private function createPromiseForServerError(ServerInterface $server) diff --git a/tests/FunctionalTcpServerTest.php b/tests/FunctionalTcpServerTest.php index eae1ceaa..0965f90d 100644 --- a/tests/FunctionalTcpServerTest.php +++ b/tests/FunctionalTcpServerTest.php @@ -3,7 +3,6 @@ namespace React\Tests\Socket; use Clue\React\Block; -use React\EventLoop\Factory; use React\Promise\Promise; use React\Socket\ConnectionInterface; use React\Socket\TcpConnector; @@ -15,44 +14,44 @@ class FunctionalTcpServerTest extends TestCase public function testEmitsConnectionForNewConnection() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $server->on('connection', $this->expectCallableOnce()); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', $resolve); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); + + $server->close(); + + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testEmitsNoConnectionForNewConnectionWhenPaused() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $server->on('connection', $this->expectCallableNever()); $server->pause(); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); - Block\await($promise, $loop, self::TIMEOUT); + Block\await($promise, null, self::TIMEOUT); } public function testConnectionForNewConnectionWhenResumedAfterPause() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $server->on('connection', $this->expectCallableOnce()); $server->pause(); $server->resume(); @@ -61,57 +60,68 @@ public function testConnectionForNewConnectionWhenResumedAfterPause() $server->on('connection', $resolve); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); + + $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testEmitsConnectionWithRemoteIp() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', function (ConnectionInterface $connection) use ($resolve) { $resolve($connection->getRemoteAddress()); }); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); - $peer = Block\await($peer, $loop, self::TIMEOUT); + $peer = Block\await($peer, null, self::TIMEOUT); $this->assertContainsString('127.0.0.1:', $peer); + + $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testEmitsConnectionWithLocalIp() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', function (ConnectionInterface $connection) use ($resolve) { $resolve($connection->getLocalAddress()); }); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); $promise->then($this->expectCallableOnce()); - $local = Block\await($peer, $loop, self::TIMEOUT); + $local = Block\await($peer, null, self::TIMEOUT); $this->assertContainsString('127.0.0.1:', $local); $this->assertEquals($server->getAddress(), $local); + + $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testEmitsConnectionWithLocalIpDespiteListeningOnAll() @@ -120,30 +130,31 @@ public function testEmitsConnectionWithLocalIpDespiteListeningOnAll() $this->markTestSkipped('Skipping on Windows due to default firewall rules'); } - $loop = Factory::create(); - - $server = new TcpServer('0.0.0.0:0', $loop); + $server = new TcpServer('0.0.0.0:0'); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', function (ConnectionInterface $connection) use ($resolve) { $resolve($connection->getLocalAddress()); }); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); - $local = Block\await($peer, $loop, self::TIMEOUT); + $local = Block\await($peer, null, self::TIMEOUT); $this->assertContainsString('127.0.0.1:', $local); + + $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testEmitsConnectionWithRemoteIpAfterConnectionIsClosedByPeer() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', function (ConnectionInterface $connection) use ($resolve) { $connection->on('close', function () use ($connection, $resolve) { @@ -152,21 +163,21 @@ public function testEmitsConnectionWithRemoteIpAfterConnectionIsClosedByPeer() }); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $connector->connect($server->getAddress())->then(function (ConnectionInterface $connection) { $connection->end(); }); - $peer = Block\await($peer, $loop, self::TIMEOUT); + $peer = Block\await($peer, null, self::TIMEOUT); $this->assertContainsString('127.0.0.1:', $peer); + + $server->close(); } public function testEmitsConnectionWithRemoteNullAddressAfterConnectionIsClosedByServer() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', function (ConnectionInterface $connection) use ($resolve) { $connection->close(); @@ -174,14 +185,16 @@ public function testEmitsConnectionWithRemoteNullAddressAfterConnectionIsClosedB }); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); - $peer = Block\await($peer, $loop, self::TIMEOUT); + $peer = Block\await($peer, null, self::TIMEOUT); $this->assertNull($peer); + + $server->close(); } public function testEmitsConnectionEvenIfClientConnectionIsCancelled() @@ -190,30 +203,28 @@ public function testEmitsConnectionEvenIfClientConnectionIsCancelled() $this->markTestSkipped('Linux only (OS is ' . PHP_OS . ')'); } - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $server->on('connection', $this->expectCallableOnce()); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', $resolve); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->cancel(); $promise->then(null, $this->expectCallableOnce()); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); + + $server->close(); } public function testEmitsConnectionForNewIpv6Connection() { - $loop = Factory::create(); - try { - $server = new TcpServer('[::1]:0', $loop); + $server = new TcpServer('[::1]:0'); } catch (\RuntimeException $e) { $this->markTestSkipped('Unable to start IPv6 server socket (not available on your platform?)'); } @@ -224,20 +235,23 @@ public function testEmitsConnectionForNewIpv6Connection() $server->on('connection', $resolve); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); + + $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testEmitsConnectionWithRemoteIpv6() { - $loop = Factory::create(); - try { - $server = new TcpServer('[::1]:0', $loop); + $server = new TcpServer('[::1]:0'); } catch (\RuntimeException $e) { $this->markTestSkipped('Unable to start IPv6 server socket (not available on your platform?)'); } @@ -248,22 +262,25 @@ public function testEmitsConnectionWithRemoteIpv6() }); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); - $peer = Block\await($peer, $loop, self::TIMEOUT); + $peer = Block\await($peer, null, self::TIMEOUT); $this->assertContainsString('[::1]:', $peer); + + $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testEmitsConnectionWithLocalIpv6() { - $loop = Factory::create(); - try { - $server = new TcpServer('[::1]:0', $loop); + $server = new TcpServer('[::1]:0'); } catch (\RuntimeException $e) { $this->markTestSkipped('Unable to start IPv6 server socket (not available on your platform?)'); } @@ -274,22 +291,25 @@ public function testEmitsConnectionWithLocalIpv6() }); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); - $local = Block\await($peer, $loop, self::TIMEOUT); + $local = Block\await($peer, null, self::TIMEOUT); $this->assertContainsString('[::1]:', $local); $this->assertEquals($server->getAddress(), $local); + + $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testServerPassesContextOptionsToSocket() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop, array( + $server = new TcpServer(0, null, array( 'backlog' => 4 )); @@ -300,13 +320,13 @@ public function testServerPassesContextOptionsToSocket() $context = stream_context_get_options($socket); $this->assertEquals(array('socket' => array('backlog' => 4)), $context); + + $server->close(); } public function testServerPassesDefaultBacklogSizeViaContextOptionsToSocket() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $ref = new \ReflectionProperty($server, 'master'); $ref->setAccessible(true); @@ -315,6 +335,8 @@ public function testServerPassesDefaultBacklogSizeViaContextOptionsToSocket() $context = stream_context_get_options($socket); $this->assertEquals(array('socket' => array('backlog' => 511)), $context); + + $server->close(); } public function testEmitsConnectionWithInheritedContextOptions() @@ -324,9 +346,7 @@ public function testEmitsConnectionWithInheritedContextOptions() $this->markTestSkipped('Not supported on legacy HHVM < 3.13'); } - $loop = Factory::create(); - - $server = new TcpServer(0, $loop, array( + $server = new TcpServer(0, null, array( 'backlog' => 4 )); @@ -336,61 +356,58 @@ public function testEmitsConnectionWithInheritedContextOptions() }); }); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($server->getAddress()); $promise->then($this->expectCallableOnce()); - $all = Block\await($peer, $loop, self::TIMEOUT); + $all = Block\await($peer, null, self::TIMEOUT); $this->assertEquals(array('socket' => array('backlog' => 4)), $all); + + $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testFailsToListenOnInvalidUri() { - $loop = Factory::create(); - $this->setExpectedException( 'InvalidArgumentException', 'Invalid URI "tcp://///" given (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : 22 ); - new TcpServer('///', $loop); + new TcpServer('///'); } public function testFailsToListenOnUriWithoutPort() { - $loop = Factory::create(); - $this->setExpectedException( 'InvalidArgumentException', 'Invalid URI "tcp://127.0.0.1" given (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : 22 ); - new TcpServer('127.0.0.1', $loop); + new TcpServer('127.0.0.1'); } public function testFailsToListenOnUriWithWrongScheme() { - $loop = Factory::create(); - $this->setExpectedException( 'InvalidArgumentException', 'Invalid URI "udp://127.0.0.1:0" given (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : 22 ); - new TcpServer('udp://127.0.0.1:0', $loop); + new TcpServer('udp://127.0.0.1:0'); } public function testFailsToListenOnUriWIthHostname() { - $loop = Factory::create(); - $this->setExpectedException( 'InvalidArgumentException', 'Given URI "tcp://localhost:8080" does not contain a valid host IP (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : 22 ); - new TcpServer('localhost:8080', $loop); + new TcpServer('localhost:8080'); } } diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index f23e980f..faa91294 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -4,7 +4,6 @@ use Clue\React\Block; use React\Dns\Resolver\Factory as ResolverFactory; -use React\EventLoop\Factory; use React\Socket\Connector; use React\Socket\DnsConnector; use React\Socket\SecureConnector; @@ -18,17 +17,16 @@ class IntegrationTest extends TestCase /** @test */ public function gettingStuffFromGoogleShouldWork() { - $loop = Factory::create(); - $connector = new Connector(array(), $loop); + $connector = new Connector(array()); - $conn = Block\await($connector->connect('google.com:80'), $loop); + $conn = Block\await($connector->connect('google.com:80')); $this->assertContainsString(':80', $conn->getRemoteAddress()); $this->assertNotEquals('google.com:80', $conn->getRemoteAddress()); $conn->write("GET / HTTP/1.0\r\n\r\n"); - $response = $this->buffer($conn, $loop, self::TIMEOUT); + $response = $this->buffer($conn, self::TIMEOUT); $this->assertMatchesRegExp('#^HTTP/1\.0#', $response); } @@ -40,14 +38,13 @@ public function gettingEncryptedStuffFromGoogleShouldWork() $this->markTestSkipped('Not supported on legacy HHVM'); } - $loop = Factory::create(); - $secureConnector = new Connector(array(), $loop); + $secureConnector = new Connector(array()); - $conn = Block\await($secureConnector->connect('tls://google.com:443'), $loop); + $conn = Block\await($secureConnector->connect('tls://google.com:443')); $conn->write("GET / HTTP/1.0\r\n\r\n"); - $response = $this->buffer($conn, $loop, self::TIMEOUT); + $response = $this->buffer($conn, self::TIMEOUT); $this->assertMatchesRegExp('#^HTTP/1\.0#', $response); } @@ -59,24 +56,21 @@ public function gettingEncryptedStuffFromGoogleShouldWorkIfHostIsResolvedFirst() $this->markTestSkipped('Not supported on legacy HHVM'); } - $loop = Factory::create(); - $factory = new ResolverFactory(); - $dns = $factory->create('8.8.8.8', $loop); + $dns = $factory->create('8.8.8.8'); $connector = new DnsConnector( new SecureConnector( - new TcpConnector($loop), - $loop + new TcpConnector() ), $dns ); - $conn = Block\await($connector->connect('google.com:443'), $loop); + $conn = Block\await($connector->connect('google.com:443')); $conn->write("GET / HTTP/1.0\r\n\r\n"); - $response = $this->buffer($conn, $loop, self::TIMEOUT); + $response = $this->buffer($conn, self::TIMEOUT); $this->assertMatchesRegExp('#^HTTP/1\.0#', $response); } @@ -84,17 +78,16 @@ public function gettingEncryptedStuffFromGoogleShouldWorkIfHostIsResolvedFirst() /** @test */ public function gettingPlaintextStuffFromEncryptedGoogleShouldNotWork() { - $loop = Factory::create(); - $connector = new Connector(array(), $loop); + $connector = new Connector(array()); - $conn = Block\await($connector->connect('google.com:443'), $loop); + $conn = Block\await($connector->connect('google.com:443')); $this->assertContainsString(':443', $conn->getRemoteAddress()); $this->assertNotEquals('google.com:443', $conn->getRemoteAddress()); $conn->write("GET / HTTP/1.0\r\n\r\n"); - $response = $this->buffer($conn, $loop, self::TIMEOUT); + $response = $this->buffer($conn, self::TIMEOUT); $this->assertDoesNotMatchRegExp('#^HTTP/1\.0#', $response); } @@ -105,17 +98,15 @@ public function testConnectingFailsIfConnectorUsesInvalidDnsResolverAddress() $this->markTestSkipped('Skipped on macOS due to a bug in reactphp/dns (solved in reactphp/dns#171)'); } - $loop = Factory::create(); - $factory = new ResolverFactory(); - $dns = $factory->create('255.255.255.255', $loop); + $dns = $factory->create('255.255.255.255'); $connector = new Connector(array( 'dns' => $dns - ), $loop); + )); $this->setExpectedException('RuntimeException'); - Block\await($connector->connect('google.com:80'), $loop, self::TIMEOUT); + Block\await($connector->connect('google.com:80'), null, self::TIMEOUT); } public function testCancellingPendingConnectionWithoutTimeoutShouldNotCreateAnyGarbageReferences() @@ -124,8 +115,7 @@ public function testCancellingPendingConnectionWithoutTimeoutShouldNotCreateAnyG $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $loop = Factory::create(); - $connector = new Connector(array('timeout' => false), $loop); + $connector = new Connector(array('timeout' => false)); gc_collect_cycles(); gc_collect_cycles(); // clear twice to avoid leftovers in PHP 7.4 with ext-xdebug and code coverage turned on @@ -143,8 +133,7 @@ public function testCancellingPendingConnectionShouldNotCreateAnyGarbageReferenc $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $loop = Factory::create(); - $connector = new Connector(array(), $loop); + $connector = new Connector(array()); gc_collect_cycles(); $promise = $connector->connect('8.8.8.8:80'); @@ -160,8 +149,7 @@ public function testWaitingForRejectedConnectionShouldNotCreateAnyGarbageReferen $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $loop = Factory::create(); - $connector = new Connector(array('timeout' => false), $loop); + $connector = new Connector(array('timeout' => false)); gc_collect_cycles(); @@ -175,11 +163,11 @@ function ($e) use (&$wait) { ); // run loop for short period to ensure we detect connection refused error - Block\sleep(0.01, $loop); + Block\sleep(0.01); if ($wait) { - Block\sleep(0.2, $loop); + Block\sleep(0.2); if ($wait) { - Block\sleep(2.0, $loop); + Block\sleep(2.0); if ($wait) { $this->fail('Connection attempt did not fail'); } @@ -196,8 +184,7 @@ public function testWaitingForConnectionTimeoutDuringDnsLookupShouldNotCreateAny $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $loop = Factory::create(); - $connector = new Connector(array('timeout' => 0.001), $loop); + $connector = new Connector(array('timeout' => 0.001)); gc_collect_cycles(); @@ -211,9 +198,9 @@ function ($e) use (&$wait) { ); // run loop for short period to ensure we detect a connection timeout error - Block\sleep(0.01, $loop); + Block\sleep(0.01); if ($wait) { - Block\sleep(0.2, $loop); + Block\sleep(0.2); if ($wait) { $this->fail('Connection attempt did not fail'); } @@ -229,8 +216,7 @@ public function testWaitingForConnectionTimeoutDuringTcpConnectionShouldNotCreat $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $loop = Factory::create(); - $connector = new Connector(array('timeout' => 0.000001), $loop); + $connector = new Connector(array('timeout' => 0.000001)); gc_collect_cycles(); @@ -244,9 +230,9 @@ function ($e) use (&$wait) { ); // run loop for short period to ensure we detect a connection timeout error - Block\sleep(0.01, $loop); + Block\sleep(0.01); if ($wait) { - Block\sleep(0.2, $loop); + Block\sleep(0.2); if ($wait) { $this->fail('Connection attempt did not fail'); } @@ -262,8 +248,7 @@ public function testWaitingForInvalidDnsConnectionShouldNotCreateAnyGarbageRefer $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $loop = Factory::create(); - $connector = new Connector(array('timeout' => false), $loop); + $connector = new Connector(array('timeout' => false)); gc_collect_cycles(); @@ -277,11 +262,11 @@ function ($e) use (&$wait) { ); // run loop for short period to ensure we detect a DNS error - Block\sleep(0.01, $loop); + Block\sleep(0.01); if ($wait) { - Block\sleep(0.2, $loop); + Block\sleep(0.2); if ($wait) { - Block\sleep(2.0, $loop); + Block\sleep(2.0); if ($wait) { $this->fail('Connection attempt did not fail'); } @@ -301,12 +286,11 @@ public function testWaitingForInvalidTlsConnectionShouldNotCreateAnyGarbageRefer $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $loop = Factory::create(); $connector = new Connector(array( 'tls' => array( 'verify_peer' => true ) - ), $loop); + )); gc_collect_cycles(); @@ -320,11 +304,11 @@ function ($e) use (&$wait) { ); // run loop for short period to ensure we detect a TLS error - Block\sleep(0.1, $loop); + Block\sleep(0.1); if ($wait) { - Block\sleep(0.4, $loop); + Block\sleep(0.4); if ($wait) { - Block\sleep(self::TIMEOUT - 0.5, $loop); + Block\sleep(self::TIMEOUT - 0.5); if ($wait) { $this->fail('Connection attempt did not fail'); } @@ -341,8 +325,7 @@ public function testWaitingForSuccessfullyClosedConnectionShouldNotCreateAnyGarb $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $loop = Factory::create(); - $connector = new Connector(array('timeout' => false), $loop); + $connector = new Connector(array('timeout' => false)); gc_collect_cycles(); $promise = $connector->connect('google.com:80')->then( @@ -350,7 +333,7 @@ function ($conn) { $conn->close(); } ); - Block\await($promise, $loop, self::TIMEOUT); + Block\await($promise, null, self::TIMEOUT); unset($promise); $this->assertEquals(0, gc_collect_cycles()); @@ -358,14 +341,12 @@ function ($conn) { public function testConnectingFailsIfTimeoutIsTooSmall() { - $loop = Factory::create(); - $connector = new Connector(array( 'timeout' => 0.001 - ), $loop); + )); $this->setExpectedException('RuntimeException'); - Block\await($connector->connect('google.com:80'), $loop, self::TIMEOUT); + Block\await($connector->connect('google.com:80'), null, self::TIMEOUT); } public function testSelfSignedRejectsIfVerificationIsEnabled() @@ -374,16 +355,14 @@ public function testSelfSignedRejectsIfVerificationIsEnabled() $this->markTestSkipped('Not supported on legacy HHVM'); } - $loop = Factory::create(); - $connector = new Connector(array( 'tls' => array( 'verify_peer' => true ) - ), $loop); + )); $this->setExpectedException('RuntimeException'); - Block\await($connector->connect('tls://self-signed.badssl.com:443'), $loop, self::TIMEOUT); + Block\await($connector->connect('tls://self-signed.badssl.com:443'), null, self::TIMEOUT); } public function testSelfSignedResolvesIfVerificationIsDisabled() @@ -392,15 +371,13 @@ public function testSelfSignedResolvesIfVerificationIsDisabled() $this->markTestSkipped('Not supported on legacy HHVM'); } - $loop = Factory::create(); - $connector = new Connector(array( 'tls' => array( 'verify_peer' => false ) - ), $loop); + )); - $conn = Block\await($connector->connect('tls://self-signed.badssl.com:443'), $loop, self::TIMEOUT); + $conn = Block\await($connector->connect('tls://self-signed.badssl.com:443'), null, self::TIMEOUT); $conn->close(); // if we reach this, then everything is good diff --git a/tests/LimitingServerTest.php b/tests/LimitingServerTest.php index 0769836b..119fba40 100644 --- a/tests/LimitingServerTest.php +++ b/tests/LimitingServerTest.php @@ -3,7 +3,6 @@ namespace React\Tests\Socket; use Clue\React\Block; -use React\EventLoop\Factory; use React\Promise\Promise; use React\Socket\ConnectionInterface; use React\Socket\LimitingServer; @@ -143,9 +142,7 @@ public function testPausingServerWillBePausedOnceLimitIsReached() public function testSocketDisconnectionWillRemoveFromList() { - $loop = Factory::create(); - - $tcp = new TcpServer(0, $loop); + $tcp = new TcpServer(0); $socket = stream_socket_client($tcp->getAddress()); fclose($socket); @@ -160,16 +157,16 @@ public function testSocketDisconnectionWillRemoveFromList() }); }); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); $this->assertEquals(array(), $server->getConnections()); + + $server->close(); } public function testPausingServerWillEmitOnlyOneButAcceptTwoConnectionsDueToOperatingSystem() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $server = new LimitingServer($server, 1, true); $server->on('connection', $this->expectCallableOnce()); $server->on('error', $this->expectCallableNever()); @@ -181,17 +178,17 @@ public function testPausingServerWillEmitOnlyOneButAcceptTwoConnectionsDueToOper $first = stream_socket_client($server->getAddress()); $second = stream_socket_client($server->getAddress()); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); fclose($first); fclose($second); + + $server->close(); } public function testPausingServerWillEmitTwoConnectionsFromBacklog() { - $loop = Factory::create(); - - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $server = new LimitingServer($server, 1, true); $server->on('error', $this->expectCallableNever()); @@ -211,6 +208,8 @@ public function testPausingServerWillEmitTwoConnectionsFromBacklog() $second = stream_socket_client($server->getAddress()); fclose($second); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); + + $server->close(); } } diff --git a/tests/SecureIntegrationTest.php b/tests/SecureIntegrationTest.php index 16d6dc35..5cf741cb 100644 --- a/tests/SecureIntegrationTest.php +++ b/tests/SecureIntegrationTest.php @@ -2,7 +2,6 @@ namespace React\Tests\Socket; -use React\EventLoop\Factory as LoopFactory; use React\Socket\TcpServer; use React\Socket\SecureServer; use React\Socket\TcpConnector; @@ -17,7 +16,6 @@ class SecureIntegrationTest extends TestCase { const TIMEOUT = 2; - private $loop; private $server; private $connector; private $address; @@ -31,13 +29,12 @@ public function setUpConnector() $this->markTestSkipped('Not supported on legacy HHVM'); } - $this->loop = LoopFactory::create(); - $this->server = new TcpServer(0, $this->loop); - $this->server = new SecureServer($this->server, $this->loop, array( + $this->server = new TcpServer(0); + $this->server = new SecureServer($this->server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' )); $this->address = $this->server->getAddress(); - $this->connector = new SecureConnector(new TcpConnector($this->loop), $this->loop, array('verify_peer' => false)); + $this->connector = new SecureConnector(new TcpConnector(), null, array('verify_peer' => false)); } /** @@ -53,7 +50,7 @@ public function tearDownServer() public function testConnectToServer() { - $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT); + $client = Block\await($this->connector->connect($this->address), null, self::TIMEOUT); /* @var $client ConnectionInterface */ $client->close(); @@ -68,7 +65,7 @@ public function testConnectToServerEmitsConnection() $promiseClient = $this->connector->connect($this->address); - list($_, $client) = Block\awaitAll(array($promiseServer, $promiseClient), $this->loop, self::TIMEOUT); + list($_, $client) = Block\awaitAll(array($promiseServer, $promiseClient), null, self::TIMEOUT); /* @var $client ConnectionInterface */ $client->close(); @@ -84,13 +81,13 @@ public function testSendSmallDataToServerReceivesOneChunk() }); }); - $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT); + $client = Block\await($this->connector->connect($this->address), null, self::TIMEOUT); /* @var $client ConnectionInterface */ $client->write('hello'); // await server to report one "data" event - $data = Block\await($received->promise(), $this->loop, self::TIMEOUT); + $data = Block\await($received->promise(), null, self::TIMEOUT); $client->close(); @@ -108,7 +105,7 @@ public function testSendDataWithEndToServerReceivesAllData() $this->markTestSkipped('TLS 1.3 supported, but this legacy PHP version does not support explicit choice'); } - $this->connector = new SecureConnector(new TcpConnector($this->loop), $this->loop, array( + $this->connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT )); @@ -125,14 +122,14 @@ public function testSendDataWithEndToServerReceivesAllData() }); }); - $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT); + $client = Block\await($this->connector->connect($this->address), null, self::TIMEOUT); /* @var $client ConnectionInterface */ $data = str_repeat('a', 200000); $client->end($data); // await server to report connection "close" event - $received = Block\await($disconnected->promise(), $this->loop, self::TIMEOUT); + $received = Block\await($disconnected->promise(), null, self::TIMEOUT); $this->assertEquals(strlen($data), strlen($received)); $this->assertEquals($data, $received); @@ -155,14 +152,19 @@ public function testSendDataWithoutEndingToServerReceivesAllData() }); $data = str_repeat('d', 200000); - $this->connector->connect($this->address)->then(function (ConnectionInterface $connection) use ($data) { + $connecting = $this->connector->connect($this->address); + $connecting->then(function (ConnectionInterface $connection) use ($data) { $connection->write($data); }); - $received = Block\await($promise, $this->loop, self::TIMEOUT); + $received = Block\await($promise, null, self::TIMEOUT); $this->assertEquals(strlen($data), strlen($received)); $this->assertEquals($data, $received); + + $connecting->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testConnectToServerWhichSendsSmallDataReceivesOneChunk() @@ -171,12 +173,12 @@ public function testConnectToServerWhichSendsSmallDataReceivesOneChunk() $peer->write('hello'); }); - $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT); + $client = Block\await($this->connector->connect($this->address), null, self::TIMEOUT); /* @var $client ConnectionInterface */ // await client to report one "data" event $receive = $this->createPromiseForEvent($client, 'data', $this->expectCallableOnceWith('hello')); - Block\await($receive, $this->loop, self::TIMEOUT); + Block\await($receive, null, self::TIMEOUT); $client->close(); } @@ -188,11 +190,11 @@ public function testConnectToServerWhichSendsDataWithEndReceivesAllData() $peer->end($data); }); - $client = Block\await($this->connector->connect($this->address), $this->loop, self::TIMEOUT); + $client = Block\await($this->connector->connect($this->address), null, self::TIMEOUT); /* @var $client ConnectionInterface */ // await data from client until it closes - $received = $this->buffer($client, $this->loop, self::TIMEOUT); + $received = $this->buffer($client, self::TIMEOUT); $this->assertEquals($data, $received); } @@ -204,10 +206,10 @@ public function testConnectToServerWhichSendsDataWithoutEndingReceivesAllData() $peer->write($data); }); - $promise = $this->connector->connect($this->address); + $connecting = $this->connector->connect($this->address); - $promise = new Promise(function ($resolve, $reject) use ($promise) { - $promise->then(function (ConnectionInterface $connection) use ($resolve) { + $promise = new Promise(function ($resolve, $reject) use ($connecting) { + $connecting->then(function (ConnectionInterface $connection) use ($resolve) { $received = 0; $connection->on('data', function ($chunk) use (&$received, $resolve) { $received += strlen($chunk); @@ -219,9 +221,13 @@ public function testConnectToServerWhichSendsDataWithoutEndingReceivesAllData() }, $reject); }); - $received = Block\await($promise, $this->loop, self::TIMEOUT); + $received = Block\await($promise, null, self::TIMEOUT); $this->assertEquals(strlen($data), $received); + + $connecting->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } private function createPromiseForEvent(EventEmitterInterface $emitter, $event, $fn) diff --git a/tests/ServerTest.php b/tests/ServerTest.php index b46949ba..7c6af61d 100644 --- a/tests/ServerTest.php +++ b/tests/ServerTest.php @@ -3,7 +3,6 @@ namespace React\Tests\Socket; use Clue\React\Block; -use React\EventLoop\Factory; use React\Promise\Promise; use React\Socket\ConnectionInterface; use React\Socket\Server; @@ -27,13 +26,13 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $loop = $ref->getValue($tcp); $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + + $server->close(); } public function testCreateServerWithZeroPortAssignsRandomPort() { - $loop = Factory::create(); - - $server = new Server(0, $loop); + $server = new Server(0); $this->assertNotEquals(0, $server->getAddress()); $server->close(); } @@ -48,18 +47,18 @@ public function testConstructorThrowsForInvalidUri() public function testConstructorCreatesExpectedTcpServer() { - $loop = Factory::create(); - - $server = new Server(0, $loop); + $server = new Server(0); - $connector = new TcpConnector($loop); - $connector->connect($server->getAddress()) - ->then($this->expectCallableOnce(), $this->expectCallableNever()); + $connector = new TcpConnector(); + $promise = $connector->connect($server->getAddress()); + $promise->then($this->expectCallableOnce(), $this->expectCallableNever()); - $connection = Block\await($connector->connect($server->getAddress()), $loop, self::TIMEOUT); + $connection = Block\await($connector->connect($server->getAddress()), null, self::TIMEOUT); - $connection->close(); $server->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testConstructorCreatesExpectedUnixServer() @@ -71,15 +70,13 @@ public function testConstructorCreatesExpectedUnixServer() $this->markTestSkipped('Unix domain sockets (UDS) not supported on your platform (Windows?)'); } - $loop = Factory::create(); + $server = new Server($this->getRandomSocketUri()); - $server = new Server($this->getRandomSocketUri(), $loop); - - $connector = new UnixConnector($loop); + $connector = new UnixConnector(); $connector->connect($server->getAddress()) ->then($this->expectCallableOnce(), $this->expectCallableNever()); - $connection = Block\await($connector->connect($server->getAddress()), $loop, self::TIMEOUT); + $connection = Block\await($connector->connect($server->getAddress()), null, self::TIMEOUT); $connection->close(); $server->close(); @@ -91,10 +88,8 @@ public function testConstructorThrowsForExistingUnixPath() $this->markTestSkipped('Unix domain sockets (UDS) not supported on your platform (Windows?)'); } - $loop = Factory::create(); - try { - $server = new Server('unix://' . __FILE__, $loop); + $server = new Server('unix://' . __FILE__); $this->fail(); } catch (\RuntimeException $e) { if ($e->getCode() === 0) { @@ -109,9 +104,7 @@ public function testConstructorThrowsForExistingUnixPath() public function testEmitsErrorWhenUnderlyingTcpServerEmitsError() { - $loop = Factory::create(); - - $server = new Server(0, $loop); + $server = new Server(0); $ref = new \ReflectionProperty($server, 'server'); $ref->setAccessible(true); @@ -126,9 +119,7 @@ public function testEmitsErrorWhenUnderlyingTcpServerEmitsError() public function testEmitsConnectionForNewConnection() { - $loop = Factory::create(); - - $server = new Server(0, $loop); + $server = new Server(0); $server->on('connection', $this->expectCallableOnce()); $peer = new Promise(function ($resolve, $reject) use ($server) { @@ -137,27 +128,25 @@ public function testEmitsConnectionForNewConnection() $client = stream_socket_client($server->getAddress()); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); + + $server->close(); } public function testDoesNotEmitConnectionForNewConnectionToPausedServer() { - $loop = Factory::create(); - - $server = new Server(0, $loop); + $server = new Server(0); $server->pause(); $server->on('connection', $this->expectCallableNever()); $client = stream_socket_client($server->getAddress()); - Block\sleep(0.1, $loop); + Block\sleep(0.1, null); } public function testDoesEmitConnectionForNewConnectionToResumedServer() { - $loop = Factory::create(); - - $server = new Server(0, $loop); + $server = new Server(0); $server->pause(); $server->on('connection', $this->expectCallableOnce()); @@ -169,14 +158,14 @@ public function testDoesEmitConnectionForNewConnectionToResumedServer() $server->resume(); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); + + $server->close(); } public function testDoesNotAllowConnectionToClosedServer() { - $loop = Factory::create(); - - $server = new Server(0, $loop); + $server = new Server(0); $server->on('connection', $this->expectCallableNever()); $address = $server->getAddress(); $server->close(); @@ -193,9 +182,7 @@ public function testEmitsConnectionWithInheritedContextOptions() $this->markTestSkipped('Not supported on legacy HHVM < 3.13'); } - $loop = Factory::create(); - - $server = new Server(0, $loop, array( + $server = new Server(0, null, array( 'backlog' => 4 )); @@ -208,9 +195,11 @@ public function testEmitsConnectionWithInheritedContextOptions() $client = stream_socket_client($server->getAddress()); - $all = Block\await($peer, $loop, self::TIMEOUT); + $all = Block\await($peer, null, self::TIMEOUT); $this->assertEquals(array('socket' => array('backlog' => 4)), $all); + + $server->close(); } public function testDoesNotEmitSecureConnectionForNewPlaintextConnectionThatIsIdle() @@ -219,9 +208,7 @@ public function testDoesNotEmitSecureConnectionForNewPlaintextConnectionThatIsId $this->markTestSkipped('Not supported on legacy HHVM'); } - $loop = Factory::create(); - - $server = new Server('tls://127.0.0.1:0', $loop, array( + $server = new Server('tls://127.0.0.1:0', null, array( 'tls' => array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' ) @@ -230,7 +217,9 @@ public function testDoesNotEmitSecureConnectionForNewPlaintextConnectionThatIsId $client = stream_socket_client(str_replace('tls://', '', $server->getAddress())); - Block\sleep(0.1, $loop); + Block\sleep(0.1, null); + + $server->close(); } private function getRandomSocketUri() diff --git a/tests/SocketServerTest.php b/tests/SocketServerTest.php index 8f453dd1..0011fbaa 100644 --- a/tests/SocketServerTest.php +++ b/tests/SocketServerTest.php @@ -3,7 +3,6 @@ namespace React\Tests\Socket; use Clue\React\Block; -use React\EventLoop\Factory; use React\Promise\Promise; use React\Socket\ConnectionInterface; use React\Socket\SocketServer; @@ -32,9 +31,7 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() public function testCreateServerWithZeroPortAssignsRandomPort() { - $loop = Factory::create(); - - $socket = new SocketServer('127.0.0.1:0', array(), $loop); + $socket = new SocketServer('127.0.0.1:0', array()); $this->assertNotEquals(0, $socket->getAddress()); $socket->close(); } @@ -71,18 +68,18 @@ public function testConstructorWithInvalidUriWithSchemaAndPortOnlyThrows() public function testConstructorCreatesExpectedTcpServer() { - $loop = Factory::create(); - - $socket = new SocketServer('127.0.0.1:0', array(), $loop); + $socket = new SocketServer('127.0.0.1:0', array()); - $connector = new TcpConnector($loop); - $connector->connect($socket->getAddress()) - ->then($this->expectCallableOnce(), $this->expectCallableNever()); + $connector = new TcpConnector(); + $promise = $connector->connect($socket->getAddress()); + $promise->then($this->expectCallableOnce(), $this->expectCallableNever()); - $connection = Block\await($connector->connect($socket->getAddress()), $loop, self::TIMEOUT); + $connection = Block\await($connector->connect($socket->getAddress()), null, self::TIMEOUT); - $connection->close(); $socket->close(); + $promise->then(function (ConnectionInterface $connection) { + $connection->close(); + }); } public function testConstructorCreatesExpectedUnixServer() @@ -94,17 +91,14 @@ public function testConstructorCreatesExpectedUnixServer() $this->markTestSkipped('Unix domain sockets (UDS) not supported on your platform (Windows?)'); } - $loop = Factory::create(); - - $socket = new SocketServer($this->getRandomSocketUri(), array(), $loop); + $socket = new SocketServer($this->getRandomSocketUri(), array()); - $connector = new UnixConnector($loop); + $connector = new UnixConnector(); $connector->connect($socket->getAddress()) ->then($this->expectCallableOnce(), $this->expectCallableNever()); - $connection = Block\await($connector->connect($socket->getAddress()), $loop, self::TIMEOUT); + $connection = Block\await($connector->connect($socket->getAddress()), null, self::TIMEOUT); - $connection->close(); $socket->close(); } @@ -114,10 +108,8 @@ public function testConstructorThrowsForExistingUnixPath() $this->markTestSkipped('Unix domain sockets (UDS) not supported on your platform (Windows?)'); } - $loop = Factory::create(); - try { - new SocketServer('unix://' . __FILE__, array(), $loop); + new SocketServer('unix://' . __FILE__, array()); $this->fail(); } catch (\RuntimeException $e) { if ($e->getCode() === 0) { @@ -147,9 +139,7 @@ public function testConstructWithExistingFileDescriptorReturnsSameAddressAsOrigi public function testEmitsErrorWhenUnderlyingTcpServerEmitsError() { - $loop = Factory::create(); - - $socket = new SocketServer('127.0.0.1:0', array(), $loop); + $socket = new SocketServer('127.0.0.1:0', array()); $ref = new \ReflectionProperty($socket, 'server'); $ref->setAccessible(true); @@ -164,9 +154,7 @@ public function testEmitsErrorWhenUnderlyingTcpServerEmitsError() public function testEmitsConnectionForNewConnection() { - $loop = Factory::create(); - - $socket = new SocketServer('127.0.0.1:0', array(), $loop); + $socket = new SocketServer('127.0.0.1:0', array()); $socket->on('connection', $this->expectCallableOnce()); $peer = new Promise(function ($resolve, $reject) use ($socket) { @@ -175,27 +163,25 @@ public function testEmitsConnectionForNewConnection() $client = stream_socket_client($socket->getAddress()); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); + + $socket->close(); } public function testDoesNotEmitConnectionForNewConnectionToPausedServer() { - $loop = Factory::create(); - - $socket = new SocketServer('127.0.0.1:0', array(), $loop); + $socket = new SocketServer('127.0.0.1:0', array()); $socket->pause(); $socket->on('connection', $this->expectCallableNever()); $client = stream_socket_client($socket->getAddress()); - Block\sleep(0.1, $loop); + Block\sleep(0.1); } public function testDoesEmitConnectionForNewConnectionToResumedServer() { - $loop = Factory::create(); - - $socket = new SocketServer('127.0.0.1:0', array(), $loop); + $socket = new SocketServer('127.0.0.1:0', array()); $socket->pause(); $socket->on('connection', $this->expectCallableOnce()); @@ -207,14 +193,14 @@ public function testDoesEmitConnectionForNewConnectionToResumedServer() $socket->resume(); - Block\await($peer, $loop, self::TIMEOUT); + Block\await($peer, null, self::TIMEOUT); + + $socket->close(); } public function testDoesNotAllowConnectionToClosedServer() { - $loop = Factory::create(); - - $socket = new SocketServer('127.0.0.1:0', array(), $loop); + $socket = new SocketServer('127.0.0.1:0', array()); $socket->on('connection', $this->expectCallableNever()); $address = $socket->getAddress(); $socket->close(); @@ -231,13 +217,11 @@ public function testEmitsConnectionWithInheritedContextOptions() $this->markTestSkipped('Not supported on legacy HHVM < 3.13'); } - $loop = Factory::create(); - $socket = new SocketServer('127.0.0.1:0', array( 'tcp' => array( 'backlog' => 4 ) - ), $loop); + )); $peer = new Promise(function ($resolve, $reject) use ($socket) { $socket->on('connection', function (ConnectionInterface $connection) use ($resolve) { @@ -248,9 +232,11 @@ public function testEmitsConnectionWithInheritedContextOptions() $client = stream_socket_client($socket->getAddress()); - $all = Block\await($peer, $loop, self::TIMEOUT); + $all = Block\await($peer, null, self::TIMEOUT); $this->assertEquals(array('socket' => array('backlog' => 4)), $all); + + $socket->close(); } public function testDoesNotEmitSecureConnectionForNewPlaintextConnectionThatIsIdle() @@ -259,18 +245,18 @@ public function testDoesNotEmitSecureConnectionForNewPlaintextConnectionThatIsId $this->markTestSkipped('Not supported on legacy HHVM'); } - $loop = Factory::create(); - $socket = new SocketServer('tls://127.0.0.1:0', array( 'tls' => array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' ) - ), $loop); + )); $socket->on('connection', $this->expectCallableNever()); $client = stream_socket_client(str_replace('tls://', '', $socket->getAddress())); - Block\sleep(0.1, $loop); + Block\sleep(0.1); + + $socket->close(); } private function getRandomSocketUri() diff --git a/tests/TcpConnectorTest.php b/tests/TcpConnectorTest.php index 7ce6621b..0a9da7ca 100644 --- a/tests/TcpConnectorTest.php +++ b/tests/TcpConnectorTest.php @@ -3,7 +3,7 @@ namespace React\Tests\Socket; use Clue\React\Block; -use React\EventLoop\Factory; +use React\EventLoop\Loop; use React\Socket\ConnectionInterface; use React\Socket\TcpConnector; use React\Socket\TcpServer; @@ -27,9 +27,7 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() /** @test */ public function connectionToEmptyPortShouldFail() { - $loop = Factory::create(); - - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect('127.0.0.1:9999'); $this->setExpectedException( @@ -37,7 +35,7 @@ public function connectionToEmptyPortShouldFail() 'Connection to tcp://127.0.0.1:9999 failed: Connection refused' . (function_exists('socket_import_stream') ? ' (ECONNREFUSED)' : ''), defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111 ); - Block\await($promise, $loop, self::TIMEOUT); + Block\await($promise, null, self::TIMEOUT); } /** @test */ @@ -61,13 +59,11 @@ public function connectionToTcpServerShouldAddResourceToLoop() /** @test */ public function connectionToTcpServerShouldSucceed() { - $loop = Factory::create(); + $server = new TcpServer(9999); - $server = new TcpServer(9999, $loop); - - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); - $connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT); + $connection = Block\await($connector->connect('127.0.0.1:9999'), null, self::TIMEOUT); $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); @@ -78,9 +74,7 @@ public function connectionToTcpServerShouldSucceed() /** @test */ public function connectionToTcpServerShouldFailIfFileDescriptorsAreExceeded() { - $loop = Factory::create(); - - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); /** @var string[] $_ */ /** @var int $exit */ @@ -121,7 +115,7 @@ class_exists('PHPUnit\Framework\Error\Warning', true); } $this->setExpectedException('RuntimeException'); - Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT); + Block\await($connector->connect('127.0.0.1:9999'), null, self::TIMEOUT); } /** @test */ @@ -144,8 +138,7 @@ public function connectionToInvalidNetworkShouldFailWithUnreachableError() $this->markTestSkipped('Expected error ' . $enetunreach . ' but got ' . $errno . ' (' . $errstr . ') for ' . $address); } - $loop = Factory::create(); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $promise = $connector->connect($address); @@ -154,19 +147,24 @@ public function connectionToInvalidNetworkShouldFailWithUnreachableError() 'Connection to ' . $address . ' failed: ' . (function_exists('socket_strerror') ? socket_strerror($enetunreach) . ' (ENETUNREACH)' : 'Network is unreachable'), $enetunreach ); - Block\await($promise, $loop, self::TIMEOUT); + + try { + Block\await($promise, null, self::TIMEOUT); + } catch (\Exception $e) { + fclose($client); + + throw $e; + } } /** @test */ public function connectionToTcpServerShouldSucceedWithRemoteAdressSameAsTarget() { - $loop = Factory::create(); - - $server = new TcpServer(9999, $loop); + $server = new TcpServer(9999); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); - $connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT); + $connection = Block\await($connector->connect('127.0.0.1:9999'), null, self::TIMEOUT); /* @var $connection ConnectionInterface */ $this->assertEquals('tcp://127.0.0.1:9999', $connection->getRemoteAddress()); @@ -178,13 +176,11 @@ public function connectionToTcpServerShouldSucceedWithRemoteAdressSameAsTarget() /** @test */ public function connectionToTcpServerShouldSucceedWithLocalAdressOnLocalhost() { - $loop = Factory::create(); - - $server = new TcpServer(9999, $loop); + $server = new TcpServer(9999); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); - $connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT); + $connection = Block\await($connector->connect('127.0.0.1:9999'), null, self::TIMEOUT); /* @var $connection ConnectionInterface */ $this->assertContainsString('tcp://127.0.0.1:', $connection->getLocalAddress()); @@ -197,13 +193,11 @@ public function connectionToTcpServerShouldSucceedWithLocalAdressOnLocalhost() /** @test */ public function connectionToTcpServerShouldSucceedWithNullAddressesAfterConnectionClosed() { - $loop = Factory::create(); + $server = new TcpServer(9999); - $server = new TcpServer(9999, $loop); - - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); - $connection = Block\await($connector->connect('127.0.0.1:9999'), $loop, self::TIMEOUT); + $connection = Block\await($connector->connect('127.0.0.1:9999'), null, self::TIMEOUT); /* @var $connection ConnectionInterface */ $server->close(); @@ -216,52 +210,48 @@ public function connectionToTcpServerShouldSucceedWithNullAddressesAfterConnecti /** @test */ public function connectionToTcpServerWillCloseWhenOtherSideCloses() { - $loop = Factory::create(); - // immediately close connection and server once connection is in - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $server->on('connection', function (ConnectionInterface $conn) use ($server) { $conn->close(); $server->close(); }); $once = $this->expectCallableOnce(); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $connector->connect($server->getAddress())->then(function (ConnectionInterface $conn) use ($once) { $conn->write('hello'); $conn->on('close', $once); }); - $loop->run(); + Loop::run(); } - /** @test */ + /** @test + * @group test + */ public function connectionToEmptyIp6PortShouldFail() { - $loop = Factory::create(); - - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); $connector ->connect('[::1]:9999') ->then($this->expectCallableNever(), $this->expectCallableOnce()); - $loop->run(); + Loop::run(); } /** @test */ public function connectionToIp6TcpServerShouldSucceed() { - $loop = Factory::create(); - try { - $server = new TcpServer('[::1]:9999', $loop); + $server = new TcpServer('[::1]:9999'); } catch (\Exception $e) { $this->markTestSkipped('Unable to start IPv6 server socket (IPv6 not supported on this system?)'); } - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); - $connection = Block\await($connector->connect('[::1]:9999'), $loop, self::TIMEOUT); + $connection = Block\await($connector->connect('[::1]:9999'), null, self::TIMEOUT); /* @var $connection ConnectionInterface */ $this->assertEquals('tcp://[::1]:9999', $connection->getRemoteAddress()); @@ -346,10 +336,9 @@ public function cancellingConnectionShouldRemoveResourceFromLoopAndCloseResource /** @test */ public function cancellingConnectionShouldRejectPromise() { - $loop = Factory::create(); - $connector = new TcpConnector($loop); + $connector = new TcpConnector(); - $server = new TcpServer(0, $loop); + $server = new TcpServer(0); $promise = $connector->connect($server->getAddress()); $promise->cancel(); @@ -359,7 +348,13 @@ public function cancellingConnectionShouldRejectPromise() 'Connection to ' . $server->getAddress() . ' cancelled during TCP/IP handshake (ECONNABORTED)', defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103 ); - Block\await($promise, $loop); + + try { + Block\await($promise); + } catch (\Exception $e) { + $server->close(); + throw $e; + } } public function testCancelDuringConnectionShouldNotCreateAnyGarbageReferences() diff --git a/tests/TcpServerTest.php b/tests/TcpServerTest.php index b4749cf6..dae7e7d7 100644 --- a/tests/TcpServerTest.php +++ b/tests/TcpServerTest.php @@ -3,7 +3,7 @@ namespace React\Tests\Socket; use Clue\React\Block; -use React\EventLoop\Factory; +use React\EventLoop\Loop; use React\Socket\TcpServer; use React\Stream\DuplexResourceStream; use React\Promise\Promise; @@ -12,15 +12,9 @@ class TcpServerTest extends TestCase { const TIMEOUT = 5.0; - private $loop; private $server; private $port; - private function createLoop() - { - return Factory::create(); - } - /** * @before * @covers React\Socket\TcpServer::__construct @@ -28,8 +22,7 @@ private function createLoop() */ public function setUpServer() { - $this->loop = $this->createLoop(); - $this->server = new TcpServer(0, $this->loop); + $this->server = new TcpServer(0); $this->port = parse_url($this->server->getAddress(), PHP_URL_PORT); } @@ -43,6 +36,8 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $loop = $ref->getValue($server); $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + + $server->close(); } /** @@ -58,7 +53,7 @@ public function testServerEmitsConnectionEventForNewConnection() $server->on('connection', $resolve); }); - $connection = Block\await($promise, $this->loop, self::TIMEOUT); + $connection = Block\await($promise, null, self::TIMEOUT); $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); } @@ -129,7 +124,7 @@ public function testLoopWillEndWhenServerIsClosed() $this->server->close(); $this->server = null; - $this->loop->run(); + Loop::run(); // if we reach this, then everything is good $this->assertNull(null); @@ -165,7 +160,7 @@ public function testLoopWillEndWhenServerIsClosedAfterSingleConnection() $server->close(); }); - $this->loop->run(); + Loop::run(); // if we reach this, then everything is good $this->assertNull(null); @@ -174,7 +169,7 @@ public function testLoopWillEndWhenServerIsClosedAfterSingleConnection() public function testDataWillBeEmittedInMultipleChunksWhenClientSendsExcessiveAmounts() { $client = stream_socket_client('tcp://localhost:' . $this->port); - $stream = new DuplexResourceStream($client, $this->loop); + $stream = new DuplexResourceStream($client); $bytes = 1024 * 1024; $stream->end(str_repeat('*', $bytes)); @@ -199,7 +194,7 @@ public function testDataWillBeEmittedInMultipleChunksWhenClientSendsExcessiveAmo $server->close(); }); - $this->loop->run(); + Loop::run(); $this->assertEquals($bytes, $received); } @@ -342,7 +337,7 @@ public function testListenOnBusyPortThrows() 'Failed to listen on "tcp://127.0.0.1:' . $this->port . '": ' . (function_exists('socket_strerror') ? socket_strerror(SOCKET_EADDRINUSE) . ' (EADDRINUSE)' : 'Address already in use'), defined('SOCKET_EADDRINUSE') ? SOCKET_EADDRINUSE : 0 ); - new TcpServer($this->port, $this->loop); + new TcpServer($this->port); } /** @@ -371,6 +366,6 @@ private function tick() $this->markTestSkipped('Not supported on Windows'); } - Block\sleep(0, $this->loop); + Block\sleep(0); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 6010b827..daf4e4aa 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -3,7 +3,6 @@ namespace React\Tests\Socket; use React\Stream\ReadableStreamInterface; -use React\EventLoop\LoopInterface; use Clue\React\Block; use React\Promise\Promise; use PHPUnit\Framework\TestCase as BaseTestCase; @@ -71,7 +70,7 @@ protected function createCallableMock() return $this->getMockBuilder('React\Tests\Socket\Stub\CallableStub')->getMock(); } - protected function buffer(ReadableStreamInterface $stream, LoopInterface $loop, $timeout) + protected function buffer(ReadableStreamInterface $stream, $timeout) { if (!$stream->isReadable()) { return ''; @@ -94,7 +93,7 @@ function () use ($stream) { $stream->close(); throw new \RuntimeException(); } - ), $loop, $timeout); + ), null, $timeout); } public function setExpectedException($exception, $exceptionMessage = '', $exceptionCode = null) diff --git a/tests/TimeoutConnectorTest.php b/tests/TimeoutConnectorTest.php index 81398279..806b16c5 100644 --- a/tests/TimeoutConnectorTest.php +++ b/tests/TimeoutConnectorTest.php @@ -5,7 +5,7 @@ use Clue\React\Block; use React\Socket\TimeoutConnector; use React\Promise; -use React\EventLoop\Factory; +use React\EventLoop\Loop; use React\Promise\Deferred; class TimeoutConnectorTest extends TestCase @@ -30,16 +30,14 @@ public function testRejectsWithTimeoutReasonOnTimeout() $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise)); - $loop = Factory::create(); - - $timeout = new TimeoutConnector($connector, 0.01, $loop); + $timeout = new TimeoutConnector($connector, 0.01); $this->setExpectedException( 'RuntimeException', 'Connection to google.com:80 timed out after 0.01 seconds (ETIMEDOUT)', \defined('SOCKET_ETIMEDOUT') ? \SOCKET_ETIMEDOUT : 110 ); - Block\await($timeout->connect('google.com:80'), $loop); + Block\await($timeout->connect('google.com:80')); } public function testRejectsWithOriginalReasonWhenConnectorRejects() @@ -49,16 +47,14 @@ public function testRejectsWithOriginalReasonWhenConnectorRejects() $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise)); - $loop = Factory::create(); - - $timeout = new TimeoutConnector($connector, 5.0, $loop); + $timeout = new TimeoutConnector($connector, 5.0); $this->setExpectedException( 'RuntimeException', 'Failed', 42 ); - Block\await($timeout->connect('google.com:80'), $loop); + Block\await($timeout->connect('google.com:80')); } public function testResolvesWhenConnectorResolves() @@ -68,16 +64,14 @@ public function testResolvesWhenConnectorResolves() $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise)); - $loop = Factory::create(); - - $timeout = new TimeoutConnector($connector, 5.0, $loop); + $timeout = new TimeoutConnector($connector, 5.0); $timeout->connect('google.com:80')->then( $this->expectCallableOnce(), $this->expectCallableNever() ); - $loop->run(); + Loop::run(); } public function testRejectsAndCancelsPendingPromiseOnTimeout() @@ -87,16 +81,14 @@ public function testRejectsAndCancelsPendingPromiseOnTimeout() $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise)); - $loop = Factory::create(); - - $timeout = new TimeoutConnector($connector, 0.01, $loop); + $timeout = new TimeoutConnector($connector, 0.01); $timeout->connect('google.com:80')->then( $this->expectCallableNever(), $this->expectCallableOnce() ); - $loop->run(); + Loop::run(); } public function testCancelsPendingPromiseOnCancel() @@ -106,9 +98,7 @@ public function testCancelsPendingPromiseOnCancel() $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->once())->method('connect')->with('google.com:80')->will($this->returnValue($promise)); - $loop = Factory::create(); - - $timeout = new TimeoutConnector($connector, 0.01, $loop); + $timeout = new TimeoutConnector($connector, 0.01); $out = $timeout->connect('google.com:80'); $out->cancel(); @@ -128,8 +118,7 @@ public function testRejectionDuringConnectionShouldNotCreateAnyGarbageReferences $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn($connection->promise()); - $loop = Factory::create(); - $timeout = new TimeoutConnector($connector, 0.01, $loop); + $timeout = new TimeoutConnector($connector, 0.01); $promise = $timeout->connect('example.com:80'); $connection->reject(new \RuntimeException('Connection failed')); @@ -152,12 +141,11 @@ public function testRejectionDueToTimeoutShouldNotCreateAnyGarbageReferences() $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn($connection->promise()); - $loop = Factory::create(); - $timeout = new TimeoutConnector($connector, 0, $loop); + $timeout = new TimeoutConnector($connector, 0); $promise = $timeout->connect('example.com:80'); - $loop->run(); + Loop::run(); unset($promise, $connection); $this->assertEquals(0, gc_collect_cycles()); diff --git a/tests/TimerSpeedUpEventLoop.php b/tests/TimerSpeedUpEventLoop.php index f6287276..97308023 100644 --- a/tests/TimerSpeedUpEventLoop.php +++ b/tests/TimerSpeedUpEventLoop.php @@ -4,7 +4,6 @@ use React\Dns\Model\Message; use React\Dns\Resolver\ResolverInterface; -use React\EventLoop\Factory; use React\EventLoop\LoopInterface; use React\EventLoop\TimerInterface; use React\Promise; @@ -17,12 +16,12 @@ final class TimerSpeedUpEventLoop implements LoopInterface { /** @var LoopInterface */ private $loop; - + public function __construct(LoopInterface $loop) { $this->loop = $loop; } - + public function addReadStream($stream, $listener) { return $this->loop->addReadStream($stream, $listener); diff --git a/tests/UnixServerTest.php b/tests/UnixServerTest.php index b2d4b59f..8c0b08f6 100644 --- a/tests/UnixServerTest.php +++ b/tests/UnixServerTest.php @@ -3,13 +3,12 @@ namespace React\Tests\Socket; use Clue\React\Block; -use React\EventLoop\Factory; +use React\EventLoop\Loop; use React\Socket\UnixServer; use React\Stream\DuplexResourceStream; class UnixServerTest extends TestCase { - private $loop; private $server; private $uds; @@ -24,9 +23,8 @@ public function setUpServer() $this->markTestSkipped('Unix domain sockets (UDS) not supported on your platform (Windows?)'); } - $this->loop = Factory::create(); $this->uds = $this->getRandomSocketUri(); - $this->server = new UnixServer($this->uds, $this->loop); + $this->server = new UnixServer($this->uds); } public function testConstructWithoutLoopAssignsLoopAutomatically() @@ -38,6 +36,8 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $loop = $ref->getValue($server); $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + + $server->close(); } /** @@ -115,7 +115,7 @@ public function testLoopWillEndWhenServerIsClosed() $this->server->close(); $this->server = null; - $this->loop->run(); + Loop::run(); // if we reach this, then everything is good $this->assertNull(null); @@ -150,7 +150,7 @@ public function testLoopWillEndWhenServerIsClosedAfterSingleConnection() $server->close(); }); - $this->loop->run(); + Loop::run(); // if we reach this, then everything is good $this->assertNull(null); @@ -159,7 +159,7 @@ public function testLoopWillEndWhenServerIsClosedAfterSingleConnection() public function testDataWillBeEmittedInMultipleChunksWhenClientSendsExcessiveAmounts() { $client = stream_socket_client($this->uds); - $stream = new DuplexResourceStream($client, $this->loop); + $stream = new DuplexResourceStream($client); $bytes = 1024 * 1024; $stream->end(str_repeat('*', $bytes)); @@ -184,7 +184,7 @@ public function testDataWillBeEmittedInMultipleChunksWhenClientSendsExcessiveAmo $server->close(); }); - $this->loop->run(); + Loop::run(); $this->assertEquals($bytes, $received); } @@ -339,7 +339,7 @@ public function testListenOnBusyPortThrows() } $this->setExpectedException('RuntimeException'); - $another = new UnixServer($this->uds, $this->loop); + $another = new UnixServer($this->uds); } /** @@ -360,6 +360,6 @@ private function getRandomSocketUri() private function tick() { - Block\sleep(0, $this->loop); + Block\sleep(0); } }