From d15b8df9297c091a2bab0119dce55b1ade82566b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Wed, 1 Nov 2023 15:39:29 +0100 Subject: [PATCH 1/3] Update to require PHP 7.1+ --- .github/workflows/ci.yml | 23 ------------------ README.md | 35 +++++++--------------------- composer.json | 6 ++--- phpunit.xml.legacy | 2 +- src/Connection.php | 23 +++++++----------- src/SecureConnector.php | 7 ------ src/SecureServer.php | 7 ------ src/StreamEncryption.php | 7 +++--- src/TcpConnector.php | 24 ++----------------- src/UnixServer.php | 1 - tests/ConnectionTest.php | 8 ------- tests/FdServerTest.php | 32 ++++++++++++------------- tests/FunctionalConnectorTest.php | 11 --------- tests/FunctionalSecureServerTest.php | 30 +++--------------------- tests/FunctionalTcpServerTest.php | 5 ---- tests/IntegrationTest.php | 19 --------------- tests/SecureConnectorTest.php | 4 ---- tests/SecureIntegrationTest.php | 11 +-------- tests/SecureServerTest.php | 10 -------- tests/SocketServerTest.php | 14 +---------- tests/TcpConnectorTest.php | 2 +- tests/TcpServerTest.php | 7 ------ tests/TestCase.php | 19 +++++---------- tests/UnixServerTest.php | 4 ---- 24 files changed, 55 insertions(+), 256 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e7d91e1..6182e65a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,11 +22,6 @@ jobs: - 7.3 - 7.2 - 7.1 - - 7.0 - - 5.6 - - 5.5 - - 5.4 - - 5.3 steps: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 @@ -34,8 +29,6 @@ jobs: php-version: ${{ matrix.php }} coverage: xdebug ini-file: development - - run: composer config secure-http false && composer config repo.packagist composer http://packagist.org && composer config preferred-install source - if: ${{ matrix.php < 5.5 && matrix.os == 'windows-2022' }} # legacy PHP on Windows is allowed to use insecure downloads until it will be removed again - run: composer install - run: vendor/bin/phpunit --coverage-text if: ${{ matrix.php >= 7.3 }} @@ -54,19 +47,3 @@ jobs: coverage: xdebug - run: composer install - run: vendor/bin/phpunit --coverage-text - - PHPUnit-hhvm: - name: PHPUnit (HHVM) - runs-on: ubuntu-22.04 - continue-on-error: true - steps: - - uses: actions/checkout@v4 - - run: cp "$(which composer)" composer.phar && ./composer.phar self-update --2.2 # downgrade Composer for HHVM - - name: Run hhvm composer.phar install - uses: docker://hhvm/hhvm:3.30-lts-latest - with: - args: hhvm composer.phar install - - name: Run hhvm vendor/bin/phpunit - uses: docker://hhvm/hhvm:3.30-lts-latest - with: - args: hhvm vendor/bin/phpunit diff --git a/README.md b/README.md index c6783450..3e758354 100644 --- a/README.md +++ b/README.md @@ -472,7 +472,7 @@ $socket = new React\Socket\SocketServer('tls://127.0.0.1:8000', array( ``` By default, this server supports TLSv1.0+ and excludes support for legacy -SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you +SSLv2/SSLv3. You can also explicitly choose the TLS version you want to negotiate with the remote side: ```php @@ -650,7 +650,7 @@ $server = new React\Socket\SecureServer($server, null, array( ``` By default, this server supports TLSv1.0+ and excludes support for legacy -SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you +SSLv2/SSLv3. You can also explicitly choose the TLS version you want to negotiate with the remote side: ```php @@ -1087,7 +1087,7 @@ $connector->connect('tls://localhost:443')->then(function (React\Socket\Connecti ``` By default, this connector supports TLSv1.0+ and excludes support for legacy -SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you +SSLv2/SSLv3. You can also explicitly choose the TLS version you want to negotiate with the remote side: ```php @@ -1370,7 +1370,7 @@ $secureConnector = new React\Socket\SecureConnector($dnsConnector, null, array( ``` By default, this connector supports TLSv1.0+ and excludes support for legacy -SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you +SSLv2/SSLv3. You can also explicitly choose the TLS version you want to negotiate with the remote side: ```php @@ -1490,19 +1490,10 @@ composer require react/socket:^3@dev See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. This project aims to run on any platform and thus does not require any PHP -extensions and supports running on legacy PHP 5.3 through current PHP 8+ and HHVM. -It's *highly recommended to use the latest supported PHP version* for this project, -partly due to its vast performance improvements and partly because legacy PHP -versions require several workarounds as described below. - -Secure TLS connections received some major upgrades starting with PHP 5.6, with -the defaults now being more secure, while older versions required explicit -context options. -This library does not take responsibility over these context options, so it's -up to consumers of this library to take care of setting appropriate context -options as described above. - -PHP < 7.3.3 (and PHP < 7.2.15) suffers from a bug where feof() might +extensions and supports running on PHP 7.1 through current PHP 8+. +It's *highly recommended to use the latest supported PHP version* for this project. + +Legacy PHP < 7.3.3 (and PHP < 7.2.15) suffers from a bug where feof() might block with 100% CPU usage on fragmented TLS records. We try to work around this by always consuming the complete receive buffer at once to avoid stale data in TLS buffers. This is known to @@ -1511,21 +1502,13 @@ cause very large data chunks for high throughput scenarios. The buggy behavior can still be triggered due to network I/O buffers or malicious peers on affected versions, upgrading is highly recommended. -PHP < 7.1.4 (and PHP < 7.0.18) suffers from a bug when writing big +Legacy PHP < 7.1.4 suffers from a bug when writing big chunks of data over TLS streams at once. We try to work around this by limiting the write chunk size to 8192 bytes for older PHP versions only. This is only a work-around and has a noticable performance penalty on affected versions. -This project also supports running on HHVM. -Note that really old HHVM < 3.8 does not support secure TLS connections, as it -lacks the required `stream_socket_enable_crypto()` function. -As such, trying to create a secure TLS connections on affected versions will -return a rejected promise instead. -This issue is also covered by our test suite, which will skip related tests -on affected versions. - ## Tests To run the test suite, you first need to clone this repo and then install all diff --git a/composer.json b/composer.json index 02c184fb..87bd8a1b 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ } ], "require": { - "php": ">=5.3.0", + "php": ">=7.1", "evenement/evenement": "^3.0 || ^2.0 || ^1.0", "react/dns": "^1.11", "react/event-loop": "^1.2", @@ -34,8 +34,8 @@ "react/stream": "^1.2" }, "require-dev": { - "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", - "react/async": "^4 || ^3 || ^2", + "phpunit/phpunit": "^9.6 || ^5.7", + "react/async": "^4 || ^3", "react/promise-stream": "^1.4", "react/promise-timer": "^1.10" }, diff --git a/phpunit.xml.legacy b/phpunit.xml.legacy index 89161168..a018d7ab 100644 --- a/phpunit.xml.legacy +++ b/phpunit.xml.legacy @@ -2,7 +2,7 @@ diff --git a/src/Connection.php b/src/Connection.php index 65ae26b4..72286b79 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -43,8 +43,8 @@ class Connection extends EventEmitter implements ConnectionInterface public function __construct($resource, LoopInterface $loop) { - // PHP < 7.3.3 (and PHP < 7.2.15) suffers from a bug where feof() might - // block with 100% CPU usage on fragmented TLS records. + // Legacy PHP < 7.3.3 (and PHP < 7.2.15) suffers from a bug where feof() + // might block with 100% CPU usage on fragmented TLS records. // We try to work around this by always consuming the complete receive // buffer at once to avoid stale data in TLS buffers. This is known to // work around high CPU usage for well-behaving peers, but this may @@ -54,7 +54,7 @@ public function __construct($resource, LoopInterface $loop) // @link https://bugs.php.net/bug.php?id=77390 $clearCompleteBuffer = \PHP_VERSION_ID < 70215 || (\PHP_VERSION_ID >= 70300 && \PHP_VERSION_ID < 70303); - // PHP < 7.1.4 (and PHP < 7.0.18) suffers from a bug when writing big + // Legacy PHP < 7.1.4 suffers from a bug when writing big // chunks of data over TLS streams at once. // We try to work around this by limiting the write chunk size to 8192 // bytes for older PHP versions only. @@ -62,7 +62,7 @@ public function __construct($resource, LoopInterface $loop) // affected versions. Please update your PHP version. // This applies to all streams because TLS may be enabled later on. // See https://github.com/reactphp/socket/issues/105 - $limitWriteChunks = (\PHP_VERSION_ID < 70018 || (\PHP_VERSION_ID >= 70100 && \PHP_VERSION_ID < 70104)); + $limitWriteChunks = \PHP_VERSION_ID < 70104; $this->input = new DuplexResourceStream( $resource, @@ -157,22 +157,17 @@ private function parseAddress($address) } if ($this->unix) { - // remove trailing colon from address for HHVM < 3.19: https://3v4l.org/5C1lo - // note that technically ":" is a valid address, so keep this in place otherwise - if (\substr($address, -1) === ':' && \defined('HHVM_VERSION_ID') && \HHVM_VERSION_ID < 31900) { - $address = (string)\substr($address, 0, -1); // @codeCoverageIgnore - } - - // work around unknown addresses should return null value: https://3v4l.org/5C1lo and https://bugs.php.net/bug.php?id=74556 - // PHP uses "\0" string and HHVM uses empty string (colon removed above) - if ($address === '' || $address[0] === "\x00" ) { + // Legacy PHP < 7.1.7 may use "\0" string instead of false: https://3v4l.org/5C1lo and https://bugs.php.net/bug.php?id=74556 + // Work around by returning null for "\0" string + if ($address[0] === "\x00" ) { return null; // @codeCoverageIgnore } return 'unix://' . $address; } - // check if this is an IPv6 address which includes multiple colons but no square brackets + // Legacy PHP < 7.3 uses IPv6 address which includes multiple colons but no square brackets: https://bugs.php.net/bug.php?id=76136 + // Work around by adding square brackets around IPv6 address when not already present $pos = \strrpos($address, ':'); if ($pos !== false && \strpos($address, ':') < $pos && \substr($address, 0, 1) !== '[') { $address = '[' . \substr($address, 0, $pos) . ']:' . \substr($address, $pos + 1); // @codeCoverageIgnore diff --git a/src/SecureConnector.php b/src/SecureConnector.php index 17c229d3..7c48e789 100644 --- a/src/SecureConnector.php +++ b/src/SecureConnector.php @@ -5,9 +5,6 @@ use React\EventLoop\Loop; use React\EventLoop\LoopInterface; use React\Promise; -use BadMethodCallException; -use InvalidArgumentException; -use UnexpectedValueException; final class SecureConnector implements ConnectorInterface { @@ -24,10 +21,6 @@ public function __construct(ConnectorInterface $connector, LoopInterface $loop = public function connect($uri) { - if (!\function_exists('stream_socket_enable_crypto')) { - return Promise\reject(new \BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)')); // @codeCoverageIgnore - } - if (\strpos($uri, '://') === false) { $uri = 'tls://' . $uri; } diff --git a/src/SecureServer.php b/src/SecureServer.php index d0525c94..fd1ed2c2 100644 --- a/src/SecureServer.php +++ b/src/SecureServer.php @@ -5,8 +5,6 @@ use Evenement\EventEmitter; use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -use BadMethodCallException; -use UnexpectedValueException; /** * The `SecureServer` class implements the `ServerInterface` and is responsible @@ -118,16 +116,11 @@ final class SecureServer extends EventEmitter implements ServerInterface * @param ServerInterface|TcpServer $tcp * @param ?LoopInterface $loop * @param array $context - * @throws BadMethodCallException for legacy HHVM < 3.8 due to lack of support * @see TcpServer * @link https://www.php.net/manual/en/context.ssl.php for TLS context options */ public function __construct(ServerInterface $tcp, LoopInterface $loop = null, array $context = array()) { - if (!\function_exists('stream_socket_enable_crypto')) { - throw new \BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)'); // @codeCoverageIgnore - } - // default to empty passphrase to suppress blocking passphrase prompt $context += array( 'passphrase' => '' diff --git a/src/StreamEncryption.php b/src/StreamEncryption.php index f91a3597..60f101ea 100644 --- a/src/StreamEncryption.php +++ b/src/StreamEncryption.php @@ -26,19 +26,18 @@ public function __construct(LoopInterface $loop, $server = true) // support TLSv1.0+ by default and exclude legacy SSLv2/SSLv3. // As of PHP 7.2+ the main crypto method constant includes all TLS versions. - // As of PHP 5.6+ the crypto method is a bitmask, so we explicitly include all TLS versions. - // For legacy PHP < 5.6 the crypto method is a single value only and this constant includes all TLS versions. + // In prior PHP versions, the crypto method is a bitmask, so we explicitly include all TLS versions. // @link https://3v4l.org/9PSST if ($server) { $this->method = \STREAM_CRYPTO_METHOD_TLS_SERVER; - if (\PHP_VERSION_ID < 70200 && \PHP_VERSION_ID >= 50600) { + if (\PHP_VERSION_ID < 70200) { $this->method |= \STREAM_CRYPTO_METHOD_TLSv1_0_SERVER | \STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | \STREAM_CRYPTO_METHOD_TLSv1_2_SERVER; // @codeCoverageIgnore } } else { $this->method = \STREAM_CRYPTO_METHOD_TLS_CLIENT; - if (\PHP_VERSION_ID < 70200 && \PHP_VERSION_ID >= 50600) { + if (\PHP_VERSION_ID < 70200) { $this->method |= \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; // @codeCoverageIgnore } } diff --git a/src/TcpConnector.php b/src/TcpConnector.php index 8cfc7bf4..61781e01 100644 --- a/src/TcpConnector.php +++ b/src/TcpConnector.php @@ -62,22 +62,9 @@ public function connect($uri) 'SNI_enabled' => true, 'peer_name' => $args['hostname'] ); - - // Legacy PHP < 5.6 ignores peer_name and requires legacy context options instead. - // The SNI_server_name context option has to be set here during construction, - // as legacy PHP ignores any values set later. - // @codeCoverageIgnoreStart - if (\PHP_VERSION_ID < 50600) { - $context['ssl'] += array( - 'SNI_server_name' => $args['hostname'], - 'CN_match' => $args['hostname'] - ); - } - // @codeCoverageIgnoreEnd } - // latest versions of PHP no longer accept any other URI components and - // HHVM fails to parse URIs with a query but no path, so let's simplify our URI here + // PHP 7.1.4 does not accept any other URI components (such as a query with no path), so let's simplify our URI here $remote = 'tcp://' . $parts['host'] . ':' . $parts['port']; $stream = @\stream_socket_client( @@ -108,7 +95,7 @@ public function connect($uri) // If we reach this point, we know the connection is dead, but we don't know the underlying error condition. // @codeCoverageIgnoreStart if (\function_exists('socket_import_stream')) { - // actual socket errno and errstr can be retrieved with ext-sockets on PHP 5.4+ + // actual socket errno and errstr can be retrieved with ext-sockets $socket = \socket_import_stream($stream); $errno = \socket_get_option($socket, \SOL_SOCKET, \SO_ERROR); $errstr = \socket_strerror($errno); @@ -149,13 +136,6 @@ public function connect($uri) $loop->removeWriteStream($stream); \fclose($stream); - // @codeCoverageIgnoreStart - // legacy PHP 5.3 sometimes requires a second close call (see tests) - if (\PHP_VERSION_ID < 50400 && \is_resource($stream)) { - \fclose($stream); - } - // @codeCoverageIgnoreEnd - throw new \RuntimeException( 'Connection to ' . $uri . ' cancelled during TCP/IP handshake (ECONNABORTED)', \defined('SOCKET_ECONNABORTED') ? \SOCKET_ECONNABORTED : 103 diff --git a/src/UnixServer.php b/src/UnixServer.php index cc46968d..1aca62ff 100644 --- a/src/UnixServer.php +++ b/src/UnixServer.php @@ -68,7 +68,6 @@ public function __construct($path, LoopInterface $loop = null, array $context = \set_error_handler(function ($_, $error) use (&$errno, &$errstr) { // PHP does not seem to report errno/errstr for Unix domain sockets (UDS) right now. // This only applies to UDS server sockets, see also https://3v4l.org/NAhpr. - // Parse PHP warning message containing unknown error, HHVM reports proper info at least. if (\preg_match('/\(([^\)]+)\)|\[(\d+)\]: (.*)/', $error, $match)) { $errstr = isset($match[3]) ? $match['3'] : $match[1]; $errno = isset($match[2]) ? (int)$match[2] : 0; diff --git a/tests/ConnectionTest.php b/tests/ConnectionTest.php index d3563dfc..49d53e26 100644 --- a/tests/ConnectionTest.php +++ b/tests/ConnectionTest.php @@ -8,10 +8,6 @@ class ConnectionTest extends TestCase { public function testCloseConnectionWillCloseSocketResource() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('HHVM does not support socket operation on test memory stream'); - } - $resource = fopen('php://memory', 'r+'); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); @@ -23,10 +19,6 @@ public function testCloseConnectionWillCloseSocketResource() public function testCloseConnectionWillRemoveResourceFromLoopBeforeClosingResource() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('HHVM does not support socket operation on test memory stream'); - } - $resource = fopen('php://memory', 'r+'); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->once())->method('addWriteStream')->with($resource); diff --git a/tests/FdServerTest.php b/tests/FdServerTest.php index 7a97ae7d..87fa63cf 100644 --- a/tests/FdServerTest.php +++ b/tests/FdServerTest.php @@ -10,7 +10,7 @@ class FdServerTest extends TestCase { public function testCtorAddsResourceToLoop() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -52,7 +52,7 @@ public function testCtorThrowsForInvalidUrl() public function testCtorThrowsForUnknownFdWithoutCallingCustomErrorHandler() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -86,7 +86,7 @@ public function testCtorThrowsForUnknownFdWithoutCallingCustomErrorHandler() public function testCtorThrowsIfFdIsAFileAndNotASocket() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -107,7 +107,7 @@ public function testCtorThrowsIfFdIsAFileAndNotASocket() public function testCtorThrowsIfFdIsAConnectedSocketInsteadOfServerSocket() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -130,7 +130,7 @@ public function testCtorThrowsIfFdIsAConnectedSocketInsteadOfServerSocket() public function testGetAddressReturnsSameAddressAsOriginalSocketForIpv4Socket() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -146,7 +146,7 @@ public function testGetAddressReturnsSameAddressAsOriginalSocketForIpv4Socket() public function testGetAddressReturnsSameAddressAsOriginalSocketForIpv4SocketGivenAsUrlToFd() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -162,7 +162,7 @@ public function testGetAddressReturnsSameAddressAsOriginalSocketForIpv4SocketGiv public function testGetAddressReturnsSameAddressAsOriginalSocketForIpv6Socket() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -182,7 +182,7 @@ public function testGetAddressReturnsSameAddressAsOriginalSocketForIpv6Socket() public function testGetAddressReturnsSameAddressAsOriginalSocketForUnixDomainSocket() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -204,7 +204,7 @@ public function testGetAddressReturnsSameAddressAsOriginalSocketForUnixDomainSoc public function testGetAddressReturnsNullAfterClose() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -222,7 +222,7 @@ public function testGetAddressReturnsNullAfterClose() public function testCloseRemovesResourceFromLoop() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -239,7 +239,7 @@ public function testCloseRemovesResourceFromLoop() public function testCloseTwiceRemovesResourceFromLoopOnce() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -257,7 +257,7 @@ public function testCloseTwiceRemovesResourceFromLoopOnce() public function testResumeWithoutPauseIsNoOp() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -274,7 +274,7 @@ public function testResumeWithoutPauseIsNoOp() public function testPauseRemovesResourceFromLoop() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -291,7 +291,7 @@ public function testPauseRemovesResourceFromLoop() public function testPauseAfterPauseIsNoOp() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -309,7 +309,7 @@ public function testPauseAfterPauseIsNoOp() public function testServerEmitsConnectionEventForNewConnection() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -338,7 +338,7 @@ public function testServerEmitsConnectionEventForNewConnection() public function testEmitsErrorWhenAcceptListenerFailsWithoutCallingCustomErrorHandler() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } diff --git a/tests/FunctionalConnectorTest.php b/tests/FunctionalConnectorTest.php index 5e38544f..0a54b505 100644 --- a/tests/FunctionalConnectorTest.php +++ b/tests/FunctionalConnectorTest.php @@ -37,10 +37,6 @@ public function connectionToTcpServerShouldSucceedWithLocalhost() */ public function testConnectTwiceWithoutHappyEyeBallsOnlySendsSingleDnsQueryDueToLocalDnsCache() { - if ((DIRECTORY_SEPARATOR === '\\' && PHP_VERSION_ID < 70000) || defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on Windows for PHP versions < 7.0 and legacy HHVM'); - } - $socket = stream_socket_server('udp://127.0.0.1:0', $errno, $errstr, STREAM_SERVER_BIND); $connector = new Connector(array( @@ -79,9 +75,6 @@ public function testConnectTwiceWithoutHappyEyeBallsOnlySendsSingleDnsQueryDueTo */ 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); - $connector = new Connector(array('happy_eyeballs' => true)); $ip = \React\Async\await(\React\Promise\Timer\timeout($this->request('dual.tlund.se', $connector), self::TIMEOUT)); @@ -129,10 +122,6 @@ public function connectionToRemoteTCP6ServerShouldResultInOurIP() public function testCancelPendingTlsConnectionDuringTlsHandshakeShouldCloseTcpConnectionToServer() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } - $server = new TcpServer(0); $uri = str_replace('tcp://', 'tls://', $server->getAddress()); diff --git a/tests/FunctionalSecureServerTest.php b/tests/FunctionalSecureServerTest.php index f749a591..94aace37 100644 --- a/tests/FunctionalSecureServerTest.php +++ b/tests/FunctionalSecureServerTest.php @@ -14,16 +14,6 @@ class FunctionalSecureServerTest extends TestCase { const TIMEOUT = 2; - /** - * @before - */ - public function setUpSkipTest() - { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } - } - public function testClientCanConnectToServer() { $server = new TcpServer(0); @@ -48,11 +38,11 @@ public function testClientCanConnectToServer() public function testClientUsesTls13ByDefaultWhenSupportedByOpenSSL() { - if (PHP_VERSION_ID < 70000 || (PHP_VERSION_ID >= 70300 && PHP_VERSION_ID < 70400) || !$this->supportsTls13()) { + if ((PHP_VERSION_ID >= 70300 && PHP_VERSION_ID < 70400) || !$this->supportsTls13()) { // @link https://github.com/php/php-src/pull/3909 explicitly adds TLS 1.3 on PHP 7.4 // @link https://github.com/php/php-src/pull/3317 implicitly limits to TLS 1.2 on PHP 7.3 - // all older PHP versions support TLS 1.3 (provided OpenSSL supports it), but only PHP 7 allows checking the version - $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'); + // all older PHP versions support TLS 1.3 (provided OpenSSL supports it) + $this->markTestSkipped('Test requires OpenSSL 1.1.1+ for TLS 1.3 but excludes PHP 7.3 because it implicitly limits to TLS 1.2'); } $server = new TcpServer(0); @@ -89,10 +79,6 @@ public function testClientUsesTls13ByDefaultWhenSupportedByOpenSSL() public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByClient() { - if (PHP_VERSION_ID < 70000) { - $this->markTestSkipped('Test requires PHP 7+ for crypto meta data'); - } - $server = new TcpServer(0); $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' @@ -120,10 +106,6 @@ public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByClien public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByServer() { - if (PHP_VERSION_ID < 70000) { - $this->markTestSkipped('Test requires PHP 7+ for crypto meta data'); - } - $server = new TcpServer(0); $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem', @@ -151,10 +133,6 @@ public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByServe public function testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClient() { - if (PHP_VERSION_ID < 70000) { - $this->markTestSkipped('Test requires PHP 7+ for crypto meta data'); - } - $server = new TcpServer(0); $server = new SecureServer($server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' @@ -459,7 +437,6 @@ public function testPipesDataBackInMultipleChunksFromConnection() } /** - * @requires PHP 5.6 * @depends testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClient */ public function testEmitsConnectionForNewTlsv11Connection() @@ -486,7 +463,6 @@ public function testEmitsConnectionForNewTlsv11Connection() } /** - * @requires PHP 5.6 * @depends testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClient */ public function testEmitsErrorForClientWithTlsVersionMismatch() diff --git a/tests/FunctionalTcpServerTest.php b/tests/FunctionalTcpServerTest.php index 7575d321..a020be9d 100644 --- a/tests/FunctionalTcpServerTest.php +++ b/tests/FunctionalTcpServerTest.php @@ -358,11 +358,6 @@ public function testServerPassesDefaultBacklogSizeViaContextOptionsToSocket() public function testEmitsConnectionWithInheritedContextOptions() { - if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.13', '<')) { - // https://3v4l.org/hB4Tc - $this->markTestSkipped('Not supported on legacy HHVM < 3.13'); - } - $server = new TcpServer(0, null, array( 'backlog' => 4 )); diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 4d9c8044..f7033c4a 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -37,10 +37,6 @@ public function gettingStuffFromGoogleShouldWork() /** @test */ public function gettingEncryptedStuffFromGoogleShouldWork() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } - $secureConnector = new Connector(array()); $conn = \React\Async\await($secureConnector->connect('tls://google.com:443')); @@ -57,10 +53,6 @@ public function gettingEncryptedStuffFromGoogleShouldWork() /** @test */ public function gettingEncryptedStuffFromGoogleShouldWorkIfHostIsResolvedFirst() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } - $factory = new ResolverFactory(); $dns = $factory->create('8.8.8.8'); @@ -301,9 +293,6 @@ function ($e) use (&$wait) { $this->assertEquals(0, gc_collect_cycles()); } - /** - * @requires PHP 7 - */ public function testWaitingForInvalidTlsConnectionShouldNotCreateAnyGarbageReferences() { if (class_exists('React\Promise\When')) { @@ -379,10 +368,6 @@ public function testConnectingFailsIfTimeoutIsTooSmall() public function testSelfSignedRejectsIfVerificationIsEnabled() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } - $connector = new Connector(array( 'tls' => array( 'verify_peer' => true @@ -395,10 +380,6 @@ public function testSelfSignedRejectsIfVerificationIsEnabled() public function testSelfSignedResolvesIfVerificationIsDisabled() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } - $connector = new Connector(array( 'tls' => array( 'verify_peer' => false diff --git a/tests/SecureConnectorTest.php b/tests/SecureConnectorTest.php index e81f4a97..4fdae8e0 100644 --- a/tests/SecureConnectorTest.php +++ b/tests/SecureConnectorTest.php @@ -17,10 +17,6 @@ class SecureConnectorTest extends TestCase */ public function setUpConnector() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } - $this->loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $this->tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $this->connector = new SecureConnector($this->tcp, $this->loop); diff --git a/tests/SecureIntegrationTest.php b/tests/SecureIntegrationTest.php index f3b09668..eaa7ca38 100644 --- a/tests/SecureIntegrationTest.php +++ b/tests/SecureIntegrationTest.php @@ -24,10 +24,6 @@ class SecureIntegrationTest extends TestCase */ public function setUpConnector() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } - $this->server = new TcpServer(0); $this->server = new SecureServer($this->server, null, array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' @@ -96,14 +92,9 @@ public function testSendSmallDataToServerReceivesOneChunk() public function testSendDataWithEndToServerReceivesAllData() { // PHP can report EOF on TLS 1.3 stream before consuming all data, so - // we explicitly use older TLS version instead. Selecting TLS version - // requires PHP 5.6+, so skip legacy versions if TLS 1.3 is supported. + // we explicitly use older TLS version instead. // Continue if TLS 1.3 is not supported anyway. if ($this->supportsTls13()) { - if (!defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) { - $this->markTestSkipped('TLS 1.3 supported, but this legacy PHP version does not support explicit choice'); - } - $this->connector = new SecureConnector(new TcpConnector(), null, array( 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT diff --git a/tests/SecureServerTest.php b/tests/SecureServerTest.php index a6ddcf29..b7cdefbe 100644 --- a/tests/SecureServerTest.php +++ b/tests/SecureServerTest.php @@ -8,16 +8,6 @@ class SecureServerTest extends TestCase { - /** - * @before - */ - public function setUpSkipTest() - { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } - } - public function testConstructWithoutLoopAssignsLoopAutomatically() { $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); diff --git a/tests/SocketServerTest.php b/tests/SocketServerTest.php index c7cee8ec..aa241aca 100644 --- a/tests/SocketServerTest.php +++ b/tests/SocketServerTest.php @@ -83,9 +83,6 @@ public function testConstructorCreatesExpectedTcpServer() public function testConstructorCreatesExpectedUnixServer() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } if (!in_array('unix', stream_get_transports())) { $this->markTestSkipped('Unix domain sockets (UDS) not supported on your platform (Windows?)'); } @@ -127,7 +124,7 @@ public function testConstructorThrowsForExistingUnixPath() public function testConstructWithExistingFileDescriptorReturnsSameAddressAsOriginalSocketForIpv4Socket() { - if (!is_dir('/dev/fd') || defined('HHVM_VERSION')) { + if (!is_dir('/dev/fd')) { $this->markTestSkipped('Not supported on your platform'); } @@ -219,11 +216,6 @@ public function testDoesNotAllowConnectionToClosedServer() public function testEmitsConnectionWithInheritedContextOptions() { - if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.13', '<')) { - // https://3v4l.org/hB4Tc - $this->markTestSkipped('Not supported on legacy HHVM < 3.13'); - } - $socket = new SocketServer('127.0.0.1:0', array( 'tcp' => array( 'backlog' => 4 @@ -248,10 +240,6 @@ public function testEmitsConnectionWithInheritedContextOptions() public function testDoesNotEmitSecureConnectionForNewPlaintextConnectionThatIsIdle() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on legacy HHVM'); - } - $socket = new SocketServer('tls://127.0.0.1:0', array( 'tls' => array( 'local_cert' => __DIR__ . '/../examples/localhost.pem' diff --git a/tests/TcpConnectorTest.php b/tests/TcpConnectorTest.php index fb6f871c..0f6c53c5 100644 --- a/tests/TcpConnectorTest.php +++ b/tests/TcpConnectorTest.php @@ -138,7 +138,7 @@ class_exists('PHPUnit\Framework\Error\Warning', true); public function connectionToInvalidNetworkShouldFailWithUnreachableError() { if (PHP_OS !== 'Linux' && !function_exists('socket_import_stream')) { - $this->markTestSkipped('Test requires either Linux or ext-sockets on PHP 5.4+'); + $this->markTestSkipped('Test requires either Linux or ext-sockets'); } $enetunreach = defined('SOCKET_ENETUNREACH') ? SOCKET_ENETUNREACH : 101; diff --git a/tests/TcpServerTest.php b/tests/TcpServerTest.php index 8908d1c2..3da87458 100644 --- a/tests/TcpServerTest.php +++ b/tests/TcpServerTest.php @@ -323,10 +323,6 @@ public function testEmitsErrorWhenAcceptListenerFailsWithoutCallingCustomErrorHa */ public function testEmitsTimeoutErrorWhenAcceptListenerFails(\RuntimeException $exception) { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on HHVM'); - } - $this->assertEquals('Unable to accept new connection: ' . socket_strerror(SOCKET_ETIMEDOUT) . ' (ETIMEDOUT)', $exception->getMessage()); $this->assertEquals(SOCKET_ETIMEDOUT, $exception->getCode()); } @@ -336,9 +332,6 @@ public function testListenOnBusyPortThrows() if (DIRECTORY_SEPARATOR === '\\') { $this->markTestSkipped('Windows supports listening on same port multiple times'); } - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Not supported on HHVM'); - } $this->setExpectedException( 'RuntimeException', diff --git a/tests/TestCase.php b/tests/TestCase.php index 5b02e376..b8586c79 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -105,18 +105,12 @@ function () use ($stream) { public function setExpectedException($exception, $exceptionMessage = '', $exceptionCode = null) { - if (method_exists($this, 'expectException')) { - // PHPUnit 5+ - $this->expectException($exception); - if ($exceptionMessage !== '') { - $this->expectExceptionMessage($exceptionMessage); - } - if ($exceptionCode !== null) { - $this->expectExceptionCode($exceptionCode); - } - } else { - // legacy PHPUnit 4 - parent::setExpectedException($exception, $exceptionMessage, $exceptionCode); + $this->expectException($exception); + if ($exceptionMessage !== '') { + $this->expectExceptionMessage($exceptionMessage); + } + if ($exceptionCode !== null) { + $this->expectExceptionCode($exceptionCode); } } @@ -169,5 +163,4 @@ public function assertDoesNotMatchRegExp($pattern, $string) $this->assertNotRegExp($pattern, $string); } } - } diff --git a/tests/UnixServerTest.php b/tests/UnixServerTest.php index c148de4f..e4b21124 100644 --- a/tests/UnixServerTest.php +++ b/tests/UnixServerTest.php @@ -379,10 +379,6 @@ public function testEmitsErrorWhenAcceptListenerFailsWithoutCallingCustomErrorHa */ public function testEmitsTimeoutErrorWhenAcceptListenerFails(\RuntimeException $exception) { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('not supported on HHVM'); - } - $this->assertEquals('Unable to accept new connection: ' . socket_strerror(SOCKET_ETIMEDOUT) . ' (ETIMEDOUT)', $exception->getMessage()); $this->assertEquals(SOCKET_ETIMEDOUT, $exception->getCode()); } From c8c9d42bbe46c7f677a445bfcbfff0a1580ccdca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Wed, 22 May 2024 19:04:51 +0200 Subject: [PATCH 2/3] Update PHP language syntax and remove legacy workarounds --- README.md | 110 ++++----- examples/01-echo-server.php | 10 +- examples/02-chat-server.php | 10 +- examples/03-http-server.php | 12 +- examples/11-http-client.php | 2 +- examples/12-https-client.php | 2 +- examples/22-http-client.php | 4 +- examples/91-benchmark-server.php | 10 +- examples/99-generate-self-signed.php | 8 +- src/Connection.php | 6 +- src/Connector.php | 17 +- src/DnsConnector.php | 18 +- src/FdServer.php | 15 +- src/HappyEyeBallsConnectionBuilder.php | 130 +++++----- src/HappyEyeBallsConnector.php | 17 +- src/LimitingServer.php | 17 +- src/SecureConnector.php | 21 +- src/SecureServer.php | 40 ++- src/SocketServer.php | 23 +- src/StreamEncryption.php | 24 +- src/TcpConnector.php | 42 ++-- src/TcpServer.php | 27 +- src/TimeoutConnector.php | 18 +- src/UnixConnector.php | 13 +- src/UnixServer.php | 27 +- tests/ConnectorTest.php | 44 ++-- tests/DnsConnectorTest.php | 52 ++-- tests/FdServerTest.php | 4 +- tests/FunctionalConnectorTest.php | 40 +-- tests/FunctionalSecureServerTest.php | 245 ++++++++++--------- tests/FunctionalTcpServerTest.php | 65 ++--- tests/HappyEyeBallsConnectionBuilderTest.php | 188 +++++++------- tests/HappyEyeBallsConnectorTest.php | 129 +++++----- tests/IntegrationTest.php | 101 ++++---- tests/LimitingServerTest.php | 22 +- tests/SecureConnectorTest.php | 28 ++- tests/SecureIntegrationTest.php | 35 +-- tests/SecureServerTest.php | 33 +-- tests/SocketServerTest.php | 55 +++-- tests/Stub/ConnectionStub.php | 2 +- tests/TcpConnectorTest.php | 24 +- tests/TcpServerTest.php | 14 +- tests/TestCase.php | 9 +- tests/TimeoutConnectorTest.php | 6 +- tests/UnixServerTest.php | 4 +- 45 files changed, 853 insertions(+), 870 deletions(-) diff --git a/README.md b/README.md index 3e758354..3257b688 100644 --- a/README.md +++ b/README.md @@ -423,13 +423,13 @@ Optionally, you can specify [TCP socket context options](https://www.php.net/man for the underlying stream socket resource like this: ```php -$socket = new React\Socket\SocketServer('[::1]:8080', array( - 'tcp' => array( +$socket = new React\Socket\SocketServer('[::1]:8080', [ + 'tcp' => [ 'backlog' => 200, 'so_reuseport' => true, 'ipv6_v6only' => true - ) -)); + ] +]); ``` > Note that available [socket context options](https://www.php.net/manual/en/context.socket.php), @@ -447,11 +447,11 @@ which in its most basic form may look something like this if you're using a PEM encoded certificate file: ```php -$socket = new React\Socket\SocketServer('tls://127.0.0.1:8080', array( - 'tls' => array( +$socket = new React\Socket\SocketServer('tls://127.0.0.1:8080', [ + 'tls' => [ 'local_cert' => 'server.pem' - ) -)); + ] +]); ``` > Note that the certificate file will not be loaded on instantiation but when an @@ -463,12 +463,12 @@ If your private key is encrypted with a passphrase, you have to specify it like this: ```php -$socket = new React\Socket\SocketServer('tls://127.0.0.1:8000', array( - 'tls' => array( +$socket = new React\Socket\SocketServer('tls://127.0.0.1:8000', [ + 'tls' => [ 'local_cert' => 'server.pem', 'passphrase' => 'secret' - ) -)); + ] +]); ``` By default, this server supports TLSv1.0+ and excludes support for legacy @@ -476,12 +476,12 @@ SSLv2/SSLv3. You can also explicitly choose the TLS version you want to negotiate with the remote side: ```php -$socket = new React\Socket\SocketServer('tls://127.0.0.1:8000', array( - 'tls' => array( +$socket = new React\Socket\SocketServer('tls://127.0.0.1:8000', [ + 'tls' => [ 'local_cert' => 'server.pem', 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER - ) -)); + ] +]); ``` > Note that available [TLS context options](https://www.php.net/manual/en/context.ssl.php), @@ -588,11 +588,11 @@ Optionally, you can specify [socket context options](https://www.php.net/manual/ for the underlying stream socket resource like this: ```php -$server = new React\Socket\TcpServer('[::1]:8080', null, array( +$server = new React\Socket\TcpServer('[::1]:8080', null, [ 'backlog' => 200, 'so_reuseport' => true, 'ipv6_v6only' => true -)); +]); ``` > Note that available [socket context options](https://www.php.net/manual/en/context.socket.php), @@ -628,9 +628,9 @@ PEM encoded certificate file: ```php $server = new React\Socket\TcpServer(8000); -$server = new React\Socket\SecureServer($server, null, array( +$server = new React\Socket\SecureServer($server, null, [ 'local_cert' => 'server.pem' -)); +]); ``` > Note that the certificate file will not be loaded on instantiation but when an @@ -643,10 +643,10 @@ like this: ```php $server = new React\Socket\TcpServer(8000); -$server = new React\Socket\SecureServer($server, null, array( +$server = new React\Socket\SecureServer($server, null, [ 'local_cert' => 'server.pem', 'passphrase' => 'secret' -)); +]); ``` By default, this server supports TLSv1.0+ and excludes support for legacy @@ -655,10 +655,10 @@ want to negotiate with the remote side: ```php $server = new React\Socket\TcpServer(8000); -$server = new React\Socket\SecureServer($server, null, array( +$server = new React\Socket\SecureServer($server, null, [ 'local_cert' => 'server.pem', 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER -)); +]); ``` > Note that available [TLS context options](https://www.php.net/manual/en/context.ssl.php), @@ -971,9 +971,9 @@ If you want to revert to the old behavior of only doing an IPv4 lookup and only attempt a single IPv4 connection, you can set up the `Connector` like this: ```php -$connector = new React\Socket\Connector(array( +$connector = new React\Socket\Connector([ 'happy_eyeballs' => false -)); +]); ``` Similarly, you can also affect the default DNS behavior as follows. @@ -985,9 +985,9 @@ If you explicitly want to use a custom DNS server (such as a local DNS relay or a company wide DNS server), you can set up the `Connector` like this: ```php -$connector = new React\Socket\Connector(array( +$connector = new React\Socket\Connector([ 'dns' => '127.0.1.1' -)); +]); $connector->connect('localhost:80')->then(function (React\Socket\ConnectionInterface $connection) { $connection->write('...'); @@ -999,9 +999,9 @@ If you do not want to use a DNS resolver at all and want to connect to IP addresses only, you can also set up your `Connector` like this: ```php -$connector = new React\Socket\Connector(array( +$connector = new React\Socket\Connector([ 'dns' => false -)); +]); $connector->connect('127.0.0.1:80')->then(function (React\Socket\ConnectionInterface $connection) { $connection->write('...'); @@ -1016,9 +1016,9 @@ can also set up your `Connector` like this: $dnsResolverFactory = new React\Dns\Resolver\Factory(); $resolver = $dnsResolverFactory->createCached('127.0.1.1'); -$connector = new React\Socket\Connector(array( +$connector = new React\Socket\Connector([ 'dns' => $resolver -)); +]); $connector->connect('localhost:80')->then(function (React\Socket\ConnectionInterface $connection) { $connection->write('...'); @@ -1031,18 +1031,18 @@ respects your `default_socket_timeout` ini setting (which defaults to 60s). If you want a custom timeout value, you can simply pass this like this: ```php -$connector = new React\Socket\Connector(array( +$connector = new React\Socket\Connector([ 'timeout' => 10.0 -)); +]); ``` Similarly, if you do not want to apply a timeout at all and let the operating system handle this, you can pass a boolean flag like this: ```php -$connector = new React\Socket\Connector(array( +$connector = new React\Socket\Connector([ 'timeout' => false -)); +]); ``` By default, the `Connector` supports the `tcp://`, `tls://` and `unix://` @@ -1051,7 +1051,7 @@ pass boolean flags like this: ```php // only allow secure TLS connections -$connector = new React\Socket\Connector(array( +$connector = new React\Socket\Connector([ 'tcp' => false, 'tls' => true, 'unix' => false, @@ -1070,15 +1070,15 @@ pass arrays of context options like this: ```php // allow insecure TLS connections -$connector = new React\Socket\Connector(array( - 'tcp' => array( +$connector = new React\Socket\Connector([ + 'tcp' => [ 'bindto' => '192.168.0.1:0' - ), - 'tls' => array( + ], + 'tls' => [ 'verify_peer' => false, 'verify_peer_name' => false - ), -)); + ], +]); $connector->connect('tls://localhost:443')->then(function (React\Socket\ConnectionInterface $connection) { $connection->write('...'); @@ -1091,11 +1091,11 @@ SSLv2/SSLv3. You can also explicitly choose the TLS version you want to negotiate with the remote side: ```php -$connector = new React\Socket\Connector(array( - 'tls' => array( +$connector = new React\Socket\Connector([ + 'tls' => [ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT - ) -)); + ] +]); ``` > For more details about context options, please refer to the PHP documentation @@ -1117,14 +1117,14 @@ $tls = new React\Socket\SecureConnector($tcp); $unix = new React\Socket\UnixConnector(); -$connector = new React\Socket\Connector(array( +$connector = new React\Socket\Connector([ 'tcp' => $tcp, 'tls' => $tls, 'unix' => $unix, 'dns' => false, 'timeout' => false, -)); +]); $connector->connect('google.com:80')->then(function (React\Socket\ConnectionInterface $connection) { $connection->write('...'); @@ -1192,9 +1192,9 @@ You can optionally pass additional to the constructor like this: ```php -$tcpConnector = new React\Socket\TcpConnector(null, array( +$tcpConnector = new React\Socket\TcpConnector(null, [ 'bindto' => '192.168.0.1:0' -)); +]); ``` Note that this class only allows you to connect to IP-port-combinations. @@ -1363,10 +1363,10 @@ You can optionally pass additional to the constructor like this: ```php -$secureConnector = new React\Socket\SecureConnector($dnsConnector, null, array( +$secureConnector = new React\Socket\SecureConnector($dnsConnector, null, [ 'verify_peer' => false, 'verify_peer_name' => false -)); +]); ``` By default, this connector supports TLSv1.0+ and excludes support for legacy @@ -1374,9 +1374,9 @@ SSLv2/SSLv3. You can also explicitly choose the TLS version you want to negotiate with the remote side: ```php -$secureConnector = new React\Socket\SecureConnector($dnsConnector, null, array( +$secureConnector = new React\Socket\SecureConnector($dnsConnector, null, [ 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT -)); +]); ``` > Advanced usage: Internally, the `SecureConnector` relies on setting up the diff --git a/examples/01-echo-server.php b/examples/01-echo-server.php index e073c230..e85c9c2c 100644 --- a/examples/01-echo-server.php +++ b/examples/01-echo-server.php @@ -23,11 +23,11 @@ require __DIR__ . '/../vendor/autoload.php'; -$socket = new React\Socket\SocketServer(isset($argv[1]) ? $argv[1] : '127.0.0.1:0', array( - 'tls' => array( - 'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem') - ) -)); +$socket = new React\Socket\SocketServer($argv[1] ?? '127.0.0.1:0', [ + 'tls' => [ + 'local_cert' => $argv[2] ?? __DIR__ . '/localhost.pem' + ] +]); $socket->on('connection', function (React\Socket\ConnectionInterface $connection) { echo '[' . $connection->getRemoteAddress() . ' connected]' . PHP_EOL; diff --git a/examples/02-chat-server.php b/examples/02-chat-server.php index 862a22de..cd0e826a 100644 --- a/examples/02-chat-server.php +++ b/examples/02-chat-server.php @@ -23,11 +23,11 @@ require __DIR__ . '/../vendor/autoload.php'; -$socket = new React\Socket\SocketServer(isset($argv[1]) ? $argv[1] : '127.0.0.1:0', array( - 'tls' => array( - 'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem') - ) -)); +$socket = new React\Socket\SocketServer($argv[1] ?? '127.0.0.1:0', [ + 'tls' => [ + 'local_cert' => $argv[2] ?? __DIR__ . '/localhost.pem' + ] +]); $socket = new React\Socket\LimitingServer($socket, null); diff --git a/examples/03-http-server.php b/examples/03-http-server.php index dc861a1c..14846904 100644 --- a/examples/03-http-server.php +++ b/examples/03-http-server.php @@ -38,11 +38,11 @@ require __DIR__ . '/../vendor/autoload.php'; -$socket = new React\Socket\SocketServer(isset($argv[1]) ? $argv[1] : '127.0.0.1:0', array( - 'tls' => array( - 'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem') - ) -)); +$socket = new React\Socket\SocketServer($argv[1] ?? '127.0.0.1:0', [ + 'tls' => [ + 'local_cert' => $argv[2] ?? __DIR__ . '/localhost.pem' + ] +]); $socket->on('connection', function (React\Socket\ConnectionInterface $connection) { echo '[' . $connection->getRemoteAddress() . ' connected]' . PHP_EOL; @@ -61,4 +61,4 @@ echo 'Error: ' . $e->getMessage() . PHP_EOL; }); -echo 'Listening on ' . strtr($socket->getAddress(), array('tcp:' => 'http:', 'tls:' => 'https:')) . PHP_EOL; +echo 'Listening on ' . strtr($socket->getAddress(), ['tcp:' => 'http:', 'tls:' => 'https:']) . PHP_EOL; diff --git a/examples/11-http-client.php b/examples/11-http-client.php index 008cfc81..60444eb2 100644 --- a/examples/11-http-client.php +++ b/examples/11-http-client.php @@ -14,7 +14,7 @@ use React\Socket\Connector; use React\Socket\ConnectionInterface; -$host = isset($argv[1]) ? $argv[1] : 'www.google.com'; +$host = $argv[1] ?? 'www.google.com'; require __DIR__ . '/../vendor/autoload.php'; diff --git a/examples/12-https-client.php b/examples/12-https-client.php index 492dabae..865a34ff 100644 --- a/examples/12-https-client.php +++ b/examples/12-https-client.php @@ -14,7 +14,7 @@ use React\Socket\Connector; use React\Socket\ConnectionInterface; -$host = isset($argv[1]) ? $argv[1] : 'www.google.com'; +$host = $argv[1] ?? 'www.google.com'; require __DIR__ . '/../vendor/autoload.php'; diff --git a/examples/22-http-client.php b/examples/22-http-client.php index d7f77fcf..541fe464 100644 --- a/examples/22-http-client.php +++ b/examples/22-http-client.php @@ -19,7 +19,7 @@ require __DIR__ . '/../vendor/autoload.php'; -$uri = isset($argv[1]) ? $argv[1] : 'www.google.com'; +$uri = $argv[1] ?? 'www.google.com'; if (strpos($uri, '://') === false) { $uri = 'http://' . $uri; @@ -42,7 +42,7 @@ $host .= ':' . $parts['port']; } $target = ($parts['scheme'] === 'https' ? 'tls' : 'tcp') . '://' . $parts['host'] . ':' . $parts['port']; -$resource = isset($parts['path']) ? $parts['path'] : '/'; +$resource = $parts['path'] ?? '/'; if (isset($parts['query'])) { $resource .= '?' . $parts['query']; } diff --git a/examples/91-benchmark-server.php b/examples/91-benchmark-server.php index 6a0e7828..a3ea960c 100644 --- a/examples/91-benchmark-server.php +++ b/examples/91-benchmark-server.php @@ -31,11 +31,11 @@ require __DIR__ . '/../vendor/autoload.php'; -$socket = new React\Socket\SocketServer(isset($argv[1]) ? $argv[1] : '127.0.0.1:0', array( - 'tls' => array( - 'local_cert' => isset($argv[2]) ? $argv[2] : (__DIR__ . '/localhost.pem') - ) -)); +$socket = new React\Socket\SocketServer($argv[1] ?? '127.0.0.1:0', [ + 'tls' => [ + 'local_cert' => $argv[2] ?? __DIR__ . '/localhost.pem' + ] +]); $socket->on('connection', function (React\Socket\ConnectionInterface $connection) { echo '[' . $connection->getRemoteAddress() . ' connected]' . PHP_EOL; diff --git a/examples/99-generate-self-signed.php b/examples/99-generate-self-signed.php index 2f9ce30c..bf6a9886 100644 --- a/examples/99-generate-self-signed.php +++ b/examples/99-generate-self-signed.php @@ -7,15 +7,15 @@ // certificate details (Distinguished Name) // (OpenSSL applies defaults to missing fields) -$dn = array( - "commonName" => isset($argv[1]) ? $argv[1] : "localhost", +$dn = [ + "commonName" => $argv[1] ?? "localhost", // "countryName" => "AU", // "stateOrProvinceName" => "Some-State", // "localityName" => "London", // "organizationName" => "Internet Widgits Pty Ltd", // "organizationalUnitName" => "R&D", // "emailAddress" => "admin@example.com" -); +]; // create certificate which is valid for ~10 years $privkey = openssl_pkey_new(); @@ -26,6 +26,6 @@ openssl_x509_export($cert, $out); echo $out; -$passphrase = isset($argv[2]) ? $argv[2] : null; +$passphrase = $argv[2] ?? null; openssl_pkey_export($privkey, $out, $passphrase); echo $out; diff --git a/src/Connection.php b/src/Connection.php index 72286b79..6bc8deb3 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -73,9 +73,9 @@ public function __construct($resource, LoopInterface $loop) $this->stream = $resource; - Util::forwardEvents($this->input, $this, array('data', 'end', 'error', 'close', 'pipe', 'drain')); + Util::forwardEvents($this->input, $this, ['data', 'end', 'error', 'close', 'pipe', 'drain']); - $this->input->on('close', array($this, 'close')); + $this->input->on('close', [$this, 'close']); } public function isReadable() @@ -98,7 +98,7 @@ public function resume() $this->input->resume(); } - public function pipe(WritableStreamInterface $dest, array $options = array()) + public function pipe(WritableStreamInterface $dest, array $options = []) { return $this->input->pipe($dest, $options); } diff --git a/src/Connector.php b/src/Connector.php index e2203fce..40d8ebb0 100644 --- a/src/Connector.php +++ b/src/Connector.php @@ -6,6 +6,7 @@ use React\Dns\Resolver\Factory as DnsFactory; use React\Dns\Resolver\ResolverInterface; use React\EventLoop\LoopInterface; +use function React\Promise\reject; /** * The `Connector` class is the main class in this package that implements the @@ -24,7 +25,7 @@ */ final class Connector implements ConnectorInterface { - private $connectors = array(); + private $connectors = []; /** * Instantiate new `Connector` @@ -52,7 +53,7 @@ final class Connector implements ConnectorInterface public function __construct(array $context = array(), LoopInterface $loop = null) { // apply default options if not explicitly given - $context += array( + $context += [ 'tcp' => true, 'tls' => true, 'unix' => true, @@ -60,7 +61,7 @@ public function __construct(array $context = array(), LoopInterface $loop = null 'dns' => true, 'timeout' => true, 'happy_eyeballs' => true, - ); + ]; if ($context['timeout'] === true) { $context['timeout'] = (float)\ini_get("default_socket_timeout"); @@ -71,7 +72,7 @@ public function __construct(array $context = array(), LoopInterface $loop = null } else { $tcp = new TcpConnector( $loop, - \is_array($context['tcp']) ? $context['tcp'] : array() + \is_array($context['tcp']) ? $context['tcp'] : [] ); } @@ -122,7 +123,7 @@ public function __construct(array $context = array(), LoopInterface $loop = null $context['tls'] = new SecureConnector( $tcp, $loop, - \is_array($context['tls']) ? $context['tls'] : array() + \is_array($context['tls']) ? $context['tls'] : [] ); } @@ -153,7 +154,7 @@ public function connect($uri) } if (!isset($this->connectors[$scheme])) { - return \React\Promise\reject(new \RuntimeException( + return reject(new \RuntimeException( 'No connector available for URI scheme "' . $scheme . '" (EINVAL)', \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : (\defined('PCNTL_EINVAL') ? \PCNTL_EINVAL : 22) )); @@ -205,8 +206,8 @@ public static function uri(array $parts, $host, $ip) // append original hostname as query if resolved via DNS and if // destination URI does not contain "hostname" query param already - $args = array(); - \parse_str(isset($parts['query']) ? $parts['query'] : '', $args); + $args = []; + \parse_str($parts['query'] ?? '', $args); if ($host !== $ip && !isset($args['hostname'])) { $uri .= (isset($parts['query']) ? '&' : '?') . 'hostname=' . \rawurlencode($host); } diff --git a/src/DnsConnector.php b/src/DnsConnector.php index d2fb2c7d..0165a2be 100644 --- a/src/DnsConnector.php +++ b/src/DnsConnector.php @@ -3,8 +3,9 @@ namespace React\Socket; use React\Dns\Resolver\ResolverInterface; -use React\Promise; +use React\Promise\Promise; use React\Promise\PromiseInterface; +use function React\Promise\reject; final class DnsConnector implements ConnectorInterface { @@ -31,30 +32,29 @@ public function connect($uri) } if (!$parts || !isset($parts['host'])) { - return Promise\reject(new \InvalidArgumentException( + return reject(new \InvalidArgumentException( 'Given URI "' . $original . '" is invalid (EINVAL)', \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : (\defined('PCNTL_EINVAL') ? \PCNTL_EINVAL : 22) )); } $host = \trim($parts['host'], '[]'); - $connector = $this->connector; // skip DNS lookup / URI manipulation if this URI already contains an IP if (@\inet_pton($host) !== false) { - return $connector->connect($original); + return $this->connector->connect($original); } $promise = $this->resolver->resolve($host); $resolved = null; - return new Promise\Promise( - function ($resolve, $reject) use (&$promise, &$resolved, $uri, $connector, $host, $parts) { + return new Promise( + function ($resolve, $reject) use (&$promise, &$resolved, $uri, $host, $parts) { // resolve/reject with result of DNS lookup - $promise->then(function ($ip) use (&$promise, &$resolved, $uri, $connector, $host, $parts) { + $promise->then(function ($ip) use (&$promise, &$resolved, $uri, $host, $parts) { $resolved = $ip; - return $promise = $connector->connect( + return $promise = $this->connector->connect( Connector::uri($parts, $host, $ip) )->then(null, function (\Exception $e) use ($uri) { if ($e instanceof \RuntimeException) { @@ -67,7 +67,7 @@ function ($resolve, $reject) use (&$promise, &$resolved, $uri, $connector, $host // avoid garbage references by replacing all closures in call stack. // what a lovely piece of code! - $r = new \ReflectionProperty('Exception', 'trace'); + $r = new \ReflectionProperty(\Exception::class, 'trace'); $r->setAccessible(true); $trace = $r->getValue($e); diff --git a/src/FdServer.php b/src/FdServer.php index b1ed7779..43a95b79 100644 --- a/src/FdServer.php +++ b/src/FdServer.php @@ -87,7 +87,7 @@ public function __construct($fd, LoopInterface $loop = null) ); } - $this->loop = $loop ?: Loop::get(); + $this->loop = $loop ?? Loop::get(); $errno = 0; $errstr = ''; @@ -95,8 +95,8 @@ public function __construct($fd, LoopInterface $loop = null) // Match errstr from PHP's warning message. // fopen(php://fd/3): Failed to open stream: Error duping file descriptor 3; possibly it doesn't exist: [9]: Bad file descriptor \preg_match('/\[(\d+)\]: (.*)/', $error, $m); - $errno = isset($m[1]) ? (int) $m[1] : 0; - $errstr = isset($m[2]) ? $m[2] : $error; + $errno = (int) ($m[1] ?? 0); + $errstr = $m[2] ?? $error; }); $this->master = \fopen('php://fd/' . $fd, 'r+'); @@ -183,15 +183,14 @@ public function resume() return; } - $that = $this; - $this->loop->addReadStream($this->master, function ($master) use ($that) { + $this->loop->addReadStream($this->master, function ($master) { try { $newSocket = SocketServer::accept($master); } catch (\RuntimeException $e) { - $that->emit('error', array($e)); + $this->emit('error', [$e]); return; } - $that->handleConnection($newSocket); + $this->handleConnection($newSocket); }); $this->listening = true; } @@ -213,6 +212,6 @@ public function handleConnection($socket) $connection = new Connection($socket, $this->loop); $connection->unix = $this->unix; - $this->emit('connection', array($connection)); + $this->emit('connection', [$connection]); } } diff --git a/src/HappyEyeBallsConnectionBuilder.php b/src/HappyEyeBallsConnectionBuilder.php index d4f05e85..57a94aae 100644 --- a/src/HappyEyeBallsConnectionBuilder.php +++ b/src/HappyEyeBallsConnectionBuilder.php @@ -6,7 +6,8 @@ use React\Dns\Resolver\ResolverInterface; use React\EventLoop\LoopInterface; use React\EventLoop\TimerInterface; -use React\Promise; +use React\Promise\Deferred; +use React\Promise\Promise; use React\Promise\PromiseInterface; /** @@ -35,13 +36,13 @@ final class HappyEyeBallsConnectionBuilder public $resolver; public $uri; public $host; - public $resolved = array( + public $resolved = [ Message::TYPE_A => false, Message::TYPE_AAAA => false, - ); - public $resolverPromises = array(); - public $connectionPromises = array(); - public $connectQueue = array(); + ]; + public $resolverPromises = []; + public $connectionPromises = []; + public $connectQueue = []; public $nextAttemptTimer; public $parts; public $ipsCount = 0; @@ -65,53 +66,52 @@ public function __construct(LoopInterface $loop, ConnectorInterface $connector, public function connect() { - $that = $this; - return new Promise\Promise(function ($resolve, $reject) use ($that) { - $lookupResolve = function ($type) use ($that, $resolve, $reject) { - return function (array $ips) use ($that, $type, $resolve, $reject) { - unset($that->resolverPromises[$type]); - $that->resolved[$type] = true; + return new Promise(function ($resolve, $reject) { + $lookupResolve = function ($type) use ($resolve, $reject) { + return function (array $ips) use ($type, $resolve, $reject) { + unset($this->resolverPromises[$type]); + $this->resolved[$type] = true; - $that->mixIpsIntoConnectQueue($ips); + $this->mixIpsIntoConnectQueue($ips); // start next connection attempt if not already awaiting next - if ($that->nextAttemptTimer === null && $that->connectQueue) { - $that->check($resolve, $reject); + if ($this->nextAttemptTimer === null && $this->connectQueue) { + $this->check($resolve, $reject); } }; }; - $that->resolverPromises[Message::TYPE_AAAA] = $that->resolve(Message::TYPE_AAAA, $reject)->then($lookupResolve(Message::TYPE_AAAA)); - $that->resolverPromises[Message::TYPE_A] = $that->resolve(Message::TYPE_A, $reject)->then(function (array $ips) use ($that) { + $this->resolverPromises[Message::TYPE_AAAA] = $this->resolve(Message::TYPE_AAAA, $reject)->then($lookupResolve(Message::TYPE_AAAA)); + $this->resolverPromises[Message::TYPE_A] = $this->resolve(Message::TYPE_A, $reject)->then(function (array $ips) { // happy path: IPv6 has resolved already (or could not resolve), continue with IPv4 addresses - if ($that->resolved[Message::TYPE_AAAA] === true || !$ips) { + if ($this->resolved[Message::TYPE_AAAA] === true || !$ips) { return $ips; } // Otherwise delay processing IPv4 lookup until short timer passes or IPv6 resolves in the meantime - $deferred = new Promise\Deferred(function () use (&$ips) { + $deferred = new Deferred(function () use (&$ips) { // discard all IPv4 addresses if cancelled - $ips = array(); + $ips = []; }); - $timer = $that->loop->addTimer($that::RESOLUTION_DELAY, function () use ($deferred, $ips) { + $timer = $this->loop->addTimer($this::RESOLUTION_DELAY, function () use ($deferred, $ips) { $deferred->resolve($ips); }); - $that->resolverPromises[Message::TYPE_AAAA]->then(function () use ($that, $timer, $deferred, &$ips) { - $that->loop->cancelTimer($timer); + $this->resolverPromises[Message::TYPE_AAAA]->then(function () use ($timer, $deferred, &$ips) { + $this->loop->cancelTimer($timer); $deferred->resolve($ips); }); return $deferred->promise(); })->then($lookupResolve(Message::TYPE_A)); - }, function ($_, $reject) use ($that) { + }, function ($_, $reject) { $reject(new \RuntimeException( - 'Connection to ' . $that->uri . ' cancelled' . (!$that->connectionPromises ? ' during DNS lookup' : '') . ' (ECONNABORTED)', + 'Connection to ' . $this->uri . ' cancelled' . (!$this->connectionPromises ? ' during DNS lookup' : '') . ' (ECONNABORTED)', \defined('SOCKET_ECONNABORTED') ? \SOCKET_ECONNABORTED : 103 )); $_ = $reject = null; - $that->cleanUp(); + $this->cleanUp(); }); } @@ -125,35 +125,34 @@ public function connect() */ public function resolve($type, $reject) { - $that = $this; - return $that->resolver->resolveAll($that->host, $type)->then(null, function (\Exception $e) use ($type, $reject, $that) { - unset($that->resolverPromises[$type]); - $that->resolved[$type] = true; + return $this->resolver->resolveAll($this->host, $type)->then(null, function (\Exception $e) use ($type, $reject) { + unset($this->resolverPromises[$type]); + $this->resolved[$type] = true; if ($type === Message::TYPE_A) { - $that->lastError4 = $e->getMessage(); - $that->lastErrorFamily = 4; + $this->lastError4 = $e->getMessage(); + $this->lastErrorFamily = 4; } else { - $that->lastError6 = $e->getMessage(); - $that->lastErrorFamily = 6; + $this->lastError6 = $e->getMessage(); + $this->lastErrorFamily = 6; } // cancel next attempt timer when there are no more IPs to connect to anymore - if ($that->nextAttemptTimer !== null && !$that->connectQueue) { - $that->loop->cancelTimer($that->nextAttemptTimer); - $that->nextAttemptTimer = null; + if ($this->nextAttemptTimer !== null && !$this->connectQueue) { + $this->loop->cancelTimer($this->nextAttemptTimer); + $this->nextAttemptTimer = null; } - if ($that->hasBeenResolved() && $that->ipsCount === 0) { + if ($this->hasBeenResolved() && $this->ipsCount === 0) { $reject(new \RuntimeException( - $that->error(), + $this->error(), 0, $e )); } // Exception already handled above, so don't throw an unhandled rejection here - return array(); + return []; }); } @@ -169,46 +168,45 @@ public function check($resolve, $reject) \end($this->connectionPromises); $index = \key($this->connectionPromises); - $that = $this; - $that->connectionPromises[$index]->then(function ($connection) use ($that, $index, $resolve) { - unset($that->connectionPromises[$index]); + $this->connectionPromises[$index]->then(function ($connection) use ($index, $resolve) { + unset($this->connectionPromises[$index]); - $that->cleanUp(); + $this->cleanUp(); $resolve($connection); - }, function (\Exception $e) use ($that, $index, $ip, $resolve, $reject) { - unset($that->connectionPromises[$index]); + }, function (\Exception $e) use ($index, $ip, $resolve, $reject) { + unset($this->connectionPromises[$index]); - $that->failureCount++; + $this->failureCount++; $message = \preg_replace('/^(Connection to [^ ]+)[&?]hostname=[^ &]+/', '$1', $e->getMessage()); if (\strpos($ip, ':') === false) { - $that->lastError4 = $message; - $that->lastErrorFamily = 4; + $this->lastError4 = $message; + $this->lastErrorFamily = 4; } else { - $that->lastError6 = $message; - $that->lastErrorFamily = 6; + $this->lastError6 = $message; + $this->lastErrorFamily = 6; } // start next connection attempt immediately on error - if ($that->connectQueue) { - if ($that->nextAttemptTimer !== null) { - $that->loop->cancelTimer($that->nextAttemptTimer); - $that->nextAttemptTimer = null; + if ($this->connectQueue) { + if ($this->nextAttemptTimer !== null) { + $this->loop->cancelTimer($this->nextAttemptTimer); + $this->nextAttemptTimer = null; } - $that->check($resolve, $reject); + $this->check($resolve, $reject); } - if ($that->hasBeenResolved() === false) { + if ($this->hasBeenResolved() === false) { return; } - if ($that->ipsCount === $that->failureCount) { - $that->cleanUp(); + if ($this->ipsCount === $this->failureCount) { + $this->cleanUp(); $reject(new \RuntimeException( - $that->error(), + $this->error(), $e->getCode(), $e )); @@ -218,11 +216,11 @@ public function check($resolve, $reject) // Allow next connection attempt in 100ms: https://tools.ietf.org/html/rfc8305#section-5 // Only start timer when more IPs are queued or when DNS query is still pending (might add more IPs) if ($this->nextAttemptTimer === null && (\count($this->connectQueue) > 0 || $this->resolved[Message::TYPE_A] === false || $this->resolved[Message::TYPE_AAAA] === false)) { - $this->nextAttemptTimer = $this->loop->addTimer(self::CONNECTION_ATTEMPT_DELAY, function () use ($that, $resolve, $reject) { - $that->nextAttemptTimer = null; + $this->nextAttemptTimer = $this->loop->addTimer(self::CONNECTION_ATTEMPT_DELAY, function () use ($resolve, $reject) { + $this->nextAttemptTimer = null; - if ($that->connectQueue) { - $that->check($resolve, $reject); + if ($this->connectQueue) { + $this->check($resolve, $reject); } }); } @@ -244,7 +242,7 @@ public function attemptConnection($ip) public function cleanUp() { // clear list of outstanding IPs to avoid creating new connections - $this->connectQueue = array(); + $this->connectQueue = []; // cancel pending connection attempts foreach ($this->connectionPromises as $connectionPromise) { @@ -294,7 +292,7 @@ public function mixIpsIntoConnectQueue(array $ips) \shuffle($ips); $this->ipsCount += \count($ips); $connectQueueStash = $this->connectQueue; - $this->connectQueue = array(); + $this->connectQueue = []; while (\count($connectQueueStash) > 0 || \count($ips) > 0) { if (\count($ips) > 0) { $this->connectQueue[] = \array_shift($ips); diff --git a/src/HappyEyeBallsConnector.php b/src/HappyEyeBallsConnector.php index 98b1d58c..89ec203a 100644 --- a/src/HappyEyeBallsConnector.php +++ b/src/HappyEyeBallsConnector.php @@ -5,7 +5,7 @@ use React\Dns\Resolver\ResolverInterface; use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -use React\Promise; +use function React\Promise\reject; final class HappyEyeBallsConnector implements ConnectorInterface { @@ -13,18 +13,9 @@ final class HappyEyeBallsConnector implements ConnectorInterface private $connector; private $resolver; - public function __construct(LoopInterface $loop = null, ConnectorInterface $connector = null, ResolverInterface $resolver = null) + public function __construct(?LoopInterface $loop, ConnectorInterface $connector, ResolverInterface $resolver) { - // $connector and $resolver arguments are actually required, marked - // optional for technical reasons only. Nullable $loop without default - // requires PHP 7.1, null default is also supported in legacy PHP - // versions, but required parameters are not allowed after arguments - // with null default. Mark all parameters optional and check accordingly. - if ($connector === null || $resolver === null) { - throw new \InvalidArgumentException('Missing required $connector or $resolver argument'); - } - - $this->loop = $loop ?: Loop::get(); + $this->loop = $loop ?? Loop::get(); $this->connector = $connector; $this->resolver = $resolver; } @@ -43,7 +34,7 @@ public function connect($uri) } if (!$parts || !isset($parts['host'])) { - return Promise\reject(new \InvalidArgumentException( + return reject(new \InvalidArgumentException( 'Given URI "' . $original . '" is invalid (EINVAL)', \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : (\defined('PCNTL_EINVAL') ? \PCNTL_EINVAL : 22) )); diff --git a/src/LimitingServer.php b/src/LimitingServer.php index d19000b3..4742e252 100644 --- a/src/LimitingServer.php +++ b/src/LimitingServer.php @@ -3,8 +3,6 @@ namespace React\Socket; use Evenement\EventEmitter; -use Exception; -use OverflowException; /** * The `LimitingServer` decorator wraps a given `ServerInterface` and is responsible @@ -35,7 +33,7 @@ */ class LimitingServer extends EventEmitter implements ServerInterface { - private $connections = array(); + private $connections = []; private $server; private $limit; @@ -100,8 +98,8 @@ public function __construct(ServerInterface $server, $connectionLimit, $pauseOnL $this->pauseOnLimit = $pauseOnLimit; } - $this->server->on('connection', array($this, 'handleConnection')); - $this->server->on('error', array($this, 'handleError')); + $this->server->on('connection', [$this, 'handleConnection']); + $this->server->on('error', [$this, 'handleError']); } /** @@ -163,9 +161,8 @@ public function handleConnection(ConnectionInterface $connection) } $this->connections[] = $connection; - $that = $this; - $connection->on('close', function () use ($that, $connection) { - $that->handleDisconnection($connection); + $connection->on('close', function () use ($connection) { + $this->handleDisconnection($connection); }); // pause accepting new connections if limit exceeded @@ -177,7 +174,7 @@ public function handleConnection(ConnectionInterface $connection) } } - $this->emit('connection', array($connection)); + $this->emit('connection', [$connection]); } /** @internal */ @@ -198,6 +195,6 @@ public function handleDisconnection(ConnectionInterface $connection) /** @internal */ public function handleError(\Exception $error) { - $this->emit('error', array($error)); + $this->emit('error', [$error]); } } diff --git a/src/SecureConnector.php b/src/SecureConnector.php index 7c48e789..e3ff1ce9 100644 --- a/src/SecureConnector.php +++ b/src/SecureConnector.php @@ -4,7 +4,8 @@ use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -use React\Promise; +use React\Promise\Promise; +use function React\Promise\reject; final class SecureConnector implements ConnectorInterface { @@ -12,10 +13,10 @@ final class SecureConnector implements ConnectorInterface private $streamEncryption; private $context; - public function __construct(ConnectorInterface $connector, LoopInterface $loop = null, array $context = array()) + public function __construct(ConnectorInterface $connector, LoopInterface $loop = null, array $context = []) { $this->connector = $connector; - $this->streamEncryption = new StreamEncryption($loop ?: Loop::get(), false); + $this->streamEncryption = new StreamEncryption($loop ?? Loop::get(), false); $this->context = $context; } @@ -27,19 +28,17 @@ public function connect($uri) $parts = \parse_url($uri); if (!$parts || !isset($parts['scheme']) || $parts['scheme'] !== 'tls') { - return Promise\reject(new \InvalidArgumentException( + return reject(new \InvalidArgumentException( 'Given URI "' . $uri . '" is invalid (EINVAL)', \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : (\defined('PCNTL_EINVAL') ? \PCNTL_EINVAL : 22) )); } - $context = $this->context; - $encryption = $this->streamEncryption; $connected = false; /** @var \React\Promise\PromiseInterface $promise */ $promise = $this->connector->connect( \str_replace('tls://', '', $uri) - )->then(function (ConnectionInterface $connection) use ($context, $encryption, $uri, &$promise, &$connected) { + )->then(function (ConnectionInterface $connection) use ($uri, &$promise, &$connected) { // (unencrypted) TCP/IP connection succeeded $connected = true; @@ -49,12 +48,12 @@ public function connect($uri) } // set required SSL/TLS context options - foreach ($context as $name => $value) { + foreach ($this->context as $name => $value) { \stream_context_set_option($connection->stream, 'ssl', $name, $value); } // try to enable encryption - return $promise = $encryption->enable($connection)->then(null, function ($error) use ($connection, $uri) { + return $promise = $this->streamEncryption->enable($connection)->then(null, function ($error) use ($connection, $uri) { // establishing encryption failed => close invalid connection and return error $connection->close(); @@ -74,7 +73,7 @@ public function connect($uri) // avoid garbage references by replacing all closures in call stack. // what a lovely piece of code! - $r = new \ReflectionProperty('Exception', 'trace'); + $r = new \ReflectionProperty(\Exception::class, 'trace'); $r->setAccessible(true); $trace = $r->getValue($e); @@ -96,7 +95,7 @@ public function connect($uri) throw $e; }); - return new \React\Promise\Promise( + return new Promise( function ($resolve, $reject) use ($promise) { $promise->then($resolve, $reject); }, diff --git a/src/SecureServer.php b/src/SecureServer.php index fd1ed2c2..29c98664 100644 --- a/src/SecureServer.php +++ b/src/SecureServer.php @@ -15,9 +15,9 @@ * * ```php * $server = new React\Socket\TcpServer(8000); - * $server = new React\Socket\SecureServer($server, null, array( + * $server = new React\Socket\SecureServer($server, null, [ * // tls context options here… - * )); + * ]); * ``` * * Whenever a client completes the TLS handshake, it will emit a `connection` event @@ -67,9 +67,9 @@ final class SecureServer extends EventEmitter implements ServerInterface * * ```php * $server = new React\Socket\TcpServer(8000); - * $server = new React\Socket\SecureServer($server, null, array( + * $server = new React\Socket\SecureServer($server, null, [ * 'local_cert' => 'server.pem' - * )); + * ]); * ``` * * Note that the certificate file will not be loaded on instantiation but when an @@ -82,10 +82,10 @@ final class SecureServer extends EventEmitter implements ServerInterface * * ```php * $server = new React\Socket\TcpServer(8000); - * $server = new React\Socket\SecureServer($server, null, array( + * $server = new React\Socket\SecureServer($server, null, [ * 'local_cert' => 'server.pem', * 'passphrase' => 'secret' - * )); + * ]); * ``` * * Note that available [TLS context options], @@ -119,23 +119,22 @@ final class SecureServer extends EventEmitter implements ServerInterface * @see TcpServer * @link https://www.php.net/manual/en/context.ssl.php for TLS context options */ - public function __construct(ServerInterface $tcp, LoopInterface $loop = null, array $context = array()) + public function __construct(ServerInterface $tcp, LoopInterface $loop = null, array $context = []) { // default to empty passphrase to suppress blocking passphrase prompt - $context += array( + $context += [ 'passphrase' => '' - ); + ]; $this->tcp = $tcp; - $this->encryption = new StreamEncryption($loop ?: Loop::get()); + $this->encryption = new StreamEncryption($loop ?? Loop::get()); $this->context = $context; - $that = $this; - $this->tcp->on('connection', function ($connection) use ($that) { - $that->handleConnection($connection); + $this->tcp->on('connection', function ($connection) { + $this->handleConnection($connection); }); - $this->tcp->on('error', function ($error) use ($that) { - $that->emit('error', array($error)); + $this->tcp->on('error', function ($error) { + $this->emit('error', [$error]); }); } @@ -168,7 +167,7 @@ public function close() public function handleConnection(ConnectionInterface $connection) { if (!$connection instanceof Connection) { - $this->emit('error', array(new \UnexpectedValueException('Base server does not use internal Connection class exposing stream resource'))); + $this->emit('error', [new \UnexpectedValueException('Base server does not use internal Connection class exposing stream resource')]); $connection->close(); return; } @@ -179,19 +178,18 @@ public function handleConnection(ConnectionInterface $connection) // get remote address before starting TLS handshake in case connection closes during handshake $remote = $connection->getRemoteAddress(); - $that = $this; $this->encryption->enable($connection)->then( - function ($conn) use ($that) { - $that->emit('connection', array($conn)); + function ($conn) { + $this->emit('connection', [$conn]); }, - function ($error) use ($that, $connection, $remote) { + function ($error) use ($connection, $remote) { $error = new \RuntimeException( 'Connection from ' . $remote . ' failed during TLS handshake: ' . $error->getMessage(), $error->getCode() ); - $that->emit('error', array($error)); + $this->emit('error', [$error]); $connection->close(); } ); diff --git a/src/SocketServer.php b/src/SocketServer.php index b78dc3a4..10c43388 100644 --- a/src/SocketServer.php +++ b/src/SocketServer.php @@ -31,14 +31,14 @@ final class SocketServer extends EventEmitter implements ServerInterface * @throws \InvalidArgumentException if the listening address is invalid * @throws \RuntimeException if listening on this address fails (already in use etc.) */ - public function __construct($uri, array $context = array(), LoopInterface $loop = null) + public function __construct($uri, array $context = [], LoopInterface $loop = null) { // apply default options if not explicitly given - $context += array( - 'tcp' => array(), - 'tls' => array(), - 'unix' => array() - ); + $context += [ + 'tcp' => [], + 'tls' => [], + 'unix' => [] + ]; $scheme = 'tcp'; $pos = \strpos($uri, '://'); @@ -67,12 +67,11 @@ public function __construct($uri, array $context = array(), LoopInterface $loop $this->server = $server; - $that = $this; - $server->on('connection', function (ConnectionInterface $conn) use ($that) { - $that->emit('connection', array($conn)); + $server->on('connection', function (ConnectionInterface $conn) { + $this->emit('connection', [$conn]); }); - $server->on('error', function (\Exception $error) use ($that) { - $that->emit('error', array($error)); + $server->on('error', function (\Exception $error) { + $this->emit('error', [$error]); }); } @@ -112,7 +111,7 @@ public static function accept($socket) // Match errstr from PHP's warning message. // stream_socket_accept(): accept failed: Connection timed out $errstr = \preg_replace('#.*: #', '', $error); - $errno = SocketServer::errno($errstr); + $errno = self::errno($errstr); }); $newSocket = \stream_socket_accept($socket, 0); diff --git a/src/StreamEncryption.php b/src/StreamEncryption.php index 60f101ea..b03b79b8 100644 --- a/src/StreamEncryption.php +++ b/src/StreamEncryption.php @@ -4,8 +4,6 @@ use React\EventLoop\LoopInterface; use React\Promise\Deferred; -use RuntimeException; -use UnexpectedValueException; /** * This class is considered internal and its API should not be relied upon @@ -73,15 +71,11 @@ public function toggle(Connection $stream, $toggle) $socket = $stream->stream; // get crypto method from context options or use global setting from constructor - $method = $this->method; $context = \stream_context_get_options($socket); - if (isset($context['ssl']['crypto_method'])) { - $method = $context['ssl']['crypto_method']; - } + $method = $context['ssl']['crypto_method'] ?? $this->method; - $that = $this; - $toggleCrypto = function () use ($socket, $deferred, $toggle, $method, $that) { - $that->toggleCrypto($socket, $deferred, $toggle, $method); + $toggleCrypto = function () use ($socket, $deferred, $toggle, $method) { + $this->toggleCrypto($socket, $deferred, $toggle, $method); }; $this->loop->addReadStream($socket, $toggleCrypto); @@ -90,17 +84,15 @@ public function toggle(Connection $stream, $toggle) $toggleCrypto(); } - $loop = $this->loop; - - return $deferred->promise()->then(function () use ($stream, $socket, $loop, $toggle) { - $loop->removeReadStream($socket); + return $deferred->promise()->then(function () use ($stream, $socket, $toggle) { + $this->loop->removeReadStream($socket); $stream->encryptionEnabled = $toggle; $stream->resume(); return $stream; - }, function($error) use ($stream, $socket, $loop) { - $loop->removeReadStream($socket); + }, function($error) use ($stream, $socket) { + $this->loop->removeReadStream($socket); $stream->resume(); throw $error; }); @@ -118,7 +110,7 @@ public function toggleCrypto($socket, Deferred $deferred, $toggle, $method) { $error = null; \set_error_handler(function ($_, $errstr) use (&$error) { - $error = \str_replace(array("\r", "\n"), ' ', $errstr); + $error = \str_replace(["\r", "\n"], ' ', $errstr); // remove useless function name from error message if (($pos = \strpos($error, "): ")) !== false) { diff --git a/src/TcpConnector.php b/src/TcpConnector.php index 61781e01..1f17c0e5 100644 --- a/src/TcpConnector.php +++ b/src/TcpConnector.php @@ -4,18 +4,17 @@ use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -use React\Promise; -use InvalidArgumentException; -use RuntimeException; +use React\Promise\Promise; +use function React\Promise\reject; final class TcpConnector implements ConnectorInterface { private $loop; private $context; - public function __construct(LoopInterface $loop = null, array $context = array()) + public function __construct(LoopInterface $loop = null, array $context = []) { - $this->loop = $loop ?: Loop::get(); + $this->loop = $loop ?? Loop::get(); $this->context = $context; } @@ -27,7 +26,7 @@ public function connect($uri) $parts = \parse_url($uri); if (!$parts || !isset($parts['scheme'], $parts['host'], $parts['port']) || $parts['scheme'] !== 'tcp') { - return Promise\reject(new \InvalidArgumentException( + return reject(new \InvalidArgumentException( 'Given URI "' . $uri . '" is invalid (EINVAL)', \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : (\defined('PCNTL_EINVAL') ? \PCNTL_EINVAL : 22) )); @@ -35,19 +34,19 @@ public function connect($uri) $ip = \trim($parts['host'], '[]'); if (@\inet_pton($ip) === false) { - return Promise\reject(new \InvalidArgumentException( + return reject(new \InvalidArgumentException( 'Given URI "' . $uri . '" does not contain a valid host IP (EINVAL)', \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : (\defined('PCNTL_EINVAL') ? \PCNTL_EINVAL : 22) )); } // use context given in constructor - $context = array( + $context = [ 'socket' => $this->context - ); + ]; // parse arguments from query component of URI - $args = array(); + $args = []; if (isset($parts['query'])) { \parse_str($parts['query'], $args); } @@ -58,10 +57,10 @@ public function connect($uri) // These context options are here in case TLS is enabled later on this stream. // If TLS is not enabled later, this doesn't hurt either. if (isset($args['hostname'])) { - $context['ssl'] = array( + $context['ssl'] = [ 'SNI_enabled' => true, 'peer_name' => $args['hostname'] - ); + ]; } // PHP 7.1.4 does not accept any other URI components (such as a query with no path), so let's simplify our URI here @@ -77,17 +76,16 @@ public function connect($uri) ); if (false === $stream) { - return Promise\reject(new \RuntimeException( + return reject(new \RuntimeException( 'Connection to ' . $uri . ' failed: ' . $errstr . SocketServer::errconst($errno), $errno )); } // wait for connection - $loop = $this->loop; - return new Promise\Promise(function ($resolve, $reject) use ($loop, $stream, $uri) { - $loop->addWriteStream($stream, function ($stream) use ($loop, $resolve, $reject, $uri) { - $loop->removeWriteStream($stream); + return new Promise(function ($resolve, $reject) use ($stream, $uri) { + $this->loop->addWriteStream($stream, function ($stream) use ($resolve, $reject, $uri) { + $this->loop->removeWriteStream($stream); // The following hack looks like the only way to // detect connection refused errors with PHP's stream sockets. @@ -109,8 +107,8 @@ public function connect($uri) // Match errstr from PHP's warning message. // fwrite(): send of 1 bytes failed with errno=111 Connection refused \preg_match('/errno=(\d+) (.+)/', $error, $m); - $errno = isset($m[1]) ? (int) $m[1] : 0; - $errstr = isset($m[2]) ? $m[2] : $error; + $errno = (int) ($m[1] ?? 0); + $errstr = $m[2] ?? $error; }); \fwrite($stream, \PHP_EOL); @@ -129,11 +127,11 @@ public function connect($uri) $errno )); } else { - $resolve(new Connection($stream, $loop)); + $resolve(new Connection($stream, $this->loop)); } }); - }, function () use ($loop, $stream, $uri) { - $loop->removeWriteStream($stream); + }, function () use ($stream, $uri) { + $this->loop->removeWriteStream($stream); \fclose($stream); throw new \RuntimeException( diff --git a/src/TcpServer.php b/src/TcpServer.php index 235761d4..42f86d63 100644 --- a/src/TcpServer.php +++ b/src/TcpServer.php @@ -5,8 +5,6 @@ use Evenement\EventEmitter; use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -use InvalidArgumentException; -use RuntimeException; /** * The `TcpServer` class implements the `ServerInterface` and @@ -109,11 +107,11 @@ final class TcpServer extends EventEmitter implements ServerInterface * for the underlying stream socket resource like this: * * ```php - * $server = new React\Socket\TcpServer('[::1]:8080', null, array( + * $server = new React\Socket\TcpServer('[::1]:8080', null, [ * 'backlog' => 200, * 'so_reuseport' => true, * 'ipv6_v6only' => true - * )); + * ]); * ``` * * Note that available [socket context options](https://www.php.net/manual/en/context.socket.php), @@ -125,12 +123,12 @@ final class TcpServer extends EventEmitter implements ServerInterface * @param string|int $uri * @param ?LoopInterface $loop * @param array $context - * @throws InvalidArgumentException if the listening address is invalid - * @throws RuntimeException if listening on this address fails (already in use etc.) + * @throws \InvalidArgumentException if the listening address is invalid + * @throws \RuntimeException if listening on this address fails (already in use etc.) */ - public function __construct($uri, LoopInterface $loop = null, array $context = array()) + public function __construct($uri, LoopInterface $loop = null, array $context = []) { - $this->loop = $loop ?: Loop::get(); + $this->loop = $loop ?? Loop::get(); // a single port has been given => assume localhost if ((string)(int)$uri === (string)$uri) { @@ -172,7 +170,7 @@ public function __construct($uri, LoopInterface $loop = null, array $context = a $errno, $errstr, \STREAM_SERVER_BIND | \STREAM_SERVER_LISTEN, - \stream_context_create(array('socket' => $context + array('backlog' => 511))) + \stream_context_create(['socket' => $context + ['backlog' => 511]]) ); if (false === $this->master) { if ($errno === 0) { @@ -224,15 +222,14 @@ public function resume() return; } - $that = $this; - $this->loop->addReadStream($this->master, function ($master) use ($that) { + $this->loop->addReadStream($this->master, function ($master) { try { $newSocket = SocketServer::accept($master); } catch (\RuntimeException $e) { - $that->emit('error', array($e)); + $this->emit('error', [$e]); return; } - $that->handleConnection($newSocket); + $this->handleConnection($newSocket); }); $this->listening = true; } @@ -251,8 +248,8 @@ public function close() /** @internal */ public function handleConnection($socket) { - $this->emit('connection', array( + $this->emit('connection', [ new Connection($socket, $this->loop) - )); + ]); } } diff --git a/src/TimeoutConnector.php b/src/TimeoutConnector.php index a20ea5a6..75414b61 100644 --- a/src/TimeoutConnector.php +++ b/src/TimeoutConnector.php @@ -16,26 +16,24 @@ public function __construct(ConnectorInterface $connector, $timeout, LoopInterfa { $this->connector = $connector; $this->timeout = $timeout; - $this->loop = $loop ?: Loop::get(); + $this->loop = $loop ?? Loop::get(); } public function connect($uri) { $promise = $this->connector->connect($uri); - $loop = $this->loop; - $time = $this->timeout; - return new Promise(function ($resolve, $reject) use ($loop, $time, $promise, $uri) { + return new Promise(function ($resolve, $reject) use ($promise, $uri) { $timer = null; - $promise = $promise->then(function ($v) use (&$timer, $loop, $resolve) { + $promise = $promise->then(function ($v) use (&$timer, $resolve) { if ($timer) { - $loop->cancelTimer($timer); + $this->loop->cancelTimer($timer); } $timer = false; $resolve($v); - }, function ($v) use (&$timer, $loop, $reject) { + }, function ($v) use (&$timer, $reject) { if ($timer) { - $loop->cancelTimer($timer); + $this->loop->cancelTimer($timer); } $timer = false; $reject($v); @@ -47,9 +45,9 @@ public function connect($uri) } // start timeout timer which will cancel the pending promise - $timer = $loop->addTimer($time, function () use ($time, &$promise, $reject, $uri) { + $timer = $this->loop->addTimer($this->timeout, function () use (&$promise, $reject, $uri) { $reject(new \RuntimeException( - 'Connection to ' . $uri . ' timed out after ' . $time . ' seconds (ETIMEDOUT)', + 'Connection to ' . $uri . ' timed out after ' . $this->timeout . ' seconds (ETIMEDOUT)', \defined('SOCKET_ETIMEDOUT') ? \SOCKET_ETIMEDOUT : 110 )); diff --git a/src/UnixConnector.php b/src/UnixConnector.php index 627d60f7..eb3f18e1 100644 --- a/src/UnixConnector.php +++ b/src/UnixConnector.php @@ -4,9 +4,8 @@ use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -use React\Promise; -use InvalidArgumentException; -use RuntimeException; +use function React\Promise\reject; +use function React\Promise\resolve; /** * Unix domain socket connector @@ -20,7 +19,7 @@ final class UnixConnector implements ConnectorInterface public function __construct(LoopInterface $loop = null) { - $this->loop = $loop ?: Loop::get(); + $this->loop = $loop ?? Loop::get(); } public function connect($path) @@ -28,7 +27,7 @@ public function connect($path) if (\strpos($path, '://') === false) { $path = 'unix://' . $path; } elseif (\substr($path, 0, 7) !== 'unix://') { - return Promise\reject(new \InvalidArgumentException( + return reject(new \InvalidArgumentException( 'Given URI "' . $path . '" is invalid (EINVAL)', \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : (\defined('PCNTL_EINVAL') ? \PCNTL_EINVAL : 22) )); @@ -37,7 +36,7 @@ public function connect($path) $resource = @\stream_socket_client($path, $errno, $errstr, 1.0); if (!$resource) { - return Promise\reject(new \RuntimeException( + return reject(new \RuntimeException( 'Unable to connect to unix domain socket "' . $path . '": ' . $errstr . SocketServer::errconst($errno), $errno )); @@ -46,6 +45,6 @@ public function connect($path) $connection = new Connection($resource, $this->loop); $connection->unix = true; - return Promise\resolve($connection); + return resolve($connection); } } diff --git a/src/UnixServer.php b/src/UnixServer.php index 1aca62ff..d16502d9 100644 --- a/src/UnixServer.php +++ b/src/UnixServer.php @@ -5,8 +5,6 @@ use Evenement\EventEmitter; use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -use InvalidArgumentException; -use RuntimeException; /** * The `UnixServer` class implements the `ServerInterface` and @@ -47,12 +45,12 @@ final class UnixServer extends EventEmitter implements ServerInterface * @param string $path * @param ?LoopInterface $loop * @param array $context - * @throws InvalidArgumentException if the listening address is invalid - * @throws RuntimeException if listening on this address fails (already in use etc.) + * @throws \InvalidArgumentException if the listening address is invalid + * @throws \RuntimeException if listening on this address fails (already in use etc.) */ - public function __construct($path, LoopInterface $loop = null, array $context = array()) + public function __construct($path, LoopInterface $loop = null, array $context = []) { - $this->loop = $loop ?: Loop::get(); + $this->loop = $loop ?? Loop::get(); if (\strpos($path, '://') === false) { $path = 'unix://' . $path; @@ -69,8 +67,8 @@ public function __construct($path, LoopInterface $loop = null, array $context = // PHP does not seem to report errno/errstr for Unix domain sockets (UDS) right now. // This only applies to UDS server sockets, see also https://3v4l.org/NAhpr. if (\preg_match('/\(([^\)]+)\)|\[(\d+)\]: (.*)/', $error, $match)) { - $errstr = isset($match[3]) ? $match['3'] : $match[1]; - $errno = isset($match[2]) ? (int)$match[2] : 0; + $errstr = $match[3] ?? $match[1]; + $errno = (int) ($match[2] ?? 0); } }); @@ -79,7 +77,7 @@ public function __construct($path, LoopInterface $loop = null, array $context = $errno, $errstr, \STREAM_SERVER_BIND | \STREAM_SERVER_LISTEN, - \stream_context_create(array('socket' => $context)) + \stream_context_create(['socket' => $context]) ); \restore_error_handler(); @@ -120,15 +118,14 @@ public function resume() return; } - $that = $this; - $this->loop->addReadStream($this->master, function ($master) use ($that) { + $this->loop->addReadStream($this->master, function ($master) { try { $newSocket = SocketServer::accept($master); } catch (\RuntimeException $e) { - $that->emit('error', array($e)); + $this->emit('error', [$e]); return; } - $that->handleConnection($newSocket); + $this->handleConnection($newSocket); }); $this->listening = true; } @@ -150,8 +147,8 @@ public function handleConnection($socket) $connection = new Connection($socket, $this->loop); $connection->unix = true; - $this->emit('connection', array( + $this->emit('connection', [ $connection - )); + ]); } } diff --git a/tests/ConnectorTest.php b/tests/ConnectorTest.php index a56d69aa..039d7cb1 100644 --- a/tests/ConnectorTest.php +++ b/tests/ConnectorTest.php @@ -26,7 +26,7 @@ public function testConstructWithLoopAssignsGivenLoop() { $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $connector = new Connector(array(), $loop); + $connector = new Connector([], $loop); $ref = new \ReflectionProperty($connector, 'connectors'); $ref->setAccessible(true); @@ -43,11 +43,11 @@ public function testConstructWithContextAssignsGivenContext() { $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); - $connector = new Connector(array( + $connector = new Connector([ 'tcp' => $tcp, 'dns' => false, 'timeout' => false - )); + ]); $ref = new \ReflectionProperty($connector, 'connectors'); $ref->setAccessible(true); @@ -64,9 +64,9 @@ public function testConnectorUsesTcpAsDefaultScheme() $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $tcp->expects($this->once())->method('connect')->with('127.0.0.1:80')->willReturn($promise); - $connector = new Connector(array( + $connector = new Connector([ 'tcp' => $tcp - ), $loop); + ], $loop); $connector->connect('127.0.0.1:80'); } @@ -79,10 +79,10 @@ public function testConnectorPassedThroughHostnameIfDnsIsDisabled() $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $tcp->expects($this->once())->method('connect')->with('tcp://google.com:80')->willReturn($promise); - $connector = new Connector(array( + $connector = new Connector([ 'tcp' => $tcp, 'dns' => false - ), $loop); + ], $loop); $connector->connect('tcp://google.com:80'); } @@ -90,7 +90,7 @@ public function testConnectorPassedThroughHostnameIfDnsIsDisabled() public function testConnectorWithUnknownSchemeAlwaysFails() { $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $connector = new Connector(array(), $loop); + $connector = new Connector([], $loop); $promise = $connector->connect('unknown://google.com:80'); @@ -104,9 +104,9 @@ public function testConnectorWithUnknownSchemeAlwaysFails() public function testConnectorWithDisabledTcpDefaultSchemeAlwaysFails() { $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $connector = new Connector(array( + $connector = new Connector([ 'tcp' => false - ), $loop); + ], $loop); $promise = $connector->connect('google.com:80'); @@ -120,9 +120,9 @@ public function testConnectorWithDisabledTcpDefaultSchemeAlwaysFails() public function testConnectorWithDisabledTcpSchemeAlwaysFails() { $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $connector = new Connector(array( + $connector = new Connector([ 'tcp' => false - ), $loop); + ], $loop); $promise = $connector->connect('tcp://google.com:80'); @@ -136,9 +136,9 @@ public function testConnectorWithDisabledTcpSchemeAlwaysFails() public function testConnectorWithDisabledTlsSchemeAlwaysFails() { $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $connector = new Connector(array( + $connector = new Connector([ 'tls' => false - ), $loop); + ], $loop); $promise = $connector->connect('tls://google.com:443'); @@ -152,9 +152,9 @@ public function testConnectorWithDisabledTlsSchemeAlwaysFails() public function testConnectorWithDisabledUnixSchemeAlwaysFails() { $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $connector = new Connector(array( + $connector = new Connector([ 'unix' => false - ), $loop); + ], $loop); $promise = $connector->connect('unix://demo.sock'); @@ -173,10 +173,10 @@ public function testConnectorUsesGivenResolverInstance() $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn($promise); - $connector = new Connector(array( + $connector = new Connector([ 'dns' => $resolver, - 'happy_eyeballs' => false, - ), $loop); + 'happy_eyeballs' => false + ], $loop); $connector->connect('google.com:80'); } @@ -193,11 +193,11 @@ public function testConnectorUsesResolvedHostnameIfDnsIsUsed() $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $tcp->expects($this->once())->method('connect')->with('tcp://127.0.0.1:80?hostname=google.com')->willReturn($promise); - $connector = new Connector(array( + $connector = new Connector([ 'tcp' => $tcp, 'dns' => $resolver, - 'happy_eyeballs' => false, - ), $loop); + 'happy_eyeballs' => false + ], $loop); $connector->connect('tcp://google.com:80'); } diff --git a/tests/DnsConnectorTest.php b/tests/DnsConnectorTest.php index 41fdb559..da2df865 100644 --- a/tests/DnsConnectorTest.php +++ b/tests/DnsConnectorTest.php @@ -2,9 +2,11 @@ namespace React\Tests\Socket; -use React\Promise; use React\Promise\Deferred; +use React\Promise\Promise; use React\Socket\DnsConnector; +use function React\Promise\reject; +use function React\Promise\resolve; class DnsConnectorTest extends TestCase { @@ -26,7 +28,7 @@ public function setUpMocks() public function testPassByResolverIfGivenIp() { $this->resolver->expects($this->never())->method('resolve'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('127.0.0.1:80'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('127.0.0.1:80'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('127.0.0.1:80'); @@ -35,8 +37,8 @@ public function testPassByResolverIfGivenIp() public function testPassThroughResolverIfGivenHost() { - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('1.2.3.4'))); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=google.com'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(resolve('1.2.3.4'))); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('google.com:80'); @@ -45,8 +47,8 @@ public function testPassThroughResolverIfGivenHost() public function testPassThroughResolverIfGivenHostWhichResolvesToIpv6() { - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('::1'))); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('[::1]:80?hostname=google.com'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(resolve('::1'))); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('[::1]:80?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('google.com:80'); @@ -56,7 +58,7 @@ public function testPassThroughResolverIfGivenHostWhichResolvesToIpv6() public function testPassByResolverIfGivenCompleteUri() { $this->resolver->expects($this->never())->method('resolve'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://127.0.0.1:80/path?query#fragment'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://127.0.0.1:80/path?query#fragment'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('scheme://127.0.0.1:80/path?query#fragment'); @@ -65,8 +67,8 @@ public function testPassByResolverIfGivenCompleteUri() public function testPassThroughResolverIfGivenCompleteUri() { - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('1.2.3.4'))); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/path?query&hostname=google.com#fragment'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(resolve('1.2.3.4'))); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/path?query&hostname=google.com#fragment'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('scheme://google.com:80/path?query#fragment'); @@ -75,8 +77,8 @@ public function testPassThroughResolverIfGivenCompleteUri() public function testPassThroughResolverIfGivenExplicitHost() { - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(Promise\resolve('1.2.3.4'))); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/?hostname=google.de'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(resolve('1.2.3.4'))); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/?hostname=google.de'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('scheme://google.com:80/?hostname=google.de'); @@ -99,7 +101,7 @@ public function testRejectsImmediatelyIfUriIsInvalid() public function testConnectRejectsIfGivenIpAndTcpConnectorRejectsWithRuntimeException() { - $promise = Promise\reject(new \RuntimeException('Connection to tcp://1.2.3.4:80 failed: Connection failed', 42)); + $promise = reject(new \RuntimeException('Connection to tcp://1.2.3.4:80 failed: Connection failed', 42)); $this->resolver->expects($this->never())->method('resolve'); $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80')->willReturn($promise); @@ -120,7 +122,7 @@ public function testConnectRejectsIfGivenIpAndTcpConnectorRejectsWithRuntimeExce public function testConnectRejectsIfGivenIpAndTcpConnectorRejectsWithInvalidArgumentException() { - $promise = Promise\reject(new \InvalidArgumentException('Invalid', 42)); + $promise = reject(new \InvalidArgumentException('Invalid', 42)); $this->resolver->expects($this->never())->method('resolve'); $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80')->willReturn($promise); @@ -141,8 +143,8 @@ public function testConnectRejectsIfGivenIpAndTcpConnectorRejectsWithInvalidArgu public function testConnectRejectsWithOriginalHostnameInMessageAfterResolvingIfTcpConnectorRejectsWithRuntimeException() { - $promise = Promise\reject(new \RuntimeException('Connection to tcp://1.2.3.4:80?hostname=example.com failed: Connection failed', 42)); - $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn(Promise\resolve('1.2.3.4')); + $promise = reject(new \RuntimeException('Connection to tcp://1.2.3.4:80?hostname=example.com failed: Connection failed', 42)); + $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn(resolve('1.2.3.4')); $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80?hostname=example.com')->willReturn($promise); $promise = $this->connector->connect('example.com:80'); @@ -162,8 +164,8 @@ public function testConnectRejectsWithOriginalHostnameInMessageAfterResolvingIfT public function testConnectRejectsWithOriginalExceptionAfterResolvingIfTcpConnectorRejectsWithInvalidArgumentException() { - $promise = Promise\reject(new \InvalidArgumentException('Invalid', 42)); - $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn(Promise\resolve('1.2.3.4')); + $promise = reject(new \InvalidArgumentException('Invalid', 42)); + $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn(resolve('1.2.3.4')); $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80?hostname=example.com')->willReturn($promise); $promise = $this->connector->connect('example.com:80'); @@ -183,7 +185,7 @@ public function testConnectRejectsWithOriginalExceptionAfterResolvingIfTcpConnec public function testSkipConnectionIfDnsFails() { - $promise = Promise\reject(new \RuntimeException('DNS error')); + $promise = reject(new \RuntimeException('DNS error')); $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.invalid'))->willReturn($promise); $this->tcp->expects($this->never())->method('connect'); @@ -206,7 +208,7 @@ public function testRejectionExceptionUsesPreviousExceptionIfDnsFails() { $exception = new \RuntimeException(); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.invalid'))->willReturn(Promise\reject($exception)); + $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.invalid'))->willReturn(reject($exception)); $promise = $this->connector->connect('example.invalid:80'); @@ -217,7 +219,7 @@ public function testRejectionExceptionUsesPreviousExceptionIfDnsFails() public function testCancelDuringDnsCancelsDnsAndDoesNotStartTcpConnection() { - $pending = new Promise\Promise(function () { }, $this->expectCallableOnce()); + $pending = new Promise(function () { }, $this->expectCallableOnce()); $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->will($this->returnValue($pending)); $this->tcp->expects($this->never())->method('connect'); @@ -239,7 +241,7 @@ public function testCancelDuringDnsCancelsDnsAndDoesNotStartTcpConnection() public function testCancelDuringTcpConnectionCancelsTcpConnectionIfGivenIp() { - $pending = new Promise\Promise(function () { }, $this->expectCallableOnce()); + $pending = new Promise(function () { }, $this->expectCallableOnce()); $this->resolver->expects($this->never())->method('resolve'); $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80'))->willReturn($pending); @@ -249,8 +251,8 @@ public function testCancelDuringTcpConnectionCancelsTcpConnectionIfGivenIp() public function testCancelDuringTcpConnectionCancelsTcpConnectionAfterDnsIsResolved() { - $pending = new Promise\Promise(function () { }, $this->expectCallableOnce()); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn(Promise\resolve('1.2.3.4')); + $pending = new Promise(function () { }, $this->expectCallableOnce()); + $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn(resolve('1.2.3.4')); $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->willReturn($pending); $promise = $this->connector->connect('example.com:80'); @@ -261,7 +263,7 @@ public function testCancelDuringTcpConnectionCancelsTcpConnectionWithTcpRejectio { $first = new Deferred(); $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn($first->promise()); - $pending = new Promise\Promise(function () { }, function () { + $pending = new Promise(function () { }, function () { throw new \RuntimeException( 'Connection cancelled', defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103 @@ -404,7 +406,7 @@ public function testCancelDuringTcpConnectionShouldNotCreateAnyGarbageReferences $dns = new Deferred(); $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn($dns->promise()); - $tcp = new Promise\Promise(function () { }, function () { + $tcp = new Promise(function () { }, function () { throw new \RuntimeException('Connection cancelled'); }); $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->willReturn($tcp); diff --git a/tests/FdServerTest.php b/tests/FdServerTest.php index 87fa63cf..e7d3c679 100644 --- a/tests/FdServerTest.php +++ b/tests/FdServerTest.php @@ -5,6 +5,8 @@ use React\Promise\Promise; use React\Socket\ConnectionInterface; use React\Socket\FdServer; +use function React\Async\await; +use function React\Promise\Timer\timeout; class FdServerTest extends TestCase { @@ -324,7 +326,7 @@ public function testServerEmitsConnectionEventForNewConnection() $server->on('connection', $resolve); }); - $connection = \React\Async\await(\React\Promise\Timer\timeout($promise, 1.0)); + $connection = await(timeout($promise, 1.0)); /** * @var ConnectionInterface $connection diff --git a/tests/FunctionalConnectorTest.php b/tests/FunctionalConnectorTest.php index 0a54b505..117e827f 100644 --- a/tests/FunctionalConnectorTest.php +++ b/tests/FunctionalConnectorTest.php @@ -8,6 +8,9 @@ use React\Socket\Connector; use React\Socket\ConnectorInterface; use React\Socket\TcpServer; +use function React\Async\await; +use function React\Promise\Stream\buffer; +use function React\Promise\Timer\timeout; class FunctionalConnectorTest extends TestCase { @@ -21,9 +24,9 @@ public function connectionToTcpServerShouldSucceedWithLocalhost() { $server = new TcpServer(9998); - $connector = new Connector(array()); + $connector = new Connector([]); - $connection = \React\Async\await(\React\Promise\Timer\timeout($connector->connect('localhost:9998'), self::TIMEOUT)); + $connection = await(timeout($connector->connect('localhost:9998'), self::TIMEOUT)); $server->close(); @@ -39,10 +42,10 @@ public function testConnectTwiceWithoutHappyEyeBallsOnlySendsSingleDnsQueryDueTo { $socket = stream_socket_server('udp://127.0.0.1:0', $errno, $errstr, STREAM_SERVER_BIND); - $connector = new Connector(array( + $connector = new Connector([ 'dns' => 'udp://' . stream_socket_get_name($socket, false), 'happy_eyeballs' => false - )); + ]); // minimal DNS proxy stub which forwards DNS messages to actual DNS server $received = 0; @@ -58,11 +61,11 @@ public function testConnectTwiceWithoutHappyEyeBallsOnlySendsSingleDnsQueryDueTo fclose($client); }); - $connection = \React\Async\await($connector->connect('example.com:80')); + $connection = await($connector->connect('example.com:80')); $connection->close(); $this->assertEquals(1, $received); - $connection = \React\Async\await($connector->connect('example.com:80')); + $connection = await($connector->connect('example.com:80')); $connection->close(); $this->assertEquals(1, $received); @@ -75,9 +78,9 @@ public function testConnectTwiceWithoutHappyEyeBallsOnlySendsSingleDnsQueryDueTo */ public function connectionToRemoteTCP4n6ServerShouldResultInOurIP() { - $connector = new Connector(array('happy_eyeballs' => true)); + $connector = new Connector(['happy_eyeballs' => true]); - $ip = \React\Async\await(\React\Promise\Timer\timeout($this->request('dual.tlund.se', $connector), self::TIMEOUT)); + $ip = await(timeout($this->request('dual.tlund.se', $connector), self::TIMEOUT)); $this->assertNotFalse(inet_pton($ip)); } @@ -88,10 +91,10 @@ public function connectionToRemoteTCP4n6ServerShouldResultInOurIP() */ public function connectionToRemoteTCP4ServerShouldResultInOurIP() { - $connector = new Connector(array('happy_eyeballs' => true)); + $connector = new Connector(['happy_eyeballs' => true]); try { - $ip = \React\Async\await(\React\Promise\Timer\timeout($this->request('ipv4.tlund.se', $connector), self::TIMEOUT)); + $ip = await(timeout($this->request('ipv4.tlund.se', $connector), self::TIMEOUT)); } catch (\Exception $e) { $this->checkIpv4(); throw $e; @@ -107,10 +110,10 @@ public function connectionToRemoteTCP4ServerShouldResultInOurIP() */ public function connectionToRemoteTCP6ServerShouldResultInOurIP() { - $connector = new Connector(array('happy_eyeballs' => true)); + $connector = new Connector(['happy_eyeballs' => true]); try { - $ip = \React\Async\await(\React\Promise\Timer\timeout($this->request('ipv6.tlund.se', $connector), self::TIMEOUT)); + $ip = await(timeout($this->request('ipv6.tlund.se', $connector), self::TIMEOUT)); } catch (\Exception $e) { $this->checkIpv6(); throw $e; @@ -125,7 +128,7 @@ public function testCancelPendingTlsConnectionDuringTlsHandshakeShouldCloseTcpCo $server = new TcpServer(0); $uri = str_replace('tcp://', 'tls://', $server->getAddress()); - $connector = new Connector(array()); + $connector = new Connector([]); $promise = $connector->connect($uri); $deferred = new Deferred(); @@ -139,11 +142,11 @@ public function testCancelPendingTlsConnectionDuringTlsHandshakeShouldCloseTcpCo }); }); - \React\Async\await(\React\Promise\Timer\timeout($deferred->promise(), self::TIMEOUT)); + await(timeout($deferred->promise(), self::TIMEOUT)); $server->close(); try { - \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + await(timeout($promise, self::TIMEOUT)); $this->fail(); } catch (\Exception $e) { $this->assertInstanceOf('RuntimeException', $e); @@ -164,13 +167,12 @@ public function parseIpFromPage($body) private function request($host, ConnectorInterface $connector) { - $that = $this; return $connector->connect($host . ':80')->then(function (ConnectionInterface $connection) use ($host) { $connection->write("GET / HTTP/1.1\r\nHost: " . $host . "\r\nConnection: close\r\n\r\n"); - return \React\Promise\Stream\buffer($connection); - })->then(function ($response) use ($that) { - return $that->parseIpFromPage($response); + return buffer($connection); + })->then(function ($response) { + return $this->parseIpFromPage($response); }); } diff --git a/tests/FunctionalSecureServerTest.php b/tests/FunctionalSecureServerTest.php index 94aace37..4c91faec 100644 --- a/tests/FunctionalSecureServerTest.php +++ b/tests/FunctionalSecureServerTest.php @@ -9,6 +9,9 @@ use React\Socket\SecureServer; use React\Socket\TcpConnector; use React\Socket\TcpServer; +use function React\Async\await; +use function React\Promise\all; +use function React\Promise\Timer\timeout; class FunctionalSecureServerTest extends TestCase { @@ -17,17 +20,17 @@ class FunctionalSecureServerTest extends TestCase public function testClientCanConnectToServer() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $promise = $connector->connect($server->getAddress()); /* @var ConnectionInterface $client */ - $client = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $client = await(timeout($promise, self::TIMEOUT)); $this->assertInstanceOf('React\Socket\ConnectionInterface', $client); $this->assertEquals($server->getAddress(), $client->getRemoteAddress()); @@ -46,17 +49,17 @@ public function testClientUsesTls13ByDefaultWhenSupportedByOpenSSL() } $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $promise = $connector->connect($server->getAddress()); /* @var ConnectionInterface $client */ - $client = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $client = await(timeout($promise, self::TIMEOUT)); $this->assertInstanceOf('React\Socket\Connection', $client); $this->assertTrue(isset($client->stream)); @@ -80,18 +83,18 @@ public function testClientUsesTls13ByDefaultWhenSupportedByOpenSSL() public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByClient() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT - )); + ]); $promise = $connector->connect($server->getAddress()); /* @var ConnectionInterface $client */ - $client = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $client = await(timeout($promise, self::TIMEOUT)); $this->assertInstanceOf('React\Socket\Connection', $client); $this->assertTrue(isset($client->stream)); @@ -107,18 +110,18 @@ public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByClien public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByServer() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem', 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER - )); + ]); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $promise = $connector->connect($server->getAddress()); /* @var ConnectionInterface $client */ - $client = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $client = await(timeout($promise, self::TIMEOUT)); $this->assertInstanceOf('React\Socket\Connection', $client); $this->assertTrue(isset($client->stream)); @@ -134,19 +137,19 @@ public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByServe public function testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClient() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT - )); + ]); $promise = $connector->connect($server->getAddress()); /* @var ConnectionInterface $client */ try { - $client = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $client = await(timeout($promise, 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 @@ -172,23 +175,23 @@ public function testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClien public function testServerEmitsConnectionForClientConnection() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', $resolve); $server->on('error', $reject); }); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $client = $connector->connect($server->getAddress()); // await both client and server side end of connection /* @var ConnectionInterface[] $both */ - $both = \React\Async\await(\React\Promise\Timer\timeout(\React\Promise\all(array($peer, $client)), self::TIMEOUT)); + $both = await(timeout(all([$peer, $client]), self::TIMEOUT)); // both ends of the connection are represented by different instances of ConnectionInterface $this->assertCount(2, $both); @@ -209,17 +212,17 @@ public function testServerEmitsConnectionForClientConnection() public function testClientEmitsDataEventOnceForDataWrittenFromServer() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', function (ConnectionInterface $conn) { $conn->write('foo'); }); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $connecting = $connector->connect($server->getAddress()); $promise = new Promise(function ($resolve, $reject) use ($connecting) { @@ -228,7 +231,7 @@ public function testClientEmitsDataEventOnceForDataWrittenFromServer() }, $reject); }); - $data = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $data = await(timeout($promise, self::TIMEOUT)); $this->assertEquals('foo', $data); @@ -242,18 +245,18 @@ public function testClientEmitsDataEventOnceForDataWrittenFromServer() public function testWritesDataInMultipleChunksToConnection() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableOnce()); $server->on('connection', function (ConnectionInterface $conn) { $conn->write(str_repeat('*', 400000)); }); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $connecting = $connector->connect($server->getAddress()); $promise = new Promise(function ($resolve, $reject) use ($connecting) { @@ -269,7 +272,7 @@ public function testWritesDataInMultipleChunksToConnection() }, $reject); }); - $received = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $received = await(timeout($promise, self::TIMEOUT)); $this->assertEquals(400000, $received); @@ -283,18 +286,18 @@ public function testWritesDataInMultipleChunksToConnection() public function testWritesMoreDataInMultipleChunksToConnection() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableOnce()); $server->on('connection', function (ConnectionInterface $conn) { $conn->write(str_repeat('*', 2000000)); }); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $connecting = $connector->connect($server->getAddress()); $promise = new Promise(function ($resolve, $reject) use ($connecting) { @@ -310,7 +313,7 @@ public function testWritesMoreDataInMultipleChunksToConnection() }, $reject); }); - $received = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $received = await(timeout($promise, self::TIMEOUT)); $this->assertEquals(2000000, $received); @@ -324,9 +327,9 @@ public function testWritesMoreDataInMultipleChunksToConnection() public function testEmitsDataFromConnection() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableOnce()); $promise = new Promise(function ($resolve, $reject) use ($server) { @@ -335,15 +338,15 @@ public function testEmitsDataFromConnection() }); }); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $connecting = $connector->connect($server->getAddress()); $connecting->then(function (ConnectionInterface $connection) { $connection->write('foo'); }); - $data = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $data = await(timeout($promise, self::TIMEOUT)); $this->assertEquals('foo', $data); @@ -357,9 +360,9 @@ public function testEmitsDataFromConnection() public function testEmitsDataInMultipleChunksFromConnection() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableOnce()); $promise = new Promise(function ($resolve, $reject) use ($server) { @@ -375,15 +378,15 @@ public function testEmitsDataInMultipleChunksFromConnection() }); }); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $connecting = $connector->connect($server->getAddress()); $connecting->then(function (ConnectionInterface $connection) { $connection->write(str_repeat('*', 400000)); }); - $received = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $received = await(timeout($promise, self::TIMEOUT)); $this->assertEquals(400000, $received); @@ -397,18 +400,18 @@ public function testEmitsDataInMultipleChunksFromConnection() public function testPipesDataBackInMultipleChunksFromConnection() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableOnce()); $server->on('connection', function (ConnectionInterface $conn) { $conn->pipe($conn); }); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $connecting = $connector->connect($server->getAddress()); $promise = new Promise(function ($resolve, $reject) use ($connecting) { @@ -425,7 +428,7 @@ public function testPipesDataBackInMultipleChunksFromConnection() }, $reject); }); - $received = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $received = await(timeout($promise, self::TIMEOUT)); $this->assertEquals(400000, $received); @@ -442,19 +445,19 @@ public function testPipesDataBackInMultipleChunksFromConnection() public function testEmitsConnectionForNewTlsv11Connection() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem', 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_SERVER - )); + ]); $server->on('connection', $this->expectCallableOnce()); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT - )); + ]); $promise = $connector->connect($server->getAddress()); - \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + await(timeout($promise, self::TIMEOUT)); $server->close(); $promise->then(function (ConnectionInterface $connection) { @@ -468,23 +471,23 @@ public function testEmitsConnectionForNewTlsv11Connection() public function testEmitsErrorForClientWithTlsVersionMismatch() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ '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(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT - )); + ]); $promise = $connector->connect($server->getAddress()); $this->setExpectedException('RuntimeException', 'handshake'); try { - \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + await(timeout($promise, self::TIMEOUT)); } catch (\Exception $e) { $server->close(); @@ -495,22 +498,22 @@ public function testEmitsErrorForClientWithTlsVersionMismatch() public function testServerEmitsConnectionForNewConnectionWithEncryptedCertificate() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem', 'passphrase' => 'swordfish' - )); + ]); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', $resolve); $server->on('error', $reject); }); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $connector->connect($server->getAddress()); - $connection = \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); + $connection = await(timeout($peer, self::TIMEOUT)); $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); @@ -521,19 +524,19 @@ public function testServerEmitsConnectionForNewConnectionWithEncryptedCertificat public function testClientRejectsWithErrorForServerWithInvalidCertificate() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => 'invalid.pem' - )); + ]); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $promise = $connector->connect($server->getAddress()); $this->setExpectedException('RuntimeException', 'handshake'); try { - \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + await(timeout($promise, self::TIMEOUT)); } catch (\Exception $e) { $server->close(); @@ -544,9 +547,9 @@ public function testClientRejectsWithErrorForServerWithInvalidCertificate() public function testServerEmitsErrorForClientWithInvalidCertificate() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => 'invalid.pem' - )); + ]); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', function () use ($reject) { @@ -555,13 +558,13 @@ public function testServerEmitsErrorForClientWithInvalidCertificate() $server->on('error', $reject); }); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $promise = $connector->connect($server->getAddress()); try { - \React\Async\await($promise); + await($promise); } catch (\RuntimeException $e) { // ignore client-side exception } @@ -569,7 +572,7 @@ public function testServerEmitsErrorForClientWithInvalidCertificate() $this->setExpectedException('RuntimeException', 'handshake'); try { - \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); + await(timeout($peer, self::TIMEOUT)); } catch (\Exception $e) { $server->close(); @@ -584,21 +587,21 @@ public function testEmitsErrorForServerWithEncryptedCertificateMissingPassphrase } $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem' - )); + ]); $server->on('connection', $this->expectCallableNever()); $server->on('error', $this->expectCallableOnce()); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $promise = $connector->connect($server->getAddress()); $this->setExpectedException('RuntimeException', 'handshake'); try { - \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + await(timeout($promise, self::TIMEOUT)); } catch (\Exception $e) { $server->close(); @@ -613,22 +616,22 @@ public function testEmitsErrorForServerWithEncryptedCertificateWithInvalidPassph } $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost_swordfish.pem', 'passphrase' => 'nope' - )); + ]); $server->on('connection', $this->expectCallableNever()); $server->on('error', $this->expectCallableOnce()); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $promise = $connector->connect($server->getAddress()); $this->setExpectedException('RuntimeException', 'handshake'); try { - \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + await(timeout($promise, self::TIMEOUT)); } catch (\Exception $e) { $server->close(); @@ -639,19 +642,19 @@ public function testEmitsErrorForServerWithEncryptedCertificateWithInvalidPassph public function testEmitsErrorForConnectionWithPeerVerification() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => true - )); + ]); $promise = $connector->connect($server->getAddress()); $promise->then(null, $this->expectCallableOnce()); - \React\Async\await(\React\Promise\Timer\timeout($errorEvent, self::TIMEOUT)); + await(timeout($errorEvent, self::TIMEOUT)); $server->close(); } @@ -663,20 +666,20 @@ public function testEmitsErrorIfConnectionIsCancelled() } $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); - $connector = new SecureConnector(new TcpConnector(), null, array( + $connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false - )); + ]); $promise = $connector->connect($server->getAddress()); $promise->cancel(); $promise->then(null, $this->expectCallableOnce()); - \React\Async\await(\React\Promise\Timer\timeout($errorEvent, self::TIMEOUT)); + await(timeout($errorEvent, self::TIMEOUT)); $server->close(); } @@ -684,9 +687,9 @@ public function testEmitsErrorIfConnectionIsCancelled() public function testEmitsErrorIfConnectionIsClosedBeforeHandshake() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); @@ -697,7 +700,7 @@ public function testEmitsErrorIfConnectionIsClosedBeforeHandshake() $stream->close(); }); - $error = \React\Async\await(\React\Promise\Timer\timeout($errorEvent, self::TIMEOUT)); + $error = await(timeout($errorEvent, self::TIMEOUT)); // Connection from tcp://127.0.0.1:39528 failed during TLS handshake: Connection lost during TLS handshake (ECONNRESET) $this->assertInstanceOf('RuntimeException', $error); @@ -712,9 +715,9 @@ public function testEmitsErrorIfConnectionIsClosedBeforeHandshake() public function testEmitsErrorIfConnectionIsClosedWithIncompleteHandshake() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); @@ -725,7 +728,7 @@ public function testEmitsErrorIfConnectionIsClosedWithIncompleteHandshake() $stream->end("\x1e"); }); - $error = \React\Async\await(\React\Promise\Timer\timeout($errorEvent, self::TIMEOUT)); + $error = await(timeout($errorEvent, self::TIMEOUT)); // Connection from tcp://127.0.0.1:39528 failed during TLS handshake: Connection lost during TLS handshake (ECONNRESET) $this->assertInstanceOf('RuntimeException', $error); @@ -740,16 +743,16 @@ public function testEmitsErrorIfConnectionIsClosedWithIncompleteHandshake() public function testEmitsNothingIfPlaintextConnectionIsIdle() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableNever()); $server->on('error', $this->expectCallableNever()); $connector = new TcpConnector(); $promise = $connector->connect(str_replace('tls://', '', $server->getAddress())); - $connection = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $connection = await(timeout($promise, self::TIMEOUT)); $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); $server->close(); @@ -761,9 +764,9 @@ public function testEmitsNothingIfPlaintextConnectionIsIdle() public function testEmitsErrorIfConnectionIsHttpInsteadOfSecureHandshake() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); @@ -774,7 +777,7 @@ public function testEmitsErrorIfConnectionIsHttpInsteadOfSecureHandshake() $stream->write("GET / HTTP/1.0\r\n\r\n"); }); - $error = \React\Async\await(\React\Promise\Timer\timeout($errorEvent, self::TIMEOUT)); + $error = await(timeout($errorEvent, self::TIMEOUT)); $this->assertInstanceOf('RuntimeException', $error); @@ -790,9 +793,9 @@ public function testEmitsErrorIfConnectionIsHttpInsteadOfSecureHandshake() public function testEmitsErrorIfConnectionIsUnknownProtocolInsteadOfSecureHandshake() { $server = new TcpServer(0); - $server = new SecureServer($server, null, array( + $server = new SecureServer($server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $server->on('connection', $this->expectCallableNever()); $errorEvent = $this->createPromiseForServerError($server); @@ -803,7 +806,7 @@ public function testEmitsErrorIfConnectionIsUnknownProtocolInsteadOfSecureHandsh $stream->write("Hello world!\n"); }); - $error = \React\Async\await(\React\Promise\Timer\timeout($errorEvent, self::TIMEOUT)); + $error = await(timeout($errorEvent, self::TIMEOUT)); $this->assertInstanceOf('RuntimeException', $error); diff --git a/tests/FunctionalTcpServerTest.php b/tests/FunctionalTcpServerTest.php index a020be9d..c612e327 100644 --- a/tests/FunctionalTcpServerTest.php +++ b/tests/FunctionalTcpServerTest.php @@ -6,6 +6,9 @@ use React\Socket\ConnectionInterface; use React\Socket\TcpConnector; use React\Socket\TcpServer; +use function React\Async\await; +use function React\Promise\Timer\sleep; +use function React\Promise\Timer\timeout; class FunctionalTcpServerTest extends TestCase { @@ -27,8 +30,8 @@ public function testEmitsConnectionForNewConnection() $promise->then($this->expectCallableOnce()); - \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + await(timeout($peer, self::TIMEOUT)); + await(sleep(0.0)); $server->close(); @@ -48,8 +51,8 @@ public function testEmitsNoConnectionForNewConnectionWhenPaused() $promise->then($this->expectCallableOnce()); - \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + await(timeout($promise, self::TIMEOUT)); + await(sleep(0.0)); } public function testConnectionForNewConnectionWhenResumedAfterPause() @@ -70,8 +73,8 @@ public function testConnectionForNewConnectionWhenResumedAfterPause() $promise->then($this->expectCallableOnce()); - \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + await(timeout($peer, self::TIMEOUT)); + await(sleep(0.0)); $server->close(); $promise->then(function (ConnectionInterface $connection) { @@ -93,8 +96,8 @@ public function testEmitsConnectionWithRemoteIp() $promise->then($this->expectCallableOnce()); - $peer = \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + $peer = await(timeout($peer, self::TIMEOUT)); + await(sleep(0.0)); $this->assertContainsString('127.0.0.1:', $peer); @@ -120,8 +123,8 @@ public function testEmitsConnectionWithLocalIp() $promise->then($this->expectCallableOnce()); - $local = \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + $local = await(timeout($peer, self::TIMEOUT)); + await(sleep(0.0)); $this->assertContainsString('127.0.0.1:', $local); $this->assertEquals($server->getAddress(), $local); @@ -150,8 +153,8 @@ public function testEmitsConnectionWithLocalIpDespiteListeningOnAll() $promise->then($this->expectCallableOnce()); - $local = \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + $local = await(timeout($peer, self::TIMEOUT)); + await(sleep(0.0)); $this->assertContainsString('127.0.0.1:', $local); @@ -177,7 +180,7 @@ public function testEmitsConnectionWithRemoteIpAfterConnectionIsClosedByPeer() $connection->end(); }); - $peer = \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); + $peer = await(timeout($peer, self::TIMEOUT)); $this->assertContainsString('127.0.0.1:', $peer); @@ -199,8 +202,8 @@ public function testEmitsConnectionWithRemoteNullAddressAfterConnectionIsClosedB $promise->then($this->expectCallableOnce()); - $peer = \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + $peer = await(timeout($peer, self::TIMEOUT)); + await(sleep(0.0)); $this->assertNull($peer); @@ -228,7 +231,7 @@ public function testEmitsConnectionEvenIfClientConnectionIsCancelled() $promise->then(null, $this->expectCallableOnce()); - \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); + await(timeout($peer, self::TIMEOUT)); $server->close(); } @@ -254,8 +257,8 @@ public function testEmitsConnectionForNewIpv6Connection() $promise->then($this->expectCallableOnce()); - \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + await(timeout($peer, self::TIMEOUT)); + await(sleep(0.0)); $server->close(); $promise->then(function (ConnectionInterface $connection) { @@ -282,8 +285,8 @@ public function testEmitsConnectionWithRemoteIpv6() $promise->then($this->expectCallableOnce()); - $peer = \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + $peer = await(timeout($peer, self::TIMEOUT)); + await(sleep(0.0)); $this->assertContainsString('[::1]:', $peer); @@ -312,8 +315,8 @@ public function testEmitsConnectionWithLocalIpv6() $promise->then($this->expectCallableOnce()); - $local = \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + $local = await(timeout($peer, self::TIMEOUT)); + await(sleep(0.0)); $this->assertContainsString('[::1]:', $local); $this->assertEquals($server->getAddress(), $local); @@ -326,9 +329,9 @@ public function testEmitsConnectionWithLocalIpv6() public function testServerPassesContextOptionsToSocket() { - $server = new TcpServer(0, null, array( + $server = new TcpServer(0, null, [ 'backlog' => 4 - )); + ]); $ref = new \ReflectionProperty($server, 'master'); $ref->setAccessible(true); @@ -336,7 +339,7 @@ public function testServerPassesContextOptionsToSocket() $context = stream_context_get_options($socket); - $this->assertEquals(array('socket' => array('backlog' => 4)), $context); + $this->assertEquals(['socket' => ['backlog' => 4]], $context); $server->close(); } @@ -351,16 +354,16 @@ public function testServerPassesDefaultBacklogSizeViaContextOptionsToSocket() $context = stream_context_get_options($socket); - $this->assertEquals(array('socket' => array('backlog' => 511)), $context); + $this->assertEquals(['socket' => ['backlog' => 511]], $context); $server->close(); } public function testEmitsConnectionWithInheritedContextOptions() { - $server = new TcpServer(0, null, array( + $server = new TcpServer(0, null, [ 'backlog' => 4 - )); + ]); $peer = new Promise(function ($resolve, $reject) use ($server) { $server->on('connection', function (ConnectionInterface $connection) use ($resolve) { @@ -373,10 +376,10 @@ public function testEmitsConnectionWithInheritedContextOptions() $promise->then($this->expectCallableOnce()); - $all = \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + $all = await(timeout($peer, self::TIMEOUT)); + await(sleep(0.0)); - $this->assertEquals(array('socket' => array('backlog' => 4)), $all); + $this->assertEquals(['socket' => ['backlog' => 4]], $all); $server->close(); $promise->then(function (ConnectionInterface $connection) { diff --git a/tests/HappyEyeBallsConnectionBuilderTest.php b/tests/HappyEyeBallsConnectionBuilderTest.php index 581d8836..b63a623f 100644 --- a/tests/HappyEyeBallsConnectionBuilderTest.php +++ b/tests/HappyEyeBallsConnectionBuilderTest.php @@ -6,6 +6,8 @@ use React\Socket\HappyEyeBallsConnectionBuilder; use React\Dns\Model\Message; use React\Promise\Deferred; +use function React\Promise\reject; +use function React\Promise\resolve; class HappyEyeBallsConnectionBuilderTest extends TestCase { @@ -19,8 +21,8 @@ public function testConnectWillResolveTwiceViaResolver() $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturn(new Promise(function () { })); $uri = 'tcp://reactphp.org:80'; @@ -42,8 +44,8 @@ public function testConnectWillRejectWhenBothDnsLookupsReject() $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturn(new Promise(function () { throw new \RuntimeException('DNS lookup error'); })); @@ -80,11 +82,11 @@ public function testConnectWillRejectWhenBothDnsLookupsRejectWithDifferentMessag $deferred = new Deferred(); $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( $deferred->promise(), - \React\Promise\reject(new \RuntimeException('DNS4 error')) + reject(new \RuntimeException('DNS4 error')) ); $uri = 'tcp://reactphp.org:80'; @@ -120,11 +122,11 @@ public function testConnectWillStartDelayTimerWhenIpv4ResolvesAndIpv6IsPending() $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( new Promise(function () { }), - \React\Promise\resolve(array('127.0.0.1')) + resolve(['127.0.0.1']) ); $uri = 'tcp://reactphp.org:80'; @@ -147,10 +149,10 @@ public function testConnectWillStartConnectingWithAttemptTimerButWithoutResoluti $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1')), + resolve(['::1']), new Promise(function () { }) ); @@ -178,10 +180,10 @@ public function testConnectWillStartConnectingAndWillStartNextConnectionWithNewA $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1', '::2')), + resolve(['::1', '::2']), new Promise(function () { }) ); @@ -212,10 +214,10 @@ public function testConnectWillStartConnectingAndWillDoNothingWhenNextAttemptTim $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1')), + resolve(['::1']), new Promise(function () { }) ); @@ -244,10 +246,10 @@ public function testConnectWillStartConnectingWithAttemptTimerButWithoutResoluti $deferred = new Deferred(); $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1')), + resolve(['::1']), $deferred->promise() ); @@ -271,8 +273,8 @@ public function testConnectWillStartConnectingWithAttemptTimerWhenIpv6AndIpv4Res $deferred = new Deferred(); $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->exactly(2))->method('connect')->withConsecutive( - array('tcp://[::1]:80?hostname=reactphp.org'), - array('tcp://127.0.0.1:80?hostname=reactphp.org') + ['tcp://[::1]:80?hostname=reactphp.org'], + ['tcp://127.0.0.1:80?hostname=reactphp.org'] )->willReturnOnConsecutiveCalls( $deferred->promise(), new Promise(function () { }) @@ -280,11 +282,11 @@ public function testConnectWillStartConnectingWithAttemptTimerWhenIpv6AndIpv4Res $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1')), - \React\Promise\resolve(array('127.0.0.1')) + resolve(['::1']), + resolve(['127.0.0.1']) ); $uri = 'tcp://reactphp.org:80'; @@ -308,10 +310,10 @@ public function testConnectWillStartConnectingWithAlternatingIPv6AndIPv4WhenReso $deferred = new Deferred(); $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->exactly(4))->method('connect')->withConsecutive( - array('tcp://[::1]:80?hostname=reactphp.org'), - array('tcp://127.0.0.1:80?hostname=reactphp.org'), - array('tcp://[::1]:80?hostname=reactphp.org'), - array('tcp://127.0.0.1:80?hostname=reactphp.org') + ['tcp://[::1]:80?hostname=reactphp.org'], + ['tcp://127.0.0.1:80?hostname=reactphp.org'], + ['tcp://[::1]:80?hostname=reactphp.org'], + ['tcp://127.0.0.1:80?hostname=reactphp.org'] )->willReturnOnConsecutiveCalls( $deferred->promise(), $deferred->promise(), @@ -321,11 +323,11 @@ public function testConnectWillStartConnectingWithAlternatingIPv6AndIPv4WhenReso $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1', '::1')), - \React\Promise\resolve(array('127.0.0.1', '127.0.0.1')) + resolve(['::1', '::1']), + resolve(['127.0.0.1', '127.0.0.1']) ); $uri = 'tcp://reactphp.org:80'; @@ -348,20 +350,20 @@ public function testConnectWillStartConnectingWithAttemptTimerWhenOnlyIpv6Resolv $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->exactly(2))->method('connect')->withConsecutive( - array('tcp://[::1]:80?hostname=reactphp.org'), - array('tcp://[::1]:80?hostname=reactphp.org') + ['tcp://[::1]:80?hostname=reactphp.org'], + ['tcp://[::1]:80?hostname=reactphp.org'] )->willReturnOnConsecutiveCalls( - \React\Promise\reject(new \RuntimeException()), + reject(new \RuntimeException()), new Promise(function () { }) ); $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1', '::1')), - \React\Promise\reject(new \RuntimeException()) + resolve(['::1', '::1']), + reject(new \RuntimeException()) ); $uri = 'tcp://reactphp.org:80'; @@ -389,10 +391,10 @@ public function testConnectWillStartConnectingAndWillStartNextConnectionWithoutN $deferred = new Deferred(); $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1', '::2')), + resolve(['::1', '::2']), $deferred->promise() ); @@ -415,14 +417,8 @@ public function testConnectWillStartAndCancelResolutionTimerAndStartAttemptTimer $timerAttempt = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $loop->expects($this->exactly(2))->method('addTimer')->withConsecutive( - array( - 0.05, - $this->anything() - ), - array( - 0.1, - $this->anything() - ) + [0.05, $this->anything()], + [0.1, $this->anything()] )->willReturnOnConsecutiveCalls($timerDelay, $timerAttempt); $loop->expects($this->once())->method('cancelTimer')->with($timerDelay); @@ -432,11 +428,11 @@ public function testConnectWillStartAndCancelResolutionTimerAndStartAttemptTimer $deferred = new Deferred(); $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( $deferred->promise(), - \React\Promise\resolve(array('127.0.0.1')) + resolve(['127.0.0.1']) ); $uri = 'tcp://reactphp.org:80'; @@ -446,7 +442,7 @@ public function testConnectWillStartAndCancelResolutionTimerAndStartAttemptTimer $builder = new HappyEyeBallsConnectionBuilder($loop, $connector, $resolver, $uri, $host, $parts); $builder->connect(); - $deferred->resolve(array('::1')); + $deferred->resolve(['::1']); } public function testConnectWillRejectWhenOnlyTcp6ConnectionRejectsAndCancelNextAttemptTimerImmediately() @@ -462,11 +458,11 @@ public function testConnectWillRejectWhenOnlyTcp6ConnectionRejectsAndCancelNextA $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1')), - \React\Promise\reject(new \RuntimeException('DNS failed')) + resolve(['::1']), + reject(new \RuntimeException('DNS failed')) ); $uri = 'tcp://reactphp.org:80'; @@ -505,11 +501,11 @@ public function testConnectWillRejectWhenOnlyTcp4ConnectionRejectsAndWillNeverSt $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\reject(new \RuntimeException('DNS failed')), - \React\Promise\resolve(array('127.0.0.1')) + reject(new \RuntimeException('DNS failed')), + resolve(['127.0.0.1']) ); $uri = 'tcp://reactphp.org:80'; @@ -550,11 +546,11 @@ public function testConnectWillRejectWhenAllConnectionsRejectAndCancelNextAttemp $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1')), - \React\Promise\resolve(array('127.0.0.1')) + resolve(['::1']), + resolve(['127.0.0.1']) ); $uri = 'tcp://reactphp.org:80'; @@ -593,7 +589,7 @@ public function testConnectWillRejectWithMessageWithoutHostnameWhenAllConnection $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $connector->expects($this->exactly(2))->method('connect')->willReturnOnConsecutiveCalls( $deferred->promise(), - \React\Promise\reject(new \RuntimeException( + reject(new \RuntimeException( 'Connection to tcp://127.0.0.1:80?hostname=localhost failed: Connection refused (ECONNREFUSED)', defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111 )) @@ -601,11 +597,11 @@ public function testConnectWillRejectWithMessageWithoutHostnameWhenAllConnection $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('localhost', Message::TYPE_AAAA), - array('localhost', Message::TYPE_A) + ['localhost', Message::TYPE_AAAA], + ['localhost', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1')), - \React\Promise\resolve(array('127.0.0.1')) + resolve(['::1']), + resolve(['127.0.0.1']) ); $uri = 'tcp://localhost:80'; @@ -644,8 +640,8 @@ public function testCancelConnectWillRejectPromiseAndCancelBothDnsLookups() $cancelled = 0; $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( new Promise(function () { }, function () use (&$cancelled) { ++$cancelled; @@ -692,13 +688,13 @@ public function testCancelConnectWillRejectPromiseAndCancelPendingIpv6LookupAndC $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( new Promise(function () { }, function () { throw new \RuntimeException('DNS cancelled'); }), - \React\Promise\resolve(array('127.0.0.1')) + resolve(['127.0.0.1']) ); $uri = 'tcp://reactphp.org:80'; @@ -738,10 +734,10 @@ public function testCancelConnectWillRejectPromiseAndCancelPendingIpv6Connection $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('reactphp.org', Message::TYPE_AAAA), - array('reactphp.org', Message::TYPE_A) + ['reactphp.org', Message::TYPE_AAAA], + ['reactphp.org', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - \React\Promise\resolve(array('::1')), + resolve(['::1']), new Promise(function () { }, $this->expectCallableOnce()) ); @@ -775,7 +771,7 @@ public function testResolveWillReturnResolvedPromiseWithEmptyListWhenDnsResolver $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); - $resolver->expects($this->once())->method('resolveAll')->with('reactphp.org', Message::TYPE_A)->willReturn(\React\Promise\reject(new \RuntimeException())); + $resolver->expects($this->once())->method('resolveAll')->with('reactphp.org', Message::TYPE_A)->willReturn(reject(new \RuntimeException())); $uri = 'tcp://reactphp.org:80'; $host = 'reactphp.org'; @@ -786,7 +782,7 @@ public function testResolveWillReturnResolvedPromiseWithEmptyListWhenDnsResolver $promise = $builder->resolve(Message::TYPE_A, $this->expectCallableNever()); $this->assertInstanceof('React\Promise\PromiseInterface', $promise); - $promise->then($this->expectCallableOnceWith(array()), $this->expectCallableNever()); + $promise->then($this->expectCallableOnceWith([]), $this->expectCallableNever()); } public function testAttemptConnectionWillConnectViaConnectorToGivenIpWithPortAndHostnameFromUriParts() @@ -832,7 +828,7 @@ public function testCheckCallsRejectFunctionImmediateWithoutLeavingDanglingPromi $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); - $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80/path?test=yes&hostname=reactphp.org#start')->willReturn(\React\Promise\reject(new \RuntimeException())); + $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80/path?test=yes&hostname=reactphp.org#start')->willReturn(reject(new \RuntimeException())); $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); $resolver->expects($this->never())->method('resolveAll'); @@ -845,7 +841,7 @@ public function testCheckCallsRejectFunctionImmediateWithoutLeavingDanglingPromi $ref = new \ReflectionProperty($builder, 'connectQueue'); $ref->setAccessible(true); - $ref->setValue($builder, array('::1')); + $ref->setValue($builder, ['::1']); $builder->check($this->expectCallableNever(), function () { }); @@ -853,7 +849,7 @@ public function testCheckCallsRejectFunctionImmediateWithoutLeavingDanglingPromi $ref->setAccessible(true); $promises = $ref->getValue($builder); - $this->assertEquals(array(), $promises); + $this->assertEquals([], $promises); } public function testCleanUpCancelsAllPendingConnectionAttempts() @@ -877,7 +873,7 @@ public function testCleanUpCancelsAllPendingConnectionAttempts() $ref = new \ReflectionProperty($builder, 'connectQueue'); $ref->setAccessible(true); - $ref->setValue($builder, array('::1', '::1')); + $ref->setValue($builder, ['::1', '::1']); $builder->check($this->expectCallableNever(), function () { }); $builder->check($this->expectCallableNever(), function () { }); @@ -905,7 +901,7 @@ public function testCleanUpCancelsAllPendingConnectionAttemptsWithoutStartingNew $ref = new \ReflectionProperty($builder, 'connectQueue'); $ref->setAccessible(true); - $ref->setValue($builder, array('::1', '::1')); + $ref->setValue($builder, ['::1', '::1']); $builder->check($this->expectCallableNever(), function () { }); @@ -924,18 +920,18 @@ public function testMixIpsIntoConnectQueueSometimesAssignsInOriginalOrder() for ($i = 0; $i < 100; ++$i) { $builder = new HappyEyeBallsConnectionBuilder($loop, $connector, $resolver, $uri, $host, $parts); - $builder->mixIpsIntoConnectQueue(array('::1', '::2')); + $builder->mixIpsIntoConnectQueue(['::1', '::2']); $ref = new \ReflectionProperty($builder, 'connectQueue'); $ref->setAccessible(true); $value = $ref->getValue($builder); - if ($value === array('::1', '::2')) { + if ($value === ['::1', '::2']) { break; } } - $this->assertEquals(array('::1', '::2'), $value); + $this->assertEquals(['::1', '::2'], $value); } public function testMixIpsIntoConnectQueueSometimesAssignsInReverseOrder() @@ -950,17 +946,17 @@ public function testMixIpsIntoConnectQueueSometimesAssignsInReverseOrder() for ($i = 0; $i < 100; ++$i) { $builder = new HappyEyeBallsConnectionBuilder($loop, $connector, $resolver, $uri, $host, $parts); - $builder->mixIpsIntoConnectQueue(array('::1', '::2')); + $builder->mixIpsIntoConnectQueue(['::1', '::2']); $ref = new \ReflectionProperty($builder, 'connectQueue'); $ref->setAccessible(true); $value = $ref->getValue($builder); - if ($value === array('::2', '::1')) { + if ($value === ['::2', '::1']) { break; } } - $this->assertEquals(array('::2', '::1'), $value); + $this->assertEquals(['::2', '::1'], $value); } } diff --git a/tests/HappyEyeBallsConnectorTest.php b/tests/HappyEyeBallsConnectorTest.php index 5301b3b4..6d744f09 100644 --- a/tests/HappyEyeBallsConnectorTest.php +++ b/tests/HappyEyeBallsConnectorTest.php @@ -4,9 +4,11 @@ use React\Dns\Model\Message; use React\EventLoop\StreamSelectLoop; -use React\Promise; use React\Promise\Deferred; +use React\Promise\Promise; use React\Socket\HappyEyeBallsConnector; +use function React\Promise\reject; +use function React\Promise\resolve; class HappyEyeBallsConnectorTest extends TestCase { @@ -40,27 +42,15 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); } - public function testConstructWithoutRequiredConnectorThrows() - { - $this->setExpectedException('InvalidArgumentException'); - new HappyEyeBallsConnector(null, null, $this->resolver); - } - - public function testConstructWithoutRequiredResolverThrows() - { - $this->setExpectedException('InvalidArgumentException'); - new HappyEyeBallsConnector(null, $this->tcp); - } - public function testHappyFlow() { $first = new Deferred(); $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('example.com'), $this->anything())->willReturn($first->promise()); $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); - $this->tcp->expects($this->exactly(1))->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->willReturn(Promise\resolve($connection)); + $this->tcp->expects($this->exactly(1))->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->willReturn(resolve($connection)); $promise = $this->connector->connect('example.com:80'); - $first->resolve(array('1.2.3.4')); + $first->resolve(['1.2.3.4']); $resolvedConnection = null; $promise->then(function ($value) use (&$resolvedConnection) { @@ -73,15 +63,15 @@ public function testHappyFlow() public function testThatAnyOtherPendingConnectionAttemptsWillBeCanceledOnceAConnectionHasBeenEstablished() { $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); - $lookupAttempts = array( - Promise\reject(new \Exception('error')), - Promise\resolve(array('1.2.3.4', '5.6.7.8', '9.10.11.12')), - ); - $connectionAttempts = array( - new Promise\Promise(function () {}, $this->expectCallableOnce()), - Promise\resolve($connection), - new Promise\Promise(function () {}, $this->expectCallableNever()), - ); + $lookupAttempts = [ + reject(new \Exception('error')), + resolve(['1.2.3.4', '5.6.7.8', '9.10.11.12']), + ]; + $connectionAttempts = [ + new Promise(function () {}, $this->expectCallableOnce()), + resolve($connection), + new Promise(function () {}, $this->expectCallableNever()), + ]; $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('example.com'), $this->anything())->will($this->returnCallback(function () use (&$lookupAttempts) { return array_shift($lookupAttempts); })); @@ -103,7 +93,7 @@ public function testThatAnyOtherPendingConnectionAttemptsWillBeCanceledOnceAConn public function testPassByResolverIfGivenIp() { $this->resolver->expects($this->never())->method('resolveAll'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('127.0.0.1:80'))->will($this->returnValue(Promise\resolve(null))); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('127.0.0.1:80'))->will($this->returnValue(resolve(null))); $this->connector->connect('127.0.0.1:80'); @@ -113,7 +103,7 @@ public function testPassByResolverIfGivenIp() public function testPassByResolverIfGivenIpv6() { $this->resolver->expects($this->never())->method('resolveAll'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('[::1]:80'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('[::1]:80'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('[::1]:80'); @@ -124,8 +114,8 @@ public function testPassByResolverIfGivenIpv6() public function testPassThroughResolverIfGivenHost() { - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(Promise\resolve(array('1.2.3.4')))); - $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=google.com'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(resolve(['1.2.3.4']))); + $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('google.com:80'); @@ -136,8 +126,8 @@ public function testPassThroughResolverIfGivenHost() public function testPassThroughResolverIfGivenHostWhichResolvesToIpv6() { - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(Promise\resolve(array('::1')))); - $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('[::1]:80?hostname=google.com'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(resolve(['::1']))); + $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('[::1]:80?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('google.com:80'); @@ -149,7 +139,7 @@ public function testPassThroughResolverIfGivenHostWhichResolvesToIpv6() public function testPassByResolverIfGivenCompleteUri() { $this->resolver->expects($this->never())->method('resolveAll'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://127.0.0.1:80/path?query#fragment'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://127.0.0.1:80/path?query#fragment'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('scheme://127.0.0.1:80/path?query#fragment'); @@ -160,8 +150,8 @@ public function testPassByResolverIfGivenCompleteUri() public function testPassThroughResolverIfGivenCompleteUri() { - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(Promise\resolve(array('1.2.3.4')))); - $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/path?query&hostname=google.com#fragment'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(resolve(['1.2.3.4']))); + $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/path?query&hostname=google.com#fragment'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('scheme://google.com:80/path?query#fragment'); @@ -172,8 +162,8 @@ public function testPassThroughResolverIfGivenCompleteUri() public function testPassThroughResolverIfGivenExplicitHost() { - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(Promise\resolve(array('1.2.3.4')))); - $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/?hostname=google.de'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(resolve(['1.2.3.4']))); + $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/?hostname=google.de'))->will($this->returnValue(reject(new \Exception('reject')))); $promise = $this->connector->connect('scheme://google.com:80/?hostname=google.de'); @@ -190,13 +180,13 @@ public function testIpv6ResolvesFirstSoIsTheFirstToConnect(array $ipv6, array $i $deferred = new Deferred(); $this->resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('google.com', Message::TYPE_AAAA), - array('google.com', Message::TYPE_A) + ['google.com', Message::TYPE_AAAA], + ['google.com', Message::TYPE_A] )->willReturnOnConsecutiveCalls( - $this->returnValue(Promise\resolve($ipv6)), + $this->returnValue(resolve($ipv6)), $this->returnValue($deferred->promise()) ); - $this->tcp->expects($this->any())->method('connect')->with($this->stringContains(']:80/?hostname=google.com'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->tcp->expects($this->any())->method('connect')->with($this->stringContains(']:80/?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); $this->connector->connect('scheme://google.com:80/?hostname=google.com'); @@ -215,13 +205,13 @@ public function testIpv6DoesntResolvesWhileIpv4DoesFirstSoIpv4Connects(array $ip $deferred = new Deferred(); $this->resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( - array('google.com', Message::TYPE_AAAA), - array('google.com', Message::TYPE_A) + ['google.com', Message::TYPE_AAAA], + ['google.com', Message::TYPE_A] )->willReturnOnConsecutiveCalls( $this->returnValue($deferred->promise()), - $this->returnValue(Promise\resolve($ipv4)) + $this->returnValue(resolve($ipv4)) ); - $this->tcp->expects($this->any())->method('connect')->with($this->stringContains(':80/?hostname=google.com'))->will($this->returnValue(Promise\reject(new \Exception('reject')))); + $this->tcp->expects($this->any())->method('connect')->with($this->stringContains(':80/?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); $this->connector->connect('scheme://google.com:80/?hostname=google.com'); @@ -248,16 +238,15 @@ public function testRejectsImmediatelyIfUriIsInvalid() public function testRejectsWithTcpConnectorRejectionIfGivenIp() { - $that = $this; - $promise = Promise\reject(new \RuntimeException('Connection failed')); + $promise = reject(new \RuntimeException('Connection failed')); $this->resolver->expects($this->never())->method('resolveAll'); $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80'))->willReturn($promise); $promise = $this->connector->connect('1.2.3.4:80'); - $this->loop->addTimer(0.5, function () use ($that, $promise) { + $this->loop->addTimer(0.5, function () use ($promise) { $promise->cancel(); - $that->throwRejection($promise); + $this->throwRejection($promise); }); $this->setExpectedException('RuntimeException', 'Connection failed'); @@ -266,14 +255,13 @@ public function testRejectsWithTcpConnectorRejectionIfGivenIp() public function testSkipConnectionIfDnsFails() { - $that = $this; - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('example.invalid'), $this->anything())->willReturn(Promise\reject(new \RuntimeException('DNS error'))); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('example.invalid'), $this->anything())->willReturn(reject(new \RuntimeException('DNS error'))); $this->tcp->expects($this->never())->method('connect'); $promise = $this->connector->connect('example.invalid:80'); - $this->loop->addTimer(0.5, function () use ($that, $promise) { - $that->throwRejection($promise); + $this->loop->addTimer(0.5, function () use ($promise) { + $this->throwRejection($promise); }); $this->setExpectedException('RuntimeException', 'Connection to tcp://example.invalid:80 failed during DNS lookup: DNS error'); @@ -282,17 +270,16 @@ public function testSkipConnectionIfDnsFails() public function testCancelDuringDnsCancelsDnsAndDoesNotStartTcpConnection() { - $that = $this; - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('example.com', $this->anything())->will($this->returnCallback(function () use ($that) { - return new Promise\Promise(function () { }, $that->expectCallableExactly(1)); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('example.com', $this->anything())->will($this->returnCallback(function () { + return new Promise(function () { }, $this->expectCallableExactly(1)); })); $this->tcp->expects($this->never())->method('connect'); $promise = $this->connector->connect('example.com:80'); - $this->loop->addTimer(0.05, function () use ($that, $promise) { + $this->loop->addTimer(0.05, function () use ($promise) { $promise->cancel(); - $that->throwRejection($promise); + $this->throwRejection($promise); }); $this->setExpectedException( @@ -305,7 +292,7 @@ public function testCancelDuringDnsCancelsDnsAndDoesNotStartTcpConnection() public function testCancelDuringTcpConnectionCancelsTcpConnectionIfGivenIp() { - $pending = new Promise\Promise(function () { }, $this->expectCallableOnce()); + $pending = new Promise(function () { }, $this->expectCallableOnce()); $this->resolver->expects($this->never())->method('resolveAll'); $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80'))->willReturn($pending); @@ -332,25 +319,25 @@ public function throwRejection($promise) public function provideIpvAddresses() { - $ipv6 = array( - array('1:2:3:4'), - array('1:2:3:4', '5:6:7:8'), - array('1:2:3:4', '5:6:7:8', '9:10:11:12'), - ); - $ipv4 = array( - array('1.2.3.4'), - array('1.2.3.4', '5.6.7.8'), - array('1.2.3.4', '5.6.7.8', '9.10.11.12'), - ); - - $ips = array(); + $ipv6 = [ + ['1:2:3:4'], + ['1:2:3:4', '5:6:7:8'], + ['1:2:3:4', '5:6:7:8', '9:10:11:12'], + ]; + $ipv4 = [ + ['1.2.3.4'], + ['1.2.3.4', '5.6.7.8'], + ['1.2.3.4', '5.6.7.8', '9.10.11.12'] + ]; + + $ips = []; foreach ($ipv6 as $v6) { foreach ($ipv4 as $v4) { - $ips[] = array( + $ips[] = [ $v6, $v4 - ); + ]; } } diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index f7033c4a..acf42c12 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -9,6 +9,9 @@ use React\Socket\DnsConnector; use React\Socket\SecureConnector; use React\Socket\TcpConnector; +use function React\Async\await; +use function React\Promise\Timer\sleep; +use function React\Promise\Timer\timeout; /** @group internet */ class IntegrationTest extends TestCase @@ -18,9 +21,9 @@ class IntegrationTest extends TestCase /** @test */ public function gettingStuffFromGoogleShouldWork() { - $connector = new Connector(array()); + $connector = new Connector([]); - $conn = \React\Async\await($connector->connect('google.com:80')); + $conn = await($connector->connect('google.com:80')); assert($conn instanceof ConnectionInterface); $this->assertContainsString(':80', $conn->getRemoteAddress()); @@ -37,9 +40,9 @@ public function gettingStuffFromGoogleShouldWork() /** @test */ public function gettingEncryptedStuffFromGoogleShouldWork() { - $secureConnector = new Connector(array()); + $secureConnector = new Connector([]); - $conn = \React\Async\await($secureConnector->connect('tls://google.com:443')); + $conn = await($secureConnector->connect('tls://google.com:443')); assert($conn instanceof ConnectionInterface); $conn->write("GET / HTTP/1.0\r\n\r\n"); @@ -63,7 +66,7 @@ public function gettingEncryptedStuffFromGoogleShouldWorkIfHostIsResolvedFirst() $dns ); - $conn = \React\Async\await($connector->connect('google.com:443')); + $conn = await($connector->connect('google.com:443')); assert($conn instanceof ConnectionInterface); $conn->write("GET / HTTP/1.0\r\n\r\n"); @@ -77,9 +80,9 @@ public function gettingEncryptedStuffFromGoogleShouldWorkIfHostIsResolvedFirst() /** @test */ public function gettingPlaintextStuffFromEncryptedGoogleShouldNotWork() { - $connector = new Connector(array()); + $connector = new Connector([]); - $conn = \React\Async\await($connector->connect('google.com:443')); + $conn = await($connector->connect('google.com:443')); assert($conn instanceof ConnectionInterface); $this->assertContainsString(':443', $conn->getRemoteAddress()); @@ -102,12 +105,12 @@ public function testConnectingFailsIfConnectorUsesInvalidDnsResolverAddress() $factory = new ResolverFactory(); $dns = $factory->create('255.255.255.255'); - $connector = new Connector(array( + $connector = new Connector([ 'dns' => $dns - )); + ]); $this->setExpectedException('RuntimeException'); - \React\Async\await(\React\Promise\Timer\timeout($connector->connect('google.com:80'), self::TIMEOUT)); + await(timeout($connector->connect('google.com:80'), self::TIMEOUT)); } public function testCancellingPendingConnectionWithoutTimeoutShouldNotCreateAnyGarbageReferences() @@ -116,7 +119,7 @@ public function testCancellingPendingConnectionWithoutTimeoutShouldNotCreateAnyG $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $connector = new Connector(array('timeout' => false)); + $connector = new Connector(['timeout' => false]); while (gc_collect_cycles()) { // collect all garbage cycles @@ -135,7 +138,7 @@ public function testCancellingPendingConnectionShouldNotCreateAnyGarbageReferenc $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $connector = new Connector(array()); + $connector = new Connector([]); while (gc_collect_cycles()) { // collect all garbage cycles @@ -157,11 +160,11 @@ public function testWaitingForRejectedConnectionShouldNotCreateAnyGarbageReferen // let loop tick for reactphp/async v4 to clean up any remaining stream resources // @link https://github.com/reactphp/async/pull/65 reported upstream // TODO remove me once merged if (function_exists('React\Async\async')) { - \React\Async\await(\React\Promise\Timer\sleep(0)); + await(sleep(0)); Loop::run(); } - $connector = new Connector(array('timeout' => false)); + $connector = new Connector(['timeout' => false]); while (gc_collect_cycles()) { // collect all garbage cycles @@ -176,11 +179,11 @@ function ($e) use (&$wait) { ); // run loop for short period to ensure we detect connection refused error - \React\Async\await(\React\Promise\Timer\sleep(0.01)); + await(sleep(0.01)); if ($wait) { - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); if ($wait) { - \React\Async\await(\React\Promise\Timer\sleep(2.0)); + await(sleep(2.0)); if ($wait) { $this->fail('Connection attempt did not fail'); } @@ -197,7 +200,7 @@ public function testWaitingForConnectionTimeoutDuringDnsLookupShouldNotCreateAny $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $connector = new Connector(array('timeout' => 0.001)); + $connector = new Connector(['timeout' => 0.001]); while (gc_collect_cycles()) { // collect all garbage cycles @@ -212,9 +215,9 @@ function ($e) use (&$wait) { ); // run loop for short period to ensure we detect a connection timeout error - \React\Async\await(\React\Promise\Timer\sleep(0.01)); + await(sleep(0.01)); if ($wait) { - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); if ($wait) { $this->fail('Connection attempt did not fail'); } @@ -230,7 +233,7 @@ public function testWaitingForConnectionTimeoutDuringTcpConnectionShouldNotCreat $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $connector = new Connector(array('timeout' => 0.000001)); + $connector = new Connector(['timeout' => 0.000001]); while (gc_collect_cycles()) { // collect all garbage cycles @@ -245,9 +248,9 @@ function ($e) use (&$wait) { ); // run loop for short period to ensure we detect a connection timeout error - \React\Async\await(\React\Promise\Timer\sleep(0.01)); + await(sleep(0.01)); if ($wait) { - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); if ($wait) { $this->fail('Connection attempt did not fail'); } @@ -263,7 +266,7 @@ public function testWaitingForInvalidDnsConnectionShouldNotCreateAnyGarbageRefer $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $connector = new Connector(array('timeout' => false)); + $connector = new Connector(['timeout' => false]); while (gc_collect_cycles()) { // collect all garbage cycles @@ -278,11 +281,11 @@ function ($e) use (&$wait) { ); // run loop for short period to ensure we detect a DNS error - \React\Async\await(\React\Promise\Timer\sleep(0.01)); + await(sleep(0.01)); if ($wait) { - \React\Async\await(\React\Promise\Timer\sleep(0.2)); + await(sleep(0.2)); if ($wait) { - \React\Async\await(\React\Promise\Timer\sleep(2.0)); + await(sleep(2.0)); if ($wait) { $this->fail('Connection attempt did not fail'); } @@ -299,11 +302,11 @@ public function testWaitingForInvalidTlsConnectionShouldNotCreateAnyGarbageRefer $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $connector = new Connector(array( - 'tls' => array( + $connector = new Connector([ + 'tls' => [ 'verify_peer' => true - ) - )); + ] + ]); while (gc_collect_cycles()) { // collect all garbage cycles @@ -318,11 +321,11 @@ function ($e) use (&$wait) { ); // run loop for short period to ensure we detect a TLS error - \React\Async\await(\React\Promise\Timer\sleep(0.01)); + await(sleep(0.01)); if ($wait) { - \React\Async\await(\React\Promise\Timer\sleep(0.4)); + await(sleep(0.4)); if ($wait) { - \React\Async\await(\React\Promise\Timer\sleep(self::TIMEOUT - 0.5)); + await(sleep(self::TIMEOUT - 0.5)); if ($wait) { $this->fail('Connection attempt did not fail'); } @@ -339,7 +342,7 @@ public function testWaitingForSuccessfullyClosedConnectionShouldNotCreateAnyGarb $this->markTestSkipped('Not supported on legacy Promise v1 API'); } - $connector = new Connector(array('timeout' => false)); + $connector = new Connector(['timeout' => false]); while (gc_collect_cycles()) { // collect all garbage cycles @@ -350,7 +353,7 @@ function ($conn) { $conn->close(); } ); - \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + await(timeout($promise, self::TIMEOUT)); unset($promise); $this->assertEquals(0, gc_collect_cycles()); @@ -358,35 +361,35 @@ function ($conn) { public function testConnectingFailsIfTimeoutIsTooSmall() { - $connector = new Connector(array( + $connector = new Connector([ 'timeout' => 0.001 - )); + ]); $this->setExpectedException('RuntimeException'); - \React\Async\await(\React\Promise\Timer\timeout($connector->connect('google.com:80'), self::TIMEOUT)); + await(timeout($connector->connect('google.com:80'), self::TIMEOUT)); } public function testSelfSignedRejectsIfVerificationIsEnabled() { - $connector = new Connector(array( - 'tls' => array( + $connector = new Connector([ + 'tls' => [ 'verify_peer' => true - ) - )); + ] + ]); $this->setExpectedException('RuntimeException'); - \React\Async\await(\React\Promise\Timer\timeout($connector->connect('tls://self-signed.badssl.com:443'), self::TIMEOUT)); + await(timeout($connector->connect('tls://self-signed.badssl.com:443'), self::TIMEOUT)); } public function testSelfSignedResolvesIfVerificationIsDisabled() { - $connector = new Connector(array( - 'tls' => array( + $connector = new Connector([ + 'tls' => [ 'verify_peer' => false - ) - )); + ] + ]); - $conn = \React\Async\await(\React\Promise\Timer\timeout($connector->connect('tls://self-signed.badssl.com:443'), self::TIMEOUT)); + $conn = await(timeout($connector->connect('tls://self-signed.badssl.com:443'), self::TIMEOUT)); assert($conn instanceof ConnectionInterface); $conn->close(); diff --git a/tests/LimitingServerTest.php b/tests/LimitingServerTest.php index 1430e362..9fc634d9 100644 --- a/tests/LimitingServerTest.php +++ b/tests/LimitingServerTest.php @@ -6,6 +6,8 @@ use React\Socket\ConnectionInterface; use React\Socket\LimitingServer; use React\Socket\TcpServer; +use function React\Async\await; +use function React\Promise\Timer\timeout; class LimitingServerTest extends TestCase { @@ -85,7 +87,7 @@ public function testSocketErrorWillBeForwarded() $server->on('error', $this->expectCallableOnce()); - $tcp->emit('error', array(new \RuntimeException('test'))); + $tcp->emit('error', [new \RuntimeException('test')]); } public function testSocketConnectionWillBeForwarded() @@ -100,9 +102,9 @@ public function testSocketConnectionWillBeForwarded() $server->on('connection', $this->expectCallableOnceWith($connection)); $server->on('error', $this->expectCallableNever()); - $tcp->emit('connection', array($connection)); + $tcp->emit('connection', [$connection]); - $this->assertEquals(array($connection), $server->getConnections()); + $this->assertEquals([$connection], $server->getConnections()); } public function testSocketConnectionWillBeClosedOnceLimitIsReached() @@ -120,8 +122,8 @@ public function testSocketConnectionWillBeClosedOnceLimitIsReached() $server->on('connection', $this->expectCallableOnceWith($first)); $server->on('error', $this->expectCallableOnce()); - $tcp->emit('connection', array($first)); - $tcp->emit('connection', array($second)); + $tcp->emit('connection', [$first]); + $tcp->emit('connection', [$second]); } public function testPausingServerWillBePausedOnceLimitIsReached() @@ -136,7 +138,7 @@ public function testPausingServerWillBePausedOnceLimitIsReached() $server = new LimitingServer($tcp, 1, true); - $tcp->emit('connection', array($connection)); + $tcp->emit('connection', [$connection]); } public function testSocketDisconnectionWillRemoveFromList() @@ -158,9 +160,9 @@ public function testSocketDisconnectionWillRemoveFromList() }); }); - \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); + await(timeout($peer, self::TIMEOUT)); - $this->assertEquals(array(), $server->getConnections()); + $this->assertEquals([], $server->getConnections()); $server->close(); } @@ -181,7 +183,7 @@ public function testPausingServerWillEmitOnlyOneButAcceptTwoConnectionsDueToOper $first = stream_socket_client($server->getAddress()); $second = stream_socket_client($server->getAddress()); - \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); + await(timeout($peer, self::TIMEOUT)); fclose($first); fclose($second); @@ -211,7 +213,7 @@ public function testPausingServerWillEmitTwoConnectionsFromBacklog() $second = stream_socket_client($server->getAddress()); fclose($second); - \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); + await(timeout($peer, self::TIMEOUT)); $server->close(); } diff --git a/tests/SecureConnectorTest.php b/tests/SecureConnectorTest.php index 4fdae8e0..833e874f 100644 --- a/tests/SecureConnectorTest.php +++ b/tests/SecureConnectorTest.php @@ -2,9 +2,11 @@ namespace React\Tests\Socket; -use React\Promise; use React\Promise\Deferred; +use React\Promise\Promise; use React\Socket\SecureConnector; +use function React\Promise\reject; +use function React\Promise\resolve; class SecureConnectorTest extends TestCase { @@ -39,7 +41,7 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() public function testConnectionWillWaitForTcpConnection() { - $pending = new Promise\Promise(function () { }); + $pending = new Promise(function () { }); $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->will($this->returnValue($pending)); $promise = $this->connector->connect('example.com:80'); @@ -49,7 +51,7 @@ public function testConnectionWillWaitForTcpConnection() public function testConnectionWithCompleteUriWillBePassedThroughExpectForScheme() { - $pending = new Promise\Promise(function () { }); + $pending = new Promise(function () { }); $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80/path?query#fragment'))->will($this->returnValue($pending)); $this->connector->connect('tls://example.com:80/path?query#fragment'); @@ -70,7 +72,7 @@ public function testConnectionToInvalidSchemeWillReject() public function testConnectWillRejectWithTlsUriWhenUnderlyingConnectorRejects() { - $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn(\React\Promise\reject(new \RuntimeException( + $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn(reject(new \RuntimeException( 'Connection to tcp://example.com:80 failed: Connection refused (ECONNREFUSED)', defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111 ))); @@ -92,7 +94,7 @@ public function testConnectWillRejectWithTlsUriWhenUnderlyingConnectorRejects() public function testConnectWillRejectWithOriginalMessageWhenUnderlyingConnectorRejectsWithInvalidArgumentException() { - $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn(\React\Promise\reject(new \InvalidArgumentException( + $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn(reject(new \InvalidArgumentException( 'Invalid', 42 ))); @@ -114,7 +116,7 @@ public function testConnectWillRejectWithOriginalMessageWhenUnderlyingConnectorR public function testCancelDuringTcpConnectionCancelsTcpConnection() { - $pending = new Promise\Promise(function () { }, $this->expectCallableOnce()); + $pending = new Promise(function () { }, $this->expectCallableOnce()); $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn($pending); $promise = $this->connector->connect('example.com:80'); @@ -123,7 +125,7 @@ public function testCancelDuringTcpConnectionCancelsTcpConnection() public function testCancelDuringTcpConnectionCancelsTcpConnectionAndRejectsWithTcpRejection() { - $pending = new Promise\Promise(function () { }, function () { throw new \RuntimeException( + $pending = new Promise(function () { }, function () { throw new \RuntimeException( 'Connection to tcp://example.com:80 cancelled (ECONNABORTED)', defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103 ); }); @@ -150,7 +152,7 @@ public function testConnectionWillBeClosedAndRejectedIfConnectionIsNoStream() $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); $connection->expects($this->once())->method('close'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(Promise\resolve($connection)); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(resolve($connection)); $promise = $this->connector->connect('example.com:80'); @@ -172,13 +174,13 @@ public function testStreamEncryptionWillBeEnabledAfterConnecting() $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->getMock(); $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock(); - $encryption->expects($this->once())->method('enable')->with($connection)->willReturn(new \React\Promise\Promise(function () { })); + $encryption->expects($this->once())->method('enable')->with($connection)->willReturn(new Promise(function () { })); $ref = new \ReflectionProperty($this->connector, 'streamEncryption'); $ref->setAccessible(true); $ref->setValue($this->connector, $encryption); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(Promise\resolve($connection)); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(resolve($connection)); $this->connector->connect('example.com:80'); } @@ -189,13 +191,13 @@ public function testConnectionWillBeRejectedIfStreamEncryptionFailsAndClosesConn $connection->expects($this->once())->method('close'); $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock(); - $encryption->expects($this->once())->method('enable')->willReturn(Promise\reject(new \RuntimeException('TLS error', 123))); + $encryption->expects($this->once())->method('enable')->willReturn(reject(new \RuntimeException('TLS error', 123))); $ref = new \ReflectionProperty($this->connector, 'streamEncryption'); $ref->setAccessible(true); $ref->setValue($this->connector, $encryption); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(Promise\resolve($connection)); + $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(resolve($connection)); $promise = $this->connector->connect('example.com:80'); @@ -217,7 +219,7 @@ public function testCancelDuringStreamEncryptionCancelsEncryptionAndClosesConnec $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->getMock(); $connection->expects($this->once())->method('close'); - $pending = new Promise\Promise(function () { }, function () { + $pending = new Promise(function () { }, function () { throw new \Exception('Ignored'); }); $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock(); diff --git a/tests/SecureIntegrationTest.php b/tests/SecureIntegrationTest.php index eaa7ca38..c5f3d416 100644 --- a/tests/SecureIntegrationTest.php +++ b/tests/SecureIntegrationTest.php @@ -10,6 +10,9 @@ use React\Socket\SecureServer; use React\Socket\TcpConnector; use React\Socket\TcpServer; +use function React\Async\await; +use function React\Promise\all; +use function React\Promise\Timer\timeout; class SecureIntegrationTest extends TestCase { @@ -25,11 +28,11 @@ class SecureIntegrationTest extends TestCase public function setUpConnector() { $this->server = new TcpServer(0); - $this->server = new SecureServer($this->server, null, array( + $this->server = new SecureServer($this->server, null, [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - )); + ]); $this->address = $this->server->getAddress(); - $this->connector = new SecureConnector(new TcpConnector(), null, array('verify_peer' => false)); + $this->connector = new SecureConnector(new TcpConnector(), null, ['verify_peer' => false]); } /** @@ -45,7 +48,7 @@ public function tearDownServer() public function testConnectToServer() { - $client = \React\Async\await(\React\Promise\Timer\timeout($this->connector->connect($this->address), self::TIMEOUT)); + $client = await(timeout($this->connector->connect($this->address), self::TIMEOUT)); /* @var $client ConnectionInterface */ $client->close(); @@ -60,7 +63,7 @@ public function testConnectToServerEmitsConnection() $promiseClient = $this->connector->connect($this->address); - list($_, $client) = \React\Async\await(\React\Promise\Timer\timeout(\React\Promise\all(array($promiseServer, $promiseClient)), self::TIMEOUT)); + [$_, $client] = await(timeout(all([$promiseServer, $promiseClient]), self::TIMEOUT)); /* @var $client ConnectionInterface */ $client->close(); @@ -76,13 +79,13 @@ public function testSendSmallDataToServerReceivesOneChunk() }); }); - $client = \React\Async\await(\React\Promise\Timer\timeout($this->connector->connect($this->address), self::TIMEOUT)); + $client = await(timeout($this->connector->connect($this->address), self::TIMEOUT)); /* @var $client ConnectionInterface */ $client->write('hello'); // await server to report one "data" event - $data = \React\Async\await(\React\Promise\Timer\timeout($received->promise(), self::TIMEOUT)); + $data = await(timeout($received->promise(), self::TIMEOUT)); $client->close(); @@ -95,10 +98,10 @@ public function testSendDataWithEndToServerReceivesAllData() // we explicitly use older TLS version instead. // Continue if TLS 1.3 is not supported anyway. if ($this->supportsTls13()) { - $this->connector = new SecureConnector(new TcpConnector(), null, array( + $this->connector = new SecureConnector(new TcpConnector(), null, [ 'verify_peer' => false, 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT - )); + ]); } $disconnected = new Deferred(); @@ -112,14 +115,14 @@ public function testSendDataWithEndToServerReceivesAllData() }); }); - $client = \React\Async\await(\React\Promise\Timer\timeout($this->connector->connect($this->address), self::TIMEOUT)); + $client = await(timeout($this->connector->connect($this->address), self::TIMEOUT)); /* @var $client ConnectionInterface */ $data = str_repeat('a', 200000); $client->end($data); // await server to report connection "close" event - $received = \React\Async\await(\React\Promise\Timer\timeout($disconnected->promise(), self::TIMEOUT)); + $received = await(timeout($disconnected->promise(), self::TIMEOUT)); $this->assertEquals(strlen($data), strlen($received)); $this->assertEquals($data, $received); @@ -147,7 +150,7 @@ public function testSendDataWithoutEndingToServerReceivesAllData() $connection->write($data); }); - $received = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $received = await(timeout($promise, self::TIMEOUT)); $this->assertEquals(strlen($data), strlen($received)); $this->assertEquals($data, $received); @@ -163,12 +166,12 @@ public function testConnectToServerWhichSendsSmallDataReceivesOneChunk() $peer->write('hello'); }); - $client = \React\Async\await(\React\Promise\Timer\timeout($this->connector->connect($this->address), self::TIMEOUT)); + $client = await(timeout($this->connector->connect($this->address), self::TIMEOUT)); /* @var $client ConnectionInterface */ // await client to report one "data" event $receive = $this->createPromiseForEvent($client, 'data', $this->expectCallableOnceWith('hello')); - \React\Async\await(\React\Promise\Timer\timeout($receive, self::TIMEOUT)); + await(timeout($receive, self::TIMEOUT)); $client->close(); } @@ -180,7 +183,7 @@ public function testConnectToServerWhichSendsDataWithEndReceivesAllData() $peer->end($data); }); - $client = \React\Async\await(\React\Promise\Timer\timeout($this->connector->connect($this->address), self::TIMEOUT)); + $client = await(timeout($this->connector->connect($this->address), self::TIMEOUT)); /* @var $client ConnectionInterface */ // await data from client until it closes @@ -211,7 +214,7 @@ public function testConnectToServerWhichSendsDataWithoutEndingReceivesAllData() }, $reject); }); - $received = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $received = await(timeout($promise, self::TIMEOUT)); $this->assertEquals(strlen($data), $received); diff --git a/tests/SecureServerTest.php b/tests/SecureServerTest.php index b7cdefbe..cfa2e72e 100644 --- a/tests/SecureServerTest.php +++ b/tests/SecureServerTest.php @@ -5,6 +5,7 @@ use React\Socket\SecureServer; use React\Socket\TcpServer; use React\Promise\Promise; +use function React\Promise\reject; class SecureServerTest extends TestCase { @@ -32,7 +33,7 @@ public function testGetAddressWillBePassedThroughToTcpServer() $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $server = new SecureServer($tcp, $loop, array()); + $server = new SecureServer($tcp, $loop, []); $this->assertEquals('tls://127.0.0.1:1234', $server->getAddress()); } @@ -44,7 +45,7 @@ public function testGetAddressWillReturnNullIfTcpServerReturnsNull() $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $server = new SecureServer($tcp, $loop, array()); + $server = new SecureServer($tcp, $loop, []); $this->assertNull($server->getAddress()); } @@ -56,7 +57,7 @@ public function testPauseWillBePassedThroughToTcpServer() $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $server = new SecureServer($tcp, $loop, array()); + $server = new SecureServer($tcp, $loop, []); $server->pause(); } @@ -68,7 +69,7 @@ public function testResumeWillBePassedThroughToTcpServer() $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $server = new SecureServer($tcp, $loop, array()); + $server = new SecureServer($tcp, $loop, []); $server->resume(); } @@ -80,7 +81,7 @@ public function testCloseWillBePassedThroughToTcpServer() $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $server = new SecureServer($tcp, $loop, array()); + $server = new SecureServer($tcp, $loop, []); $server->close(); } @@ -94,11 +95,11 @@ public function testConnectionWillBeClosedWithErrorIfItIsNotAStream() $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); $connection->expects($this->once())->method('close'); - $server = new SecureServer($tcp, $loop, array()); + $server = new SecureServer($tcp, $loop, []); $server->on('error', $this->expectCallableOnce()); - $tcp->emit('connection', array($connection)); + $tcp->emit('connection', [$connection]); } public function testConnectionWillTryToEnableEncryptionAndWaitForHandshake() @@ -111,7 +112,7 @@ public function testConnectionWillTryToEnableEncryptionAndWaitForHandshake() $connection->expects($this->once())->method('getRemoteAddress')->willReturn('tcp://127.0.0.1:1234'); $connection->expects($this->never())->method('close'); - $server = new SecureServer($tcp, $loop, array()); + $server = new SecureServer($tcp, $loop, []); $pending = new Promise(function () { }); @@ -124,12 +125,12 @@ public function testConnectionWillTryToEnableEncryptionAndWaitForHandshake() $ref = new \ReflectionProperty($server, 'context'); $ref->setAccessible(true); - $ref->setValue($server, array()); + $ref->setValue($server, []); $server->on('error', $this->expectCallableNever()); $server->on('connection', $this->expectCallableNever()); - $tcp->emit('connection', array($connection)); + $tcp->emit('connection', [$connection]); } public function testConnectionWillBeClosedWithErrorIfEnablingEncryptionFails() @@ -142,12 +143,12 @@ public function testConnectionWillBeClosedWithErrorIfEnablingEncryptionFails() $connection->expects($this->once())->method('getRemoteAddress')->willReturn('tcp://127.0.0.1:1234'); $connection->expects($this->once())->method('close'); - $server = new SecureServer($tcp, $loop, array()); + $server = new SecureServer($tcp, $loop, []); $error = new \RuntimeException('Original'); $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock(); - $encryption->expects($this->once())->method('enable')->willReturn(\React\Promise\reject($error)); + $encryption->expects($this->once())->method('enable')->willReturn(reject($error)); $ref = new \ReflectionProperty($server, 'encryption'); $ref->setAccessible(true); @@ -155,7 +156,7 @@ public function testConnectionWillBeClosedWithErrorIfEnablingEncryptionFails() $ref = new \ReflectionProperty($server, 'context'); $ref->setAccessible(true); - $ref->setValue($server, array()); + $ref->setValue($server, []); $error = null; $server->on('error', $this->expectCallableOnce()); @@ -163,7 +164,7 @@ public function testConnectionWillBeClosedWithErrorIfEnablingEncryptionFails() $error = $e; }); - $tcp->emit('connection', array($connection)); + $tcp->emit('connection', [$connection]); $this->assertInstanceOf('RuntimeException', $error); $this->assertEquals('Connection from tcp://127.0.0.1:1234 failed during TLS handshake: Original', $error->getMessage()); @@ -175,10 +176,10 @@ public function testSocketErrorWillBeForwarded() $tcp = new TcpServer(0, $loop); - $server = new SecureServer($tcp, $loop, array()); + $server = new SecureServer($tcp, $loop, []); $server->on('error', $this->expectCallableOnce()); - $tcp->emit('error', array(new \RuntimeException('test'))); + $tcp->emit('error', [new \RuntimeException('test')]); } } diff --git a/tests/SocketServerTest.php b/tests/SocketServerTest.php index aa241aca..3ec87c74 100644 --- a/tests/SocketServerTest.php +++ b/tests/SocketServerTest.php @@ -7,6 +7,9 @@ use React\Socket\SocketServer; use React\Socket\TcpConnector; use React\Socket\UnixConnector; +use function React\Async\await; +use function React\Promise\Timer\sleep; +use function React\Promise\Timer\timeout; class SocketServerTest extends TestCase { @@ -30,7 +33,7 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() public function testCreateServerWithZeroPortAssignsRandomPort() { - $socket = new SocketServer('127.0.0.1:0', array()); + $socket = new SocketServer('127.0.0.1:0', []); $this->assertNotEquals(0, $socket->getAddress()); $socket->close(); } @@ -67,13 +70,13 @@ public function testConstructorWithInvalidUriWithSchemaAndPortOnlyThrows() public function testConstructorCreatesExpectedTcpServer() { - $socket = new SocketServer('127.0.0.1:0', array()); + $socket = new SocketServer('127.0.0.1:0', []); $connector = new TcpConnector(); $promise = $connector->connect($socket->getAddress()); $promise->then($this->expectCallableOnce(), $this->expectCallableNever()); - $connection = \React\Async\await(\React\Promise\Timer\timeout($connector->connect($socket->getAddress()), self::TIMEOUT)); + $connection = await(timeout($connector->connect($socket->getAddress()), self::TIMEOUT)); $socket->close(); $promise->then(function (ConnectionInterface $connection) { @@ -87,13 +90,13 @@ public function testConstructorCreatesExpectedUnixServer() $this->markTestSkipped('Unix domain sockets (UDS) not supported on your platform (Windows?)'); } - $socket = new SocketServer($this->getRandomSocketUri(), array()); + $socket = new SocketServer($this->getRandomSocketUri(), []); $connector = new UnixConnector(); $connector->connect($socket->getAddress()) ->then($this->expectCallableOnce(), $this->expectCallableNever()); - $connection = \React\Async\await(\React\Promise\Timer\timeout($connector->connect($socket->getAddress()), self::TIMEOUT)); + $connection = await(timeout($connector->connect($socket->getAddress()), self::TIMEOUT)); assert($connection instanceof ConnectionInterface); unlink(str_replace('unix://', '', $connection->getRemoteAddress())); @@ -109,7 +112,7 @@ public function testConstructorThrowsForExistingUnixPath() } try { - new SocketServer('unix://' . __FILE__, array()); + new SocketServer('unix://' . __FILE__, []); $this->fail(); } catch (\RuntimeException $e) { if ($e->getCode() === 0) { @@ -139,7 +142,7 @@ public function testConstructWithExistingFileDescriptorReturnsSameAddressAsOrigi public function testEmitsErrorWhenUnderlyingTcpServerEmitsError() { - $socket = new SocketServer('127.0.0.1:0', array()); + $socket = new SocketServer('127.0.0.1:0', []); $ref = new \ReflectionProperty($socket, 'server'); $ref->setAccessible(true); @@ -147,14 +150,14 @@ public function testEmitsErrorWhenUnderlyingTcpServerEmitsError() $error = new \RuntimeException(); $socket->on('error', $this->expectCallableOnceWith($error)); - $tcp->emit('error', array($error)); + $tcp->emit('error', [$error]); $socket->close(); } public function testEmitsConnectionForNewConnection() { - $socket = new SocketServer('127.0.0.1:0', array()); + $socket = new SocketServer('127.0.0.1:0', []); $socket->on('connection', $this->expectCallableOnce()); $peer = new Promise(function ($resolve, $reject) use ($socket) { @@ -165,25 +168,25 @@ public function testEmitsConnectionForNewConnection() $client = stream_socket_client($socket->getAddress()); - \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); + await(timeout($peer, self::TIMEOUT)); $socket->close(); } public function testDoesNotEmitConnectionForNewConnectionToPausedServer() { - $socket = new SocketServer('127.0.0.1:0', array()); + $socket = new SocketServer('127.0.0.1:0', []); $socket->pause(); $socket->on('connection', $this->expectCallableNever()); $client = stream_socket_client($socket->getAddress()); - \React\Async\await(\React\Promise\Timer\sleep(0.1)); + await(sleep(0.1)); } public function testDoesEmitConnectionForNewConnectionToResumedServer() { - $socket = new SocketServer('127.0.0.1:0', array()); + $socket = new SocketServer('127.0.0.1:0', []); $socket->pause(); $socket->on('connection', $this->expectCallableOnce()); @@ -197,14 +200,14 @@ public function testDoesEmitConnectionForNewConnectionToResumedServer() $socket->resume(); - \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); + await(timeout($peer, self::TIMEOUT)); $socket->close(); } public function testDoesNotAllowConnectionToClosedServer() { - $socket = new SocketServer('127.0.0.1:0', array()); + $socket = new SocketServer('127.0.0.1:0', []); $socket->on('connection', $this->expectCallableNever()); $address = $socket->getAddress(); $socket->close(); @@ -216,11 +219,11 @@ public function testDoesNotAllowConnectionToClosedServer() public function testEmitsConnectionWithInheritedContextOptions() { - $socket = new SocketServer('127.0.0.1:0', array( - 'tcp' => array( + $socket = new SocketServer('127.0.0.1:0', [ + 'tcp' => [ 'backlog' => 4 - ) - )); + ] + ]); $peer = new Promise(function ($resolve, $reject) use ($socket) { $socket->on('connection', function (ConnectionInterface $connection) use ($resolve) { @@ -231,25 +234,25 @@ public function testEmitsConnectionWithInheritedContextOptions() $client = stream_socket_client($socket->getAddress()); - $all = \React\Async\await(\React\Promise\Timer\timeout($peer, self::TIMEOUT)); + $all = await(timeout($peer, self::TIMEOUT)); - $this->assertEquals(array('socket' => array('backlog' => 4)), $all); + $this->assertEquals(['socket' => ['backlog' => 4]], $all); $socket->close(); } public function testDoesNotEmitSecureConnectionForNewPlaintextConnectionThatIsIdle() { - $socket = new SocketServer('tls://127.0.0.1:0', array( - 'tls' => array( + $socket = new SocketServer('tls://127.0.0.1:0', [ + 'tls' => [ 'local_cert' => __DIR__ . '/../examples/localhost.pem' - ) - )); + ] + ]); $socket->on('connection', $this->expectCallableNever()); $client = stream_socket_client(str_replace('tls://', '', $socket->getAddress())); - \React\Async\await(\React\Promise\Timer\sleep(0.1)); + await(sleep(0.1)); $socket->close(); } diff --git a/tests/Stub/ConnectionStub.php b/tests/Stub/ConnectionStub.php index 844b2adc..ae440b4a 100644 --- a/tests/Stub/ConnectionStub.php +++ b/tests/Stub/ConnectionStub.php @@ -29,7 +29,7 @@ public function resume() { } - public function pipe(WritableStreamInterface $dest, array $options = array()) + public function pipe(WritableStreamInterface $dest, array $options = []) { Util::pipe($this, $dest, $options); diff --git a/tests/TcpConnectorTest.php b/tests/TcpConnectorTest.php index 0f6c53c5..48062a9f 100644 --- a/tests/TcpConnectorTest.php +++ b/tests/TcpConnectorTest.php @@ -3,10 +3,12 @@ namespace React\Tests\Socket; use React\EventLoop\Loop; +use React\Promise\Promise; use React\Socket\ConnectionInterface; use React\Socket\TcpConnector; use React\Socket\TcpServer; -use React\Promise\Promise; +use function React\Async\await; +use function React\Promise\Timer\timeout; class TcpConnectorTest extends TestCase { @@ -41,7 +43,7 @@ public function connectionToEmptyPortShouldFailWithoutCallingCustomErrorHandler( ); try { - \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + await(timeout($promise, self::TIMEOUT)); restore_error_handler(); } catch (\Exception $e) { @@ -77,7 +79,7 @@ public function connectionToTcpServerShouldSucceed() $connector = new TcpConnector(); - $connection = \React\Async\await(\React\Promise\Timer\timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); + $connection = await(timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); @@ -121,7 +123,7 @@ class_exists('PHPUnit\Framework\Error\Warning', true); unset($promise); // keep creating dummy file handles until all file descriptors are exhausted - $fds = array(); + $fds = []; for ($i = 0; $i < $ulimit; ++$i) { $fd = @fopen('/dev/null', 'r'); if ($fd === false) { @@ -131,7 +133,7 @@ class_exists('PHPUnit\Framework\Error\Warning', true); } $this->setExpectedException('RuntimeException'); - \React\Async\await(\React\Promise\Timer\timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); + await(timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); } /** @test */ @@ -163,7 +165,7 @@ public function connectionToInvalidNetworkShouldFailWithUnreachableError() 'Connection to ' . $address . ' failed: ' . (function_exists('socket_strerror') ? socket_strerror($enetunreach) . ' (ENETUNREACH)' : 'Network is unreachable'), $enetunreach ); - \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + await(timeout($promise, self::TIMEOUT)); } /** @test */ @@ -173,7 +175,7 @@ public function connectionToTcpServerShouldSucceedWithRemoteAdressSameAsTarget() $connector = new TcpConnector(); - $connection = \React\Async\await(\React\Promise\Timer\timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); + $connection = await(timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); /* @var $connection ConnectionInterface */ $this->assertEquals('tcp://127.0.0.1:9999', $connection->getRemoteAddress()); @@ -189,7 +191,7 @@ public function connectionToTcpServerShouldSucceedWithLocalAdressOnLocalhost() $connector = new TcpConnector(); - $connection = \React\Async\await(\React\Promise\Timer\timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); + $connection = await(timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); /* @var $connection ConnectionInterface */ $this->assertContainsString('tcp://127.0.0.1:', $connection->getLocalAddress()); @@ -206,7 +208,7 @@ public function connectionToTcpServerShouldSucceedWithNullAddressesAfterConnecti $connector = new TcpConnector(); - $connection = \React\Async\await(\React\Promise\Timer\timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); + $connection = await(timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); /* @var $connection ConnectionInterface */ $server->close(); @@ -260,7 +262,7 @@ public function connectionToIp6TcpServerShouldSucceed() $connector = new TcpConnector(); - $connection = \React\Async\await(\React\Promise\Timer\timeout($connector->connect('[::1]:9999'), self::TIMEOUT)); + $connection = await(timeout($connector->connect('[::1]:9999'), self::TIMEOUT)); /* @var $connection ConnectionInterface */ $this->assertEquals('tcp://[::1]:9999', $connection->getRemoteAddress()); @@ -359,7 +361,7 @@ public function cancellingConnectionShouldRejectPromise() ); try { - \React\Async\await($promise); + await($promise); } catch (\Exception $e) { $server->close(); throw $e; diff --git a/tests/TcpServerTest.php b/tests/TcpServerTest.php index 3da87458..7f052c3e 100644 --- a/tests/TcpServerTest.php +++ b/tests/TcpServerTest.php @@ -3,9 +3,12 @@ namespace React\Tests\Socket; use React\EventLoop\Loop; +use React\Promise\Promise; use React\Socket\TcpServer; use React\Stream\DuplexResourceStream; -use React\Promise\Promise; +use function React\Async\await; +use function React\Promise\Timer\sleep; +use function React\Promise\Timer\timeout; class TcpServerTest extends TestCase { @@ -47,12 +50,11 @@ public function testServerEmitsConnectionEventForNewConnection() $client = stream_socket_client('tcp://localhost:'.$this->port); assert($client !== false); - $server = $this->server; - $promise = new Promise(function ($resolve) use ($server) { - $server->on('connection', $resolve); + $promise = new Promise(function ($resolve) { + $this->server->on('connection', $resolve); }); - $connection = \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT)); + $connection = await(timeout($promise, self::TIMEOUT)); $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); } @@ -367,6 +369,6 @@ private function tick() $this->markTestSkipped('Not supported on Windows'); } - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + await(sleep(0.0)); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index b8586c79..d707db08 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,10 +5,13 @@ use PHPUnit\Framework\TestCase as BaseTestCase; use React\Promise\Promise; use React\Stream\ReadableStreamInterface; +use function React\Async\await; +use function React\Promise\Timer\sleep; +use function React\Promise\Timer\timeout; class TestCase extends BaseTestCase { - public function expectCallableExactly($amount) + protected function expectCallableExactly($amount) { $mock = $this->createCallableMock(); $mock @@ -75,7 +78,7 @@ protected function buffer(ReadableStreamInterface $stream, $timeout) return ''; } - $buffer = \React\Async\await(\React\Promise\Timer\timeout(new Promise( + $buffer = await(timeout(new Promise( function ($resolve, $reject) use ($stream) { $buffer = ''; $stream->on('data', function ($chunk) use (&$buffer) { @@ -97,7 +100,7 @@ function () use ($stream) { // let loop tick for reactphp/async v4 to clean up any remaining stream resources // @link https://github.com/reactphp/async/pull/65 reported upstream // TODO remove me once merged if (function_exists('React\Async\async')) { - \React\Async\await(\React\Promise\Timer\sleep(0)); + await(sleep(0)); } return $buffer; diff --git a/tests/TimeoutConnectorTest.php b/tests/TimeoutConnectorTest.php index fc218c46..f4c5dfc1 100644 --- a/tests/TimeoutConnectorTest.php +++ b/tests/TimeoutConnectorTest.php @@ -6,6 +6,8 @@ use React\Promise\Deferred; use React\Promise\Promise; use React\Socket\TimeoutConnector; +use function React\Promise\reject; +use function React\Promise\resolve; class TimeoutConnectorTest extends TestCase { @@ -29,7 +31,7 @@ public function testRejectsPromiseWithoutStartingTimerWhenWrappedConnectorReturn $loop->expects($this->never())->method('cancelTimer'); $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); - $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn(\React\Promise\reject(new \RuntimeException('Failed', 42))); + $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn(reject(new \RuntimeException('Failed', 42))); $timeout = new TimeoutConnector($connector, 5.0, $loop); @@ -80,7 +82,7 @@ public function testResolvesPromiseWithoutStartingTimerWhenWrappedConnectorRetur $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); - $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn(\React\Promise\resolve($connection)); + $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn(resolve($connection)); $timeout = new TimeoutConnector($connector, 5.0, $loop); diff --git a/tests/UnixServerTest.php b/tests/UnixServerTest.php index e4b21124..6d972b9f 100644 --- a/tests/UnixServerTest.php +++ b/tests/UnixServerTest.php @@ -5,6 +5,8 @@ use React\EventLoop\Loop; use React\Socket\UnixServer; use React\Stream\DuplexResourceStream; +use function React\Async\await; +use function React\Promise\Timer\sleep; class UnixServerTest extends TestCase { @@ -415,6 +417,6 @@ private function getRandomSocketUri() private function tick() { - \React\Async\await(\React\Promise\Timer\sleep(0.0)); + await(sleep(0.0)); } } From 3523f5178d2fdb55906803307358aa79064b5a19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Thu, 23 May 2024 22:14:44 +0200 Subject: [PATCH 3/3] Update test suite and remove legacy PHPUnit workarounds --- composer.json | 2 +- phpunit.xml.legacy | 2 +- tests/ConnectionTest.php | 5 +- tests/ConnectorTest.php | 51 ++-- tests/DnsConnectorTest.php | 80 +++---- tests/FdServerTest.php | 79 +++---- tests/FixedUriConnectorTest.php | 3 +- tests/FunctionalConnectorTest.php | 4 +- tests/FunctionalSecureServerTest.php | 42 ++-- tests/FunctionalTcpServerTest.php | 44 ++-- tests/HappyEyeBallsConnectionBuilderTest.php | 231 ++++++++++--------- tests/HappyEyeBallsConnectorTest.php | 88 +++---- tests/IntegrationTest.php | 18 +- tests/LimitingServerTest.php | 30 +-- tests/SecureConnectorTest.php | 64 ++--- tests/SecureServerTest.php | 51 ++-- tests/SocketServerTest.php | 27 +-- tests/Stub/CallableStub.php | 10 - tests/TcpConnectorTest.php | 57 +++-- tests/TcpServerTest.php | 28 +-- tests/TestCase.php | 53 +---- tests/TimeoutConnectorTest.php | 48 ++-- tests/UnixConnectorTest.php | 9 +- tests/UnixServerTest.php | 33 ++- 24 files changed, 511 insertions(+), 548 deletions(-) delete mode 100644 tests/Stub/CallableStub.php diff --git a/composer.json b/composer.json index 87bd8a1b..3c7690a4 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "react/stream": "^1.2" }, "require-dev": { - "phpunit/phpunit": "^9.6 || ^5.7", + "phpunit/phpunit": "^9.6 || ^7.5", "react/async": "^4 || ^3", "react/promise-stream": "^1.4", "react/promise-timer": "^1.10" diff --git a/phpunit.xml.legacy b/phpunit.xml.legacy index a018d7ab..00868603 100644 --- a/phpunit.xml.legacy +++ b/phpunit.xml.legacy @@ -2,7 +2,7 @@ diff --git a/tests/ConnectionTest.php b/tests/ConnectionTest.php index 49d53e26..2ef1e5ce 100644 --- a/tests/ConnectionTest.php +++ b/tests/ConnectionTest.php @@ -2,6 +2,7 @@ namespace React\Tests\Socket; +use React\EventLoop\LoopInterface; use React\Socket\Connection; class ConnectionTest extends TestCase @@ -9,7 +10,7 @@ class ConnectionTest extends TestCase public function testCloseConnectionWillCloseSocketResource() { $resource = fopen('php://memory', 'r+'); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connection = new Connection($resource, $loop); $connection->close(); @@ -20,7 +21,7 @@ public function testCloseConnectionWillCloseSocketResource() public function testCloseConnectionWillRemoveResourceFromLoopBeforeClosingResource() { $resource = fopen('php://memory', 'r+'); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addWriteStream')->with($resource); $onRemove = null; diff --git a/tests/ConnectorTest.php b/tests/ConnectorTest.php index 039d7cb1..dd2f87bf 100644 --- a/tests/ConnectorTest.php +++ b/tests/ConnectorTest.php @@ -2,8 +2,11 @@ namespace React\Tests\Socket; -use React\Socket\Connector; +use React\Dns\Resolver\ResolverInterface; +use React\EventLoop\LoopInterface; use React\Promise\Promise; +use React\Socket\Connector; +use React\Socket\ConnectorInterface; class ConnectorTest extends TestCase { @@ -19,12 +22,12 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $ref->setAccessible(true); $loop = $ref->getValue($connectors['tcp']); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testConstructWithLoopAssignsGivenLoop() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new Connector([], $loop); @@ -36,12 +39,12 @@ public function testConstructWithLoopAssignsGivenLoop() $ref->setAccessible(true); $loop = $ref->getValue($connectors['tcp']); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testConstructWithContextAssignsGivenContext() { - $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $tcp = $this->createMock(ConnectorInterface::class); $connector = new Connector([ 'tcp' => $tcp, @@ -58,10 +61,10 @@ public function testConstructWithContextAssignsGivenContext() public function testConnectorUsesTcpAsDefaultScheme() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $promise = new Promise(function () { }); - $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $tcp = $this->createMock(ConnectorInterface::class); $tcp->expects($this->once())->method('connect')->with('127.0.0.1:80')->willReturn($promise); $connector = new Connector([ @@ -73,10 +76,10 @@ public function testConnectorUsesTcpAsDefaultScheme() public function testConnectorPassedThroughHostnameIfDnsIsDisabled() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $promise = new Promise(function () { }); - $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $tcp = $this->createMock(ConnectorInterface::class); $tcp->expects($this->once())->method('connect')->with('tcp://google.com:80')->willReturn($promise); $connector = new Connector([ @@ -89,13 +92,13 @@ public function testConnectorPassedThroughHostnameIfDnsIsDisabled() public function testConnectorWithUnknownSchemeAlwaysFails() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new Connector([], $loop); $promise = $connector->connect('unknown://google.com:80'); $promise->then(null, $this->expectCallableOnceWithException( - 'RuntimeException', + \RuntimeException::class, 'No connector available for URI scheme "unknown" (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); @@ -103,7 +106,7 @@ public function testConnectorWithUnknownSchemeAlwaysFails() public function testConnectorWithDisabledTcpDefaultSchemeAlwaysFails() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new Connector([ 'tcp' => false ], $loop); @@ -111,7 +114,7 @@ public function testConnectorWithDisabledTcpDefaultSchemeAlwaysFails() $promise = $connector->connect('google.com:80'); $promise->then(null, $this->expectCallableOnceWithException( - 'RuntimeException', + \RuntimeException::class, 'No connector available for URI scheme "tcp" (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); @@ -119,7 +122,7 @@ public function testConnectorWithDisabledTcpDefaultSchemeAlwaysFails() public function testConnectorWithDisabledTcpSchemeAlwaysFails() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new Connector([ 'tcp' => false ], $loop); @@ -127,7 +130,7 @@ public function testConnectorWithDisabledTcpSchemeAlwaysFails() $promise = $connector->connect('tcp://google.com:80'); $promise->then(null, $this->expectCallableOnceWithException( - 'RuntimeException', + \RuntimeException::class, 'No connector available for URI scheme "tcp" (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); @@ -135,7 +138,7 @@ public function testConnectorWithDisabledTcpSchemeAlwaysFails() public function testConnectorWithDisabledTlsSchemeAlwaysFails() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new Connector([ 'tls' => false ], $loop); @@ -143,7 +146,7 @@ public function testConnectorWithDisabledTlsSchemeAlwaysFails() $promise = $connector->connect('tls://google.com:443'); $promise->then(null, $this->expectCallableOnceWithException( - 'RuntimeException', + \RuntimeException::class, 'No connector available for URI scheme "tls" (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); @@ -151,7 +154,7 @@ public function testConnectorWithDisabledTlsSchemeAlwaysFails() public function testConnectorWithDisabledUnixSchemeAlwaysFails() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new Connector([ 'unix' => false ], $loop); @@ -159,7 +162,7 @@ public function testConnectorWithDisabledUnixSchemeAlwaysFails() $promise = $connector->connect('unix://demo.sock'); $promise->then(null, $this->expectCallableOnceWithException( - 'RuntimeException', + \RuntimeException::class, 'No connector available for URI scheme "unix" (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); @@ -167,10 +170,10 @@ public function testConnectorWithDisabledUnixSchemeAlwaysFails() public function testConnectorUsesGivenResolverInstance() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $promise = new Promise(function () { }); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn($promise); $connector = new Connector([ @@ -183,14 +186,14 @@ public function testConnectorUsesGivenResolverInstance() public function testConnectorUsesResolvedHostnameIfDnsIsUsed() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $promise = new Promise(function ($resolve) { $resolve('127.0.0.1'); }); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn($promise); $promise = new Promise(function () { }); - $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $tcp = $this->createMock(ConnectorInterface::class); $tcp->expects($this->once())->method('connect')->with('tcp://127.0.0.1:80?hostname=google.com')->willReturn($promise); $connector = new Connector([ diff --git a/tests/DnsConnectorTest.php b/tests/DnsConnectorTest.php index da2df865..11d1f2f0 100644 --- a/tests/DnsConnectorTest.php +++ b/tests/DnsConnectorTest.php @@ -2,8 +2,10 @@ namespace React\Tests\Socket; +use React\Dns\Resolver\ResolverInterface; use React\Promise\Deferred; use React\Promise\Promise; +use React\Socket\ConnectorInterface; use React\Socket\DnsConnector; use function React\Promise\reject; use function React\Promise\resolve; @@ -19,8 +21,8 @@ class DnsConnectorTest extends TestCase */ public function setUpMocks() { - $this->tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); - $this->resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $this->tcp = $this->createMock(ConnectorInterface::class); + $this->resolver = $this->createMock(ResolverInterface::class); $this->connector = new DnsConnector($this->tcp, $this->resolver); } @@ -28,7 +30,7 @@ public function setUpMocks() public function testPassByResolverIfGivenIp() { $this->resolver->expects($this->never())->method('resolve'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('127.0.0.1:80'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->tcp->expects($this->once())->method('connect')->with('127.0.0.1:80')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('127.0.0.1:80'); @@ -37,8 +39,8 @@ public function testPassByResolverIfGivenIp() public function testPassThroughResolverIfGivenHost() { - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(resolve('1.2.3.4'))); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn(resolve('1.2.3.4')); + $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80?hostname=google.com')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('google.com:80'); @@ -47,8 +49,8 @@ public function testPassThroughResolverIfGivenHost() public function testPassThroughResolverIfGivenHostWhichResolvesToIpv6() { - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(resolve('::1'))); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('[::1]:80?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn(resolve('::1')); + $this->tcp->expects($this->once())->method('connect')->with('[::1]:80?hostname=google.com')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('google.com:80'); @@ -58,7 +60,7 @@ public function testPassThroughResolverIfGivenHostWhichResolvesToIpv6() public function testPassByResolverIfGivenCompleteUri() { $this->resolver->expects($this->never())->method('resolve'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://127.0.0.1:80/path?query#fragment'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->tcp->expects($this->once())->method('connect')->with('scheme://127.0.0.1:80/path?query#fragment')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('scheme://127.0.0.1:80/path?query#fragment'); @@ -67,8 +69,8 @@ public function testPassByResolverIfGivenCompleteUri() public function testPassThroughResolverIfGivenCompleteUri() { - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(resolve('1.2.3.4'))); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/path?query&hostname=google.com#fragment'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn(resolve('1.2.3.4')); + $this->tcp->expects($this->once())->method('connect')->with('scheme://1.2.3.4:80/path?query&hostname=google.com#fragment')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('scheme://google.com:80/path?query#fragment'); @@ -77,8 +79,8 @@ public function testPassThroughResolverIfGivenCompleteUri() public function testPassThroughResolverIfGivenExplicitHost() { - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('google.com'))->will($this->returnValue(resolve('1.2.3.4'))); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/?hostname=google.de'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn(resolve('1.2.3.4')); + $this->tcp->expects($this->once())->method('connect')->with('scheme://1.2.3.4:80/?hostname=google.de')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('scheme://google.com:80/?hostname=google.de'); @@ -93,7 +95,7 @@ public function testRejectsImmediatelyIfUriIsInvalid() $promise = $this->connector->connect('////'); $promise->then(null, $this->expectCallableOnceWithException( - 'InvalidArgumentException', + \InvalidArgumentException::class, 'Given URI "////" is invalid (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); @@ -113,7 +115,7 @@ public function testConnectRejectsIfGivenIpAndTcpConnectorRejectsWithRuntimeExce }); assert($exception instanceof \RuntimeException); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('Connection to tcp://1.2.3.4:80 failed: Connection failed', $exception->getMessage()); $this->assertEquals(42, $exception->getCode()); $this->assertNull($exception->getPrevious()); @@ -134,7 +136,7 @@ public function testConnectRejectsIfGivenIpAndTcpConnectorRejectsWithInvalidArgu }); assert($exception instanceof \InvalidArgumentException); - $this->assertInstanceOf('InvalidArgumentException', $exception); + $this->assertInstanceOf(\InvalidArgumentException::class, $exception); $this->assertEquals('Invalid', $exception->getMessage()); $this->assertEquals(42, $exception->getCode()); $this->assertNull($exception->getPrevious()); @@ -155,10 +157,10 @@ public function testConnectRejectsWithOriginalHostnameInMessageAfterResolvingIfT }); assert($exception instanceof \RuntimeException); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('Connection to tcp://example.com:80 failed: Connection to tcp://1.2.3.4:80 failed: Connection failed', $exception->getMessage()); $this->assertEquals(42, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); $this->assertNotEquals('', $exception->getTraceAsString()); } @@ -176,7 +178,7 @@ public function testConnectRejectsWithOriginalExceptionAfterResolvingIfTcpConnec }); assert($exception instanceof \InvalidArgumentException); - $this->assertInstanceOf('InvalidArgumentException', $exception); + $this->assertInstanceOf(\InvalidArgumentException::class, $exception); $this->assertEquals('Invalid', $exception->getMessage()); $this->assertEquals(42, $exception->getCode()); $this->assertNull($exception->getPrevious()); @@ -186,7 +188,7 @@ public function testConnectRejectsWithOriginalExceptionAfterResolvingIfTcpConnec public function testSkipConnectionIfDnsFails() { $promise = reject(new \RuntimeException('DNS error')); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.invalid'))->willReturn($promise); + $this->resolver->expects($this->once())->method('resolve')->with('example.invalid')->willReturn($promise); $this->tcp->expects($this->never())->method('connect'); $promise = $this->connector->connect('example.invalid:80'); @@ -197,10 +199,10 @@ public function testSkipConnectionIfDnsFails() }); assert($exception instanceof \RuntimeException); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('Connection to tcp://example.invalid:80 failed during DNS lookup: DNS error', $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); $this->assertNotEquals('', $exception->getTraceAsString()); } @@ -208,7 +210,7 @@ public function testRejectionExceptionUsesPreviousExceptionIfDnsFails() { $exception = new \RuntimeException(); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.invalid'))->willReturn(reject($exception)); + $this->resolver->expects($this->once())->method('resolve')->with('example.invalid')->willReturn(reject($exception)); $promise = $this->connector->connect('example.invalid:80'); @@ -220,7 +222,7 @@ public function testRejectionExceptionUsesPreviousExceptionIfDnsFails() public function testCancelDuringDnsCancelsDnsAndDoesNotStartTcpConnection() { $pending = new Promise(function () { }, $this->expectCallableOnce()); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->will($this->returnValue($pending)); + $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn($pending); $this->tcp->expects($this->never())->method('connect'); $promise = $this->connector->connect('example.com:80'); @@ -232,7 +234,7 @@ public function testCancelDuringDnsCancelsDnsAndDoesNotStartTcpConnection() }); assert($exception instanceof \RuntimeException); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('Connection to tcp://example.com:80 cancelled during DNS lookup (ECONNABORTED)', $exception->getMessage()); $this->assertEquals(defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103, $exception->getCode()); $this->assertNull($exception->getPrevious()); @@ -243,7 +245,7 @@ public function testCancelDuringTcpConnectionCancelsTcpConnectionIfGivenIp() { $pending = new Promise(function () { }, $this->expectCallableOnce()); $this->resolver->expects($this->never())->method('resolve'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80'))->willReturn($pending); + $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80')->willReturn($pending); $promise = $this->connector->connect('1.2.3.4:80'); $promise->cancel(); @@ -252,8 +254,8 @@ public function testCancelDuringTcpConnectionCancelsTcpConnectionIfGivenIp() public function testCancelDuringTcpConnectionCancelsTcpConnectionAfterDnsIsResolved() { $pending = new Promise(function () { }, $this->expectCallableOnce()); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn(resolve('1.2.3.4')); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->willReturn($pending); + $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn(resolve('1.2.3.4')); + $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80?hostname=example.com')->willReturn($pending); $promise = $this->connector->connect('example.com:80'); $promise->cancel(); @@ -262,14 +264,14 @@ public function testCancelDuringTcpConnectionCancelsTcpConnectionAfterDnsIsResol public function testCancelDuringTcpConnectionCancelsTcpConnectionWithTcpRejectionAfterDnsIsResolved() { $first = new Deferred(); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn($first->promise()); + $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn($first->promise()); $pending = new Promise(function () { }, function () { throw new \RuntimeException( 'Connection cancelled', defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103 ); }); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->willReturn($pending); + $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80?hostname=example.com')->willReturn($pending); $promise = $this->connector->connect('example.com:80'); $first->resolve('1.2.3.4'); @@ -282,10 +284,10 @@ public function testCancelDuringTcpConnectionCancelsTcpConnectionWithTcpRejectio }); assert($exception instanceof \RuntimeException); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('Connection to tcp://example.com:80 failed: Connection cancelled', $exception->getMessage()); $this->assertEquals(defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); $this->assertNotEquals('', $exception->getTraceAsString()); } @@ -300,7 +302,7 @@ public function testRejectionDuringDnsLookupShouldNotCreateAnyGarbageReferences( } $dns = new Deferred(); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn($dns->promise()); + $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn($dns->promise()); $this->tcp->expects($this->never())->method('connect'); $promise = $this->connector->connect('example.com:80'); @@ -324,10 +326,10 @@ public function testRejectionAfterDnsLookupShouldNotCreateAnyGarbageReferences() } $dns = new Deferred(); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn($dns->promise()); + $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn($dns->promise()); $tcp = new Deferred(); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->willReturn($tcp->promise()); + $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80?hostname=example.com')->willReturn($tcp->promise()); $promise = $this->connector->connect('example.com:80'); @@ -351,13 +353,13 @@ public function testRejectionAfterDnsLookupShouldNotCreateAnyGarbageReferencesAg } $dns = new Deferred(); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn($dns->promise()); + $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn($dns->promise()); $tcp = new Deferred(); $dns->promise()->then(function () use ($tcp) { $tcp->reject(new \RuntimeException('Connection failed')); }); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->willReturn($tcp->promise()); + $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80?hostname=example.com')->willReturn($tcp->promise()); $promise = $this->connector->connect('example.com:80'); @@ -383,7 +385,7 @@ public function testCancelDuringDnsLookupShouldNotCreateAnyGarbageReferences() $dns = new Deferred(function () { throw new \RuntimeException(); }); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn($dns->promise()); + $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn($dns->promise()); $this->tcp->expects($this->never())->method('connect'); $promise = $this->connector->connect('example.com:80'); @@ -405,11 +407,11 @@ public function testCancelDuringTcpConnectionShouldNotCreateAnyGarbageReferences } $dns = new Deferred(); - $this->resolver->expects($this->once())->method('resolve')->with($this->equalTo('example.com'))->willReturn($dns->promise()); + $this->resolver->expects($this->once())->method('resolve')->with('example.com')->willReturn($dns->promise()); $tcp = new Promise(function () { }, function () { throw new \RuntimeException('Connection cancelled'); }); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->willReturn($tcp); + $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80?hostname=example.com')->willReturn($tcp); $promise = $this->connector->connect('example.com:80'); $dns->resolve('1.2.3.4'); diff --git a/tests/FdServerTest.php b/tests/FdServerTest.php index e7d3c679..4ecd81e4 100644 --- a/tests/FdServerTest.php +++ b/tests/FdServerTest.php @@ -2,6 +2,7 @@ namespace React\Tests\Socket; +use React\EventLoop\LoopInterface; use React\Promise\Promise; use React\Socket\ConnectionInterface; use React\Socket\FdServer; @@ -20,7 +21,7 @@ public function testCtorAddsResourceToLoop() $socket = stream_socket_server('127.0.0.1:0'); assert($socket !== false); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream'); new FdServer($fd, $loop); @@ -28,27 +29,23 @@ public function testCtorAddsResourceToLoop() public function testCtorThrowsForInvalidFd() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addReadStream'); - $this->setExpectedException( - 'InvalidArgumentException', - 'Invalid FD number given (EINVAL)', - defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid FD number given (EINVAL)'); + $this->expectExceptionCode(defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)); new FdServer(-1, $loop); } public function testCtorThrowsForInvalidUrl() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addReadStream'); - $this->setExpectedException( - 'InvalidArgumentException', - 'Invalid FD number given (EINVAL)', - defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid FD number given (EINVAL)'); + $this->expectExceptionCode(defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)); new FdServer('tcp://127.0.0.1:8080', $loop); } @@ -60,7 +57,7 @@ public function testCtorThrowsForUnknownFdWithoutCallingCustomErrorHandler() $fd = self::getNextFreeFd(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addReadStream'); $error = null; @@ -68,11 +65,9 @@ public function testCtorThrowsForUnknownFdWithoutCallingCustomErrorHandler() $error = $errstr; }); - $this->setExpectedException( - 'RuntimeException', - 'Failed to listen on FD ' . $fd . ': ' . (function_exists('socket_strerror') ? socket_strerror(SOCKET_EBADF) . ' (EBADF)' : 'Bad file descriptor'), - defined('SOCKET_EBADF') ? SOCKET_EBADF : 9 - ); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Failed to listen on FD ' . $fd . ': ' . (function_exists('socket_strerror') ? socket_strerror(SOCKET_EBADF) . ' (EBADF)' : 'Bad file descriptor')); + $this->expectExceptionCode(defined('SOCKET_EBADF') ? SOCKET_EBADF : 9); try { new FdServer($fd, $loop); @@ -96,14 +91,12 @@ public function testCtorThrowsIfFdIsAFileAndNotASocket() $tmpfile = tmpfile(); assert($tmpfile !== false); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addReadStream'); - $this->setExpectedException( - 'RuntimeException', - 'Failed to listen on FD ' . $fd . ': ' . (function_exists('socket_strerror') ? socket_strerror(SOCKET_ENOTSOCK) : 'Not a socket') . ' (ENOTSOCK)', - defined('SOCKET_ENOTSOCK') ? SOCKET_ENOTSOCK : 88 - ); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Failed to listen on FD ' . $fd . ': ' . (function_exists('socket_strerror') ? socket_strerror(SOCKET_ENOTSOCK) : 'Not a socket') . ' (ENOTSOCK)'); + $this->expectExceptionCode(defined('SOCKET_ENOTSOCK') ? SOCKET_ENOTSOCK : 88); new FdServer($fd, $loop); } @@ -119,14 +112,12 @@ public function testCtorThrowsIfFdIsAConnectedSocketInsteadOfServerSocket() $client = stream_socket_client('tcp://' . stream_socket_get_name($socket, false)); assert($client !== false); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addReadStream'); - $this->setExpectedException( - 'RuntimeException', - 'Failed to listen on FD ' . $fd . ': ' . (function_exists('socket_strerror') ? socket_strerror(SOCKET_EISCONN) : 'Socket is connected') . ' (EISCONN)', - defined('SOCKET_EISCONN') ? SOCKET_EISCONN : 106 - ); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Failed to listen on FD ' . $fd . ': ' . (function_exists('socket_strerror') ? socket_strerror(SOCKET_EISCONN) : 'Socket is connected') . ' (EISCONN)'); + $this->expectExceptionCode(defined('SOCKET_EISCONN') ? SOCKET_EISCONN : 106); new FdServer($fd, $loop); } @@ -139,7 +130,7 @@ public function testGetAddressReturnsSameAddressAsOriginalSocketForIpv4Socket() $fd = self::getNextFreeFd(); $socket = stream_socket_server('127.0.0.1:0'); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $server = new FdServer($fd, $loop); @@ -155,7 +146,7 @@ public function testGetAddressReturnsSameAddressAsOriginalSocketForIpv4SocketGiv $fd = self::getNextFreeFd(); $socket = stream_socket_server('127.0.0.1:0'); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $server = new FdServer('php://fd/' . $fd, $loop); @@ -174,7 +165,7 @@ public function testGetAddressReturnsSameAddressAsOriginalSocketForIpv6Socket() $this->markTestSkipped('Listening on IPv6 not supported'); } - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $server = new FdServer($fd, $loop); @@ -197,7 +188,7 @@ public function testGetAddressReturnsSameAddressAsOriginalSocketForUnixDomainSoc assert(is_resource($socket)); unlink(str_replace('unix://', '', stream_socket_get_name($socket, false))); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $server = new FdServer($fd, $loop); @@ -214,7 +205,7 @@ public function testGetAddressReturnsNullAfterClose() $socket = stream_socket_server('127.0.0.1:0'); assert($socket !== false); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $server = new FdServer($fd, $loop); $server->close(); @@ -232,7 +223,7 @@ public function testCloseRemovesResourceFromLoop() $socket = stream_socket_server('127.0.0.1:0'); assert($socket !== false); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('removeReadStream'); $server = new FdServer($fd, $loop); @@ -249,7 +240,7 @@ public function testCloseTwiceRemovesResourceFromLoopOnce() $socket = stream_socket_server('127.0.0.1:0'); assert($socket !== false); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('removeReadStream'); $server = new FdServer($fd, $loop); @@ -267,7 +258,7 @@ public function testResumeWithoutPauseIsNoOp() $socket = stream_socket_server('127.0.0.1:0'); assert($socket !== false); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream'); $server = new FdServer($fd, $loop); @@ -284,7 +275,7 @@ public function testPauseRemovesResourceFromLoop() $socket = stream_socket_server('127.0.0.1:0'); assert($socket !== false); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('removeReadStream'); $server = new FdServer($fd, $loop); @@ -301,7 +292,7 @@ public function testPauseAfterPauseIsNoOp() $socket = stream_socket_server('127.0.0.1:0'); assert($socket !== false); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('removeReadStream'); $server = new FdServer($fd, $loop); @@ -331,7 +322,7 @@ public function testServerEmitsConnectionEventForNewConnection() /** * @var ConnectionInterface $connection */ - $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); + $this->assertInstanceOf(ConnectionInterface::class, $connection); fclose($client); $connection->close(); @@ -345,7 +336,7 @@ public function testEmitsErrorWhenAcceptListenerFailsWithoutCallingCustomErrorHa } $listener = null; - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream')->with($this->anything(), $this->callback(function ($cb) use (&$listener) { $listener = $cb; return true; @@ -379,7 +370,7 @@ public function testEmitsErrorWhenAcceptListenerFailsWithoutCallingCustomErrorHa $this->assertLessThan(1, $time); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertStringStartsWith('Unable to accept new connection: ', $exception->getMessage()); diff --git a/tests/FixedUriConnectorTest.php b/tests/FixedUriConnectorTest.php index bdc1d770..b649b61a 100644 --- a/tests/FixedUriConnectorTest.php +++ b/tests/FixedUriConnectorTest.php @@ -2,13 +2,14 @@ namespace React\Tests\Socket; +use React\Socket\ConnectorInterface; use React\Socket\FixedUriConnector; class FixedUriConnectorTest extends TestCase { public function testWillInvokeGivenConnector() { - $base = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $base = $this->createMock(ConnectorInterface::class); $base->expects($this->once())->method('connect')->with('test')->willReturn('ret'); $connector = new FixedUriConnector('test', $base); diff --git a/tests/FunctionalConnectorTest.php b/tests/FunctionalConnectorTest.php index 117e827f..ad1aa992 100644 --- a/tests/FunctionalConnectorTest.php +++ b/tests/FunctionalConnectorTest.php @@ -30,7 +30,7 @@ public function connectionToTcpServerShouldSucceedWithLocalhost() $server->close(); - $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); + $this->assertInstanceOf(ConnectionInterface::class, $connection); $connection->close(); } @@ -149,7 +149,7 @@ public function testCancelPendingTlsConnectionDuringTlsHandshakeShouldCloseTcpCo await(timeout($promise, self::TIMEOUT)); $this->fail(); } catch (\Exception $e) { - $this->assertInstanceOf('RuntimeException', $e); + $this->assertInstanceOf(\RuntimeException::class, $e); $this->assertEquals('Connection to ' . $uri . ' cancelled during TLS handshake (ECONNABORTED)', $e->getMessage()); } } diff --git a/tests/FunctionalSecureServerTest.php b/tests/FunctionalSecureServerTest.php index 4c91faec..b30bbbb5 100644 --- a/tests/FunctionalSecureServerTest.php +++ b/tests/FunctionalSecureServerTest.php @@ -3,6 +3,7 @@ namespace React\Tests\Socket; use React\Promise\Promise; +use React\Socket\Connection; use React\Socket\ConnectionInterface; use React\Socket\SecureConnector; use React\Socket\ServerInterface; @@ -32,7 +33,7 @@ public function testClientCanConnectToServer() /* @var ConnectionInterface $client */ $client = await(timeout($promise, self::TIMEOUT)); - $this->assertInstanceOf('React\Socket\ConnectionInterface', $client); + $this->assertInstanceOf(ConnectionInterface::class, $client); $this->assertEquals($server->getAddress(), $client->getRemoteAddress()); $client->close(); @@ -61,7 +62,7 @@ public function testClientUsesTls13ByDefaultWhenSupportedByOpenSSL() /* @var ConnectionInterface $client */ $client = await(timeout($promise, self::TIMEOUT)); - $this->assertInstanceOf('React\Socket\Connection', $client); + $this->assertInstanceOf(Connection::class, $client); $this->assertTrue(isset($client->stream)); $meta = stream_get_meta_data($client->stream); @@ -96,7 +97,7 @@ public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByClien /* @var ConnectionInterface $client */ $client = await(timeout($promise, self::TIMEOUT)); - $this->assertInstanceOf('React\Socket\Connection', $client); + $this->assertInstanceOf(Connection::class, $client); $this->assertTrue(isset($client->stream)); $meta = stream_get_meta_data($client->stream); @@ -123,7 +124,7 @@ public function testClientUsesTls12WhenCryptoMethodIsExplicitlyConfiguredByServe /* @var ConnectionInterface $client */ $client = await(timeout($promise, self::TIMEOUT)); - $this->assertInstanceOf('React\Socket\Connection', $client); + $this->assertInstanceOf(Connection::class, $client); $this->assertTrue(isset($client->stream)); $meta = stream_get_meta_data($client->stream); @@ -161,7 +162,7 @@ public function testClientUsesTls10WhenCryptoMethodIsExplicitlyConfiguredByClien $this->markTestSkipped('TLS 1.0 not available on this system (' . $e->getMessage() . ')'); } - $this->assertInstanceOf('React\Socket\Connection', $client); + $this->assertInstanceOf(Connection::class, $client); $this->assertTrue(isset($client->stream)); $meta = stream_get_meta_data($client->stream); @@ -195,8 +196,8 @@ public function testServerEmitsConnectionForClientConnection() // both ends of the connection are represented by different instances of ConnectionInterface $this->assertCount(2, $both); - $this->assertInstanceOf('React\Socket\ConnectionInterface', $both[0]); - $this->assertInstanceOf('React\Socket\ConnectionInterface', $both[1]); + $this->assertInstanceOf(ConnectionInterface::class, $both[0]); + $this->assertInstanceOf(ConnectionInterface::class, $both[1]); $this->assertNotSame($both[0], $both[1]); // server side end has local server address and client end has remote server address @@ -484,7 +485,8 @@ public function testEmitsErrorForClientWithTlsVersionMismatch() ]); $promise = $connector->connect($server->getAddress()); - $this->setExpectedException('RuntimeException', 'handshake'); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('handshake'); try { await(timeout($promise, self::TIMEOUT)); @@ -515,7 +517,7 @@ public function testServerEmitsConnectionForNewConnectionWithEncryptedCertificat $connection = await(timeout($peer, self::TIMEOUT)); - $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); + $this->assertInstanceOf(ConnectionInterface::class, $connection); $server->close(); $connection->close(); @@ -533,7 +535,8 @@ public function testClientRejectsWithErrorForServerWithInvalidCertificate() ]); $promise = $connector->connect($server->getAddress()); - $this->setExpectedException('RuntimeException', 'handshake'); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('handshake'); try { await(timeout($promise, self::TIMEOUT)); @@ -569,7 +572,8 @@ public function testServerEmitsErrorForClientWithInvalidCertificate() // ignore client-side exception } - $this->setExpectedException('RuntimeException', 'handshake'); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('handshake'); try { await(timeout($peer, self::TIMEOUT)); @@ -598,7 +602,8 @@ public function testEmitsErrorForServerWithEncryptedCertificateMissingPassphrase ]); $promise = $connector->connect($server->getAddress()); - $this->setExpectedException('RuntimeException', 'handshake'); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('handshake'); try { await(timeout($promise, self::TIMEOUT)); @@ -628,7 +633,8 @@ public function testEmitsErrorForServerWithEncryptedCertificateWithInvalidPassph ]); $promise = $connector->connect($server->getAddress()); - $this->setExpectedException('RuntimeException', 'handshake'); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('handshake'); try { await(timeout($promise, self::TIMEOUT)); @@ -703,7 +709,7 @@ public function testEmitsErrorIfConnectionIsClosedBeforeHandshake() $error = await(timeout($errorEvent, self::TIMEOUT)); // Connection from tcp://127.0.0.1:39528 failed during TLS handshake: Connection lost during TLS handshake (ECONNRESET) - $this->assertInstanceOf('RuntimeException', $error); + $this->assertInstanceOf(\RuntimeException::class, $error); $this->assertStringStartsWith('Connection from tcp://', $error->getMessage()); $this->assertStringEndsWith('failed during TLS handshake: Connection lost during TLS handshake (ECONNRESET)', $error->getMessage()); $this->assertEquals(defined('SOCKET_ECONNRESET') ? SOCKET_ECONNRESET : 104, $error->getCode()); @@ -731,7 +737,7 @@ public function testEmitsErrorIfConnectionIsClosedWithIncompleteHandshake() $error = await(timeout($errorEvent, self::TIMEOUT)); // Connection from tcp://127.0.0.1:39528 failed during TLS handshake: Connection lost during TLS handshake (ECONNRESET) - $this->assertInstanceOf('RuntimeException', $error); + $this->assertInstanceOf(\RuntimeException::class, $error); $this->assertStringStartsWith('Connection from tcp://', $error->getMessage()); $this->assertStringEndsWith('failed during TLS handshake: Connection lost during TLS handshake (ECONNRESET)', $error->getMessage()); $this->assertEquals(defined('SOCKET_ECONNRESET') ? SOCKET_ECONNRESET : 104, $error->getCode()); @@ -753,7 +759,7 @@ public function testEmitsNothingIfPlaintextConnectionIsIdle() $promise = $connector->connect(str_replace('tls://', '', $server->getAddress())); $connection = await(timeout($promise, self::TIMEOUT)); - $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); + $this->assertInstanceOf(ConnectionInterface::class, $connection); $server->close(); $promise->then(function (ConnectionInterface $connection) { @@ -779,7 +785,7 @@ public function testEmitsErrorIfConnectionIsHttpInsteadOfSecureHandshake() $error = await(timeout($errorEvent, self::TIMEOUT)); - $this->assertInstanceOf('RuntimeException', $error); + $this->assertInstanceOf(\RuntimeException::class, $error); // OpenSSL error messages are version/platform specific // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:SSL3_GET_RECORD:http request @@ -808,7 +814,7 @@ public function testEmitsErrorIfConnectionIsUnknownProtocolInsteadOfSecureHandsh $error = await(timeout($errorEvent, self::TIMEOUT)); - $this->assertInstanceOf('RuntimeException', $error); + $this->assertInstanceOf(\RuntimeException::class, $error); // OpenSSL error messages are version/platform specific // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:SSL3_GET_RECORD:unknown protocol diff --git a/tests/FunctionalTcpServerTest.php b/tests/FunctionalTcpServerTest.php index c612e327..3a08b48c 100644 --- a/tests/FunctionalTcpServerTest.php +++ b/tests/FunctionalTcpServerTest.php @@ -99,7 +99,7 @@ public function testEmitsConnectionWithRemoteIp() $peer = await(timeout($peer, self::TIMEOUT)); await(sleep(0.0)); - $this->assertContainsString('127.0.0.1:', $peer); + $this->assertStringContainsString('127.0.0.1:', $peer); $server->close(); $promise->then(function (ConnectionInterface $connection) { @@ -126,7 +126,7 @@ public function testEmitsConnectionWithLocalIp() $local = await(timeout($peer, self::TIMEOUT)); await(sleep(0.0)); - $this->assertContainsString('127.0.0.1:', $local); + $this->assertStringContainsString('127.0.0.1:', $local); $this->assertEquals($server->getAddress(), $local); $server->close(); @@ -156,7 +156,7 @@ public function testEmitsConnectionWithLocalIpDespiteListeningOnAll() $local = await(timeout($peer, self::TIMEOUT)); await(sleep(0.0)); - $this->assertContainsString('127.0.0.1:', $local); + $this->assertStringContainsString('127.0.0.1:', $local); $server->close(); $promise->then(function (ConnectionInterface $connection) { @@ -182,7 +182,7 @@ public function testEmitsConnectionWithRemoteIpAfterConnectionIsClosedByPeer() $peer = await(timeout($peer, self::TIMEOUT)); - $this->assertContainsString('127.0.0.1:', $peer); + $this->assertStringContainsString('127.0.0.1:', $peer); $server->close(); } @@ -288,7 +288,7 @@ public function testEmitsConnectionWithRemoteIpv6() $peer = await(timeout($peer, self::TIMEOUT)); await(sleep(0.0)); - $this->assertContainsString('[::1]:', $peer); + $this->assertStringContainsString('[::1]:', $peer); $server->close(); $promise->then(function (ConnectionInterface $connection) { @@ -318,7 +318,7 @@ public function testEmitsConnectionWithLocalIpv6() $local = await(timeout($peer, self::TIMEOUT)); await(sleep(0.0)); - $this->assertContainsString('[::1]:', $local); + $this->assertStringContainsString('[::1]:', $local); $this->assertEquals($server->getAddress(), $local); $server->close(); @@ -389,41 +389,33 @@ public function testEmitsConnectionWithInheritedContextOptions() public function testFailsToListenOnInvalidUri() { - $this->setExpectedException( - 'InvalidArgumentException', - 'Invalid URI "tcp://///" given (EINVAL)', - defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid URI "tcp://///" given (EINVAL)'); + $this->expectExceptionCode(defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)); new TcpServer('///'); } public function testFailsToListenOnUriWithoutPort() { - $this->setExpectedException( - 'InvalidArgumentException', - 'Invalid URI "tcp://127.0.0.1" given (EINVAL)', - defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid URI "tcp://127.0.0.1" given (EINVAL)'); + $this->expectExceptionCode(defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)); new TcpServer('127.0.0.1'); } public function testFailsToListenOnUriWithWrongScheme() { - $this->setExpectedException( - 'InvalidArgumentException', - 'Invalid URI "udp://127.0.0.1:0" given (EINVAL)', - defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid URI "udp://127.0.0.1:0" given (EINVAL)'); + $this->expectExceptionCode(defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)); new TcpServer('udp://127.0.0.1:0'); } public function testFailsToListenOnUriWIthHostname() { - $this->setExpectedException( - 'InvalidArgumentException', - 'Given URI "tcp://localhost:8080" does not contain a valid host IP (EINVAL)', - defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Given URI "tcp://localhost:8080" does not contain a valid host IP (EINVAL)'); + $this->expectExceptionCode(defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)); new TcpServer('localhost:8080'); } } diff --git a/tests/HappyEyeBallsConnectionBuilderTest.php b/tests/HappyEyeBallsConnectionBuilderTest.php index b63a623f..60b5ead4 100644 --- a/tests/HappyEyeBallsConnectionBuilderTest.php +++ b/tests/HappyEyeBallsConnectionBuilderTest.php @@ -2,10 +2,15 @@ namespace React\Tests\Socket; -use React\Promise\Promise; -use React\Socket\HappyEyeBallsConnectionBuilder; use React\Dns\Model\Message; +use React\Dns\Resolver\ResolverInterface; +use React\EventLoop\LoopInterface; +use React\EventLoop\TimerInterface; use React\Promise\Deferred; +use React\Promise\Promise; +use React\Promise\PromiseInterface; +use React\Socket\ConnectorInterface; +use React\Socket\HappyEyeBallsConnectionBuilder; use function React\Promise\reject; use function React\Promise\resolve; @@ -13,13 +18,13 @@ class HappyEyeBallsConnectionBuilderTest extends TestCase { public function testConnectWillResolveTwiceViaResolver() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addTimer'); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->never())->method('connect'); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -36,13 +41,13 @@ public function testConnectWillResolveTwiceViaResolver() public function testConnectWillRejectWhenBothDnsLookupsReject() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addTimer'); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->never())->method('connect'); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -63,24 +68,24 @@ public function testConnectWillRejectWhenBothDnsLookupsReject() $exception = $e; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertEquals('Connection to tcp://reactphp.org:80 failed during DNS lookup: DNS lookup error', $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); } public function testConnectWillRejectWhenBothDnsLookupsRejectWithDifferentMessages() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addTimer'); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->never())->method('connect'); $deferred = new Deferred(); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -103,24 +108,24 @@ public function testConnectWillRejectWhenBothDnsLookupsRejectWithDifferentMessag $exception = $e; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertEquals('Connection to tcp://reactphp.org:80 failed during DNS lookup. Last error for IPv6: DNS6 error. Previous error for IPv4: DNS4 error', $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); } public function testConnectWillStartDelayTimerWhenIpv4ResolvesAndIpv6IsPending() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.05, $this->anything()); $loop->expects($this->never())->method('cancelTimer'); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->never())->method('connect'); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -140,14 +145,14 @@ public function testConnectWillStartDelayTimerWhenIpv4ResolvesAndIpv6IsPending() public function testConnectWillStartConnectingWithAttemptTimerButWithoutResolutionTimerWhenIpv6ResolvesAndIpv4IsPending() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->anything()); $loop->expects($this->never())->method('cancelTimer'); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80?hostname=reactphp.org')->willReturn(new Promise(function () { })); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -168,17 +173,17 @@ public function testConnectWillStartConnectingWithAttemptTimerButWithoutResoluti public function testConnectWillStartConnectingAndWillStartNextConnectionWithNewAttemptTimerWhenNextAttemptTimerFiresWithIpv4StillPending() { $timer = null; - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->exactly(2))->method('addTimer')->with(0.1, $this->callback(function ($cb) use (&$timer) { $timer = $cb; return true; })); $loop->expects($this->never())->method('cancelTimer'); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->exactly(2))->method('connect')->willReturn(new Promise(function () { })); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -202,17 +207,17 @@ public function testConnectWillStartConnectingAndWillStartNextConnectionWithNewA public function testConnectWillStartConnectingAndWillDoNothingWhenNextAttemptTimerFiresWithNoOtherIps() { $timer = null; - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->callback(function ($cb) use (&$timer) { $timer = $cb; return true; })); $loop->expects($this->never())->method('cancelTimer'); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80?hostname=reactphp.org')->willReturn(new Promise(function () { })); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -235,16 +240,16 @@ public function testConnectWillStartConnectingAndWillDoNothingWhenNextAttemptTim public function testConnectWillStartConnectingWithAttemptTimerButWithoutResolutionTimerWhenIpv6ResolvesAndWillCancelAttemptTimerWhenIpv4Rejects() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80?hostname=reactphp.org')->willReturn(new Promise(function () { })); $deferred = new Deferred(); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -265,13 +270,13 @@ public function testConnectWillStartConnectingWithAttemptTimerButWithoutResoluti public function testConnectWillStartConnectingWithAttemptTimerWhenIpv6AndIpv4ResolvesAndWillStartNextConnectionAttemptWithoutAttemptTimerImmediatelyWhenFirstConnectionAttemptFails() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); $deferred = new Deferred(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->exactly(2))->method('connect')->withConsecutive( ['tcp://[::1]:80?hostname=reactphp.org'], ['tcp://127.0.0.1:80?hostname=reactphp.org'] @@ -280,7 +285,7 @@ public function testConnectWillStartConnectingWithAttemptTimerWhenIpv6AndIpv4Res new Promise(function () { }) ); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -302,13 +307,13 @@ public function testConnectWillStartConnectingWithAttemptTimerWhenIpv6AndIpv4Res public function testConnectWillStartConnectingWithAlternatingIPv6AndIPv4WhenResolverReturnsMultipleIPAdresses() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); $deferred = new Deferred(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->exactly(4))->method('connect')->withConsecutive( ['tcp://[::1]:80?hostname=reactphp.org'], ['tcp://127.0.0.1:80?hostname=reactphp.org'], @@ -321,7 +326,7 @@ public function testConnectWillStartConnectingWithAlternatingIPv6AndIPv4WhenReso new Promise(function () { }) ); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -343,12 +348,12 @@ public function testConnectWillStartConnectingWithAlternatingIPv6AndIPv4WhenReso public function testConnectWillStartConnectingWithAttemptTimerWhenOnlyIpv6ResolvesAndWillStartNextConnectionAttemptWithoutAttemptTimerImmediatelyWhenFirstConnectionAttemptFails() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->exactly(2))->method('connect')->withConsecutive( ['tcp://[::1]:80?hostname=reactphp.org'], ['tcp://[::1]:80?hostname=reactphp.org'] @@ -357,7 +362,7 @@ public function testConnectWillStartConnectingWithAttemptTimerWhenOnlyIpv6Resolv new Promise(function () { }) ); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -378,18 +383,18 @@ public function testConnectWillStartConnectingWithAttemptTimerWhenOnlyIpv6Resolv public function testConnectWillStartConnectingAndWillStartNextConnectionWithoutNewAttemptTimerWhenNextAttemptTimerFiresAfterIpv4Rejected() { $timer = null; - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->callback(function ($cb) use (&$timer) { $timer = $cb; return true; })); $loop->expects($this->never())->method('cancelTimer'); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->exactly(2))->method('connect')->willReturn(new Promise(function () { })); $deferred = new Deferred(); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -413,20 +418,20 @@ public function testConnectWillStartConnectingAndWillStartNextConnectionWithoutN public function testConnectWillStartAndCancelResolutionTimerAndStartAttemptTimerWhenIpv4ResolvesAndIpv6ResolvesAfterwardsAndStartConnectingToIpv6() { - $timerDelay = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $timerAttempt = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timerDelay = $this->createMock(TimerInterface::class); + $timerAttempt = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->exactly(2))->method('addTimer')->withConsecutive( [0.05, $this->anything()], [0.1, $this->anything()] )->willReturnOnConsecutiveCalls($timerDelay, $timerAttempt); $loop->expects($this->once())->method('cancelTimer')->with($timerDelay); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80?hostname=reactphp.org')->willReturn(new Promise(function () { })); $deferred = new Deferred(); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -447,16 +452,16 @@ public function testConnectWillStartAndCancelResolutionTimerAndStartAttemptTimer public function testConnectWillRejectWhenOnlyTcp6ConnectionRejectsAndCancelNextAttemptTimerImmediately() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); $deferred = new Deferred(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80?hostname=reactphp.org')->willReturn($deferred->promise()); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -482,24 +487,24 @@ public function testConnectWillRejectWhenOnlyTcp6ConnectionRejectsAndCancelNextA $exception = $e; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertEquals('Connection to tcp://reactphp.org:80 failed: Last error for IPv6: Connection refused (ECONNREFUSED). Previous error for IPv4: DNS failed', $exception->getMessage()); $this->assertEquals(defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); } public function testConnectWillRejectWhenOnlyTcp4ConnectionRejectsAndWillNeverStartNextAttemptTimer() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addTimer'); $deferred = new Deferred(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://127.0.0.1:80?hostname=reactphp.org')->willReturn($deferred->promise()); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -525,26 +530,26 @@ public function testConnectWillRejectWhenOnlyTcp4ConnectionRejectsAndWillNeverSt $exception = $e; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertEquals('Connection to tcp://reactphp.org:80 failed: Last error for IPv4: Connection refused (ECONNREFUSED). Previous error for IPv6: DNS failed', $exception->getMessage()); $this->assertEquals(defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); } public function testConnectWillRejectWhenAllConnectionsRejectAndCancelNextAttemptTimerImmediately() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); $deferred = new Deferred(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->exactly(2))->method('connect')->willReturn($deferred->promise()); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -570,23 +575,23 @@ public function testConnectWillRejectWhenAllConnectionsRejectAndCancelNextAttemp $exception = $e; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertEquals('Connection to tcp://reactphp.org:80 failed: Connection refused (ECONNREFUSED)', $exception->getMessage()); $this->assertEquals(defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); } public function testConnectWillRejectWithMessageWithoutHostnameWhenAllConnectionsRejectAndCancelNextAttemptTimerImmediately() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); $deferred = new Deferred(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->exactly(2))->method('connect')->willReturnOnConsecutiveCalls( $deferred->promise(), reject(new \RuntimeException( @@ -595,7 +600,7 @@ public function testConnectWillRejectWithMessageWithoutHostnameWhenAllConnection )) ); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['localhost', Message::TYPE_AAAA], ['localhost', Message::TYPE_A] @@ -621,24 +626,24 @@ public function testConnectWillRejectWithMessageWithoutHostnameWhenAllConnection $exception = $e; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertEquals('Connection to tcp://localhost:80 failed: Last error for IPv4: Connection to tcp://127.0.0.1:80 failed: Connection refused (ECONNREFUSED). Previous error for IPv6: Connection to tcp://[::1]:80 failed: Connection refused (ECONNREFUSED)', $exception->getMessage()); $this->assertEquals(defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); } public function testCancelConnectWillRejectPromiseAndCancelBothDnsLookups() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addTimer'); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->never())->method('connect'); $cancelled = 0; - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -669,7 +674,7 @@ public function testCancelConnectWillRejectPromiseAndCancelBothDnsLookups() $exception = $e; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertEquals('Connection to tcp://reactphp.org:80 cancelled during DNS lookup (ECONNABORTED)', $exception->getMessage()); @@ -678,15 +683,15 @@ public function testCancelConnectWillRejectPromiseAndCancelBothDnsLookups() public function testCancelConnectWillRejectPromiseAndCancelPendingIpv6LookupAndCancelDelayTimer() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->never())->method('connect'); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -711,7 +716,7 @@ public function testCancelConnectWillRejectPromiseAndCancelPendingIpv6LookupAndC $exception = $e; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertEquals('Connection to tcp://reactphp.org:80 cancelled during DNS lookup (ECONNABORTED)', $exception->getMessage()); @@ -720,19 +725,19 @@ public function testCancelConnectWillRejectPromiseAndCancelPendingIpv6LookupAndC public function testCancelConnectWillRejectPromiseAndCancelPendingIpv6ConnectionAttemptAndPendingIpv4LookupAndCancelAttemptTimer() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.1, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); $cancelled = 0; - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80?hostname=reactphp.org')->willReturn(new Promise(function () { }, function () use (&$cancelled) { ++$cancelled; throw new \RuntimeException('Ignored message'); })); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive( ['reactphp.org', Message::TYPE_AAAA], ['reactphp.org', Message::TYPE_A] @@ -757,7 +762,7 @@ public function testCancelConnectWillRejectPromiseAndCancelPendingIpv6Connection $exception = $e; }); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertEquals('Connection to tcp://reactphp.org:80 cancelled (ECONNABORTED)', $exception->getMessage()); @@ -766,11 +771,11 @@ public function testCancelConnectWillRejectPromiseAndCancelPendingIpv6Connection public function testResolveWillReturnResolvedPromiseWithEmptyListWhenDnsResolverFails() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->once())->method('resolveAll')->with('reactphp.org', Message::TYPE_A)->willReturn(reject(new \RuntimeException())); $uri = 'tcp://reactphp.org:80'; @@ -781,18 +786,18 @@ public function testResolveWillReturnResolvedPromiseWithEmptyListWhenDnsResolver $promise = $builder->resolve(Message::TYPE_A, $this->expectCallableNever()); - $this->assertInstanceof('React\Promise\PromiseInterface', $promise); + $this->assertInstanceof(PromiseInterface::class, $promise); $promise->then($this->expectCallableOnceWith([]), $this->expectCallableNever()); } public function testAttemptConnectionWillConnectViaConnectorToGivenIpWithPortAndHostnameFromUriParts() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://10.1.1.1:80?hostname=reactphp.org')->willReturn(new Promise(function () { })); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->never())->method('resolveAll'); $uri = 'tcp://reactphp.org:80'; @@ -806,12 +811,12 @@ public function testAttemptConnectionWillConnectViaConnectorToGivenIpWithPortAnd public function testAttemptConnectionWillConnectViaConnectorToGivenIpv6WithAllUriParts() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80/path?test=yes&hostname=reactphp.org#start')->willReturn(new Promise(function () { })); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->never())->method('resolveAll'); $uri = 'tcp://reactphp.org:80/path?test=yes#start'; @@ -825,12 +830,12 @@ public function testAttemptConnectionWillConnectViaConnectorToGivenIpv6WithAllUr public function testCheckCallsRejectFunctionImmediateWithoutLeavingDanglingPromiseWhenConnectorRejectsImmediately() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80/path?test=yes&hostname=reactphp.org#start')->willReturn(reject(new \RuntimeException())); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->never())->method('resolveAll'); $uri = 'tcp://reactphp.org:80/path?test=yes#start'; @@ -854,15 +859,15 @@ public function testCheckCallsRejectFunctionImmediateWithoutLeavingDanglingPromi public function testCleanUpCancelsAllPendingConnectionAttempts() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->exactly(2))->method('connect')->with('tcp://[::1]:80/path?test=yes&hostname=reactphp.org#start')->willReturnOnConsecutiveCalls( new Promise(function () { }, $this->expectCallableOnce()), new Promise(function () { }, $this->expectCallableOnce()) ); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->never())->method('resolveAll'); $uri = 'tcp://reactphp.org:80/path?test=yes#start'; @@ -883,14 +888,14 @@ public function testCleanUpCancelsAllPendingConnectionAttempts() public function testCleanUpCancelsAllPendingConnectionAttemptsWithoutStartingNewAttemptsDueToCancellationRejection() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('tcp://[::1]:80/path?test=yes&hostname=reactphp.org#start')->willReturn(new Promise(function () { }, function () { throw new \RuntimeException(); })); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $resolver = $this->createMock(ResolverInterface::class); $resolver->expects($this->never())->method('resolveAll'); $uri = 'tcp://reactphp.org:80/path?test=yes#start'; @@ -910,9 +915,9 @@ public function testCleanUpCancelsAllPendingConnectionAttemptsWithoutStartingNew public function testMixIpsIntoConnectQueueSometimesAssignsInOriginalOrder() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); + $connector = $this->createMock(ConnectorInterface::class); + $resolver = $this->createMock(ResolverInterface::class); $uri = 'tcp://reactphp.org:80/path?test=yes#start'; $host = 'reactphp.org'; @@ -936,9 +941,9 @@ public function testMixIpsIntoConnectQueueSometimesAssignsInOriginalOrder() public function testMixIpsIntoConnectQueueSometimesAssignsInReverseOrder() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); - $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); + $connector = $this->createMock(ConnectorInterface::class); + $resolver = $this->createMock(ResolverInterface::class); $uri = 'tcp://reactphp.org:80/path?test=yes#start'; $host = 'reactphp.org'; diff --git a/tests/HappyEyeBallsConnectorTest.php b/tests/HappyEyeBallsConnectorTest.php index 6d744f09..068aefc4 100644 --- a/tests/HappyEyeBallsConnectorTest.php +++ b/tests/HappyEyeBallsConnectorTest.php @@ -3,9 +3,13 @@ namespace React\Tests\Socket; use React\Dns\Model\Message; +use React\Dns\Resolver\ResolverInterface; +use React\EventLoop\LoopInterface; use React\EventLoop\StreamSelectLoop; use React\Promise\Deferred; use React\Promise\Promise; +use React\Socket\ConnectionInterface; +use React\Socket\ConnectorInterface; use React\Socket\HappyEyeBallsConnector; use function React\Promise\reject; use function React\Promise\resolve; @@ -24,9 +28,9 @@ class HappyEyeBallsConnectorTest extends TestCase public function setUpMocks() { $this->loop = new TimerSpeedUpEventLoop(new StreamSelectLoop()); - $this->tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); - $this->resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->disableOriginalConstructor()->getMock(); - $this->connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); + $this->tcp = $this->createMock(ConnectorInterface::class); + $this->resolver = $this->createMock(ResolverInterface::class); + $this->connection = $this->createMock(ConnectionInterface::class); $this->connector = new HappyEyeBallsConnector($this->loop, $this->tcp, $this->resolver); } @@ -39,15 +43,15 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $ref->setAccessible(true); $loop = $ref->getValue($connector); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testHappyFlow() { $first = new Deferred(); - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('example.com'), $this->anything())->willReturn($first->promise()); - $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); - $this->tcp->expects($this->exactly(1))->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=example.com'))->willReturn(resolve($connection)); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('example.com', $this->anything())->willReturn($first->promise()); + $connection = $this->createMock(ConnectionInterface::class); + $this->tcp->expects($this->exactly(1))->method('connect')->with('1.2.3.4:80?hostname=example.com')->willReturn(resolve($connection)); $promise = $this->connector->connect('example.com:80'); $first->resolve(['1.2.3.4']); @@ -62,7 +66,7 @@ public function testHappyFlow() public function testThatAnyOtherPendingConnectionAttemptsWillBeCanceledOnceAConnectionHasBeenEstablished() { - $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); + $connection = $this->createMock(ConnectionInterface::class); $lookupAttempts = [ reject(new \Exception('error')), resolve(['1.2.3.4', '5.6.7.8', '9.10.11.12']), @@ -72,12 +76,12 @@ public function testThatAnyOtherPendingConnectionAttemptsWillBeCanceledOnceAConn resolve($connection), new Promise(function () {}, $this->expectCallableNever()), ]; - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('example.com'), $this->anything())->will($this->returnCallback(function () use (&$lookupAttempts) { + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('example.com', $this->anything())->willReturnCallback(function () use (&$lookupAttempts) { return array_shift($lookupAttempts); - })); - $this->tcp->expects($this->exactly(2))->method('connect')->with($this->isType('string'))->will($this->returnCallback(function () use (&$connectionAttempts) { + }); + $this->tcp->expects($this->exactly(2))->method('connect')->with($this->isType('string'))->willReturnCallback(function () use (&$connectionAttempts) { return array_shift($connectionAttempts); - })); + }); $promise = $this->connector->connect('example.com:80'); @@ -93,7 +97,7 @@ public function testThatAnyOtherPendingConnectionAttemptsWillBeCanceledOnceAConn public function testPassByResolverIfGivenIp() { $this->resolver->expects($this->never())->method('resolveAll'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('127.0.0.1:80'))->will($this->returnValue(resolve(null))); + $this->tcp->expects($this->once())->method('connect')->with('127.0.0.1:80')->willReturn(resolve(null)); $this->connector->connect('127.0.0.1:80'); @@ -103,7 +107,7 @@ public function testPassByResolverIfGivenIp() public function testPassByResolverIfGivenIpv6() { $this->resolver->expects($this->never())->method('resolveAll'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('[::1]:80'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->tcp->expects($this->once())->method('connect')->with('[::1]:80')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('[::1]:80'); @@ -114,8 +118,8 @@ public function testPassByResolverIfGivenIpv6() public function testPassThroughResolverIfGivenHost() { - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(resolve(['1.2.3.4']))); - $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('1.2.3.4:80?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('google.com', $this->anything())->willReturn(resolve(['1.2.3.4'])); + $this->tcp->expects($this->exactly(2))->method('connect')->with('1.2.3.4:80?hostname=google.com')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('google.com:80'); @@ -126,8 +130,8 @@ public function testPassThroughResolverIfGivenHost() public function testPassThroughResolverIfGivenHostWhichResolvesToIpv6() { - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(resolve(['::1']))); - $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('[::1]:80?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('google.com', $this->anything())->willReturn(resolve(['::1'])); + $this->tcp->expects($this->exactly(2))->method('connect')->with('[::1]:80?hostname=google.com')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('google.com:80'); @@ -139,7 +143,7 @@ public function testPassThroughResolverIfGivenHostWhichResolvesToIpv6() public function testPassByResolverIfGivenCompleteUri() { $this->resolver->expects($this->never())->method('resolveAll'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('scheme://127.0.0.1:80/path?query#fragment'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->tcp->expects($this->once())->method('connect')->with('scheme://127.0.0.1:80/path?query#fragment')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('scheme://127.0.0.1:80/path?query#fragment'); @@ -150,8 +154,8 @@ public function testPassByResolverIfGivenCompleteUri() public function testPassThroughResolverIfGivenCompleteUri() { - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(resolve(['1.2.3.4']))); - $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/path?query&hostname=google.com#fragment'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('google.com', $this->anything())->willReturn(resolve(['1.2.3.4'])); + $this->tcp->expects($this->exactly(2))->method('connect')->with('scheme://1.2.3.4:80/path?query&hostname=google.com#fragment')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('scheme://google.com:80/path?query#fragment'); @@ -162,8 +166,8 @@ public function testPassThroughResolverIfGivenCompleteUri() public function testPassThroughResolverIfGivenExplicitHost() { - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('google.com'), $this->anything())->will($this->returnValue(resolve(['1.2.3.4']))); - $this->tcp->expects($this->exactly(2))->method('connect')->with($this->equalTo('scheme://1.2.3.4:80/?hostname=google.de'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('google.com', $this->anything())->willReturn(resolve(['1.2.3.4'])); + $this->tcp->expects($this->exactly(2))->method('connect')->with('scheme://1.2.3.4:80/?hostname=google.de')->willReturn(reject(new \Exception('reject'))); $promise = $this->connector->connect('scheme://google.com:80/?hostname=google.de'); @@ -186,7 +190,7 @@ public function testIpv6ResolvesFirstSoIsTheFirstToConnect(array $ipv6, array $i $this->returnValue(resolve($ipv6)), $this->returnValue($deferred->promise()) ); - $this->tcp->expects($this->any())->method('connect')->with($this->stringContains(']:80/?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->tcp->expects($this->any())->method('connect')->with($this->stringContains(']:80/?hostname=google.com'))->willReturn(reject(new \Exception('reject'))); $this->connector->connect('scheme://google.com:80/?hostname=google.com'); @@ -211,7 +215,7 @@ public function testIpv6DoesntResolvesWhileIpv4DoesFirstSoIpv4Connects(array $ip $this->returnValue($deferred->promise()), $this->returnValue(resolve($ipv4)) ); - $this->tcp->expects($this->any())->method('connect')->with($this->stringContains(':80/?hostname=google.com'))->will($this->returnValue(reject(new \Exception('reject')))); + $this->tcp->expects($this->any())->method('connect')->with($this->stringContains(':80/?hostname=google.com'))->willReturn(reject(new \Exception('reject'))); $this->connector->connect('scheme://google.com:80/?hostname=google.com'); @@ -230,7 +234,7 @@ public function testRejectsImmediatelyIfUriIsInvalid() $promise = $this->connector->connect('////'); $promise->then(null, $this->expectCallableOnceWithException( - 'InvalidArgumentException', + \InvalidArgumentException::class, 'Given URI "////" is invalid (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); @@ -240,7 +244,7 @@ public function testRejectsWithTcpConnectorRejectionIfGivenIp() { $promise = reject(new \RuntimeException('Connection failed')); $this->resolver->expects($this->never())->method('resolveAll'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80'))->willReturn($promise); + $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80')->willReturn($promise); $promise = $this->connector->connect('1.2.3.4:80'); $this->loop->addTimer(0.5, function () use ($promise) { @@ -249,13 +253,14 @@ public function testRejectsWithTcpConnectorRejectionIfGivenIp() $this->throwRejection($promise); }); - $this->setExpectedException('RuntimeException', 'Connection failed'); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Connection failed'); $this->loop->run(); } public function testSkipConnectionIfDnsFails() { - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with($this->equalTo('example.invalid'), $this->anything())->willReturn(reject(new \RuntimeException('DNS error'))); + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('example.invalid', $this->anything())->willReturn(reject(new \RuntimeException('DNS error'))); $this->tcp->expects($this->never())->method('connect'); $promise = $this->connector->connect('example.invalid:80'); @@ -264,15 +269,16 @@ public function testSkipConnectionIfDnsFails() $this->throwRejection($promise); }); - $this->setExpectedException('RuntimeException', 'Connection to tcp://example.invalid:80 failed during DNS lookup: DNS error'); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Connection to tcp://example.invalid:80 failed during DNS lookup: DNS error'); $this->loop->run(); } public function testCancelDuringDnsCancelsDnsAndDoesNotStartTcpConnection() { - $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('example.com', $this->anything())->will($this->returnCallback(function () { + $this->resolver->expects($this->exactly(2))->method('resolveAll')->with('example.com', $this->anything())->willReturnCallback(function () { return new Promise(function () { }, $this->expectCallableExactly(1)); - })); + }); $this->tcp->expects($this->never())->method('connect'); $promise = $this->connector->connect('example.com:80'); @@ -282,11 +288,9 @@ public function testCancelDuringDnsCancelsDnsAndDoesNotStartTcpConnection() $this->throwRejection($promise); }); - $this->setExpectedException( - 'RuntimeException', - 'Connection to tcp://example.com:80 cancelled during DNS lookup (ECONNABORTED)', - \defined('SOCKET_ECONNABORTED') ? \SOCKET_ECONNABORTED : 103 - ); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Connection to tcp://example.com:80 cancelled during DNS lookup (ECONNABORTED)'); + $this->expectExceptionCode(\defined('SOCKET_ECONNABORTED') ? \SOCKET_ECONNABORTED : 103); $this->loop->run(); } @@ -294,7 +298,7 @@ public function testCancelDuringTcpConnectionCancelsTcpConnectionIfGivenIp() { $pending = new Promise(function () { }, $this->expectCallableOnce()); $this->resolver->expects($this->never())->method('resolveAll'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('1.2.3.4:80'))->willReturn($pending); + $this->tcp->expects($this->once())->method('connect')->with('1.2.3.4:80')->willReturn($pending); $promise = $this->connector->connect('1.2.3.4:80'); $this->loop->addTimer(0.1, function () use ($promise) { @@ -317,7 +321,7 @@ public function throwRejection($promise) throw $ex; } - public function provideIpvAddresses() + public static function provideIpvAddresses() { $ipv6 = [ ['1:2:3:4'], @@ -330,17 +334,13 @@ public function provideIpvAddresses() ['1.2.3.4', '5.6.7.8', '9.10.11.12'] ]; - $ips = []; - foreach ($ipv6 as $v6) { foreach ($ipv4 as $v4) { - $ips[] = [ + yield [ $v6, $v4 ]; } } - - return $ips; } } diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index acf42c12..361443e1 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -26,7 +26,7 @@ public function gettingStuffFromGoogleShouldWork() $conn = await($connector->connect('google.com:80')); assert($conn instanceof ConnectionInterface); - $this->assertContainsString(':80', $conn->getRemoteAddress()); + $this->assertStringContainsString(':80', $conn->getRemoteAddress()); $this->assertNotEquals('google.com:80', $conn->getRemoteAddress()); $conn->write("GET / HTTP/1.0\r\n\r\n"); @@ -34,7 +34,7 @@ public function gettingStuffFromGoogleShouldWork() $response = $this->buffer($conn, self::TIMEOUT); assert(!$conn->isReadable()); - $this->assertMatchesRegExp('#^HTTP/1\.0#', $response); + $this->assertStringMatchesFormat('HTTP/1.0%a', $response); } /** @test */ @@ -50,7 +50,7 @@ public function gettingEncryptedStuffFromGoogleShouldWork() $response = $this->buffer($conn, self::TIMEOUT); assert(!$conn->isReadable()); - $this->assertMatchesRegExp('#^HTTP/1\.0#', $response); + $this->assertStringMatchesFormat('HTTP/1.0%a', $response); } /** @test */ @@ -74,7 +74,7 @@ public function gettingEncryptedStuffFromGoogleShouldWorkIfHostIsResolvedFirst() $response = $this->buffer($conn, self::TIMEOUT); assert(!$conn->isReadable()); - $this->assertMatchesRegExp('#^HTTP/1\.0#', $response); + $this->assertStringMatchesFormat('HTTP/1.0%a', $response); } /** @test */ @@ -85,7 +85,7 @@ public function gettingPlaintextStuffFromEncryptedGoogleShouldNotWork() $conn = await($connector->connect('google.com:443')); assert($conn instanceof ConnectionInterface); - $this->assertContainsString(':443', $conn->getRemoteAddress()); + $this->assertStringContainsString(':443', $conn->getRemoteAddress()); $this->assertNotEquals('google.com:443', $conn->getRemoteAddress()); $conn->write("GET / HTTP/1.0\r\n\r\n"); @@ -93,7 +93,7 @@ public function gettingPlaintextStuffFromEncryptedGoogleShouldNotWork() $response = $this->buffer($conn, self::TIMEOUT); assert(!$conn->isReadable()); - $this->assertDoesNotMatchRegExp('#^HTTP/1\.0#', $response); + $this->assertStringNotMatchesFormat('HTTP/1.0%a', $response); } public function testConnectingFailsIfConnectorUsesInvalidDnsResolverAddress() @@ -109,7 +109,7 @@ public function testConnectingFailsIfConnectorUsesInvalidDnsResolverAddress() 'dns' => $dns ]); - $this->setExpectedException('RuntimeException'); + $this->expectException(\RuntimeException::class); await(timeout($connector->connect('google.com:80'), self::TIMEOUT)); } @@ -365,7 +365,7 @@ public function testConnectingFailsIfTimeoutIsTooSmall() 'timeout' => 0.001 ]); - $this->setExpectedException('RuntimeException'); + $this->expectException(\RuntimeException::class); await(timeout($connector->connect('google.com:80'), self::TIMEOUT)); } @@ -377,7 +377,7 @@ public function testSelfSignedRejectsIfVerificationIsEnabled() ] ]); - $this->setExpectedException('RuntimeException'); + $this->expectException(\RuntimeException::class); await(timeout($connector->connect('tls://self-signed.badssl.com:443'), self::TIMEOUT)); } diff --git a/tests/LimitingServerTest.php b/tests/LimitingServerTest.php index 9fc634d9..96d41986 100644 --- a/tests/LimitingServerTest.php +++ b/tests/LimitingServerTest.php @@ -2,9 +2,11 @@ namespace React\Tests\Socket; +use React\EventLoop\LoopInterface; use React\Promise\Promise; use React\Socket\ConnectionInterface; use React\Socket\LimitingServer; +use React\Socket\ServerInterface; use React\Socket\TcpServer; use function React\Async\await; use function React\Promise\Timer\timeout; @@ -15,7 +17,7 @@ class LimitingServerTest extends TestCase public function testGetAddressWillBePassedThroughToTcpServer() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('getAddress')->willReturn('127.0.0.1:1234'); $server = new LimitingServer($tcp, 100); @@ -25,7 +27,7 @@ public function testGetAddressWillBePassedThroughToTcpServer() public function testPauseWillBePassedThroughToTcpServer() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('pause'); $server = new LimitingServer($tcp, 100); @@ -35,7 +37,7 @@ public function testPauseWillBePassedThroughToTcpServer() public function testPauseTwiceWillBePassedThroughToTcpServerOnce() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('pause'); $server = new LimitingServer($tcp, 100); @@ -46,7 +48,7 @@ public function testPauseTwiceWillBePassedThroughToTcpServerOnce() public function testResumeWillBePassedThroughToTcpServer() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('resume'); $server = new LimitingServer($tcp, 100); @@ -57,7 +59,7 @@ public function testResumeWillBePassedThroughToTcpServer() public function testResumeTwiceWillBePassedThroughToTcpServerOnce() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('resume'); $server = new LimitingServer($tcp, 100); @@ -69,7 +71,7 @@ public function testResumeTwiceWillBePassedThroughToTcpServerOnce() public function testCloseWillBePassedThroughToTcpServer() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('close'); $server = new LimitingServer($tcp, 100); @@ -79,7 +81,7 @@ public function testCloseWillBePassedThroughToTcpServer() public function testSocketErrorWillBeForwarded() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $tcp = new TcpServer(0, $loop); @@ -92,9 +94,9 @@ public function testSocketErrorWillBeForwarded() public function testSocketConnectionWillBeForwarded() { - $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); + $connection = $this->createMock(ConnectionInterface::class); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $tcp = new TcpServer(0, $loop); @@ -109,12 +111,12 @@ public function testSocketConnectionWillBeForwarded() public function testSocketConnectionWillBeClosedOnceLimitIsReached() { - $first = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); + $first = $this->createMock(ConnectionInterface::class); $first->expects($this->never())->method('close'); - $second = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); + $second = $this->createMock(ConnectionInterface::class); $second->expects($this->once())->method('close'); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $tcp = new TcpServer(0, $loop); @@ -128,13 +130,13 @@ public function testSocketConnectionWillBeClosedOnceLimitIsReached() public function testPausingServerWillBePausedOnceLimitIsReached() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream'); $loop->expects($this->once())->method('removeReadStream'); $tcp = new TcpServer(0, $loop); - $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); + $connection = $this->createMock(ConnectionInterface::class); $server = new LimitingServer($tcp, 1, true); diff --git a/tests/SecureConnectorTest.php b/tests/SecureConnectorTest.php index 833e874f..b96d3c33 100644 --- a/tests/SecureConnectorTest.php +++ b/tests/SecureConnectorTest.php @@ -2,9 +2,15 @@ namespace React\Tests\Socket; +use React\EventLoop\LoopInterface; use React\Promise\Deferred; use React\Promise\Promise; +use React\Promise\PromiseInterface; +use React\Socket\Connection; +use React\Socket\ConnectionInterface; +use React\Socket\ConnectorInterface; use React\Socket\SecureConnector; +use React\Socket\StreamEncryption; use function React\Promise\reject; use function React\Promise\resolve; @@ -19,8 +25,8 @@ class SecureConnectorTest extends TestCase */ public function setUpConnector() { - $this->loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); - $this->tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $this->loop = $this->createMock(LoopInterface::class); + $this->tcp = $this->createMock(ConnectorInterface::class); $this->connector = new SecureConnector($this->tcp, $this->loop); } @@ -36,23 +42,23 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $ref->setAccessible(true); $loop = $ref->getValue($streamEncryption); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testConnectionWillWaitForTcpConnection() { $pending = new Promise(function () { }); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->will($this->returnValue($pending)); + $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn($pending); $promise = $this->connector->connect('example.com:80'); - $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertInstanceOf(PromiseInterface::class, $promise); } public function testConnectionWithCompleteUriWillBePassedThroughExpectForScheme() { $pending = new Promise(function () { }); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80/path?query#fragment'))->will($this->returnValue($pending)); + $this->tcp->expects($this->once())->method('connect')->with('example.com:80/path?query#fragment')->willReturn($pending); $this->connector->connect('tls://example.com:80/path?query#fragment'); } @@ -64,7 +70,7 @@ public function testConnectionToInvalidSchemeWillReject() $promise = $this->connector->connect('tcp://example.com:80'); $promise->then(null, $this->expectCallableOnceWithException( - 'InvalidArgumentException', + \InvalidArgumentException::class, 'Given URI "tcp://example.com:80" is invalid (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); @@ -85,10 +91,10 @@ public function testConnectWillRejectWithTlsUriWhenUnderlyingConnectorRejects() }); assert($exception instanceof \RuntimeException); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('Connection to tls://example.com:80 failed: Connection refused (ECONNREFUSED)', $exception->getMessage()); $this->assertEquals(defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); $this->assertNotEquals('', $exception->getTraceAsString()); } @@ -107,7 +113,7 @@ public function testConnectWillRejectWithOriginalMessageWhenUnderlyingConnectorR }); assert($exception instanceof \InvalidArgumentException); - $this->assertInstanceOf('InvalidArgumentException', $exception); + $this->assertInstanceOf(\InvalidArgumentException::class, $exception); $this->assertEquals('Invalid', $exception->getMessage()); $this->assertEquals(42, $exception->getCode()); $this->assertNull($exception->getPrevious()); @@ -129,7 +135,7 @@ public function testCancelDuringTcpConnectionCancelsTcpConnectionAndRejectsWithT 'Connection to tcp://example.com:80 cancelled (ECONNABORTED)', defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103 ); }); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->will($this->returnValue($pending)); + $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn($pending); $promise = $this->connector->connect('example.com:80'); $promise->cancel(); @@ -140,19 +146,19 @@ public function testCancelDuringTcpConnectionCancelsTcpConnectionAndRejectsWithT }); assert($exception instanceof \RuntimeException); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('Connection to tls://example.com:80 cancelled (ECONNABORTED)', $exception->getMessage()); $this->assertEquals(defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103, $exception->getCode()); - $this->assertInstanceOf('RuntimeException', $exception->getPrevious()); + $this->assertInstanceOf(\RuntimeException::class, $exception->getPrevious()); $this->assertNotEquals('', $exception->getTraceAsString()); } public function testConnectionWillBeClosedAndRejectedIfConnectionIsNoStream() { - $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); + $connection = $this->createMock(ConnectionInterface::class); $connection->expects($this->once())->method('close'); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(resolve($connection)); + $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn(resolve($connection)); $promise = $this->connector->connect('example.com:80'); @@ -162,7 +168,7 @@ public function testConnectionWillBeClosedAndRejectedIfConnectionIsNoStream() }); assert($exception instanceof \UnexpectedValueException); - $this->assertInstanceOf('UnexpectedValueException', $exception); + $this->assertInstanceOf(\UnexpectedValueException::class, $exception); $this->assertEquals('Base connector does not use internal Connection class exposing stream resource', $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); $this->assertNull($exception->getPrevious()); @@ -171,33 +177,33 @@ public function testConnectionWillBeClosedAndRejectedIfConnectionIsNoStream() public function testStreamEncryptionWillBeEnabledAfterConnecting() { - $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->getMock(); + $connection = $this->createMock(Connection::class); - $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock(); + $encryption = $this->createMock(StreamEncryption::class); $encryption->expects($this->once())->method('enable')->with($connection)->willReturn(new Promise(function () { })); $ref = new \ReflectionProperty($this->connector, 'streamEncryption'); $ref->setAccessible(true); $ref->setValue($this->connector, $encryption); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(resolve($connection)); + $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn(resolve($connection)); $this->connector->connect('example.com:80'); } public function testConnectionWillBeRejectedIfStreamEncryptionFailsAndClosesConnection() { - $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->getMock(); + $connection = $this->createMock(Connection::class); $connection->expects($this->once())->method('close'); - $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock(); + $encryption = $this->createMock(StreamEncryption::class); $encryption->expects($this->once())->method('enable')->willReturn(reject(new \RuntimeException('TLS error', 123))); $ref = new \ReflectionProperty($this->connector, 'streamEncryption'); $ref->setAccessible(true); $ref->setValue($this->connector, $encryption); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn(resolve($connection)); + $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn(resolve($connection)); $promise = $this->connector->connect('example.com:80'); @@ -207,7 +213,7 @@ public function testConnectionWillBeRejectedIfStreamEncryptionFailsAndClosesConn }); assert($exception instanceof \RuntimeException); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('Connection to tls://example.com:80 failed during TLS handshake: TLS error', $exception->getMessage()); $this->assertEquals(123, $exception->getCode()); $this->assertNull($exception->getPrevious()); @@ -216,13 +222,13 @@ public function testConnectionWillBeRejectedIfStreamEncryptionFailsAndClosesConn public function testCancelDuringStreamEncryptionCancelsEncryptionAndClosesConnection() { - $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->getMock(); + $connection = $this->createMock(Connection::class); $connection->expects($this->once())->method('close'); $pending = new Promise(function () { }, function () { throw new \Exception('Ignored'); }); - $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock(); + $encryption = $this->createMock(StreamEncryption::class); $encryption->expects($this->once())->method('enable')->willReturn($pending); $ref = new \ReflectionProperty($this->connector, 'streamEncryption'); @@ -230,7 +236,7 @@ public function testCancelDuringStreamEncryptionCancelsEncryptionAndClosesConnec $ref->setValue($this->connector, $encryption); $deferred = new Deferred(); - $this->tcp->expects($this->once())->method('connect')->with($this->equalTo('example.com:80'))->willReturn($deferred->promise()); + $this->tcp->expects($this->once())->method('connect')->with('example.com:80')->willReturn($deferred->promise()); $promise = $this->connector->connect('example.com:80'); $deferred->resolve($connection); @@ -243,7 +249,7 @@ public function testCancelDuringStreamEncryptionCancelsEncryptionAndClosesConnec }); assert($exception instanceof \RuntimeException); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); $this->assertEquals('Connection to tls://example.com:80 cancelled during TLS handshake (ECONNABORTED)', $exception->getMessage()); $this->assertEquals(defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103, $exception->getCode()); $this->assertNull($exception->getPrevious()); @@ -283,13 +289,13 @@ public function testRejectionDuringTlsHandshakeShouldNotCreateAnyGarbageReferenc // collect all garbage cycles } - $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->getMock(); + $connection = $this->createMock(Connection::class); $tcp = new Deferred(); $this->tcp->expects($this->once())->method('connect')->willReturn($tcp->promise()); $tls = new Deferred(); - $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock(); + $encryption = $this->createMock(StreamEncryption::class); $encryption->expects($this->once())->method('enable')->willReturn($tls->promise()); $ref = new \ReflectionProperty($this->connector, 'streamEncryption'); diff --git a/tests/SecureServerTest.php b/tests/SecureServerTest.php index cfa2e72e..07c238ed 100644 --- a/tests/SecureServerTest.php +++ b/tests/SecureServerTest.php @@ -2,16 +2,21 @@ namespace React\Tests\Socket; +use React\EventLoop\LoopInterface; +use React\Promise\Promise; +use React\Socket\Connection; +use React\Socket\ConnectionInterface; use React\Socket\SecureServer; +use React\Socket\ServerInterface; +use React\Socket\StreamEncryption; use React\Socket\TcpServer; -use React\Promise\Promise; use function React\Promise\reject; class SecureServerTest extends TestCase { public function testConstructWithoutLoopAssignsLoopAutomatically() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $server = new SecureServer($tcp); @@ -23,15 +28,15 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $ref->setAccessible(true); $loop = $ref->getValue($encryption); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testGetAddressWillBePassedThroughToTcpServer() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('getAddress')->willReturn('tcp://127.0.0.1:1234'); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $server = new SecureServer($tcp, $loop, []); @@ -40,10 +45,10 @@ public function testGetAddressWillBePassedThroughToTcpServer() public function testGetAddressWillReturnNullIfTcpServerReturnsNull() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('getAddress')->willReturn(null); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $server = new SecureServer($tcp, $loop, []); @@ -52,10 +57,10 @@ public function testGetAddressWillReturnNullIfTcpServerReturnsNull() public function testPauseWillBePassedThroughToTcpServer() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('pause'); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $server = new SecureServer($tcp, $loop, []); @@ -64,10 +69,10 @@ public function testPauseWillBePassedThroughToTcpServer() public function testResumeWillBePassedThroughToTcpServer() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('resume'); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $server = new SecureServer($tcp, $loop, []); @@ -76,10 +81,10 @@ public function testResumeWillBePassedThroughToTcpServer() public function testCloseWillBePassedThroughToTcpServer() { - $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock(); + $tcp = $this->createMock(ServerInterface::class); $tcp->expects($this->once())->method('close'); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $server = new SecureServer($tcp, $loop, []); @@ -88,11 +93,11 @@ public function testCloseWillBePassedThroughToTcpServer() public function testConnectionWillBeClosedWithErrorIfItIsNotAStream() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $tcp = new TcpServer(0, $loop); - $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); + $connection = $this->createMock(ConnectionInterface::class); $connection->expects($this->once())->method('close'); $server = new SecureServer($tcp, $loop, []); @@ -104,11 +109,11 @@ public function testConnectionWillBeClosedWithErrorIfItIsNotAStream() public function testConnectionWillTryToEnableEncryptionAndWaitForHandshake() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $tcp = new TcpServer(0, $loop); - $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->getMock(); + $connection = $this->createMock(Connection::class); $connection->expects($this->once())->method('getRemoteAddress')->willReturn('tcp://127.0.0.1:1234'); $connection->expects($this->never())->method('close'); @@ -116,7 +121,7 @@ public function testConnectionWillTryToEnableEncryptionAndWaitForHandshake() $pending = new Promise(function () { }); - $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock(); + $encryption = $this->createMock(StreamEncryption::class); $encryption->expects($this->once())->method('enable')->willReturn($pending); $ref = new \ReflectionProperty($server, 'encryption'); @@ -135,11 +140,11 @@ public function testConnectionWillTryToEnableEncryptionAndWaitForHandshake() public function testConnectionWillBeClosedWithErrorIfEnablingEncryptionFails() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $tcp = new TcpServer(0, $loop); - $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->getMock(); + $connection = $this->createMock(Connection::class); $connection->expects($this->once())->method('getRemoteAddress')->willReturn('tcp://127.0.0.1:1234'); $connection->expects($this->once())->method('close'); @@ -147,7 +152,7 @@ public function testConnectionWillBeClosedWithErrorIfEnablingEncryptionFails() $error = new \RuntimeException('Original'); - $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock(); + $encryption = $this->createMock(StreamEncryption::class); $encryption->expects($this->once())->method('enable')->willReturn(reject($error)); $ref = new \ReflectionProperty($server, 'encryption'); @@ -166,13 +171,13 @@ public function testConnectionWillBeClosedWithErrorIfEnablingEncryptionFails() $tcp->emit('connection', [$connection]); - $this->assertInstanceOf('RuntimeException', $error); + $this->assertInstanceOf(\RuntimeException::class, $error); $this->assertEquals('Connection from tcp://127.0.0.1:1234 failed during TLS handshake: Original', $error->getMessage()); } public function testSocketErrorWillBeForwarded() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $tcp = new TcpServer(0, $loop); diff --git a/tests/SocketServerTest.php b/tests/SocketServerTest.php index 3ec87c74..537a2ce5 100644 --- a/tests/SocketServerTest.php +++ b/tests/SocketServerTest.php @@ -2,6 +2,7 @@ namespace React\Tests\Socket; +use React\EventLoop\LoopInterface; use React\Promise\Promise; use React\Socket\ConnectionInterface; use React\Socket\SocketServer; @@ -28,7 +29,7 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $ref->setAccessible(true); $loop = $ref->getValue($tcp); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testCreateServerWithZeroPortAssignsRandomPort() @@ -40,31 +41,25 @@ public function testCreateServerWithZeroPortAssignsRandomPort() public function testConstructorWithInvalidUriThrows() { - $this->setExpectedException( - 'InvalidArgumentException', - 'Invalid URI "tcp://invalid URI" given (EINVAL)', - defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid URI "tcp://invalid URI" given (EINVAL)'); + $this->expectExceptionCode(defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)); new SocketServer('invalid URI'); } public function testConstructorWithInvalidUriWithPortOnlyThrows() { - $this->setExpectedException( - 'InvalidArgumentException', - 'Invalid URI given (EINVAL)', - defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid URI given (EINVAL)'); + $this->expectExceptionCode(defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)); new SocketServer('0'); } public function testConstructorWithInvalidUriWithSchemaAndPortOnlyThrows() { - $this->setExpectedException( - 'InvalidArgumentException', - 'Invalid URI given (EINVAL)', - defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid URI given (EINVAL)'); + $this->expectExceptionCode(defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)); new SocketServer('tcp://0'); } diff --git a/tests/Stub/CallableStub.php b/tests/Stub/CallableStub.php deleted file mode 100644 index 1b197ebd..00000000 --- a/tests/Stub/CallableStub.php +++ /dev/null @@ -1,10 +0,0 @@ -setAccessible(true); $loop = $ref->getValue($connector); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } /** @test */ @@ -36,11 +39,9 @@ public function connectionToEmptyPortShouldFailWithoutCallingCustomErrorHandler( $error = $errstr; }); - $this->setExpectedException( - 'RuntimeException', - 'Connection to tcp://127.0.0.1:9999 failed: Connection refused' . (function_exists('socket_import_stream') ? ' (ECONNREFUSED)' : ''), - defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111 - ); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Connection to tcp://127.0.0.1:9999 failed: Connection refused' . (function_exists('socket_import_stream') ? ' (ECONNREFUSED)' : '')); + $this->expectExceptionCode(defined('SOCKET_ECONNREFUSED') ? SOCKET_ECONNREFUSED : 111); try { await(timeout($promise, self::TIMEOUT)); @@ -57,7 +58,7 @@ public function connectionToEmptyPortShouldFailWithoutCallingCustomErrorHandler( /** @test */ public function connectionToTcpServerShouldAddResourceToLoop() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new TcpConnector($loop); $server = new TcpServer(0, $loop); @@ -81,7 +82,7 @@ public function connectionToTcpServerShouldSucceed() $connection = await(timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); - $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); + $this->assertInstanceOf(ConnectionInterface::class, $connection); $connection->close(); $server->close(); @@ -116,8 +117,8 @@ public function connectionToTcpServerShouldFailIfFileDescriptorsAreExceeded() } // dummy rejected promise to make sure autoloader has initialized all classes - class_exists('React\Socket\SocketServer', true); - class_exists('PHPUnit\Framework\Error\Warning', true); + class_exists(SocketServer::class, true); + class_exists(Warning::class, true); $promise = new Promise(function () { throw new \RuntimeException('dummy'); }); $promise->then(null, $this->expectCallableOnce()); // avoid reporting unhandled rejection unset($promise); @@ -132,7 +133,7 @@ class_exists('PHPUnit\Framework\Error\Warning', true); $fds[] = $fd; } - $this->setExpectedException('RuntimeException'); + $this->expectException(\RuntimeException::class); await(timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); } @@ -160,11 +161,9 @@ public function connectionToInvalidNetworkShouldFailWithUnreachableError() $promise = $connector->connect($address); - $this->setExpectedException( - 'RuntimeException', - 'Connection to ' . $address . ' failed: ' . (function_exists('socket_strerror') ? socket_strerror($enetunreach) . ' (ENETUNREACH)' : 'Network is unreachable'), - $enetunreach - ); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Connection to ' . $address . ' failed: ' . (function_exists('socket_strerror') ? socket_strerror($enetunreach) . ' (ENETUNREACH)' : 'Network is unreachable')); + $this->expectExceptionCode($enetunreach); await(timeout($promise, self::TIMEOUT)); } @@ -194,7 +193,7 @@ public function connectionToTcpServerShouldSucceedWithLocalAdressOnLocalhost() $connection = await(timeout($connector->connect('127.0.0.1:9999'), self::TIMEOUT)); /* @var $connection ConnectionInterface */ - $this->assertContainsString('tcp://127.0.0.1:', $connection->getLocalAddress()); + $this->assertStringContainsString('tcp://127.0.0.1:', $connection->getLocalAddress()); $this->assertNotEquals('tcp://127.0.0.1:9999', $connection->getLocalAddress()); $connection->close(); @@ -267,7 +266,7 @@ public function connectionToIp6TcpServerShouldSucceed() $this->assertEquals('tcp://[::1]:9999', $connection->getRemoteAddress()); - $this->assertContainsString('tcp://[::1]:', $connection->getLocalAddress()); + $this->assertStringContainsString('tcp://[::1]:', $connection->getLocalAddress()); $this->assertNotEquals('tcp://[::1]:9999', $connection->getLocalAddress()); $connection->close(); @@ -277,13 +276,13 @@ public function connectionToIp6TcpServerShouldSucceed() /** @test */ public function connectionToHostnameShouldFailImmediately() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new TcpConnector($loop); $promise = $connector->connect('www.google.com:80'); $promise->then(null, $this->expectCallableOnceWithException( - 'InvalidArgumentException', + \InvalidArgumentException::class, 'Given URI "tcp://www.google.com:80" does not contain a valid host IP (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); @@ -292,13 +291,13 @@ public function connectionToHostnameShouldFailImmediately() /** @test */ public function connectionToInvalidPortShouldFailImmediately() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new TcpConnector($loop); $promise = $connector->connect('255.255.255.255:12345678'); $promise->then(null, $this->expectCallableOnceWithException( - 'InvalidArgumentException', + \InvalidArgumentException::class, 'Given URI "tcp://255.255.255.255:12345678" is invalid (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); @@ -307,7 +306,7 @@ public function connectionToInvalidPortShouldFailImmediately() /** @test */ public function connectionToInvalidSchemeShouldFailImmediately() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new TcpConnector($loop); $connector->connect('tls://google.com:443')->then( @@ -319,7 +318,7 @@ public function connectionToInvalidSchemeShouldFailImmediately() /** @test */ public function cancellingConnectionShouldRemoveResourceFromLoopAndCloseResource() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new TcpConnector($loop); $server = new TcpServer(0, $loop); @@ -354,11 +353,9 @@ public function cancellingConnectionShouldRejectPromise() $promise = $connector->connect($server->getAddress()); $promise->cancel(); - $this->setExpectedException( - 'RuntimeException', - 'Connection to ' . $server->getAddress() . ' cancelled during TCP/IP handshake (ECONNABORTED)', - defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103 - ); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Connection to ' . $server->getAddress() . ' cancelled during TCP/IP handshake (ECONNABORTED)'); + $this->expectExceptionCode(defined('SOCKET_ECONNABORTED') ? SOCKET_ECONNABORTED : 103); try { await($promise); @@ -378,7 +375,7 @@ public function testCancelDuringConnectionShouldNotCreateAnyGarbageReferences() // collect all garbage cycles } - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $connector = new TcpConnector($loop); $promise = $connector->connect('127.0.0.1:9999'); diff --git a/tests/TcpServerTest.php b/tests/TcpServerTest.php index 7f052c3e..1adf91b8 100644 --- a/tests/TcpServerTest.php +++ b/tests/TcpServerTest.php @@ -3,7 +3,9 @@ namespace React\Tests\Socket; use React\EventLoop\Loop; +use React\EventLoop\LoopInterface; use React\Promise\Promise; +use React\Socket\ConnectionInterface; use React\Socket\TcpServer; use React\Stream\DuplexResourceStream; use function React\Async\await; @@ -37,7 +39,7 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $ref->setAccessible(true); $loop = $ref->getValue($server); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); $server->close(); } @@ -56,7 +58,7 @@ public function testServerEmitsConnectionEventForNewConnection() $connection = await(timeout($promise, self::TIMEOUT)); - $this->assertInstanceOf('React\Socket\ConnectionInterface', $connection); + $this->assertInstanceOf(ConnectionInterface::class, $connection); } /** @@ -235,7 +237,7 @@ public function testConnectionDoesEndWhenClientCloses() public function testCtorAddsResourceToLoop() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream'); new TcpServer(0, $loop); @@ -243,7 +245,7 @@ public function testCtorAddsResourceToLoop() public function testResumeWithoutPauseIsNoOp() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream'); $server = new TcpServer(0, $loop); @@ -252,7 +254,7 @@ public function testResumeWithoutPauseIsNoOp() public function testPauseRemovesResourceFromLoop() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('removeReadStream'); $server = new TcpServer(0, $loop); @@ -261,7 +263,7 @@ public function testPauseRemovesResourceFromLoop() public function testPauseAfterPauseIsNoOp() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('removeReadStream'); $server = new TcpServer(0, $loop); @@ -271,7 +273,7 @@ public function testPauseAfterPauseIsNoOp() public function testCloseRemovesResourceFromLoop() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('removeReadStream'); $server = new TcpServer(0, $loop); @@ -281,7 +283,7 @@ public function testCloseRemovesResourceFromLoop() public function testEmitsErrorWhenAcceptListenerFailsWithoutCallingCustomErrorHandler() { $listener = null; - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream')->with($this->anything(), $this->callback(function ($cb) use (&$listener) { $listener = $cb; return true; @@ -311,7 +313,7 @@ public function testEmitsErrorWhenAcceptListenerFailsWithoutCallingCustomErrorHa $this->assertLessThan(1, $time); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertStringStartsWith('Unable to accept new connection: ', $exception->getMessage()); @@ -335,11 +337,9 @@ public function testListenOnBusyPortThrows() $this->markTestSkipped('Windows supports listening on same port multiple times'); } - $this->setExpectedException( - 'RuntimeException', - '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 - ); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Failed to listen on "tcp://127.0.0.1:' . $this->port . '": ' . (function_exists('socket_strerror') ? socket_strerror(SOCKET_EADDRINUSE) . ' (EADDRINUSE)' : 'Address already in use')); + $this->expectExceptionCode(defined('SOCKET_EADDRINUSE') ? SOCKET_EADDRINUSE : 0); new TcpServer($this->port); } diff --git a/tests/TestCase.php b/tests/TestCase.php index d707db08..1e7a79e0 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -69,7 +69,14 @@ protected function expectCallableNever() protected function createCallableMock() { - return $this->getMockBuilder('React\Tests\Socket\Stub\CallableStub')->getMock(); + $builder = $this->getMockBuilder(\stdClass::class); + if (method_exists($builder, 'addMethods')) { + // PHPUnit 9+ + return $builder->addMethods(['__invoke'])->getMock(); + } else { + // legacy PHPUnit + return $builder->setMethods(['__invoke'])->getMock(); + } } protected function buffer(ReadableStreamInterface $stream, $timeout) @@ -106,17 +113,6 @@ function () use ($stream) { return $buffer; } - public function setExpectedException($exception, $exceptionMessage = '', $exceptionCode = null) - { - $this->expectException($exception); - if ($exceptionMessage !== '') { - $this->expectExceptionMessage($exceptionMessage); - } - if ($exceptionCode !== null) { - $this->expectExceptionCode($exceptionCode); - } - } - protected function supportsTls13() { // TLS 1.3 is supported as of OpenSSL 1.1.1 (https://www.openssl.org/blog/blog/2018/09/11/release111/) @@ -133,37 +129,4 @@ protected function supportsTls13() } return false; } - - public function assertContainsString($needle, $haystack) - { - if (method_exists($this, 'assertStringContainsString')) { - // PHPUnit 7.5+ - $this->assertStringContainsString($needle, $haystack); - } else { - // legacy PHPUnit 4- PHPUnit 7.5 - $this->assertContains($needle, $haystack); - } - } - - public function assertMatchesRegExp($pattern, $string) - { - if (method_exists($this, 'assertMatchesRegularExpression')) { - // PHPUnit 10 - $this->assertMatchesRegularExpression($pattern, $string); - } else { - // legacy PHPUnit 4 - PHPUnit 9.2 - $this->assertRegExp($pattern, $string); - } - } - - public function assertDoesNotMatchRegExp($pattern, $string) - { - if (method_exists($this, 'assertDoesNotMatchRegularExpression')) { - // PHPUnit 10 - $this->assertDoesNotMatchRegularExpression($pattern, $string); - } else { - // legacy PHPUnit 4 - PHPUnit 9.2 - $this->assertNotRegExp($pattern, $string); - } - } } diff --git a/tests/TimeoutConnectorTest.php b/tests/TimeoutConnectorTest.php index f4c5dfc1..e121cab4 100644 --- a/tests/TimeoutConnectorTest.php +++ b/tests/TimeoutConnectorTest.php @@ -3,8 +3,12 @@ namespace React\Tests\Socket; use React\EventLoop\Loop; +use React\EventLoop\LoopInterface; +use React\EventLoop\TimerInterface; use React\Promise\Deferred; use React\Promise\Promise; +use React\Socket\ConnectionInterface; +use React\Socket\ConnectorInterface; use React\Socket\TimeoutConnector; use function React\Promise\reject; use function React\Promise\resolve; @@ -13,7 +17,7 @@ class TimeoutConnectorTest extends TestCase { public function testConstructWithoutLoopAssignsLoopAutomatically() { - $base = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $base = $this->createMock(ConnectorInterface::class); $connector = new TimeoutConnector($base, 0.01); @@ -21,16 +25,16 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $ref->setAccessible(true); $loop = $ref->getValue($connector); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testRejectsPromiseWithoutStartingTimerWhenWrappedConnectorReturnsRejectedPromise() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addTimer'); $loop->expects($this->never())->method('cancelTimer'); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn(reject(new \RuntimeException('Failed', 42))); $timeout = new TimeoutConnector($connector, 5.0, $loop); @@ -49,13 +53,13 @@ public function testRejectsPromiseWithoutStartingTimerWhenWrappedConnectorReturn public function testRejectsPromiseAfterCancellingTimerWhenWrappedConnectorReturnsPendingPromiseThatRejects() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(5.0, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); $deferred = new Deferred(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn($deferred->promise()); $timeout = new TimeoutConnector($connector, 5.0, $loop); @@ -76,12 +80,12 @@ public function testRejectsPromiseAfterCancellingTimerWhenWrappedConnectorReturn public function testResolvesPromiseWithoutStartingTimerWhenWrappedConnectorReturnsResolvedPromise() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->never())->method('addTimer'); $loop->expects($this->never())->method('cancelTimer'); - $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connection = $this->createMock(ConnectionInterface::class); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn(resolve($connection)); $timeout = new TimeoutConnector($connector, 5.0, $loop); @@ -98,20 +102,20 @@ public function testResolvesPromiseWithoutStartingTimerWhenWrappedConnectorRetur public function testResolvesPromiseAfterCancellingTimerWhenWrappedConnectorReturnsPendingPromiseThatResolves() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(5.0, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); $deferred = new Deferred(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn($deferred->promise()); $timeout = new TimeoutConnector($connector, 5.0, $loop); $promise = $timeout->connect('example.com:80'); - $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock(); + $connection = $this->createMock(ConnectionInterface::class); $deferred->resolve($connection); $resolved = null; @@ -125,8 +129,8 @@ public function testResolvesPromiseAfterCancellingTimerWhenWrappedConnectorRetur public function testRejectsPromiseAndCancelsPendingConnectionWhenTimeoutTriggers() { $timerCallback = null; - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.01, $this->callback(function ($callback) use (&$timerCallback) { $timerCallback = $callback; return true; @@ -134,7 +138,7 @@ public function testRejectsPromiseAndCancelsPendingConnectionWhenTimeoutTriggers $loop->expects($this->once())->method('cancelTimer')->with($timer); $cancelled = 0; - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn(new Promise(function () { }, function () use (&$cancelled) { ++$cancelled; throw new \RuntimeException(); @@ -163,13 +167,13 @@ public function testRejectsPromiseAndCancelsPendingConnectionWhenTimeoutTriggers public function testCancellingPromiseWillCancelPendingConnectionAndRejectPromise() { - $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $timer = $this->createMock(TimerInterface::class); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addTimer')->with(0.01, $this->anything())->willReturn($timer); $loop->expects($this->once())->method('cancelTimer')->with($timer); $cancelled = 0; - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn(new Promise(function () { }, function () use (&$cancelled) { ++$cancelled; throw new \RuntimeException('Cancelled'); @@ -206,7 +210,7 @@ public function testRejectionDuringConnectionShouldNotCreateAnyGarbageReferences } $connection = new Deferred(); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn($connection->promise()); $timeout = new TimeoutConnector($connector, 0.01); @@ -234,7 +238,7 @@ public function testRejectionDueToTimeoutShouldNotCreateAnyGarbageReferences() $connection = new Deferred(function () { throw new \RuntimeException('Connection cancelled'); }); - $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector = $this->createMock(ConnectorInterface::class); $connector->expects($this->once())->method('connect')->with('example.com:80')->willReturn($connection->promise()); $timeout = new TimeoutConnector($connector, 0); diff --git a/tests/UnixConnectorTest.php b/tests/UnixConnectorTest.php index d7e314a4..ad6b757a 100644 --- a/tests/UnixConnectorTest.php +++ b/tests/UnixConnectorTest.php @@ -2,6 +2,7 @@ namespace React\Tests\Socket; +use React\EventLoop\LoopInterface; use React\Socket\ConnectionInterface; use React\Socket\UnixConnector; @@ -15,7 +16,7 @@ class UnixConnectorTest extends TestCase */ public function setUpConnector() { - $this->loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $this->loop = $this->createMock(LoopInterface::class); $this->connector = new UnixConnector($this->loop); } @@ -27,7 +28,7 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $ref->setAccessible(true); $loop = $ref->getValue($connector); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); } public function testInvalid() @@ -35,7 +36,7 @@ public function testInvalid() $promise = $this->connector->connect('google.com:80'); $promise->then(null, $this->expectCallableOnceWithException( - 'RuntimeException' + \RuntimeException::class )); } @@ -44,7 +45,7 @@ public function testInvalidScheme() $promise = $this->connector->connect('tcp://google.com:80'); $promise->then(null, $this->expectCallableOnceWithException( - 'InvalidArgumentException', + \InvalidArgumentException::class, 'Given URI "tcp://google.com:80" is invalid (EINVAL)', defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) )); diff --git a/tests/UnixServerTest.php b/tests/UnixServerTest.php index 6d972b9f..0e71cef7 100644 --- a/tests/UnixServerTest.php +++ b/tests/UnixServerTest.php @@ -3,6 +3,7 @@ namespace React\Tests\Socket; use React\EventLoop\Loop; +use React\EventLoop\LoopInterface; use React\Socket\UnixServer; use React\Stream\DuplexResourceStream; use function React\Async\await; @@ -42,7 +43,7 @@ public function testConstructWithoutLoopAssignsLoopAutomatically() $ref->setAccessible(true); $loop = $ref->getValue($server); - $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); + $this->assertInstanceOf(LoopInterface::class, $loop); $server->close(); } @@ -241,7 +242,7 @@ public function testCtorAddsResourceToLoop() unlink(str_replace('unix://', '', $this->uds)); $this->uds = $this->getRandomSocketUri(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream'); new UnixServer($this->uds, $loop); @@ -249,26 +250,24 @@ public function testCtorAddsResourceToLoop() public function testCtorThrowsForInvalidAddressScheme() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); - $this->setExpectedException( - 'InvalidArgumentException', - 'Given URI "tcp://localhost:0" is invalid (EINVAL)', - defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22) - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Given URI "tcp://localhost:0" is invalid (EINVAL)'); + $this->expectExceptionCode(defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)); new UnixServer('tcp://localhost:0', $loop); } public function testCtorThrowsWhenPathIsNotWritableWithoutCallingCustomErrorHandler() { - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $error = null; set_error_handler(function ($_, $errstr) use (&$error) { $error = $errstr; }); - $this->setExpectedException('RuntimeException'); + $this->expectException(\RuntimeException::class); try { new UnixServer('/dev/null', $loop); @@ -287,7 +286,7 @@ public function testResumeWithoutPauseIsNoOp() unlink(str_replace('unix://', '', $this->uds)); $this->uds = $this->getRandomSocketUri(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream'); $server = new UnixServer($this->uds, $loop); @@ -299,7 +298,7 @@ public function testPauseRemovesResourceFromLoop() unlink(str_replace('unix://', '', $this->uds)); $this->uds = $this->getRandomSocketUri(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('removeReadStream'); $server = new UnixServer($this->uds, $loop); @@ -311,7 +310,7 @@ public function testPauseAfterPauseIsNoOp() unlink(str_replace('unix://', '', $this->uds)); $this->uds = $this->getRandomSocketUri(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('removeReadStream'); $server = new UnixServer($this->uds, $loop); @@ -324,7 +323,7 @@ public function testCloseRemovesResourceFromLoop() unlink(str_replace('unix://', '', $this->uds)); $this->uds = $this->getRandomSocketUri(); - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('removeReadStream'); $server = new UnixServer($this->uds, $loop); @@ -337,7 +336,7 @@ public function testEmitsErrorWhenAcceptListenerFailsWithoutCallingCustomErrorHa $this->uds = $this->getRandomSocketUri(); $listener = null; - $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $loop = $this->createMock(LoopInterface::class); $loop->expects($this->once())->method('addReadStream')->with($this->anything(), $this->callback(function ($cb) use (&$listener) { $listener = $cb; return true; @@ -367,7 +366,7 @@ public function testEmitsErrorWhenAcceptListenerFailsWithoutCallingCustomErrorHa $this->assertLessThan(1, $time); - $this->assertInstanceOf('RuntimeException', $exception); + $this->assertInstanceOf(\RuntimeException::class, $exception); assert($exception instanceof \RuntimeException); $this->assertStringStartsWith('Unable to accept new connection: ', $exception->getMessage()); @@ -391,7 +390,7 @@ public function testListenOnBusyPortThrows() $this->markTestSkipped('Windows supports listening on same port multiple times'); } - $this->setExpectedException('RuntimeException'); + $this->expectException(\RuntimeException::class); new UnixServer($this->uds); }