From b5d318f4542c39c11bee804ee07d4b5ebbd31835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C5=82adzimir=20Tsykun?= Date: Sun, 8 Oct 2023 14:49:25 +0200 Subject: [PATCH] Symfony 7.0 support --- .gitignore | 1 + README.md | 25 ------- composer.json | 24 +++--- src/Client/ClientWrapper.php | 2 +- src/Client/DatadogDns.php | 13 ++++ src/Client/DatadogFactory.php | 15 ++++ src/Client/DatadogFactoryInterface.php | 10 +++ src/DependencyInjection/Configuration.php | 4 +- src/Logging/ErrorBag.php | 2 +- src/Logging/Watcher/DefaultWatcher.php | 2 +- src/Services/ExceptionHashService.php | 3 +- .../App/Controller/AppDatadogController.php | 6 ++ tests/Functional/App/Entity/DatadogUser.php | 5 ++ tests/Functional/App/OkvpnKernel.php | 43 +++++++---- tests/Functional/App/config6.yml | 75 +++++++++++++++++++ tests/Functional/IntegrationTest.php | 24 ++++-- 16 files changed, 188 insertions(+), 66 deletions(-) create mode 100644 src/Client/DatadogDns.php create mode 100644 src/Client/DatadogFactory.php create mode 100644 src/Client/DatadogFactoryInterface.php create mode 100644 tests/Functional/App/config6.yml diff --git a/.gitignore b/.gitignore index aec80a4..72bb2dd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /composer.lock /vendor/* /var/* +.phpunit.result.cache diff --git a/README.md b/README.md index 5401e9a..6142922 100644 --- a/README.md +++ b/README.md @@ -35,31 +35,6 @@ return [ ] ``` -For Symfony 3.4 - -```php -load($this->getRootDir().'/config/config_'.$this->getEnvironment().'.yml'); - } -} -``` - 3. Base configuration to enable the datadog client in your `config.yml` ``` diff --git a/composer.json b/composer.json index 55a3745..7e2762d 100644 --- a/composer.json +++ b/composer.json @@ -20,21 +20,21 @@ "psr-4": { "Okvpn\\Bundle\\DatadogBundle\\Tests\\": "tests/" } }, "require": { - "php":">=7.2", - "symfony/framework-bundle": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", + "php":">=7.4", + "symfony/framework-bundle": "^4.4 || ^5.4 || ^6.0 || ^7.0", "graze/dog-statsd": "^0.4 || ^1.0" }, "require-dev": { "ext-pdo_sqlite": "*", - "doctrine/doctrine-bundle": "^1.6.10 || ^2.0.6", - "doctrine/orm": "2.5.11 || 2.6.x-dev as 2.6.3 || ^2.7.0", - "phpunit/phpunit": "^6.2 || ^8.5", - "symfony/browser-kit": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "symfony/console": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "symfony/security-bundle": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "symfony/phpunit-bridge": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "symfony/monolog-bundle": "^3.2.0" + "doctrine/doctrine-bundle": "^2.6", + "doctrine/orm": "^2.7", + "phpunit/phpunit": "^8.5 || ^10.0", + "symfony/browser-kit": "^4.4 || ^5.4 || ^6.0 || ^7.0", + "symfony/console": "^4.4 || ^5.4 || ^6.0 || ^7.0", + "symfony/security-bundle": "^4.4 || ^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^4.4 || ^5.4 || ^6.0 || ^7.0", + "symfony/var-dumper": "^4.4 || ^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^4.4 || ^5.4 || ^6.0 || ^7.0", + "symfony/monolog-bundle": "^3.2" } } diff --git a/src/Client/ClientWrapper.php b/src/Client/ClientWrapper.php index 503c8da..d38ed2b 100644 --- a/src/Client/ClientWrapper.php +++ b/src/Client/ClientWrapper.php @@ -81,7 +81,7 @@ public function event($title, $text, array $metadata = [], array $tags = []) */ public function getOption(string $option, $default = null) { - return isset($this->options[$option]) ? $this->options[$option] : $default; + return $this->options[$option] ?? $default; } /** diff --git a/src/Client/DatadogDns.php b/src/Client/DatadogDns.php new file mode 100644 index 0000000..f53611d --- /dev/null +++ b/src/Client/DatadogDns.php @@ -0,0 +1,13 @@ +getRootNode() : - $treeBuilder->root('okvpn_datadog'); + $rootNode = $treeBuilder->getRootNode(); $rootNode->children() ->arrayNode('handle_exceptions') diff --git a/src/Logging/ErrorBag.php b/src/Logging/ErrorBag.php index d615b64..36146e6 100644 --- a/src/Logging/ErrorBag.php +++ b/src/Logging/ErrorBag.php @@ -35,7 +35,7 @@ public function flush(): void public function rootError(): ?array { - return isset($this->errors[0]) ? $this->errors[0] : null; + return $this->errors[0] ?? null; } public function getErrors(): array diff --git a/src/Logging/Watcher/DefaultWatcher.php b/src/Logging/Watcher/DefaultWatcher.php index b30dd45..711a9e1 100644 --- a/src/Logging/Watcher/DefaultWatcher.php +++ b/src/Logging/Watcher/DefaultWatcher.php @@ -49,7 +49,7 @@ public function watch(): array $context = []; if ($this->tokenStorage instanceof TokenStorageInterface) { $token = $this->tokenStorage->getToken(); - if (null !== $token) { + if (null !== $token) { $context['token'] = method_exists($token, '__toString') ? $token->__toString() : $token->serialize(); } } diff --git a/src/Services/ExceptionHashService.php b/src/Services/ExceptionHashService.php index 748664d..575f4d8 100644 --- a/src/Services/ExceptionHashService.php +++ b/src/Services/ExceptionHashService.php @@ -36,7 +36,6 @@ public function hash(\Throwable $exception): string } } - $hash = sha1($hash); - return $hash; + return sha1($hash); } } diff --git a/tests/Functional/App/Controller/AppDatadogController.php b/tests/Functional/App/Controller/AppDatadogController.php index 1a8d6c8..b11b283 100644 --- a/tests/Functional/App/Controller/AppDatadogController.php +++ b/tests/Functional/App/Controller/AppDatadogController.php @@ -4,6 +4,7 @@ namespace Okvpn\Bundle\DatadogBundle\Tests\Functional\App\Controller; +use Doctrine\Persistence\ManagerRegistry; use Okvpn\Bundle\DatadogBundle\Tests\Functional\App\Entity\DatadogUser; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\Controller; @@ -39,6 +40,11 @@ public function entity() class AppDatadogController extends AbstractController { use AppDatadogControllerTrait; + + public function getDoctrine(): ManagerRegistry + { + return $this->container->get('doctrine'); + } } } else { class AppDatadogController extends Controller diff --git a/tests/Functional/App/Entity/DatadogUser.php b/tests/Functional/App/Entity/DatadogUser.php index 23081f2..17f1fee 100644 --- a/tests/Functional/App/Entity/DatadogUser.php +++ b/tests/Functional/App/Entity/DatadogUser.php @@ -9,6 +9,7 @@ /** * @ORM\Entity */ +#[ORM\Entity] class DatadogUser { /** @@ -18,6 +19,9 @@ class DatadogUser * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ + #[ORM\Column('id', type: 'integer')] + #[ORM\Id] + #[ORM\CustomIdGenerator] private $id; /** @@ -25,6 +29,7 @@ class DatadogUser * * @ORM\Column(type="string", length=64) */ + #[ORM\Column('username', type: 'string', length: 64)] private $username; /** diff --git a/tests/Functional/App/OkvpnKernel.php b/tests/Functional/App/OkvpnKernel.php index 5e5a8df..567ea8f 100644 --- a/tests/Functional/App/OkvpnKernel.php +++ b/tests/Functional/App/OkvpnKernel.php @@ -7,28 +7,45 @@ use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouteCollectionBuilder; -trait OkvpnKernelTrait -{ +if (Kernel::MAJOR_VERSION >= 5) { + trait OkvpnKernelTrait + { + public function loadRoutes() + { + $routes = new RouteCollection(); - /** - * @param LoaderInterface $loader - * @return RouteCollection - */ - public function loadRoutes(LoaderInterface $loader) + $routes->add('index', $this->createRoute("/", "app.controller.base_controller::index")); + $routes->add("exception", $this->createRoute('/exception', "app.controller.base_controller::exception")); + $routes->add("entity", $this->createRoute('/entity', "app.controller.base_controller::entity")); + return $routes; + } + + private function createRoute(string $path, string $controller): Route + { + return new Route($path, ['_controller' => $controller]); + } + } +} else { + trait OkvpnKernelTrait { - $routes = new RouteCollectionBuilder($loader); + public function loadRoutes(LoaderInterface $loader) + { + $routes = new RouteCollectionBuilder($loader); - $routes->add('/', "app.controller.base_controller:index"); - $routes->add('/exception', "app.controller.base_controller:exception"); - $routes->add('/entity', "app.controller.base_controller:entity"); + $routes->add('/', "app.controller.base_controller:index"); + $routes->add('/exception', "app.controller.base_controller:exception"); + $routes->add('/entity', "app.controller.base_controller:entity"); - return $routes->build(); + return $routes->build(); + } } } + class OkvpnKernel extends Kernel { use OkvpnKernelTrait; @@ -58,7 +75,7 @@ public function registerContainerConfiguration(LoaderInterface $loader) $container->addObjectResource($this); $container->loadFromExtension('framework', [ 'router' => [ - 'resource' => self::VERSION_ID > 40000 ? AppKernelRouting::class . '::loadRoutes' : 'kernel:loadRoutes', + 'resource' => AppKernelRouting::class . '::loadRoutes', 'type' => 'service', ], ]); diff --git a/tests/Functional/App/config6.yml b/tests/Functional/App/config6.yml new file mode 100644 index 0000000..0b4626b --- /dev/null +++ b/tests/Functional/App/config6.yml @@ -0,0 +1,75 @@ +framework: + secret: test + test: true + default_locale: en + profiler: { collect: true } + session: + storage_factory_id: session.storage.factory.mock_file + +doctrine: + dbal: + driver: 'pdo_sqlite' + path: '%kernel.project_dir%/test.db' + orm: + auto_generate_proxy_classes: '%kernel.debug%' + naming_strategy: doctrine.orm.naming_strategy.underscore + auto_mapping: true + mappings: + App: + is_bundle: false + dir: '%kernel.project_dir%/Entity' + prefix: 'Okvpn\Bundle\DatadogBundle\Tests\Functional\App\Entity' + +monolog: + handlers: + nested: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + +security: + providers: + in_memory: + memory: ~ + firewalls: + main: + lazy: true + provider: in_memory + +okvpn_datadog: + profiling: true + namespace: app + dedup_keep_time: 5 + handle_exceptions: + skip_instanceof: + - 'Okvpn\Bundle\DatadogBundle\Tests\Functional\App\Command\DemoDatadogExceptionInterface' + skip_capture: + - 'UnderflowException' + skip_wildcard: + - '*entity aliases failed*' + +parameters: + request_listener.http_port: 80 + request_listener.https_port: 443 + +services: + okvpn_datadog.client_test_decorator: + class: Okvpn\Bundle\DatadogBundle\Tests\Functional\App\Client\DebugDatadogClient + decorates: okvpn_datadog.client + public: true + arguments: ['@okvpn_datadog.client_test_decorator.inner'] + + app.command.exception_command: + class: Okvpn\Bundle\DatadogBundle\Tests\Functional\App\Command\DatadogExceptionCommand + arguments: ['@logger'] + tags: + - { name: console.command } + + app.controller.base_controller: + class: Okvpn\Bundle\DatadogBundle\Tests\Functional\App\Controller\AppDatadogController + public: true + calls: + - [setContainer, ['@service_container']] + + Okvpn\Bundle\DatadogBundle\Tests\Functional\App\AppKernelRouting: + tags: [routing.route_loader] diff --git a/tests/Functional/IntegrationTest.php b/tests/Functional/IntegrationTest.php index f0ecf48..df42ae9 100644 --- a/tests/Functional/IntegrationTest.php +++ b/tests/Functional/IntegrationTest.php @@ -6,7 +6,6 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Tools\SchemaTool; -use Symfony\Bundle\FrameworkBundle\Client; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\KernelBrowser; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; @@ -16,7 +15,7 @@ class IntegrationTest extends WebTestCase { - /** @var Client|KernelBrowser */ + /** @var KernelBrowser */ private $client; /** @@ -87,10 +86,10 @@ public function testHandleConsoleException() $this->runCommand('app:exception'); } catch (\Throwable $exception) {} - list($title, $desc) = $this->getClientDecorator()->getLastEvent(); + [$title, $desc] = $this->getClientDecorator()->getLastEvent(); self::assertNotEmpty($this->getClientDecorator()->getRecords()); - self::assertContains('Call to undefined function function_do_not_exists', $desc); + self::assertContainsStr('Call to undefined function function_do_not_exists', $desc); } public function testDeduplicationLogger() @@ -103,12 +102,12 @@ public function testDeduplicationLogger() $this->client->request('GET', '/exception'); } catch (\Exception $exception) {} - list($title, $desc) = $this->getClientDecorator()->getLastEvent(); + [$title, $desc] = $this->getClientDecorator()->getLastEvent(); $desc = $desc ? $this->processDatadogArtifact($desc) : $desc; switch ($i) { case 0: self::assertNotEmpty($this->getClientDecorator()->getRecords()); - self::assertContains('GET /exception HTTP/1.1', $desc, 'Request details must be save in log'); + self::assertContainsStr('GET /exception HTTP/1.1', $desc, 'Request details must be save in log'); sleep(1); break; case 1: @@ -136,11 +135,11 @@ public function testFilterException(string $filterOption, bool $isSkip) } - list($title, $desc) = $this->getClientDecorator()->getLastEvent(); + [$title, $desc] = $this->getClientDecorator()->getLastEvent(); self::assertSame($isSkip, empty($desc)); } - public function filterExceptionDataProvider() + public static function filterExceptionDataProvider() { yield 'Filter by instanceof' => ['skip_instanceof', true]; @@ -271,4 +270,13 @@ protected function getClientDecorator() { return $this->client->getContainer()->get('okvpn_datadog.client_test_decorator'); } + + protected static function assertContainsStr(string $needle, mixed $haystack, string $message = '') + { + if (method_exists(__CLASS__, 'assertStringContainsString')) { + self::assertStringContainsString($needle, $haystack, $message); + } else { + self::assertContains($needle, $haystack, $message); + } + } }