Skip to content

Commit 964e887

Browse files
authored
PHPLIB-794: Use single/multi-mongos LB URIs when available (#1019)
* PHPLIB-794: Use single/multi-mongos LB URIs when available This ensures MONGODB_SINGLE_MONGOS_LB_URI and MONGODB_MULTI_MONGOS_LB_URI are now set for load balancer tasks in Evergreen and used within the test suite. Also fixes some bugs in the original getUri() code for reassembling a URL with a single mongos host. Previously, auth credentials were not properly appended (d5b1156) and a query string could be appended without a slash between the question mark and last host in the seedlist (49d32aa). * Fix static method invocations * Append TLS options to LB URIs if necessary
1 parent dea346e commit 964e887

File tree

5 files changed

+98
-67
lines changed

5 files changed

+98
-67
lines changed

.evergreen/config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ functions:
301301
API_VERSION=${API_VERSION} \
302302
CRYPT_SHARED_LIB_PATH=${CRYPT_SHARED_LIB_PATH} \
303303
MONGODB_URI="${MONGODB_URI}" \
304+
MONGODB_SINGLE_MONGOS_LB_URI="${SINGLE_MONGOS_LB_URI}" \
305+
MONGODB_MULTI_MONGOS_LB_URI="${MULTI_MONGOS_LB_URI}" \
304306
PHP_VERSION=${PHP_VERSION} \
305307
SKIP_CRYPT_SHARED=${SKIP_CRYPT_SHARED} \
306308
SSL=${SSL} \

.evergreen/run-tests.sh

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ CRYPT_SHARED_LIB_PATH="${CRYPT_SHARED_LIB_PATH:-}" # Optional path to crypt_shar
77
DRIVER_MONGODB_VERSION=${DRIVER_MONGODB_VERSION:-} # Required if IS_MATRIX_TESTING is "true"
88
IS_MATRIX_TESTING=${IS_MATRIX_TESTING:-} # Specify "true" to enable matrix testing. Defaults to empty string. If "true", DRIVER_MONGODB_VERSION and MONGODB_VERSION will also be checked.
99
MONGODB_URI=${MONGODB_URI:-} # Connection string (including credentials and topology info)
10+
MONGODB_SINGLE_MONGOS_LB_URI=${MONGODB_SINGLE_MONGOS_LB_URI:-} # Single-mongos LB connection string
11+
MONGODB_MULTI_MONGOS_LB_URI=${MONGODB_MULTI_MONGOS_LB_URI:-} # Multi-mongos LB connection string
1012
MONGODB_VERSION=${MONGODB_VERSION:-} # Required if IS_MATRIX_TESTING is "true"
1113
SKIP_CRYPT_SHARED="${SKIP_CRYPT_SHARED:-no}" # Specify "yes" to ignore CRYPT_SHARED_LIB_PATH. Defaults to "no"
1214
SSL=${SSL:-no} # Specify "yes" to enable SSL. Defaults to "no"
@@ -44,14 +46,25 @@ fi
4446
# Enable verbose output to see skipped and incomplete tests
4547
PHPUNIT_OPTS="${PHPUNIT_OPTS} -v --configuration phpunit.evergreen.xml"
4648

47-
# Determine if MONGODB_URI already has a query string
48-
SUFFIX=$(echo "$MONGODB_URI" | grep -Eo "\?(.*)" | cat)
49-
5049
if [ "$SSL" = "yes" ]; then
50+
SSL_OPTS="ssl=true&sslallowinvalidcertificates=true"
51+
52+
# Determine if MONGODB_URI already has a query string
53+
SUFFIX=$(echo "$MONGODB_URI" | grep -Eo "\?(.*)" | cat)
54+
5155
if [ -z "$SUFFIX" ]; then
52-
MONGODB_URI="${MONGODB_URI}/?ssl=true&sslallowinvalidcertificates=true"
56+
MONGODB_URI="${MONGODB_URI}/?${SSL_OPTS}"
5357
else
54-
MONGODB_URI="${MONGODB_URI}&ssl=true&sslallowinvalidcertificates=true"
58+
MONGODB_URI="${MONGODB_URI}&${SSL_OPTS}"
59+
fi
60+
61+
# Assume LB URIs already have a query string (e.g. "?loadBalanced=true")
62+
if [ -n "${MONGODB_SINGLE_MONGOS_LB_URI}" ]; then
63+
MONGODB_SINGLE_MONGOS_LB_URI="${MONGODB_SINGLE_MONGOS_LB_URI}&${SSL_OPTS}"
64+
fi
65+
66+
if [ -n "${MONGODB_MULTI_MONGOS_LB_URI}" ]; then
67+
MONGODB_MULTI_MONGOS_LB_URI="${MONGODB_MULTI_MONGOS_LB_URI}&${SSL_OPTS}"
5568
fi
5669
fi
5770

@@ -65,6 +78,8 @@ export SYMFONY_DEPRECATIONS_HELPER=999999
6578
export API_VERSION="${API_VERSION}"
6679
export CRYPT_SHARED_LIB_PATH="${CRYPT_SHARED_LIB_PATH}"
6780
export MONGODB_URI="${MONGODB_URI}"
81+
export MONGODB_SINGLE_MONGOS_LB_URI="${MONGODB_SINGLE_MONGOS_LB_URI}"
82+
export MONGODB_MULTI_MONGOS_LB_URI="${MONGODB_MULTI_MONGOS_LB_URI}"
6883

6984
# Run the tests, and store the results in a junit result file
7085
case "$TESTS" in

tests/FunctionalTestCase.php

Lines changed: 71 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use stdClass;
2121
use UnexpectedValueException;
2222

23-
use function array_merge;
2423
use function call_user_func;
2524
use function count;
2625
use function current;
@@ -90,63 +89,16 @@ public static function createTestManager(?string $uri = null, array $options = [
9089

9190
public static function getUri($allowMultipleMongoses = false): string
9291
{
93-
$uri = parent::getUri();
94-
92+
/* If multiple mongoses are allowed, the multi-mongos load balanced URI
93+
* can be used if available; otherwise, fall back MONGODB_URI. */
9594
if ($allowMultipleMongoses) {
96-
return $uri;
97-
}
98-
99-
$urlParts = parse_url($uri);
100-
if ($urlParts === false) {
101-
return $uri;
102-
}
103-
104-
// Only modify URIs using the mongodb scheme
105-
if ($urlParts['scheme'] !== 'mongodb') {
106-
return $uri;
95+
return getenv('MONGODB_MULTI_MONGOS_LB_URI') ?: parent::getUri();
10796
}
10897

109-
$hosts = explode(',', $urlParts['host']);
110-
$numHosts = count($hosts);
111-
if ($numHosts === 1) {
112-
return $uri;
113-
}
114-
115-
$manager = static::createTestManager($uri);
116-
if ($manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY))->getType() !== Server::TYPE_MONGOS) {
117-
return $uri;
118-
}
119-
120-
// Re-append port to last host
121-
if (isset($urlParts['port'])) {
122-
$hosts[$numHosts - 1] .= ':' . $urlParts['port'];
123-
}
124-
125-
$parts = ['mongodb://'];
126-
127-
if (isset($urlParts['user'], $urlParts['pass'])) {
128-
$parts += [
129-
$urlParts['user'],
130-
':',
131-
$urlParts['pass'],
132-
'@',
133-
];
134-
}
135-
136-
$parts[] = $hosts[0];
137-
138-
if (isset($urlParts['path'])) {
139-
$parts[] = $urlParts['path'];
140-
}
141-
142-
if (isset($urlParts['query'])) {
143-
$parts = array_merge($parts, [
144-
'?',
145-
$urlParts['query'],
146-
]);
147-
}
148-
149-
return implode('', $parts);
98+
/* If multiple mongoses are prohibited, the single-mongos load balanced
99+
* URI can be used if available; otherwise, we need to conditionally
100+
* process MONGODB_URI. */
101+
return getenv('MONGODB_SINGLE_MONGOS_LB_URI') ?: static::getUriWithoutMultipleMongoses();
150102
}
151103

152104
protected function assertCollectionCount($namespace, $count): void
@@ -629,6 +581,70 @@ private function disableFailPoints(): void
629581
}
630582
}
631583

