Skip to content

Commit 88e2829

Browse files
committed
skipped tests on clusters with version 3.5
1 parent 0dac1b5 commit 88e2829

13 files changed

+170
-41
lines changed

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ services:
2929
neo4j:
3030
networks:
3131
- neo4j
32-
image: neo4j:3.5-enterprise
32+
image: neo4j:4.2-enterprise
3333
healthcheck:
3434
test: [ "CMD", "neo4j status" ]
3535
interval: 30s

src/Authentication/BasicAuth.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ public function authenticateHttp(RequestInterface $request, UriInterface $uri, s
4444
*/
4545
public function authenticateBolt(Bolt $bolt, UriInterface $uri, string $userAgent): void
4646
{
47-
$bolt->setScheme('basic');
4847
$bolt->init($userAgent, $this->username, $this->password);
4948
}
5049
}

src/Bolt/BoltConnectionPool.php

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313

1414
namespace Laudis\Neo4j\Bolt;
1515

16-
use Bolt\Bolt;
1716
use Bolt\connection\StreamSocket;
18-
use Ds\Map;
1917
use Exception;
2018
use Laudis\Neo4j\Contracts\ConnectionPoolInterface;
2119
use Laudis\Neo4j\Enum\AccessMode;
@@ -26,22 +24,14 @@
2624
use const FILTER_VALIDATE_IP;
2725

2826
/**
29-
* @implements ConnectionPoolInterface<Bolt>
27+
* @implements ConnectionPoolInterface<StreamSocket>
3028
*/
3129
final class BoltConnectionPool implements ConnectionPoolInterface
3230
{
33-
/** @var Map<string, Bolt> */
34-
private Map $map;
35-
36-
public function __construct()
37-
{
38-
$this->map = new Map();
39-
}
40-
4131
/**
4232
* @throws Exception
4333
*/
44-
public function acquire(UriInterface $uri, AccessMode $mode): Bolt
34+
public function acquire(UriInterface $uri, AccessMode $mode): StreamSocket
4535
{
4636
$host = $uri->getHost();
4737
$socket = new StreamSocket($host, $uri->getPort() ?? 7687);
@@ -54,10 +44,7 @@ public function acquire(UriInterface $uri, AccessMode $mode): Bolt
5444
$this->enableSsl($host, $sslConfig, $socket);
5545
}
5646

57-
$bolt = new Bolt($socket);
58-
$this->map->put($uri->__toString(), $bolt);
59-
60-
return $bolt;
47+
return $socket;
6148
}
6249

6350
private function enableSsl(string $host, string $sslConfig, StreamSocket $sock): void

src/Bolt/Session.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace Laudis\Neo4j\Bolt;
1515

1616
use Bolt\Bolt;
17+
use Bolt\connection\StreamSocket;
1718
use Closure;
1819
use Ds\Vector;
1920
use Exception;
@@ -47,8 +48,8 @@ final class Session implements SessionInterface
4748
private AuthenticateInterface $auth;
4849

