Skip to content

Commit 38aeee4

Browse files
committed
wip resolving testkit tests
1 parent 1b35a06 commit 38aeee4

File tree

11 files changed

+127
-21
lines changed

11 files changed

+127
-21
lines changed

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ services:
6767
NEO4J_server_http_advertised__address: neo4j:7474
6868

6969

70-
7170
server1:
7271
<<: *common-cluster
7372
hostname: server1
@@ -141,6 +140,7 @@ services:
141140
- neo4j
142141
extra_hosts:
143142
- "host.docker.internal:host-gateway"
143+
- "thehost:host-gateway"
144144
depends_on:
145145
- neo4j
146146
ports:

src/Bolt/ConnectionPool.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace Laudis\Neo4j\Bolt;
1515

16+
use Bolt\error\ConnectionTimeoutException;
1617
use Generator;
1718
use Laudis\Neo4j\BoltFactory;
1819
use Laudis\Neo4j\Common\Neo4jLogger;
@@ -24,6 +25,7 @@
2425
use Laudis\Neo4j\Databags\DriverConfiguration;
2526
use Laudis\Neo4j\Databags\SessionConfiguration;
2627
use Laudis\Neo4j\Exception\ConnectionPoolException;
28+
use Laudis\Neo4j\Exception\TimeoutException;
2729
use Psr\Http\Message\UriInterface;
2830

2931
use function shuffle;
@@ -42,6 +44,7 @@ public function __construct(
4244
private readonly ConnectionRequestData $data,
4345
private readonly ?Neo4jLogger $logger,
4446
private readonly float $acquireConnectionTimeout,
47+
private readonly float $connectionTimeout,
4548
) {
4649
}
4750

@@ -62,7 +65,8 @@ public static function create(
6265
$conf->getSslConfiguration()
6366
),
6467
$conf->getLogger(),
65-
$conf->getAcquireConnectionTimeout()
68+
$conf->getAcquireConnectionTimeout(),
69+
$conf->getConnectionTimeout()
6670
);
6771
}
6872

@@ -101,11 +105,14 @@ public function acquire(SessionConfiguration $config): Generator
101105
return $connection;
102106
}
103107

104-
$connection = $this->factory->createConnection($this->data, $config);
108+
try {
109+
$connection = $this->factory->createConnection($this->data, $config, $this->connectionTimeout);
105110

106-
$this->activeConnections[] = $connection;
107-
108-
return $connection;
111+
$this->activeConnections[] = $connection;
112+
return $connection;
113+
} catch (ConnectionTimeoutException $e) {
114+
throw new TimeoutException($e->getMessage(), $e->getCode(), $e);
115+
}
109116
})();
110117
}
111118

src/BoltFactory.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
use Laudis\Neo4j\Databags\ConnectionRequestData;
2626
use Laudis\Neo4j\Databags\DatabaseInfo;
2727
use Laudis\Neo4j\Databags\SessionConfiguration;
28-
use Laudis\Neo4j\Databags\TransactionConfiguration;
2928
use Laudis\Neo4j\Enum\ConnectionProtocol;
3029

3130
/**
@@ -49,7 +48,7 @@ public static function create(?Neo4jLogger $logger): self
4948
return new self(SystemWideConnectionFactory::getInstance(), new ProtocolFactory(), new SslConfigurationFactory(), $logger);
5049
}
5150

52-
public function createConnection(ConnectionRequestData $data, SessionConfiguration $sessionConfig): BoltConnection
51+
public function createConnection(ConnectionRequestData $data, SessionConfiguration $sessionConfig, float $connectionTimeout): BoltConnection
5352
{
5453
[$sslLevel, $sslConfig] = $this->sslConfigurationFactory->create($data->getUri()->withHost($data->getHostname()), $data->getSslConfig());
5554

@@ -58,7 +57,7 @@ public function createConnection(ConnectionRequestData $data, SessionConfigurati
5857
$data->getUri()->getPort(),
5958
$sslLevel,
6059
$sslConfig,
61-
TransactionConfiguration::DEFAULT_TIMEOUT
60+
$connectionTimeout
6261
);
6362

6463
$connection = $this->connectionFactory->create($uriConfig);

src/Databags/DriverConfiguration.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ final class DriverConfiguration
3838
public const DEFAULT_USER_AGENT = 'neo4j-php-client/%s';
3939
public const DEFAULT_POOL_SIZE = 0x2F;
4040
public const DEFAULT_CACHE_IMPLEMENTATION = Cache::class;
41-
public const DEFAULT_ACQUIRE_CONNECTION_TIMEOUT = 2.0;
41+
public const DEFAULT_ACQUIRE_CONNECTION_TIMEOUT = 60.0;
42+
public const DEFAULT_CONNECTION_TIMEOUT = 30.0;
43+
4244
/** @var callable():(CacheInterface|null)|CacheInterface|null */
4345
private $cache;
4446
/** @var callable():(SemaphoreFactoryInterface|null)|SemaphoreFactoryInterface|null */
@@ -58,6 +60,7 @@ public function __construct(
5860
private ?int $maxPoolSize,
5961
CacheInterface|callable|null $cache,
6062
private ?float $acquireConnectionTimeout,
63+
private ?float $connectionTimeout,
6164
callable|SemaphoreFactoryInterface|null $semaphore,
6265
?string $logLevel,
6366
?LoggerInterface $logger,
@@ -80,6 +83,7 @@ public static function create(
8083
int $maxPoolSize,
8184
CacheInterface $cache,
8285
float $acquireConnectionTimeout,
86+
float $connectionTimeout,
8387
SemaphoreFactoryInterface $semaphore,
8488
?string $logLevel,
8589
?LoggerInterface $logger,
@@ -90,6 +94,7 @@ public static function create(
9094
$maxPoolSize,
9195
$cache,
9296
$acquireConnectionTimeout,
97+
$connectionTimeout,
9398
$semaphore,
9499
$logLevel,
95100
$logger
@@ -112,6 +117,7 @@ public static function default(): self
112117
null,
113118
null,
114119
null,
120+
null,
115121
null
116122
);
117123
}
@@ -233,6 +239,25 @@ public function withAcquireConnectionTimeout(?float $acquireConnectionTimeout):
233239
return $tbr;
234240
}
235241