584+
private static function getUriWithoutMultipleMongoses(): string
585+
{
586+
/* Cache the result. We can safely assume the topology type will remain
587+
* constant for the duration of the test suite. */
588+
static $uri;
589+
590+
if (isset($uri)) {
591+
return $uri;
592+
}
593+
594+
$uri = parent::getUri();
595+
$parsed = parse_url($uri);
596+
597+
if (! isset($parsed['scheme'], $parsed['host'])) {
598+
throw new UnexpectedValueException('Failed to parse scheme and host components from URI: ' . $uri);
599+
}
600+
601+
// Only modify URIs using the mongodb scheme
602+
if ($parsed['scheme'] !== 'mongodb') {
603+
return $uri;
604+
}
605+
606+
$hosts = explode(',', $parsed['host']);
607+
$numHosts = count($hosts);
608+
609+
if ($numHosts === 1) {
610+
return $uri;
611+
}
612+
613+
$manager = static::createTestManager($uri);
614+
if ($manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY))->getType() !== Server::TYPE_MONGOS) {
615+
return $uri;
616+
}
617+
618+
// Re-append port to last host
619+
if (isset($parsed['port'])) {
620+
$hosts[$numHosts - 1] .= ':' . $parsed['port'];
621+
}
622+
623+
$parts = ['mongodb://'];
624+
625+
if (isset($parsed['user'], $parsed['pass'])) {
626+
$parts[] = $parsed['user'] . ':' . $parsed['pass'] . '@';
627+
}
628+
629+
$parts[] = $hosts[0];
630+
631+
if (isset($parsed['path'])) {
632+
$parts[] = $parsed['path'];
633+
} elseif (isset($parsed['query'])) {
634+
/* URIs containing connection options but no auth database component
635+
* still require a slash before the question mark */
636+
$parts[] = '/';
637+
}
638+
639+
if (isset($parsed['query'])) {
640+
$parts[] = '?' . $parsed['query'];
641+
}
642+
643+
$uri = implode('', $parts);
644+
645+
return $uri;
646+
}
647+
632648
/**
633649
* Checks if the failCommand command is supported on this server version
634650
*/

