diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05134d6..43e3b8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,7 @@ jobs: with: php-version: ${{ matrix.php }} coverage: xdebug + ini-file: development - run: composer install - run: vendor/bin/phpunit --coverage-text if: ${{ matrix.php >= 7.3 }} @@ -57,7 +58,7 @@ jobs: continue-on-error: true steps: - uses: actions/checkout@v3 - - run: cp `which composer` composer.phar && ./composer.phar self-update --2.2 # downgrade Composer for HHVM + - 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: diff --git a/composer.json b/composer.json index ae325fc..8613aa9 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ "react/stream": "^1.2" }, "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", "react/async": "^4 || ^3 || ^2", "react/promise-stream": "^1.4" }, diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 93a36f6..7a9577e 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,8 +1,8 @@ - - +./src/ + + + + + + + + diff --git a/phpunit.xml.legacy b/phpunit.xml.legacy index fbb43e8..0d35225 100644 --- a/phpunit.xml.legacy +++ b/phpunit.xml.legacy @@ -15,4 +15,12 @@ ./src/ + + + + + + + + diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index dfd15ce..32d230c 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -3,6 +3,8 @@ namespace React\Tests\Socket; use React\Dns\Resolver\Factory as ResolverFactory; +use React\EventLoop\Loop; +use React\Socket\ConnectionInterface; use React\Socket\Connector; use React\Socket\DnsConnector; use React\Socket\SecureConnector; @@ -19,6 +21,7 @@ public function gettingStuffFromGoogleShouldWork() $connector = new Connector(array()); $conn = \React\Async\await($connector->connect('google.com:80')); + assert($conn instanceof ConnectionInterface); $this->assertContainsString(':80', $conn->getRemoteAddress()); $this->assertNotEquals('google.com:80', $conn->getRemoteAddress()); @@ -26,6 +29,7 @@ public function gettingStuffFromGoogleShouldWork() $conn->write("GET / HTTP/1.0\r\n\r\n"); $response = $this->buffer($conn, self::TIMEOUT); + assert(!$conn->isReadable()); $this->assertMatchesRegExp('#^HTTP/1\.0#', $response); } @@ -40,10 +44,12 @@ public function gettingEncryptedStuffFromGoogleShouldWork() $secureConnector = new Connector(array()); $conn = \React\Async\await($secureConnector->connect('tls://google.com:443')); + assert($conn instanceof ConnectionInterface); $conn->write("GET / HTTP/1.0\r\n\r\n"); $response = $this->buffer($conn, self::TIMEOUT); + assert(!$conn->isReadable()); $this->assertMatchesRegExp('#^HTTP/1\.0#', $response); } @@ -66,10 +72,12 @@ public function gettingEncryptedStuffFromGoogleShouldWorkIfHostIsResolvedFirst() ); $conn = \React\Async\await($connector->connect('google.com:443')); + assert($conn instanceof ConnectionInterface); $conn->write("GET / HTTP/1.0\r\n\r\n"); $response = $this->buffer($conn, self::TIMEOUT); + assert(!$conn->isReadable()); $this->assertMatchesRegExp('#^HTTP/1\.0#', $response); } @@ -80,6 +88,7 @@ public function gettingPlaintextStuffFromEncryptedGoogleShouldNotWork() $connector = new Connector(array()); $conn = \React\Async\await($connector->connect('google.com:443')); + assert($conn instanceof ConnectionInterface); $this->assertContainsString(':443', $conn->getRemoteAddress()); $this->assertNotEquals('google.com:443', $conn->getRemoteAddress()); @@ -87,6 +96,7 @@ public function gettingPlaintextStuffFromEncryptedGoogleShouldNotWork() $conn->write("GET / HTTP/1.0\r\n\r\n"); $response = $this->buffer($conn, self::TIMEOUT); + assert(!$conn->isReadable()); $this->assertDoesNotMatchRegExp('#^HTTP/1\.0#', $response); } @@ -148,6 +158,13 @@ public function testWaitingForRejectedConnectionShouldNotCreateAnyGarbageReferen $this->markTestSkipped('Not supported on legacy Promise v1 API'); } + // 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)); + Loop::run(); + } + $connector = new Connector(array('timeout' => false)); gc_collect_cycles(); @@ -377,6 +394,7 @@ public function testSelfSignedResolvesIfVerificationIsDisabled() )); $conn = \React\Async\await(\React\Promise\Timer\timeout($connector->connect('tls://self-signed.badssl.com:443'), self::TIMEOUT)); + assert($conn instanceof ConnectionInterface); $conn->close(); // if we reach this, then everything is good diff --git a/tests/TestCase.php b/tests/TestCase.php index b5725f9..5b02e37 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -75,7 +75,7 @@ protected function buffer(ReadableStreamInterface $stream, $timeout) return ''; } - return \React\Async\await(\React\Promise\Timer\timeout(new Promise( + $buffer = \React\Async\await(\React\Promise\Timer\timeout(new Promise( function ($resolve, $reject) use ($stream) { $buffer = ''; $stream->on('data', function ($chunk) use (&$buffer) { @@ -93,6 +93,14 @@ function () use ($stream) { throw new \RuntimeException(); } ), $timeout)); + + // 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)); + } + + return $buffer; } public function setExpectedException($exception, $exceptionMessage = '', $exceptionCode = null)