Skip to content

PHPLIB-1202: Assume sharded clusters use replica sets #1133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions tests/DocumentationExamplesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1550,7 +1550,7 @@ public function testSnapshotQueries(): void
{
$this->skipIfServerVersion('<', '5.0.0', 'Snapshot queries outside of transactions are not supported');

if (! ($this->isReplicaSet() || $this->isShardedClusterUsingReplicasets())) {
if ($this->isStandalone()) {
$this->markTestSkipped('Snapshot read concern is only supported with replicasets');
}

Expand Down Expand Up @@ -1803,7 +1803,7 @@ public function testWithTransactionExample(): void
*/
public function testQueryableEncryption(): void
{
if ($this->isStandalone() || ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets())) {
if ($this->isStandalone()) {
$this->markTestSkipped('Queryable encryption requires replica sets');
}

Expand Down
62 changes: 6 additions & 56 deletions tests/FunctionalTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use MongoDB\Driver\Command;
use MongoDB\Driver\Exception\CommandException;
use MongoDB\Driver\Manager;
use MongoDB\Driver\Query;
use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\Server;
use MongoDB\Driver\ServerApi;
Expand Down Expand Up @@ -444,33 +443,6 @@ protected function isShardedCluster()
return false;
}

protected function isShardedClusterUsingReplicasets()
{
// Assume serverless is a sharded cluster using replica sets
if (static::isServerless()) {
return true;
}

$cursor = $this->getPrimaryServer()->executeQuery(
'config.shards',
new Query([], ['limit' => 1]),
);

$cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
$document = current($cursor->toArray());

if (! $document) {
return false;
}

/**
* Use regular expression to distinguish between standalone or replicaset:
* Without a replicaset: "host" : "localhost:4100"
* With a replicaset: "host" : "dec6d8a7-9bc1-4c0e-960c-615f860b956f/localhost:4400,localhost:4401"
*/
return preg_match('@^.*/.*:\d+@', $document['host']);
}

protected function skipIfServerVersion(string $operator, string $version, ?string $message = null): void
{
if (version_compare($this->getServerVersion(), $version, $operator)) {
Expand All @@ -480,43 +452,25 @@ protected function skipIfServerVersion(string $operator, string $version, ?strin

protected function skipIfChangeStreamIsNotSupported(): void
{
switch ($this->getPrimaryServer()->getType()) {
case Server::TYPE_MONGOS:
case Server::TYPE_LOAD_BALANCER:
if (! $this->isShardedClusterUsingReplicasets()) {
$this->markTestSkipped('$changeStream is only supported with replicasets');
}

break;

case Server::TYPE_RS_PRIMARY:
break;

default:
$this->markTestSkipped('$changeStream is not supported');
if ($this->isStandalone()) {
$this->markTestSkipped('$changeStream requires replica sets');
}
}

protected function skipIfCausalConsistencyIsNotSupported(): void
{
switch ($this->getPrimaryServer()->getType()) {
case Server::TYPE_MONGOS:
case Server::TYPE_LOAD_BALANCER:
if (! $this->isShardedClusterUsingReplicasets()) {
$this->markTestSkipped('Causal Consistency is only supported with replicasets');
}

case Server::TYPE_STANDALONE:
$this->markTestSkipped('Causal consistency requires replica sets');
break;

case Server::TYPE_RS_PRIMARY:
// Note: mongos does not report storage engine information
if ($this->getServerStorageEngine() !== 'wiredTiger') {
$this->markTestSkipped('Causal Consistency requires WiredTiger storage engine');
$this->markTestSkipped('Causal consistency requires WiredTiger storage engine');
}

break;

default:
$this->markTestSkipped('Causal Consistency is not supported');
}
}

Expand Down Expand Up @@ -549,10 +503,6 @@ protected function skipIfTransactionsAreNotSupported(): void
}

if ($this->isShardedCluster()) {
if (! $this->isShardedClusterUsingReplicasets()) {
$this->markTestSkipped('Transactions are not supported on sharded clusters without replica sets');
}

if (version_compare($this->getFeatureCompatibilityVersion(), '4.2', '<')) {
$this->markTestSkipped('Transactions are only supported on FCV 4.2 or higher');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function setUp(): void
$this->markTestSkipped('Neither crypt_shared nor mongocryptd are available');
}

if ($this->isStandalone() || ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets())) {
if ($this->isStandalone()) {
$this->markTestSkipped('Queryable Encryption requires replica sets');
}

Expand Down
2 changes: 1 addition & 1 deletion tests/Operation/FindAndModifyFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public function testHintOptionAndUnacknowledgedWriteConcernUnsupportedClientSide

public function testFindAndModifyReportedWriteConcernError(): void
{
if (($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets()) || ! $this->isReplicaSet()) {
if ($this->isStandalone()) {
$this->markTestSkipped('Test only applies to replica sets');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function setUp(): void
{
parent::setUp();

if ($this->isStandalone() || ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets())) {
if ($this->isStandalone()) {
$this->markTestSkipped('Automatic data encryption key tests require replica sets');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function setUp(): void
{
parent::setUp();

if ($this->isStandalone() || ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets())) {
if ($this->isStandalone()) {
$this->markTestSkipped('Range explicit encryption tests require replica sets');
}

Expand Down
2 changes: 1 addition & 1 deletion tests/SpecTests/ClientSideEncryptionSpecTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,7 @@ static function (self $test, ClientEncryption $clientEncryptionNoClientCert, Cli
*/
public function testExplicitEncryption(Closure $test): void
{
if ($this->isStandalone() || ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets())) {
if ($this->isStandalone()) {
$this->markTestSkipped('Explicit encryption tests require replica sets');
}

Expand Down
4 changes: 0 additions & 4 deletions tests/SpecTests/RetryableWritesSpecTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ class RetryableWritesSpecTest extends FunctionalTestCase
*/
public function testRetryableWrites(stdClass $test, ?array $runOn, array $data): void
{
if ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets()) {
$this->markTestSkipped('Transaction numbers are only allowed on a replica set member or mongos (PHPC-1415)');
}

$useMultipleMongoses = isset($test->useMultipleMongoses) && $test->useMultipleMongoses && $this->isMongos();

if (isset($runOn)) {
Expand Down
25 changes: 4 additions & 21 deletions tests/UnifiedSpecTests/UnifiedTestRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
use function PHPUnit\Framework\assertIsString;
use function PHPUnit\Framework\assertNotEmpty;
use function PHPUnit\Framework\assertNotFalse;
use function preg_match;
use function preg_replace;
use function sprintf;
use function strlen;
Expand Down Expand Up @@ -299,9 +298,10 @@ private function getTopology(): string
return RunOnRequirement::TOPOLOGY_REPLICASET;

case Server::TYPE_MONGOS:
return $this->isShardedClusterUsingReplicasets()
? RunOnRequirement::TOPOLOGY_SHARDED_REPLICASET
: RunOnRequirement::TOPOLOGY_SHARDED;
/* Since MongoDB 3.6, all sharded clusters use replica sets. The
* unified test format deprecated use of "sharded-replicaset" in
* tests but we should still identify as such. */
return RunOnRequirement::TOPOLOGY_SHARDED_REPLICASET;

case Server::TYPE_LOAD_BALANCER:
return RunOnRequirement::TOPOLOGY_LOAD_BALANCED;
Expand Down Expand Up @@ -368,23 +368,6 @@ private function isSchemaVersionSupported(string $schemaVersion): bool
return version_compare($schemaVersion, self::MIN_SCHEMA_VERSION, '>=') && version_compare($schemaVersion, self::MAX_SCHEMA_VERSION, '<=');
}

private function isShardedClusterUsingReplicasets(): bool
{
$collection = $this->internalClient->selectCollection('config', 'shards');
$config = $collection->findOne();

if ($config === null) {
return false;
}

/**
* Use regular expression to distinguish between standalone or replicaset:
* Without a replicaset: "host" : "localhost:4100"
* With a replicaset: "host" : "dec6d8a7-9bc1-4c0e-960c-615f860b956f/localhost:4400,localhost:4401"
*/
return preg_match('@^.*/.*:\d+@', $config['host']);
}

/**
* Kill all sessions on the cluster.
*
Expand Down