From ab80123b6cd333206f3d386ff977b18d6346f187 Mon Sep 17 00:00:00 2001 From: exaby73 Date: Wed, 14 Aug 2024 12:19:46 +0530 Subject: [PATCH 1/9] fix: Existing integration tests --- docker-compose.yml | 5 +- tests/App/config/default.yml | 84 +++++++++---------- .../{Integration.php => IntegrationTest.php} | 32 +++++-- 3 files changed, 69 insertions(+), 52 deletions(-) rename tests/Functional/{Integration.php => IntegrationTest.php} (68%) diff --git a/docker-compose.yml b/docker-compose.yml index ae9637b..8e5b808 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +1,9 @@ -version: '3.7' networks: neo4j-symfony: services: app: - user: ${UID-1000}:${GID-1000} + user: root:${UID-1000}:${GID-1000} build: context: . ports: @@ -24,7 +23,7 @@ services: neo4j: environment: - NEO4J_AUTH=neo4j/testtest - image: neo4j:5 + image: neo4j:5.22 ports: - ${DOCKER_HOST_NEO4J_HTTP_PORT:-7474}:7474 - ${DOCKER_HOST_NEO4J_BOLT_PORT:-7687}:7687 diff --git a/tests/App/config/default.yml b/tests/App/config/default.yml index 8fc729e..9978e92 100644 --- a/tests/App/config/default.yml +++ b/tests/App/config/default.yml @@ -1,46 +1,44 @@ framework: - secret: test - test: true + secret: test + test: true neo4j: - default_driver: neo4j-test - default_driver_config: - acquire_connection_timeout: 10 - user_agent: 'Neo4j Symfony Bundle/testing' - pool_size: 256 - ssl: - mode: enable - verify_peer: false - default_session_config: - fetch_size: 999 - access_mode: read - database: symfony - default_transaction_config: - timeout: 40 - - drivers: - - alias: neo4j_undefined_configs - dsn: bolt://localhost - - - alias: neo4j-enforced-defaults - dsn: bolt://localhost - priority: null - - - alias: neo4j-partly-enforced-defaults - dsn: neo4j://neo4j:secret@localhost:7688 - - - alias: neo4j-simple - dsn: 'bolt://test:test@localhost' - - - alias: neo4j-fallback-mechanism - priority: 100 - dsn: bolt://localhost - - - alias: neo4j-fallback-mechanism - priority: 1000 - dsn: bolt://localhost - - - alias: neo4j-test - dsn: neo4j://neo4j:testtest@neo4j - - + default_driver: neo4j-test + default_driver_config: + acquire_connection_timeout: 10 + user_agent: "Neo4j Symfony Bundle/testing" + pool_size: 256 + ssl: + mode: disable + verify_peer: false + default_session_config: + fetch_size: 999 + access_mode: read + database: neo4j + default_transaction_config: + timeout: 40 + + drivers: + - alias: neo4j_undefined_configs + dsn: bolt://localhost + + - alias: neo4j-enforced-defaults + dsn: bolt://localhost + priority: null + + - alias: neo4j-partly-enforced-defaults + dsn: neo4j://neo4j:secret@localhost:7688 + + - alias: neo4j-simple + dsn: "bolt://test:test@localhost" + + - alias: neo4j-fallback-mechanism + priority: 100 + dsn: bolt://localhost + + - alias: neo4j-fallback-mechanism + priority: 1000 + dsn: bolt://localhost + + - alias: neo4j-test + dsn: neo4j://neo4j:testtest@neo4j diff --git a/tests/Functional/Integration.php b/tests/Functional/IntegrationTest.php similarity index 68% rename from tests/Functional/Integration.php rename to tests/Functional/IntegrationTest.php index be817d6..507702b 100644 --- a/tests/Functional/Integration.php +++ b/tests/Functional/IntegrationTest.php @@ -6,10 +6,12 @@ use Laudis\Neo4j\Contracts\ClientInterface; use Laudis\Neo4j\Contracts\DriverInterface; +use Laudis\Neo4j\Neo4j\Neo4jDriver; use Neo4j\Neo4jBundle\Tests\App\TestKernel; +use Psr\Http\Message\UriInterface; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; -class Integration extends KernelTestCase +class IntegrationTest extends KernelTestCase { protected static function getKernelClass(): string { @@ -57,10 +59,22 @@ public function testDefaultDsn(): void static::bootKernel(); $container = static::getContainer(); + /** + * @var ClientInterface $client + */ $client = $container->get('neo4j.client'); - $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage("Cannot connect to any server on alias: neo4j_undefined_configs with Uris: ('bolt://localhost')"); - $client->getDriver('default'); + /** + * @var Neo4jDriver $driver + */ + $driver = $client->getDriver('default'); + $reflection = new \ReflectionClass($driver); + $property = $reflection->getProperty('parsedUrl'); + /** + * @var UriInterface $uri + */ + $uri = $property->getValue($driver); + + $this->assertSame($uri->getScheme(), 'neo4j'); } public function testDsn(): void @@ -69,8 +83,14 @@ public function testDsn(): void $container = static::getContainer(); $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage("Cannot connect to any server on alias: neo4j_undefined_configs with Uris: ('bolt://localhost')"); + $this->expectExceptionMessage( + "Cannot connect to any server on alias: neo4j_undefined_configs with Uris: ('bolt://localhost')" + ); - $container->get('neo4j.driver'); + /** + * @var ClientInterface $client + */ + $client = $container->get('neo4j.client'); + $client->getDriver('neo4j_undefined_configs'); } } From 017e120ea6d6f31f6afefcfe76f8e4a14e9d214e Mon Sep 17 00:00:00 2001 From: exaby73 Date: Wed, 14 Aug 2024 12:24:39 +0530 Subject: [PATCH 2/9] feat: Add service container for GitHub action --- .github/workflows/tests.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c89878a..e53622f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,10 +11,12 @@ jobs: build: name: Build runs-on: ubuntu-latest + env: + NEO4J_AUTH: neo4j/testtest strategy: max-parallel: 10 matrix: - php: [ '8.1', '8.2', '8.3'] + php: [ '8.1', '8.2', '8.3' ] sf_version: [ '5.4', '6.4', '7.1' ] exclude: - php: 8.1 @@ -40,3 +42,10 @@ jobs: memory_limit: 1024M version: 9 bootstrap: vendor/autoload.php + + services: + neo4j: + image: neo4j:5.22 + ports: + - 7474:7474 + - 7687:7687 From 3abaf4d283056daf1ff14df1df679a0d45a55e92 Mon Sep 17 00:00:00 2001 From: exaby73 Date: Wed, 14 Aug 2024 12:27:25 +0530 Subject: [PATCH 3/9] feat: Add health check to service container --- .github/workflows/tests.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e53622f..7cb9b14 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -46,6 +46,13 @@ jobs: services: neo4j: image: neo4j:5.22 + options: >- + --hostname neo4j + --health-cmd "wget -q --method=HEAD http://localhost:7474 || exit 1" + --health-start-period "60s" + --health-interval "30s" + --health-timeout "15s" + --health-retries "5" ports: - 7474:7474 - 7687:7687 From 3ab5e78f77748c038a1be638652427f53deb9de4 Mon Sep 17 00:00:00 2001 From: exaby73 Date: Wed, 14 Aug 2024 12:34:36 +0530 Subject: [PATCH 4/9] fix: Auth env for service container --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7cb9b14..cf4df11 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,8 +11,6 @@ jobs: build: name: Build runs-on: ubuntu-latest - env: - NEO4J_AUTH: neo4j/testtest strategy: max-parallel: 10 matrix: @@ -46,6 +44,8 @@ jobs: services: neo4j: image: neo4j:5.22 + env: + NEO4J_AUTH: neo4j/testtest options: >- --hostname neo4j --health-cmd "wget -q --method=HEAD http://localhost:7474 || exit 1" From 0de2bcb351def7dd8de44e809208a61100e6020e Mon Sep 17 00:00:00 2001 From: exaby73 Date: Wed, 14 Aug 2024 16:08:59 +0530 Subject: [PATCH 5/9] feat: Add configs for CI --- .github/workflows/tests.yml | 3 +++ tests/App/TestKernel.php | 3 +++ tests/App/config/ci/default.yml | 3 +++ tests/App/config/default.yml | 20 +++++++++++++------- 4 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 tests/App/config/ci/default.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cf4df11..1aa931e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,6 +11,9 @@ jobs: build: name: Build runs-on: ubuntu-latest + env: + APP_ENV: ci + strategy: max-parallel: 10 matrix: diff --git a/tests/App/TestKernel.php b/tests/App/TestKernel.php index 8c2e86c..d8192cd 100644 --- a/tests/App/TestKernel.php +++ b/tests/App/TestKernel.php @@ -22,5 +22,8 @@ public function registerBundles(): array public function registerContainerConfiguration(LoaderInterface $loader): void { $loader->load(__DIR__.'/config/default.yml'); + if ('ci' === $this->environment) { + $loader->load(__DIR__.'/config/ci/default.yml'); + } } } diff --git a/tests/App/config/ci/default.yml b/tests/App/config/ci/default.yml new file mode 100644 index 0000000..cc4f3a4 --- /dev/null +++ b/tests/App/config/ci/default.yml @@ -0,0 +1,3 @@ +parameters: + neo4j.dsn.badname: bolt://localhostt + neo4j.dsn.test: neo4j://neo4j:testtest@localhost diff --git a/tests/App/config/default.yml b/tests/App/config/default.yml index 9978e92..f3f3429 100644 --- a/tests/App/config/default.yml +++ b/tests/App/config/default.yml @@ -2,6 +2,12 @@ framework: secret: test test: true +parameters: + neo4j.dsn.badname: bolt://localhost + neo4j.dsn.secret: neo4j://neo4j:secret@localhost:7688 + neo4j.dsn.test: neo4j://neo4j:testtest@neo4j + neo4j.dsn.simple: bolt://test:test@localhost + neo4j: default_driver: neo4j-test default_driver_config: @@ -20,25 +26,25 @@ neo4j: drivers: - alias: neo4j_undefined_configs - dsn: bolt://localhost + dsn: '%neo4j.dsn.badname%' - alias: neo4j-enforced-defaults - dsn: bolt://localhost + dsn: '%neo4j.dsn.badname%' priority: null - alias: neo4j-partly-enforced-defaults - dsn: neo4j://neo4j:secret@localhost:7688 + dsn: '%neo4j.dsn.secret%' - alias: neo4j-simple - dsn: "bolt://test:test@localhost" + dsn: '%neo4j.dsn.simple%' - alias: neo4j-fallback-mechanism priority: 100 - dsn: bolt://localhost + dsn: '%neo4j.dsn.badname%' - alias: neo4j-fallback-mechanism priority: 1000 - dsn: bolt://localhost + dsn: '%neo4j.dsn.badname%' - alias: neo4j-test - dsn: neo4j://neo4j:testtest@neo4j + dsn: '%neo4j.dsn.test%' From 1e808d52899082c3c0508ea8d144142af7feba37 Mon Sep 17 00:00:00 2001 From: exaby73 Date: Wed, 14 Aug 2024 16:18:56 +0530 Subject: [PATCH 6/9] fix: Expected exception message for CI --- tests/Functional/IntegrationTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/IntegrationTest.php b/tests/Functional/IntegrationTest.php index 507702b..720f865 100644 --- a/tests/Functional/IntegrationTest.php +++ b/tests/Functional/IntegrationTest.php @@ -83,8 +83,8 @@ public function testDsn(): void $container = static::getContainer(); $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage( - "Cannot connect to any server on alias: neo4j_undefined_configs with Uris: ('bolt://localhost')" + $this->expectExceptionMessageMatches( + "/Cannot connect to any server on alias: neo4j_undefined_configs with Uris: \('bolt:\/\/(localhost|localhostt)'\)/" ); /** From 6e9377ff9fa0ef12474b6743d8bde2628071cf62 Mon Sep 17 00:00:00 2001 From: exaby73 Date: Wed, 21 Aug 2024 11:14:39 +0530 Subject: [PATCH 7/9] test: Add tests for default configs --- tests/App/config/default.yml | 14 ++-- tests/Functional/IntegrationTest.php | 96 +++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/tests/App/config/default.yml b/tests/App/config/default.yml index f3f3429..2c37002 100644 --- a/tests/App/config/default.yml +++ b/tests/App/config/default.yml @@ -26,25 +26,25 @@ neo4j: drivers: - alias: neo4j_undefined_configs - dsn: '%neo4j.dsn.badname%' + dsn: "%neo4j.dsn.badname%" - alias: neo4j-enforced-defaults - dsn: '%neo4j.dsn.badname%' + dsn: "%neo4j.dsn.badname%" priority: null - alias: neo4j-partly-enforced-defaults - dsn: '%neo4j.dsn.secret%' + dsn: "%neo4j.dsn.secret%" - alias: neo4j-simple - dsn: '%neo4j.dsn.simple%' + dsn: "%neo4j.dsn.simple%" - alias: neo4j-fallback-mechanism priority: 100 - dsn: '%neo4j.dsn.badname%' + dsn: "%neo4j.dsn.badname%" - alias: neo4j-fallback-mechanism priority: 1000 - dsn: '%neo4j.dsn.badname%' + dsn: "%neo4j.dsn.badname%" - alias: neo4j-test - dsn: '%neo4j.dsn.test%' + dsn: "%neo4j.dsn.test%" diff --git a/tests/Functional/IntegrationTest.php b/tests/Functional/IntegrationTest.php index 720f865..4d7b638 100644 --- a/tests/Functional/IntegrationTest.php +++ b/tests/Functional/IntegrationTest.php @@ -1,11 +1,19 @@ getDriver('default'); - $reflection = new \ReflectionClass($driver); - $property = $reflection->getProperty('parsedUrl'); /** * @var UriInterface $uri */ - $uri = $property->getValue($driver); + $uri = $this->getPrivateProperty($driver, 'parsedUrl'); $this->assertSame($uri->getScheme(), 'neo4j'); } @@ -93,4 +99,88 @@ public function testDsn(): void $client = $container->get('neo4j.client'); $client->getDriver('neo4j_undefined_configs'); } + + public function testDefaultDriverConfig(): void + { + static::bootKernel(); + $container = static::getContainer(); + + /** + * @var ClientInterface $client + */ + $client = $container->get('neo4j.client'); + /** @var Neo4jDriver $driver */ + $driver = $client->getDriver('default'); + /** @var Neo4jConnectionPool $pool */ + $pool = $this->getPrivateProperty($driver, 'pool'); + /** @var SingleThreadedSemaphore $semaphore */ + $semaphore = $this->getPrivateProperty($pool, 'semaphore'); + /** @var int $max */ + $max = $this->getPrivateProperty($semaphore, 'max'); + + // default_driver_config.pool_size + $this->assertSame($max, 256); + + /** @var ConnectionRequestData $data */ + $data = $this->getPrivateProperty($pool, 'data'); + + $this->assertSame($data->getUserAgent(), 'Neo4j Symfony Bundle/testing'); + + /** @var SslConfiguration $sslConfig */ + $sslConfig = $this->getPrivateProperty($data, 'config'); + /** @var SslMode $sslMode */ + $sslMode = $this->getPrivateProperty($sslConfig, 'mode'); + /** @var bool $verifyPeer */ + $verifyPeer = $this->getPrivateProperty($sslConfig, 'verifyPeer'); + + $this->assertSame($sslMode, SslMode::DISABLE()); + $this->assertFalse($verifyPeer); + } + + public function testDefaultSessionConfig(): void + { + static::bootKernel(); + $container = static::getContainer(); + + /** + * @var ClientInterface $client + */ + $client = $container->get('neo4j.client'); + /** @var Client $innerClient */ + $innerClient = $this->getPrivateProperty($client, 'client'); + $sessionConfig = $innerClient->getDefaultSessionConfiguration(); + + $this->assertSame($sessionConfig->getFetchSize(), 999); + } + + public function testDefaultTrasactionConfig(): void + { + static::bootKernel(); + $container = static::getContainer(); + + /** + * @var ClientInterface $client + */ + $client = $container->get('neo4j.client'); + /** @var Client $innerClient */ + $innerClient = $this->getPrivateProperty($client, 'client'); + $transactionConfig = $innerClient->getDefaultTransactionConfiguration(); + + $this->assertSame($transactionConfig->getTimeout(), 40.0); + } + + /** + * @template T + * + * @return T + * + * @noinspection PhpDocMissingThrowsInspection + */ + private function getPrivateProperty(object $object, string $property): mixed + { + $reflection = new \ReflectionClass($object); + $property = $reflection->getProperty($property); + + return $property->getValue($object); + } } From e487d41a367155acd37f4b0c027e96c8a635e222 Mon Sep 17 00:00:00 2001 From: exaby73 Date: Wed, 21 Aug 2024 12:32:34 +0530 Subject: [PATCH 8/9] test: Add test for priority --- tests/App/config/ci/default.yml | 1 + tests/App/config/default.yml | 8 +++++ tests/Functional/IntegrationTest.php | 54 +++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/tests/App/config/ci/default.yml b/tests/App/config/ci/default.yml index cc4f3a4..df59b2c 100644 --- a/tests/App/config/ci/default.yml +++ b/tests/App/config/ci/default.yml @@ -1,3 +1,4 @@ parameters: neo4j.dsn.badname: bolt://localhostt neo4j.dsn.test: neo4j://neo4j:testtest@localhost + neo4j.dsn.auth: neo4j://localhost diff --git a/tests/App/config/default.yml b/tests/App/config/default.yml index 2c37002..323ae51 100644 --- a/tests/App/config/default.yml +++ b/tests/App/config/default.yml @@ -6,6 +6,7 @@ parameters: neo4j.dsn.badname: bolt://localhost neo4j.dsn.secret: neo4j://neo4j:secret@localhost:7688 neo4j.dsn.test: neo4j://neo4j:testtest@neo4j + neo4j.dsn.auth: neo4j://neo4j neo4j.dsn.simple: bolt://test:test@localhost neo4j: @@ -48,3 +49,10 @@ neo4j: - alias: neo4j-test dsn: "%neo4j.dsn.test%" + + - alias: neo4j-auth + dsn: "%neo4j.dsn.auth%" + authentication: + type: basic + username: neo4j + password: testtest diff --git a/tests/Functional/IntegrationTest.php b/tests/Functional/IntegrationTest.php index 4d7b638..ee7961f 100644 --- a/tests/Functional/IntegrationTest.php +++ b/tests/Functional/IntegrationTest.php @@ -7,14 +7,17 @@ namespace Neo4j\Neo4jBundle\Tests\Functional; use Laudis\Neo4j\Client; +use Laudis\Neo4j\Common\DriverSetupManager; use Laudis\Neo4j\Common\SingleThreadedSemaphore; use Laudis\Neo4j\Contracts\ClientInterface; use Laudis\Neo4j\Contracts\DriverInterface; use Laudis\Neo4j\Databags\ConnectionRequestData; +use Laudis\Neo4j\Databags\DriverSetup; use Laudis\Neo4j\Databags\SslConfiguration; use Laudis\Neo4j\Enum\SslMode; use Laudis\Neo4j\Neo4j\Neo4jConnectionPool; use Laudis\Neo4j\Neo4j\Neo4jDriver; +use Neo4j\Neo4jBundle\SymfonyClient; use Neo4j\Neo4jBundle\Tests\App\TestKernel; use Psr\Http\Message\UriInterface; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; @@ -100,6 +103,31 @@ public function testDsn(): void $client->getDriver('neo4j_undefined_configs'); } + public function testDriverAuthentication(): void + { + static::bootKernel(); + $container = static::getContainer(); + + /** + * @var ClientInterface $client + */ + $client = $container->get('neo4j.client'); + /** @var Neo4jDriver $driver */ + $driver = $client->getDriver('neo4j-auth'); + /** @var Neo4jConnectionPool $pool */ + $pool = $this->getPrivateProperty($driver, 'pool'); + /** @var ConnectionRequestData $data */ + $data = $this->getPrivateProperty($pool, 'data'); + $auth = $data->getAuth(); + /** @var string $username */ + $username = $this->getPrivateProperty($auth, 'username'); + /** @var string $password */ + $password = $this->getPrivateProperty($auth, 'password'); + + $this->assertSame($username, 'neo4j'); + $this->assertSame($password, 'testtest'); + } + public function testDefaultDriverConfig(): void { static::bootKernel(); @@ -153,7 +181,7 @@ public function testDefaultSessionConfig(): void $this->assertSame($sessionConfig->getFetchSize(), 999); } - public function testDefaultTrasactionConfig(): void + public function testDefaultTransactionConfig(): void { static::bootKernel(); $container = static::getContainer(); @@ -169,6 +197,30 @@ public function testDefaultTrasactionConfig(): void $this->assertSame($transactionConfig->getTimeout(), 40.0); } + public function testPriority(): void + { + static::bootKernel(); + $container = static::getContainer(); + + /** + * @var ClientInterface $client + */ + $client = $container->get('neo4j.client'); + /** @var Client $innerClient */ + $innerClient = $this->getPrivateProperty($client, 'client'); + /** @var DriverSetupManager $drivers */ + $drivers = $this->getPrivateProperty($innerClient, 'driverSetups'); + /** @var array<\SplPriorityQueue> $fallbackDriverQueue */ + $driverSetups = $this->getPrivateProperty($drivers, 'driverSetups'); + /** @var \SplPriorityQueue $fallbackDriverQueue */ + $fallbackDriverQueue = $driverSetups['neo4j-fallback-mechanism']; + $fallbackDriverQueue->setExtractFlags(\SplPriorityQueue::EXTR_BOTH); + /** @var array{data: DriverSetup, priority: int} $extractedValue */ + $extractedValue = $fallbackDriverQueue->extract(); + + $this->assertSame($extractedValue['priority'], 1000); + } + /** * @template T * From 5194b7d62bbb196577d55c4200f09402412934f8 Mon Sep 17 00:00:00 2001 From: exaby73 Date: Wed, 21 Aug 2024 12:38:10 +0530 Subject: [PATCH 9/9] chore: Remove unused import --- tests/Functional/IntegrationTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Functional/IntegrationTest.php b/tests/Functional/IntegrationTest.php index ee7961f..ece543a 100644 --- a/tests/Functional/IntegrationTest.php +++ b/tests/Functional/IntegrationTest.php @@ -17,7 +17,6 @@ use Laudis\Neo4j\Enum\SslMode; use Laudis\Neo4j\Neo4j\Neo4jConnectionPool; use Laudis\Neo4j\Neo4j\Neo4jDriver; -use Neo4j\Neo4jBundle\SymfonyClient; use Neo4j\Neo4jBundle\Tests\App\TestKernel; use Psr\Http\Message\UriInterface; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;