tests/SpecTests/TransactionsSpecTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ public function testStartingNewTransactionOnPinnedSessionUnpinsSession(): void
235235
$this->markTestSkipped('Pinning tests require mongos');
236236
}
237237

238-
$client = self::createTestClient($this->getUri(true));
238+
$client = self::createTestClient(static::getUri(true));
239239

240240
$session = $client->startSession();
241241
$collection = $client->selectCollection($this->getDatabaseName(), $this->getCollectionName());
@@ -275,7 +275,7 @@ public function testRunningNonTransactionOperationOnPinnedSessionUnpinsSession()
275275
$this->markTestSkipped('Pinning tests require mongos');
276276
}
277277

278-
$client = self::createTestClient($this->getUri(true));
278+
$client = self::createTestClient(static::getUri(true));
279279

280280
$session = $client->startSession();
281281
$collection = $client->selectCollection($this->getDatabaseName(), $this->getCollectionName());

tests/UnifiedSpecTests/UnifiedTestRunner.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -543,14 +543,12 @@ private function createContext(): Context
543543
$context->setUrisForUseMultipleMongoses($singleMongosUri, $multiMongosUri);
544544
}
545545

546-
/* TODO: Enable this logic once PHPLIB-794 is implemented. For now, load
547-
* balancer tests will continue to use MONGODB_URI. */
548-
if (false && $this->getPrimaryServer()->getType() === Server::TYPE_LOAD_BALANCER && ! $this->isServerless()) {
546+
if ($this->getPrimaryServer()->getType() === Server::TYPE_LOAD_BALANCER && ! $this->isServerless()) {
549547
$singleMongosUri = getenv('MONGODB_SINGLE_MONGOS_LB_URI');
550548
$multiMongosUri = getenv('MONGODB_MULTI_MONGOS_LB_URI');
551549

552-
assertNotFalse($singleMongosUri);
553-
assertNotFalse($multiMongosUri);
550+
assertNotEmpty($singleMongosUri);
551+
assertNotEmpty($multiMongosUri);
554552

555553
$context->setUrisForUseMultipleMongoses($singleMongosUri, $multiMongosUri);
556554
}

0 commit comments

Comments
 (0)