From ef58615bb56bf5d256343841be0ddf515d5c66a4 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Mon, 25 Feb 2019 08:54:50 +0100 Subject: [PATCH] feat: Support HTTPlug 2 / PSR-18 (#777) * Allow HTTPlug 2 * Fix tests to allow HTTPlug 2 * Add a CI job to test HTTPlug 2 * Use MockClient everywhere in tests * Remove curl client; revert adding a dedicated CI job for HTTPlug 2 * Increase php-http/discovery constraint * Move php-http/message as an explicit dependency * Address review * Require Curl client in CI to fix PHPStan analysis * Require fixed version of the Discovery package * Revert CI changes * Ignore PHPStan errors about missing Curl client class * Fix error found in review --- composer.json | 9 ++++----- phpstan.neon | 1 + src/ClientBuilder.php | 11 ++++++----- tests/ClientBuilderTest.php | 5 +++-- tests/bootstrap.php | 5 +++++ tests/phpt/fatal_error.phpt | 5 +---- tests/phpt/out_of_memory.phpt | 26 ++++++++++++-------------- 7 files changed, 32 insertions(+), 30 deletions(-) diff --git a/composer.json b/composer.json index 4871a35e6..d22ff95e2 100644 --- a/composer.json +++ b/composer.json @@ -21,9 +21,10 @@ "ext-mbstring": "*", "jean85/pretty-package-versions": "^1.2", "php-http/async-client-implementation": "^1.0", - "php-http/client-common": "^1.5", - "php-http/discovery": "^1.2", - "php-http/httplug": "^1.1", + "php-http/client-common": "^1.5|^2.0", + "php-http/discovery": "^1.6.1", + "php-http/httplug": "^1.1|^2.0", + "php-http/message": "^1.5", "psr/http-message-implementation": "^1.0", "ramsey/uuid": "^3.3", "symfony/options-resolver": "^2.7|^3.0|^4.0", @@ -32,8 +33,6 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^2.13", "monolog/monolog": "^1.3", - "php-http/curl-client": "^1.7.1", - "php-http/message": "^1.5", "php-http/mock-client": "^1.0", "phpstan/phpstan-phpunit": "^0.10", "phpstan/phpstan": "^0.10.3", diff --git a/phpstan.neon b/phpstan.neon index 44470014f..e6714eab8 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -8,6 +8,7 @@ parameters: - '/Argument of an invalid type object supplied for foreach, only iterables are supported/' - '/Binary operation "\*" between array and 2 results in an error\./' - '/Method Sentry\\Serializer\\RepresentationSerializer::(representationSerialize|serializeValue)\(\) should return [\w|]+ but returns [\w|]+/' + - '/Http\\Client\\Curl\\Client/' excludes_analyse: - tests/resources includes: diff --git a/src/ClientBuilder.php b/src/ClientBuilder.php index 33ab7c922..eb440736a 100644 --- a/src/ClientBuilder.php +++ b/src/ClientBuilder.php @@ -14,6 +14,7 @@ use Http\Client\Common\PluginClient; use Http\Client\Curl\Client as HttpCurlClient; use Http\Client\HttpAsyncClient; +use Http\Discovery\ClassDiscovery; use Http\Discovery\HttpAsyncClientDiscovery; use Http\Discovery\MessageFactoryDiscovery; use Http\Discovery\UriFactoryDiscovery; @@ -321,13 +322,13 @@ private function createTransportInstance(): TransportInterface throw new \RuntimeException('The `http_proxy` option does not work together with a custom client.'); } - if (HttpAsyncClientDiscovery::safeClassExists(HttpCurlClient::class)) { - $this->httpClient = new HttpCurlClient(null, null, [ - CURLOPT_PROXY => $this->options->getHttpProxy(), - ]); - } else { + if (!ClassDiscovery::safeClassExists(HttpCurlClient::class)) { throw new \RuntimeException('The `http_proxy` option requires the `php-http/curl-client` package to be installed.'); } + + $this->httpClient = new HttpCurlClient(null, null, [ + CURLOPT_PROXY => $this->options->getHttpProxy(), + ]); } $this->httpClient = $this->httpClient ?? HttpAsyncClientDiscovery::find(); diff --git a/tests/ClientBuilderTest.php b/tests/ClientBuilderTest.php index 9dad066f5..984b0ca14 100644 --- a/tests/ClientBuilderTest.php +++ b/tests/ClientBuilderTest.php @@ -9,6 +9,7 @@ use Http\Client\HttpAsyncClient; use Http\Message\MessageFactory; use Http\Message\UriFactory; +use Http\Promise\Promise; use Jean85\PrettyVersions; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -317,14 +318,14 @@ public function setupOnce(): void final class PluginStub1 implements Plugin { - public function handleRequest(RequestInterface $request, callable $next, callable $first) + public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise { } } final class PluginStub2 implements Plugin { - public function handleRequest(RequestInterface $request, callable $next, callable $first) + public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise { } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 57982bce2..166f1c4ba 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,8 +2,13 @@ declare(strict_types=1); +use Http\Discovery\ClassDiscovery; +use Http\Discovery\Strategy\MockClientStrategy; + error_reporting(E_ALL | E_STRICT); session_start(); require_once __DIR__ . '/../vendor/autoload.php'; + +ClassDiscovery::appendStrategy(MockClientStrategy::class); diff --git a/tests/phpt/fatal_error.phpt b/tests/phpt/fatal_error.phpt index 4d040c05f..4f8539179 100644 --- a/tests/phpt/fatal_error.phpt +++ b/tests/phpt/fatal_error.phpt @@ -17,10 +17,7 @@ while (!file_exists($vendor . '/vendor')) { require $vendor . '/vendor/autoload.php'; -init([ - 'dsn' => 'http://public:secret@local.host/1', - 'send_attempts' => 1, -]); +init(); ErrorHandler::addErrorListener(new StubErrorListener(function () { echo 'Listener called'; diff --git a/tests/phpt/out_of_memory.phpt b/tests/phpt/out_of_memory.phpt index 151cddbfb..ded7b8718 100644 --- a/tests/phpt/out_of_memory.phpt +++ b/tests/phpt/out_of_memory.phpt @@ -6,8 +6,9 @@ Test catching out of memory fatal error namespace Sentry\Tests; use PHPUnit\Framework\Assert; +use Sentry\Event; +use Sentry\Severity; use function Sentry\init; -use Sentry\State\Hub; ini_set('memory_limit', '20M'); @@ -20,23 +21,20 @@ while (!file_exists($vendor . '/vendor')) { require $vendor . '/vendor/autoload.php'; init([ - 'dsn' => 'http://public:secret@local.host/1', - 'send_attempts' => 1, -]); - -register_shutdown_function('register_shutdown_function', function () { - $client = Hub::getCurrent()->getClient(); + 'before_send' => function (Event $event): ?Event { + Assert::assertArrayHasKey(0, $event->getExceptions()); + $error = $event->getExceptions()[0]; + Assert::assertContains('Allowed memory size', $error['value']); + Assert::assertTrue($event->getLevel()->isEqualTo(Severity::fatal())); - /** @var \Sentry\Transport\HttpTransport $transport */ - $transport = Assert::getObjectAttribute($client, 'transport'); + echo 'Sending event'; - Assert::assertAttributeEmpty('pendingRequests', $transport); - - echo 'Shutdown function called'; -}); + return null; + }, +]); $foo = str_repeat('x', 1024 * 1024 * 30); ?> --EXPECTF-- Fatal error: Allowed memory size of %d bytes exhausted (tried to allocate %d bytes) in %s on line %d -Shutdown function called +Sending event