From cfda672c940a63ddbc2219902d0dee017b5b96ef Mon Sep 17 00:00:00 2001 From: Allison Guilhem Date: Tue, 26 Dec 2023 22:55:13 +1100 Subject: [PATCH] long running process doctrine connection listener --- DependencyInjection/DoctrineExtension.php | 4 + Resources/config/middlewares.xml | 5 + Tests/DoctrineConnectionMiddlewareTest.php | 119 +++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 Tests/DoctrineConnectionMiddlewareTest.php diff --git a/DependencyInjection/DoctrineExtension.php b/DependencyInjection/DoctrineExtension.php index 044235f3..95d5d981 100644 --- a/DependencyInjection/DoctrineExtension.php +++ b/DependencyInjection/DoctrineExtension.php @@ -537,6 +537,10 @@ protected function ormLoad(array $config, ContainerBuilder $container) $container->removeDefinition('doctrine.mapping_import_command'); } + if (!$container->hasParameter('kernel.runtime_mode') || !$container->hasParameter('kernel.runtime_mode.worker')) { + $container->removeDefinition('doctrine.dbal.connection_middleware'); + } + $entityManagers = []; foreach (array_keys($config['entity_managers']) as $name) { /** @psalm-suppress InvalidArrayOffset */ diff --git a/Resources/config/middlewares.xml b/Resources/config/middlewares.xml index d6bf92bc..f89eccbe 100644 --- a/Resources/config/middlewares.xml +++ b/Resources/config/middlewares.xml @@ -17,5 +17,10 @@ + + + + + diff --git a/Tests/DoctrineConnectionMiddlewareTest.php b/Tests/DoctrineConnectionMiddlewareTest.php new file mode 100644 index 00000000..5e99ab02 --- /dev/null +++ b/Tests/DoctrineConnectionMiddlewareTest.php @@ -0,0 +1,119 @@ +createMock(AbstractPlatform::class); + $platform->method('getDummySelectSQL')->willReturn('SELECT 1'); + + $this->managerRegistryMock = $this->createMock(ManagerRegistry::class); + $this->connectionMock = $this->createMock(Connection::class); + $this->connectionMock->method('getDatabasePlatform')->willReturn($platform); + $connectionDriverMock = $this->createMock(Driver\Connection::class); + + $this->container = new Container(); + $this->container->set(self::CONNECTION_NAME, $this->connectionMock); + + $this->managerRegistryMock->method('getConnectionNames')->willReturn([self::CONNECTION_NAME]); + $this->managerRegistryMock->method('getManagerNames')->willReturn([self::MANAGER_NAME]); + + $this->driver = $this->createMock(Driver::class); + $this->driver->method('connect')->willReturn($connectionDriverMock); + + $this->doctrineConnectionDriver = new DoctrineConnectionDriver($this->driver, $this->managerRegistryMock, $this->container); + } + + public function testSkipNotInitializedConnections() + { + $this->container->set(self::CONNECTION_NAME, null); + + $this->connectionMock->expects($this->never())->method('isConnected'); + $this->connectionMock->expects($this->never())->method('executeQuery'); + $this->connectionMock->expects($this->never())->method('close'); + $this->connectionMock->expects($this->never())->method('connect'); + + $this->doctrineConnectionDriver->connect([]); + } + + public function testSkipWhenNotConnected(): void + { + $this->connectionMock->method('isConnected')->willReturn(false); + $this->connectionMock->expects($this->never())->method('executeQuery'); + $this->connectionMock->expects($this->never())->method('close'); + $this->connectionMock->expects($this->never())->method('connect'); + + $this->doctrineConnectionDriver->connect([]); + } + + public function testItClosesNotPingableConnection(): void + { + $this->connectionMock->expects($this->exactly(2))->method('executeQuery') + ->willReturnCallback(function () { + static $counter = 0; + + if (1 === ++$counter) { + throw $this->createMock(DBALException::class); + } + + return $this->createMock(Result::class); + }); + + $this->connectionMock->method('isConnected')->willReturn(true); + $this->connectionMock->expects($this->once())->method('close'); + $this->connectionMock->expects($this->never())->method('connect'); + + $this->doctrineConnectionDriver->connect([]); + } + + public function testItDoesNotClosePingableConnection(): void + { + $this->connectionMock->expects($this->once())->method('executeQuery'); + $this->connectionMock->method('isConnected')->willReturn(true); + $this->connectionMock->expects($this->never())->method('close'); + $this->connectionMock->expects($this->never())->method('connect'); + + $this->doctrineConnectionDriver->connect([]); + } + + public function testItForcesRebootOnClosedManagerWhenMissingProxySupport() + { + $manager = $this->createMock(EntityManagerInterface::class); + $this->container->set(self::MANAGER_NAME, $manager); + + $manager->expects($this->once())->method('isOpen')->willReturn(false); + $this->managerRegistryMock->expects($this->once()) + ->method('resetManager') + ->with(self::MANAGER_NAME) + ; + + $this->doctrineConnectionDriver->connect([]); + } +}