242+
/**
243+
* @psalm-immutable
244+
*/
245+
public function getConnectionTimeout(): float
246+
{
247+
return $this->connectionTimeout ??= self::DEFAULT_CONNECTION_TIMEOUT;
248+
}
249+
250+
/**
251+
* @psalm-immutable
252+
*/
253+
public function withConnectionTimeout(?float $connectionTimeout): self
254+
{
255+
$tbr = clone $this;
256+
$tbr->connectionTimeout = $connectionTimeout;
257+
258+
return $tbr;
259+
}
260+
236261
/**
237262
* @param callable():(SemaphoreFactoryInterface|null)|SemaphoreFactoryInterface|null $factory
238263
*

src/Exception/TimeoutException.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Laudis\Neo4j\Exception;
6+
7+
use RuntimeException;
8+
9+
class TimeoutException extends RuntimeException
10+
{
11+
12+
}

src/Neo4j/Neo4jConnectionPool.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public function __construct(
7575
private readonly AddressResolverInterface $resolver,
7676
private readonly ?Neo4jLogger $logger,
7777
private readonly float $acquireConnectionTimeout,
78+
private readonly float $connectionTimeout,
7879
) {
7980
}
8081

@@ -98,7 +99,8 @@ public static function create(
9899
Cache::getInstance(),
99100
$resolver,
100101
$conf->getLogger(),
101-
$conf->getAcquireConnectionTimeout()
102+
$conf->getAcquireConnectionTimeout(),
103+
$conf->getConnectionTimeout()
102104
);
103105
}
104106

@@ -114,7 +116,7 @@ public function createOrGetPool(string $hostname, UriInterface $uri): Connection
114116

115117
$key = $this->createKey($data);
116118
if (!array_key_exists($key, self::$pools)) {
117-
self::$pools[$key] = new ConnectionPool($this->semaphore, $this->factory, $data, $this->logger, $this->acquireConnectionTimeout);
119+
self::$pools[$key] = new ConnectionPool($this->semaphore, $this->factory, $data, $this->logger, $this->acquireConnectionTimeout, $this->connectionTimeout);
118120
}
119121

120122
return self::$pools[$key];

testkit-backend/testkit.sh

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/bin/bash
22

3+
set -ex
4+
35
TESTKIT_VERSION=5.0
46

57
[ -z "$TEST_NEO4J_HOST" ] && export TEST_NEO4J_HOST=neo4j
@@ -32,16 +34,40 @@ python3 -m venv venv
3234
source venv/bin/activate
3335
pip install -r requirements.txt
3436

37+
if [ ! -f ./tlsserver/tlsserver ]; then
38+
(cd ./tlsserver && go build -o tlsserver main.go)
39+
fi
40+
41+
CERT_DIR=$(realpath ./tests/tls)
42+
(cd certgen && go run main.go "${CERT_DIR}")
43+
3544
# python3 main.py --tests UNIT_TESTS
3645

3746
echo "Starting tests..."
3847

39-
python3 -m unittest tests.neo4j.test_authentication.TestAuthenticationBasic
40-
python3 -m unittest tests.neo4j.test_bookmarks.TestBookmarks
41-
python3 -m unittest tests.neo4j.test_session_run.TestSessionRun
42-
python3 -m unittest tests.neo4j.test_direct_driver.TestDirectDriver
43-
python3 -m unittest tests.neo4j.test_summary.TestSummary
44-
python3 -m unittest tests.neo4j.test_tx_func_run.TestTxFuncRun
45-
python3 -m unittest tests.neo4j.test_tx_run.TestTxRun
48+
#python3 -m unittest tests.neo4j.test_authentication.TestAuthenticationBasic
49+
#python3 -m unittest tests.neo4j.test_bookmarks.TestBookmarks
50+
#python3 -m unittest tests.neo4j.test_session_run.TestSessionRun
51+
#python3 -m unittest tests.neo4j.test_direct_driver.TestDirectDriver
52+
#python3 -m unittest tests.neo4j.test_summary.TestSummary
53+
python3 -m unittest tests.neo4j.test_tx_func_run.TestTxFuncRun.test_tx_timeout
54+
#python3 -m unittest tests.neo4j.test_tx_run.TestTxRun
4655

56+
#tlstest_secure_server
4757

58+
#python3 -m unittest tests.tls.test_client_certificate.TestClientCertificate
59+
#python3 -m unittest tests.tls.test_client_certificate.TestClientCertificateRotation
60+
#
61+
#python3 -m unittest tests.tls.test_explicit_options.TestExplicitSslOptions
62+
#
63+
#python3 -m unittest tests.tls.test_secure_scheme.TestSecureScheme
64+
#python3 -m unittest tests.tls.test_secure_scheme.TestTrustSystemCertsConfig
65+
#python3 -m unittest tests.tls.test_secure_scheme.TestTrustCustomCertsConfig
66+
#
67+
#
68+
#python3 -m unittest tests.tls.test_self_signed_scheme.TestSelfSignedScheme
69+
#python3 -m unittest tests.tls.test_self_signed_scheme.TestTrustAllCertsConfig
70+
#
71+
#python3 -m unittest tests.tls.test_tls_versions.TestTlsVersions
72+
#
73+
#python3 -m unittest tests.tls.test_unsecure_scheme.TestUnsecureScheme.test_secure_server #2 error

tests/Integration/BoltResultIntegrationTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Laudis\Neo4j\Bolt\SystemWideConnectionFactory;
2121
use Laudis\Neo4j\BoltFactory;
2222
use Laudis\Neo4j\Databags\ConnectionRequestData;
23+
use Laudis\Neo4j\Databags\DriverConfiguration;
2324
use Laudis\Neo4j\Databags\SessionConfiguration;
2425
use Laudis\Neo4j\Databags\SslConfiguration;
2526
use Laudis\Neo4j\Enum\SslMode;
@@ -41,7 +42,7 @@ public function testIterationLong(): void
4142
);
4243
$connection = $factory->createConnection(
4344
new ConnectionRequestData($this->getUri()->getHost(), $this->getUri(), Authenticate::fromUrl($this->getUri()), 'a/b', new SslConfiguration(SslMode::FROM_URL(), false)),
44-
SessionConfiguration::default()
45+
SessionConfiguration::default(),DriverConfiguration::DEFAULT_CONNECTION_TIMEOUT
4546
);
4647

4748
$connection->protocol()->run('UNWIND range(1, 100000) AS i RETURN i')

tests/Integration/ClientBuilderTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public function testGetClient(): void
3535
->withSslConfiguration($sslConfig)
3636
->withMaxPoolSize(4096)
3737
->withAcquireConnectionTimeout(2.5)
38+
->withConnectionTimeout(76)
3839
->withLogger(LogLevel::DEBUG, $logger);
3940
$sessionConfig = SessionConfiguration::default()->withDatabase('neo4j');
4041
$transactionConfig = TransactionConfiguration::default()->withTimeout(120.0);

tests/Integration/ClientIntegrationTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace Laudis\Neo4j\Tests\Integration;
1515

16+
use Bolt\error\ConnectionTimeoutException;
1617
use Exception;
1718
use InvalidArgumentException;
1819
use Laudis\Neo4j\Authentication\Authenticate;
@@ -359,4 +360,35 @@ public function testRedundantAcquire(): void
359360
$this->assertCount(1, $activeConnections);
360361
}
361362
}
363+
364+
public function testTimeoutExceptionIsThrown(): void
365+
{
366+
$factory = $this->createMock(BoltFactory::class);
367+
$semaphore = $this->createMock(SemaphoreInterface::class);
368+
$data = $this->createMock(ConnectionRequestData::class);
369+
$logger = $this->createMock(Neo4jLogger::class);
370+
$config = SessionConfiguration::default();
371+
372+
$factory->method('createConnection')
373+
->willThrowException(new ConnectionTimeoutException('Connection timed out'));
374+
375+
$semaphore->method('wait')->willReturn((function () {
376+
if (false) yield;
377+
})());
378+
379+
$pool = new ConnectionPool(
380+
$semaphore,
381+
$factory,
382+
$data,
383+
$logger,
384+
5.0,
385+
2.0
386+
);
387+
388+
$this->expectException(TimeoutException::class);
389+
$this->expectExceptionMessage('Connection timed out');
390+
391+
iterator_to_array($pool->acquire($config));
392+
}
393+
362394
}

0 commit comments

Comments
 (0)