4950
/**
50-
* @param FormatterInterface<T> $formatter
51-
* @param ConnectionPoolInterface<Bolt> $pool
51+
* @param FormatterInterface<T> $formatter
52+
* @param ConnectionPoolInterface<StreamSocket> $pool
5253
*/
5354
public function __construct(
5455
SessionConfiguration $config,
@@ -112,10 +113,18 @@ public function transaction(callable $tsxHandler, ?TransactionConfiguration $con
112113
public function beginTransaction(?iterable $statements = null, ?TransactionConfiguration $config = null): UnmanagedTransactionInterface
113114
{
114115
try {
115-
$bolt = $this->pool->acquire($this->uri, $this->config->getAccessMode());
116+
$bolt = new Bolt($this->pool->acquire($this->uri, $this->config->getAccessMode()));
116117
$this->auth->authenticateBolt($bolt, $this->uri, $this->userAgent);
117118

118-
if (!$bolt->begin(['db' => $this->config->getDatabase()])) {
119+
$protocolVersion = $bolt->getProtocolVersion();
120+
if ($protocolVersion >= 4.0) {
121+
$begin = $bolt->begin(['db' => $this->config->getDatabase()]);
122+
} else {
123+
$bolt->setProtocolVersions((int) $protocolVersion);
124+
$begin = $bolt->begin();
125+
}
126+
127+
if (!$begin) {
119128
throw new Neo4jException(new Vector([new Neo4jError('', 'Cannot open new transaction')]));
120129
}
121130
} catch (Exception $e) {

src/Neo4j/Neo4jConnectionPool.php

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace Laudis\Neo4j\Neo4j;
1515

1616
use Bolt\Bolt;
17+
use Bolt\connection\StreamSocket;
1718
use Exception;
1819
use Laudis\Neo4j\Bolt\BoltDriver;
1920
use Laudis\Neo4j\Common\Uri;
@@ -29,17 +30,17 @@
2930
/**
3031
* @psalm-import-type BasicDriver from \Laudis\Neo4j\Contracts\DriverInterface
3132
*
32-
* @implements ConnectionPoolInterface<Bolt>
33+
* @implements ConnectionPoolInterface<StreamSocket>
3334
*/
3435
final class Neo4jConnectionPool implements ConnectionPoolInterface
3536
{
3637
private ?RoutingTable $table = null;
37-
/** @var ConnectionPoolInterface<Bolt> */
38+
/** @var ConnectionPoolInterface<StreamSocket> */
3839
private ConnectionPoolInterface $pool;
3940
private string $version;
4041

4142
/**
42-
* @param ConnectionPoolInterface<Bolt> $pool
43+
* @param ConnectionPoolInterface<StreamSocket> $pool
4344
*/
4445
public function __construct(ConnectionPoolInterface $pool, string $version)
4546
{
@@ -50,7 +51,7 @@ public function __construct(ConnectionPoolInterface $pool, string $version)
5051
/**
5152
* @throws Exception
5253
*/
53-
public function acquire(UriInterface $uri, AccessMode $mode): Bolt
54+
public function acquire(UriInterface $uri, AccessMode $mode): StreamSocket
5455
{
5556
$table = $this->routingTable(BoltDriver::create($uri));
5657
$server = $this->getNextServer($table, $mode);
@@ -83,15 +84,25 @@ private function routingTable(DriverInterface $driver): RoutingTable
8384
if ($this->table === null || $this->table->getTtl() < time()) {
8485
$session = $driver->createSession();
8586
if (str_starts_with($this->version, '3')) {
86-
$response = $session->run('CALL dbms.cluster.overview()')->first();
87+
$response = $session->run('CALL dbms.cluster.overview()');
88+
89+
/** @var iterable<array{addresses: list<string>, role:string}> $values */
90+
$values = [];
91+
foreach ($response as $server) {
92+
/** @psalm-suppress InvalidArrayAssignment */
93+
$values[] = ['addresses' => $server->get('addresses'), 'role' => $server->get('role')];
94+
}
95+
96+
$this->table = new RoutingTable($values, time() + 3600);
8797
} else {
8898
$response = $session->run('CALL dbms.routing.getRoutingTable({context: []})')->first();
99+
/** @var iterable<array{addresses: list<string>, role:string}> $values */
100+
$values = $response->get('servers');
101+
/** @var int $ttl */
102+
$ttl = $response->get('ttl');
103+
104+
$this->table = new RoutingTable($values, time() + $ttl);
89105
}
90-
/** @var iterable<array{addresses: list<string>, role:string}> $values */
91-
$values = $response->get('servers');
92-
/** @var int $ttl */
93-
$ttl = $response->get('ttl');
94-
$this->table = new RoutingTable($values, time() + $ttl);
95106
}
96107

97108
return $this->table;

src/Neo4j/RoutingTable.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,15 @@ public function getWithRole(RoutingRoles $role): Set
4848
foreach ($server['addresses'] as $address) {
4949
$tbr->add($address);
5050
}
51+
} elseif (
52+
($role === RoutingRoles::LEADER() && $server['role'] === 'LEADER') ||
53+
($role === RoutingRoles::FOLLOWER() && $server['role'] === 'FOLLOWER')
54+
) {
55+
foreach ($server['addresses'] as $address) {
56+
$tbr->add($address);
57+
}
5158
}
59+
5260
}
5361

5462
return $tbr;

tests/Helpers/TestHelper.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
/** @noinspection PhpUndefinedMethodInspection */
3+
declare(strict_types=1);
4+
5+
6+
namespace Laudis\Neo4j\Tests\Helpers;
7+
8+
9+
use Laudis\Neo4j\Bolt\BoltDriver;
10+
use PHPUnit\Framework\TestCase;
11+
12+
final class TestHelper
13+
{
14+
/**
15+
* @param class-string<TestCase> $class
16+
*
17+
* @throws \Exception
18+
*/
19+
public static function skipIfUnsupportedVersion(string $alias, string $class): void
20+
{
21+
/** @var string $version */
22+
$version = BoltDriver::create('bolt://neo4j:test@neo4j')
23+
->createSession()
24+
->run('CALL dbms.components() yield versions UNWIND versions as version return version')
25+
->first()
26+
->get('version');
27+
28+
if ($alias === 'cluster' && str_starts_with($version, '3')) {
29+
$class::markTestSkipped('Cannot test cluster operations on version 3.5');
30+
}
31+
}
32+
}

tests/Integration/ClientIntegrationTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Laudis\Neo4j\Contracts\TransactionInterface;
2323
use Laudis\Neo4j\Databags\Statement;
2424
use Laudis\Neo4j\Exception\Neo4jException;
25+
use Laudis\Neo4j\Tests\Helpers\TestHelper;
2526
use PHPUnit\Framework\TestCase;
2627

2728
final class ClientIntegrationTest extends TestCase
@@ -71,6 +72,7 @@ public function testEqualEffect(): void
7172

7273
public function testAvailabilityFullImplementation(): void
7374
{
75+
TestHelper::skipIfUnsupportedVersion('cluster', __CLASS__);
7476
$results = $this->client->getDriver('cluster')
7577
->createSession()
7678
->beginTransaction()
@@ -107,6 +109,8 @@ public function testTransactionFunction(): void
107109
*/
108110
public function testValidRun(string $alias): void
109111
{
112+
TestHelper::skipIfUnsupportedVersion($alias, __CLASS__);
113+
110114
$response = $this->client->run(<<<'CYPHER'
111115
MERGE (x:TestNode {test: $test})
112116
WITH x
@@ -144,6 +148,8 @@ public function testInvalidRun(string $alias): void
144148
*/
145149
public function testValidStatement(string $alias): void
146150
{
151+
TestHelper::skipIfUnsupportedVersion($alias, __CLASS__);
152+
147153
$response = $this->client->runStatement(
148154
Statement::create(<<<'CYPHER'
149155
MERGE (x:TestNode {test: $test})
@@ -185,6 +191,8 @@ public function testInvalidStatement(string $alias): void
185191
*/
186192
public function testStatements(string $alias): void
187193
{
194+
TestHelper::skipIfUnsupportedVersion($alias, __CLASS__);
195+
188196
$params = ['test' => 'a', 'otherTest' => 'b'];
189197
$response = $this->client->runStatements([
190198
Statement::create(<<<'CYPHER'
@@ -240,6 +248,8 @@ public function testInvalidStatements(string $alias): void
240248
*/
241249
public function testMultipleTransactions(string $alias): void
242250
{
251+
TestHelper::skipIfUnsupportedVersion($alias, __CLASS__);
252+
243253
$x = $this->client->beginTransaction(null, $alias);
244254
$y = $this->client->beginTransaction(null, $alias);
245255
self::assertNotSame($x, $y);

tests/Integration/ClusterIntegrationTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Laudis\Neo4j\Bolt\BoltConfiguration;
1919
use Laudis\Neo4j\ClientBuilder;
2020
use Laudis\Neo4j\Contracts\ClientInterface;
21+
use Laudis\Neo4j\Tests\Helpers\TestHelper;
2122
use PHPUnit\Framework\TestCase;
2223

2324
final class ClusterIntegrationTest extends TestCase
@@ -30,7 +31,7 @@ protected function setUp(): void
3031
parent::setUp();
3132
$boltInjections = BoltConfiguration::create()->withAutoRouting(true);
3233
$this->client = ClientBuilder::create()
33-
->addBoltConnection('cluster-bolt', 'bolt://neo4j:test@core1', $boltInjections)
34+
->addBoltConnection('cluster', 'bolt://neo4j:test@core1', $boltInjections)
3435
->build();
3536
}
3637

@@ -39,6 +40,8 @@ protected function setUp(): void
3940
*/
4041
public function testAcceptance(string $connection): void
4142
{
43+
TestHelper::skipIfUnsupportedVersion($connection, __CLASS__);
44+
4245
self::assertEquals(1, $this->client->run('RETURN 1 as x', [], $connection)->first()->get('x'));
4346
}
4447

@@ -47,6 +50,8 @@ public function testAcceptance(string $connection): void
4750
*/
4851
public function testWrite(string $connection): void
4952
{
53+
TestHelper::skipIfUnsupportedVersion($connection, __CLASS__);
54+
5055
self::assertEquals([], $this->client->run('CREATE (x:X) RETURN x', [], $connection)->first()->get('x'));
5156
}
5257

@@ -56,7 +61,7 @@ public function testWrite(string $connection): void
5661
public function aliasProvider(): array
5762
{
5863
return [
59-
['cluster-bolt'],
64+
['cluster'],
6065
];
6166
}
6267
}

tests/Integration/ConsistencyTest.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Laudis\Neo4j\ClientBuilder;
1919
use Laudis\Neo4j\Contracts\ClientInterface;
2020
use Laudis\Neo4j\Databags\Statement;
21+
use Laudis\Neo4j\Tests\Helpers\TestHelper;
2122
use PHPUnit\Framework\TestCase;
2223

2324
final class ConsistencyTest extends TestCase
@@ -31,19 +32,18 @@ protected function setUp(): void
3132
$this->client = ClientBuilder::create()
3233
->withDriver('http', 'http://neo4j:test@neo4j')
3334
->withDriver('bolt', 'bolt://neo4j:test@neo4j')
34-
->withDriver('neo4j', 'neo4j://neo4j:test@core1')
35+
->withDriver('cluster', 'neo4j://neo4j:test@core1')
3536
->build();
36-
37-
$this->client->run('MATCH (x) DETACH DELETE x', [], 'http');
38-
$this->client->run('MATCH (x) DETACH DELETE x', [], 'bolt');
39-
$this->client->run('MATCH (x) DETACH DELETE x', [], 'neo4j');
4037
}
4138

4239
/**
4340
* @dataProvider aliases
4441
*/
4542
public function testConsistency(string $alias): void
4643
{
44+
TestHelper::skipIfUnsupportedVersion($alias, __CLASS__);
45+
46+
$this->client->run('MATCH (x) DETACH DELETE x', [], $alias);
4747
$res = $this->client->run('MERGE (n:zzz {name: "bbbb"}) RETURN n', [], $alias);
4848
self::assertEquals(1, $res->count());
4949
self::assertEquals(['name' => 'bbbb'], $res->first()->get('n'));
@@ -58,6 +58,9 @@ public function testConsistency(string $alias): void
5858
*/
5959
public function testConsistencyTransaction(string $alias): void
6060
{
61+
TestHelper::skipIfUnsupportedVersion($alias, __CLASS__);
62+
63+
$this->client->run('MATCH (x) DETACH DELETE x', [], $alias);
6164
$tsx = $this->client->beginTransaction([
6265
Statement::create('CREATE (n:aaa) SET n.name="aaa" return n'),
6366
], $alias);
@@ -82,7 +85,7 @@ public function aliases(): array
8285
return [
8386
['http'],
8487
['bolt'],
85-
['neo4j'],
88+
['cluster'],
8689
];
8790
}
8891
}

0 commit comments

Comments
 (0)