diff options
author | Maria van Keulen <maria@mongodb.com> | 2018-01-17 17:17:48 -0500 |
---|---|---|
committer | Maria van Keulen <maria@mongodb.com> | 2018-02-01 18:18:32 -0500 |
commit | 00b93fd8f7ce1cb74ff25c1f20f7e548a14f6976 (patch) | |
tree | 5a500731cf56896114b7be4e12e46888775b1541 /src/mongo | |
parent | c9bc429c104c17a6ab8d971245b9b9a39636ef27 (diff) | |
download | mongo-00b93fd8f7ce1cb74ff25c1f20f7e548a14f6976.tar.gz |
SERVER-32741 Initialize the featureCompatibilityVersion parameter value to 3.6
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/catalog/database_test.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/catalog/drop_database_test.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/catalog/rename_collection_test.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/commands/feature_compatibility_version.cpp | 17 | ||||
-rw-r--r-- | src/mongo/db/commands/feature_compatibility_version.h | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/apply_ops_test.cpp | 34 | ||||
-rw-r--r-- | src/mongo/db/repl/check_quorum_for_config_change_test.cpp | 1 | ||||
-rw-r--r-- | src/mongo/db/repl/do_txn_test.cpp | 26 | ||||
-rw-r--r-- | src/mongo/db/repl/drop_pending_collection_reaper_test.cpp | 24 | ||||
-rw-r--r-- | src/mongo/db/repl/initial_syncer.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl_test.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_recovery_test.cpp | 19 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl_test.cpp | 252 | ||||
-rw-r--r-- | src/mongo/db/server_options.h | 14 | ||||
-rw-r--r-- | src/mongo/db/service_context_d_test_fixture.cpp | 12 | ||||
-rw-r--r-- | src/mongo/shell/shardingtest.js | 2 |
16 files changed, 182 insertions, 250 deletions
diff --git a/src/mongo/db/catalog/database_test.cpp b/src/mongo/db/catalog/database_test.cpp index 2671183e747..4610735077b 100644 --- a/src/mongo/db/catalog/database_test.cpp +++ b/src/mongo/db/catalog/database_test.cpp @@ -42,6 +42,7 @@ #include "mongo/db/namespace_string.h" #include "mongo/db/op_observer.h" #include "mongo/db/op_observer_impl.h" +#include "mongo/db/op_observer_registry.h" #include "mongo/db/operation_context.h" #include "mongo/db/repl/drop_pending_collection_reaper.h" #include "mongo/db/repl/oplog.h" @@ -97,7 +98,9 @@ void DatabaseTest::setUp() { // Set up OpObserver so that Database will append actual oplog entries to the oplog using // repl::logOp(). repl::logOp() will also store the oplog entry's optime in ReplClientInfo. - service->setOpObserver(stdx::make_unique<OpObserverImpl>()); + OpObserverRegistry* opObserverRegistry = + dynamic_cast<OpObserverRegistry*>(service->getOpObserver()); + opObserverRegistry->addObserver(stdx::make_unique<OpObserverImpl>()); _nss = NamespaceString("test.foo"); } diff --git a/src/mongo/db/catalog/drop_database_test.cpp b/src/mongo/db/catalog/drop_database_test.cpp index 9b5aa45c9d3..ee2a899c1eb 100644 --- a/src/mongo/db/catalog/drop_database_test.cpp +++ b/src/mongo/db/catalog/drop_database_test.cpp @@ -39,6 +39,7 @@ #include "mongo/db/namespace_string.h" #include "mongo/db/op_observer.h" #include "mongo/db/op_observer_noop.h" +#include "mongo/db/op_observer_registry.h" #include "mongo/db/operation_context.h" #include "mongo/db/repl/drop_pending_collection_reaper.h" #include "mongo/db/repl/oplog.h" @@ -143,9 +144,11 @@ void DropDatabaseTest::setUp() { ASSERT_OK(_replCoord->setFollowerMode(repl::MemberState::RS_PRIMARY)); // Use OpObserverMock to track notifications for collection and database drops. - auto opObserver = stdx::make_unique<OpObserverMock>(); - _opObserver = opObserver.get(); - service->setOpObserver(std::move(opObserver)); + OpObserverRegistry* opObserverRegistry = + dynamic_cast<OpObserverRegistry*>(service->getOpObserver()); + auto mockObserver = stdx::make_unique<OpObserverMock>(); + _opObserver = mockObserver.get(); + opObserverRegistry->addObserver(std::move(mockObserver)); _nss = NamespaceString("test.foo"); } diff --git a/src/mongo/db/catalog/rename_collection_test.cpp b/src/mongo/db/catalog/rename_collection_test.cpp index bc99b849732..741e2800b84 100644 --- a/src/mongo/db/catalog/rename_collection_test.cpp +++ b/src/mongo/db/catalog/rename_collection_test.cpp @@ -440,13 +440,6 @@ TEST_F(RenameCollectionTest, IndexNameTooLongForTemporaryCollectionForRenameAcro renameCollection(_opCtx.get(), _sourceNss, _targetNssDifferentDb, {})); } -TEST_F(RenameCollectionTest, RenameCollectionAcrossDatabaseWithoutUuid) { - _createCollection(_opCtx.get(), _sourceNss); - ASSERT_OK(renameCollection(_opCtx.get(), _sourceNss, _targetNssDifferentDb, {})); - ASSERT_FALSE(_collectionExists(_opCtx.get(), _sourceNss)); - ASSERT_FALSE(_getCollectionOptions(_opCtx.get(), _targetNssDifferentDb).uuid); -} - TEST_F(RenameCollectionTest, RenameCollectionAcrossDatabaseWithUuid) { auto options = _makeCollectionOptionsWithUuid(); _createCollection(_opCtx.get(), _sourceNss, options); diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp index 59b21bd46e2..98c62ba3a6d 100644 --- a/src/mongo/db/commands/feature_compatibility_version.cpp +++ b/src/mongo/db/commands/feature_compatibility_version.cpp @@ -62,7 +62,7 @@ Lock::ResourceMutex FeatureCompatibilityVersion::fcvLock("featureCompatibilityVe StatusWith<ServerGlobalParams::FeatureCompatibility::Version> FeatureCompatibilityVersion::parse( const BSONObj& featureCompatibilityVersionDoc) { ServerGlobalParams::FeatureCompatibility::Version version = - ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault34Behavior; + ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault36Behavior; std::string versionString; std::string targetVersionString; @@ -271,19 +271,12 @@ void FeatureCompatibilityVersion::setIfCleanStartup(OperationContext* opCtx, { CollectionOptions options; options.uuid = CollectionUUID::gen(); - - // Only for 3.4 shard servers, we create admin.system.version without UUID on clean startup. - // The mention of kFullyDowngradedTo34 below is to ensure this will not compile in 4.0. - if (!storeUpgradeVersion && - serverGlobalParams.featureCompatibility.getVersion() == - ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34) - options.uuid.reset(); - uassertStatusOK(storageInterface->createCollection(opCtx, nss, options)); } // We then insert the featureCompatibilityVersion document into the "admin.system.version" // collection. The server parameter will be updated on commit by the op observer. + // TODO(SERVER-32597): If storeUpgradeVersion is true, kVersion38 should be stored. uassertStatusOK(storageInterface->insertDocument( opCtx, nss, @@ -292,7 +285,7 @@ void FeatureCompatibilityVersion::setIfCleanStartup(OperationContext* opCtx, << FeatureCompatibilityVersion::kVersionField << (storeUpgradeVersion ? FeatureCompatibilityVersionCommandParser::kVersion36 - : FeatureCompatibilityVersionCommandParser::kVersion34)), + : FeatureCompatibilityVersionCommandParser::kVersion36)), Timestamp()}, repl::OpTime::kUninitializedTerm)); // No timestamp or term because this write is not // replicated. @@ -389,7 +382,7 @@ void FeatureCompatibilityVersion::updateMinWireVersion() { spec.incomingInternalClient.minWireVersion = LATEST_WIRE_VERSION - 2; spec.outgoing.minWireVersion = LATEST_WIRE_VERSION - 2; return; - case ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault34Behavior: + case ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault36Behavior: // getVersion() does not return this value. MONGO_UNREACHABLE; } @@ -504,7 +497,7 @@ public: FeatureCompatibilityVersion::kVersionField, FeatureCompatibilityVersionCommandParser::kVersion34); return; - case ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault34Behavior: + case ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault36Behavior: // getVersion() does not return this value. MONGO_UNREACHABLE; } diff --git a/src/mongo/db/commands/feature_compatibility_version.h b/src/mongo/db/commands/feature_compatibility_version.h index d124a5d0a72..7634203531e 100644 --- a/src/mongo/db/commands/feature_compatibility_version.h +++ b/src/mongo/db/commands/feature_compatibility_version.h @@ -70,7 +70,7 @@ public: static StringData toString(ServerGlobalParams::FeatureCompatibility::Version version) { switch (version) { - case ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault34Behavior: + case ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault36Behavior: return FeatureCompatibilityVersionCommandParser::kVersionUnset; case ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34: return FeatureCompatibilityVersionCommandParser::kVersion34; diff --git a/src/mongo/db/repl/apply_ops_test.cpp b/src/mongo/db/repl/apply_ops_test.cpp index 525c23c2573..7631ac2f9e9 100644 --- a/src/mongo/db/repl/apply_ops_test.cpp +++ b/src/mongo/db/repl/apply_ops_test.cpp @@ -161,6 +161,9 @@ TEST_F(ApplyOpsTest, CommandInNestedApplyOpsReturnsSuccess) { TEST_F(ApplyOpsTest, InsertInNestedApplyOpsReturnsSuccess) { auto opCtx = cc().makeOperationContext(); auto mode = OplogApplication::Mode::kApplyOpsCmd; + // Make sure the apply ops command object contains the correct UUID information. + CollectionOptions options; + options.uuid = UUID::gen(); BSONObjBuilder resultBuilder; NamespaceString nss("test", "foo"); auto innerCmdObj = BSON("op" @@ -169,7 +172,9 @@ TEST_F(ApplyOpsTest, InsertInNestedApplyOpsReturnsSuccess) { << nss.ns() << "o" << BSON("_id" - << "a")); + << "a") + << "ui" + << options.uuid.get()); auto innerApplyOpsObj = BSON("op" << "c" << "ns" @@ -178,7 +183,7 @@ TEST_F(ApplyOpsTest, InsertInNestedApplyOpsReturnsSuccess) { << BSON("applyOps" << BSON_ARRAY(innerCmdObj))); auto cmdObj = BSON("applyOps" << BSON_ARRAY(innerApplyOpsObj)); - ASSERT_OK(_storage->createCollection(opCtx.get(), nss, CollectionOptions())); + ASSERT_OK(_storage->createCollection(opCtx.get(), nss, options)); ASSERT_OK(applyOps(opCtx.get(), nss.db().toString(), cmdObj, mode, &resultBuilder)); ASSERT_BSONOBJ_EQ(BSON("applyOps" << BSON_ARRAY(innerCmdObj)), _opObserver->onApplyOpsCmdObj); } @@ -230,21 +235,6 @@ TEST_F(ApplyOpsTest, ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, status); } -TEST_F(ApplyOpsTest, AtomicApplyOpsInsertIntoCollectionWithoutUuid) { - auto opCtx = cc().makeOperationContext(); - auto mode = OplogApplication::Mode::kApplyOpsCmd; - NamespaceString nss("test.t"); - - // Collection has no uuid. - CollectionOptions collectionOptions; - ASSERT_OK(_storage->createCollection(opCtx.get(), nss, collectionOptions)); - - auto documentToInsert = BSON("_id" << 0); - auto cmdObj = makeApplyOpsWithInsertOperation(nss, boost::none, documentToInsert); - BSONObjBuilder resultBuilder; - ASSERT_OK(applyOps(opCtx.get(), "test", cmdObj, mode, &resultBuilder)); - ASSERT_BSONOBJ_EQ(cmdObj, _opObserver->onApplyOpsCmdObj); -} TEST_F(ApplyOpsTest, AtomicApplyOpsInsertWithUuidIntoCollectionWithUuid) { auto opCtx = cc().makeOperationContext(); @@ -264,21 +254,23 @@ TEST_F(ApplyOpsTest, AtomicApplyOpsInsertWithUuidIntoCollectionWithUuid) { ASSERT_BSONOBJ_EQ(cmdObj, _opObserver->onApplyOpsCmdObj); } -TEST_F(ApplyOpsTest, AtomicApplyOpsInsertWithUuidIntoCollectionWithoutUuid) { +TEST_F(ApplyOpsTest, AtomicApplyOpsInsertWithUuidIntoCollectionWithOtherUuid) { auto opCtx = cc().makeOperationContext(); auto mode = OplogApplication::Mode::kApplyOpsCmd; NamespaceString nss("test.t"); - auto uuid = UUID::gen(); + auto applyOpsUuid = UUID::gen(); - // Collection has no uuid. + // Collection has a different UUID. CollectionOptions collectionOptions; + collectionOptions.uuid = UUID::gen(); + ASSERT_NOT_EQUALS(applyOpsUuid, collectionOptions.uuid); ASSERT_OK(_storage->createCollection(opCtx.get(), nss, collectionOptions)); // The applyOps returns a NamespaceNotFound error because of the failed UUID lookup // even though a collection exists with the same namespace as the insert operation. auto documentToInsert = BSON("_id" << 0); - auto cmdObj = makeApplyOpsWithInsertOperation(nss, uuid, documentToInsert); + auto cmdObj = makeApplyOpsWithInsertOperation(nss, applyOpsUuid, documentToInsert); BSONObjBuilder resultBuilder; ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, applyOps(opCtx.get(), "test", cmdObj, mode, &resultBuilder)); diff --git a/src/mongo/db/repl/check_quorum_for_config_change_test.cpp b/src/mongo/db/repl/check_quorum_for_config_change_test.cpp index a81c5cd9d8c..e89721fa708 100644 --- a/src/mongo/db/repl/check_quorum_for_config_change_test.cpp +++ b/src/mongo/db/repl/check_quorum_for_config_change_test.cpp @@ -208,6 +208,7 @@ TEST_F(CheckQuorumForInitiate, QuorumCheckFailedDueToSeveralDownNodes) { const BSONObj makeHeartbeatRequest(const ReplSetConfig& rsConfig, int myConfigIndex) { const MemberConfig& myConfig = rsConfig.getMemberAt(myConfigIndex); ReplSetHeartbeatArgsV1 hbArgs; + hbArgs.setHeartbeatVersion(1); hbArgs.setSetName(rsConfig.getReplSetName()); hbArgs.setConfigVersion(rsConfig.getConfigVersion()); if (rsConfig.getConfigVersion() == 1) { diff --git a/src/mongo/db/repl/do_txn_test.cpp b/src/mongo/db/repl/do_txn_test.cpp index 419b28a82e2..b70c21d1635 100644 --- a/src/mongo/db/repl/do_txn_test.cpp +++ b/src/mongo/db/repl/do_txn_test.cpp @@ -194,22 +194,6 @@ TEST_F(DoTxnTest, AtomicDoTxnInsertIntoNonexistentCollectionReturnsNamespaceNotF ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, status); } -TEST_F(DoTxnTest, AtomicDoTxnInsertIntoCollectionWithoutUuid) { - auto opCtx = cc().makeOperationContext(); - NamespaceString nss("test.t"); - - // Collection has no uuid. - CollectionOptions collectionOptions; - ASSERT_OK(_storage->createCollection(opCtx.get(), nss, collectionOptions)); - - auto documentToInsert = BSON("_id" << 0); - auto cmdObj = makeDoTxnWithInsertOperation(nss, boost::none, documentToInsert); - auto expectedCmdObj = makeApplyOpsWithInsertOperation(nss, boost::none, documentToInsert); - BSONObjBuilder resultBuilder; - ASSERT_OK(doTxn(opCtx.get(), "test", cmdObj, &resultBuilder)); - ASSERT_BSONOBJ_EQ(expectedCmdObj, _opObserver->onApplyOpsCmdObj); -} - TEST_F(DoTxnTest, AtomicDoTxnInsertWithUuidIntoCollectionWithUuid) { auto opCtx = cc().makeOperationContext(); NamespaceString nss("test.t"); @@ -228,20 +212,22 @@ TEST_F(DoTxnTest, AtomicDoTxnInsertWithUuidIntoCollectionWithUuid) { ASSERT_BSONOBJ_EQ(expectedCmdObj, _opObserver->onApplyOpsCmdObj); } -TEST_F(DoTxnTest, AtomicDoTxnInsertWithUuidIntoCollectionWithoutUuid) { +TEST_F(DoTxnTest, AtomicDoTxnInsertWithUuidIntoCollectionWithOtherUuid) { auto opCtx = cc().makeOperationContext(); NamespaceString nss("test.t"); - auto uuid = UUID::gen(); + auto doTxnUuid = UUID::gen(); - // Collection has no uuid. + // Collection has a different UUID. CollectionOptions collectionOptions; + collectionOptions.uuid = UUID::gen(); + ASSERT_NOT_EQUALS(doTxnUuid, collectionOptions.uuid); ASSERT_OK(_storage->createCollection(opCtx.get(), nss, collectionOptions)); // The doTxn returns a NamespaceNotFound error because of the failed UUID lookup // even though a collection exists with the same namespace as the insert operation. auto documentToInsert = BSON("_id" << 0); - auto cmdObj = makeDoTxnWithInsertOperation(nss, uuid, documentToInsert); + auto cmdObj = makeDoTxnWithInsertOperation(nss, doTxnUuid, documentToInsert); BSONObjBuilder resultBuilder; ASSERT_EQUALS(ErrorCodes::UnknownError, doTxn(opCtx.get(), "test", cmdObj, &resultBuilder)); auto result = resultBuilder.obj(); diff --git a/src/mongo/db/repl/drop_pending_collection_reaper_test.cpp b/src/mongo/db/repl/drop_pending_collection_reaper_test.cpp index 8f733d8ca6e..024771ec949 100644 --- a/src/mongo/db/repl/drop_pending_collection_reaper_test.cpp +++ b/src/mongo/db/repl/drop_pending_collection_reaper_test.cpp @@ -30,8 +30,10 @@ #include <memory> +#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/jsobj.h" +#include "mongo/db/op_observer_registry.h" #include "mongo/db/repl/drop_pending_collection_reaper.h" #include "mongo/db/repl/optime.h" #include "mongo/db/repl/replication_coordinator.h" @@ -60,6 +62,14 @@ protected: */ bool collectionExists(OperationContext* opCtx, const NamespaceString& nss); + /** + * Generates a default CollectionOptions object with a UUID. These options should be used + * when creating a collection in this test because otherwise, collections will not be created + * with UUIDs. All collections are expected to have UUIDs. + * TODO(SERVER-31540) Remove once UUID is no longer a boost::optional in CollectionOptions. + */ + CollectionOptions generateOptionsWithUuid(); + std::unique_ptr<StorageInterface> _storageInterface; }; @@ -80,6 +90,12 @@ bool DropPendingCollectionReaperTest::collectionExists(OperationContext* opCtx, return _storageInterface->getCollectionCount(opCtx, nss).isOK(); } +CollectionOptions DropPendingCollectionReaperTest::generateOptionsWithUuid() { + CollectionOptions options; + options.uuid = UUID::gen(); + return options; +} + ServiceContext::UniqueOperationContext makeOpCtx() { return cc().makeOperationContext(); } @@ -153,7 +169,8 @@ TEST_F(DropPendingCollectionReaperTest, opTime[i] = OpTime({Seconds((i + 1) * 10), 0}, 1LL); ns[i] = NamespaceString("test", str::stream() << "coll" << i); dpns[i] = ns[i].makeDropPendingNamespace(opTime[i]); - _storageInterface->createCollection(opCtx.get(), dpns[i], {}).transitional_ignore(); + _storageInterface->createCollection(opCtx.get(), dpns[i], generateOptionsWithUuid()) + .transitional_ignore(); } // Add drop-pending namespaces with drop optimes out of order and check that @@ -265,7 +282,8 @@ TEST_F(DropPendingCollectionReaperTest, RollBackDropPendingCollection) { opTime[i] = OpTime({Seconds((i + 1) * 10), 0}, 1LL); ns[i] = NamespaceString("test", str::stream() << "coll" << i); dpns[i] = ns[i].makeDropPendingNamespace(opTime[i]); - ASSERT_OK(_storageInterface->createCollection(opCtx.get(), dpns[i], {})); + ASSERT_OK( + _storageInterface->createCollection(opCtx.get(), dpns[i], generateOptionsWithUuid())); } DropPendingCollectionReaper reaper(_storageInterface.get()); @@ -300,7 +318,7 @@ TEST_F(DropPendingCollectionReaperTest, RollBackDropPendingCollection) { // only removes a single collection from the list of drop-pending namespaces NamespaceString ns4 = NamespaceString("test", "coll4"); NamespaceString dpns4 = ns4.makeDropPendingNamespace(opTime[1]); - ASSERT_OK(_storageInterface->createCollection(opCtx.get(), dpns4, {})); + ASSERT_OK(_storageInterface->createCollection(opCtx.get(), dpns4, generateOptionsWithUuid())); reaper.addDropPendingNamespace(opTime[1], dpns4); ASSERT_TRUE(reaper.rollBackDropPendingCollection(opCtx.get(), opTime[1], ns[1])); ASSERT_EQUALS(opTime[1], *reaper.getEarliestDropOpTime()); diff --git a/src/mongo/db/repl/initial_syncer.cpp b/src/mongo/db/repl/initial_syncer.cpp index 18f9ea8c907..0591b2230ea 100644 --- a/src/mongo/db/repl/initial_syncer.cpp +++ b/src/mongo/db/repl/initial_syncer.cpp @@ -427,9 +427,9 @@ void InitialSyncer::_startInitialSyncAttemptCallback( _lastApplied = {}; _lastFetched = {}; - LOG(2) << "Resetting feature compatibility version to 3.4. If the sync source is in feature " - "compatibility version 3.6, we will find out when we clone the admin.system.version " - "collection."; + LOG(2) << "Resetting feature compatibility version to last-stable. If the sync source is in " + "latest feature compatibility version, we will find out when we clone the " + "admin.system.version collection."; serverGlobalParams.featureCompatibility.reset(); // Clear the oplog buffer. diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp index 318ec29d11c..42955b0a207 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp @@ -335,6 +335,7 @@ TEST_F(ReplCoordTest, NodeReturnsNodeNotFoundWhenQuorumCheckFailsWhileInitiating hbArgs.setSenderHost(HostAndPort("node1", 12345)); hbArgs.setSenderId(0); hbArgs.setTerm(0); + hbArgs.setHeartbeatVersion(1); Status status(ErrorCodes::InternalError, "Not set"); stdx::thread prsiThread([&] { doReplSetInitiate(getReplCoord(), &status); }); @@ -367,6 +368,7 @@ TEST_F(ReplCoordTest, InitiateSucceedsWhenQuorumCheckPasses) { hbArgs.setSenderHost(HostAndPort("node1", 12345)); hbArgs.setSenderId(0); hbArgs.setTerm(0); + hbArgs.setHeartbeatVersion(1); auto appliedTS = Timestamp(3, 3); getReplCoord()->setMyLastAppliedOpTime(OpTime(appliedTS, 1)); diff --git a/src/mongo/db/repl/replication_recovery_test.cpp b/src/mongo/db/repl/replication_recovery_test.cpp index 37f075ff917..335c801101c 100644 --- a/src/mongo/db/repl/replication_recovery_test.cpp +++ b/src/mongo/db/repl/replication_recovery_test.cpp @@ -96,6 +96,18 @@ protected: return _consistencyMarkers.get(); } + /** + * Generates a default CollectionOptions object with a UUID. These options should be used + * when creating a collection in this test because otherwise, collections will not be created + * with UUIDs. All collections are expected to have UUIDs. + * TODO(SERVER-31540) Remove once UUID is no longer a boost::optional in CollectionOptions. + */ + CollectionOptions generateOptionsWithUuid() { + CollectionOptions options; + options.uuid = UUID::gen(); + return options; + } + private: void setUp() override { ServiceContextMongoDTest::setUp(); @@ -108,7 +120,7 @@ private: stdx::make_unique<ReplicationCoordinatorMock>(service)); ASSERT_OK(_storageInterface->createCollection( - getOperationContext(), testNs, CollectionOptions())); + getOperationContext(), testNs, generateOptionsWithUuid())); } void tearDown() override { @@ -153,6 +165,7 @@ CollectionOptions _createOplogCollectionOptions() { options.capped = true; options.cappedSize = 64 * 1024 * 1024LL; options.autoIndexId = CollectionOptions::NO; + options.uuid = UUID::gen(); return options; } @@ -212,7 +225,7 @@ TEST_F(ReplicationRecoveryTest, RecoveryWithNoOplogSucceeds) { // Create the database. ASSERT_OK(getStorageInterface()->createCollection( - opCtx, NamespaceString("local.other"), CollectionOptions())); + opCtx, NamespaceString("local.other"), generateOptionsWithUuid())); recovery.recoverFromOplog(opCtx); @@ -245,7 +258,7 @@ DEATH_TEST_F(ReplicationRecoveryTest, // Create the database. ASSERT_OK(getStorageInterface()->createCollection( - opCtx, NamespaceString("local.other"), CollectionOptions())); + opCtx, NamespaceString("local.other"), generateOptionsWithUuid())); recovery.recoverFromOplog(opCtx); } diff --git a/src/mongo/db/repl/storage_interface_impl_test.cpp b/src/mongo/db/repl/storage_interface_impl_test.cpp index c119935ab6f..8a7fbd9e0d4 100644 --- a/src/mongo/db/repl/storage_interface_impl_test.cpp +++ b/src/mongo/db/repl/storage_interface_impl_test.cpp @@ -84,10 +84,22 @@ NamespaceString makeNamespace(const T& t, const std::string& suffix = "") { } /** + * Generates a default CollectionOptions object with a UUID. These options should be used + * when creating a collection in this test because otherwise, collections will not be created + * with UUIDs. All collections are expected to have UUIDs. + * TODO(SERVER-31540) Remove once UUID is no longer a boost::optional in CollectionOptions. + */ +CollectionOptions generateOptionsWithUuid() { + CollectionOptions options; + options.uuid = UUID::gen(); + return options; +} + +/** * Creates collection options suitable for oplog. */ CollectionOptions createOplogCollectionOptions() { - CollectionOptions options; + CollectionOptions options = generateOptionsWithUuid(); options.capped = true; options.cappedSize = 64 * 1024 * 1024LL; options.autoIndexId = CollectionOptions::NO; @@ -100,7 +112,7 @@ CollectionOptions createOplogCollectionOptions() { */ void createCollection(OperationContext* opCtx, const NamespaceString& nss, - const CollectionOptions& options = CollectionOptions()) { + const CollectionOptions& options = generateOptionsWithUuid()) { writeConflictRetry(opCtx, "createCollection", nss.ns(), [&] { Lock::DBLock dblk(opCtx, nss.db(), MODE_X); OldClientContext ctx(opCtx, nss.ns()); @@ -395,7 +407,7 @@ TEST_F(StorageInterfaceImplTest, // Create a collection that does not support all-at-once inserting. auto opCtx = getOperationContext(); auto nss = makeNamespace(_agent); - CollectionOptions options; + CollectionOptions options = generateOptionsWithUuid(); options.capped = true; options.cappedSize = 1024 * 1024; createCollection(opCtx, nss, options); @@ -458,7 +470,7 @@ TEST_F(StorageInterfaceImplTest, InsertMissingDocWorksOnExistingCappedCollection auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - CollectionOptions opts; + CollectionOptions opts = generateOptionsWithUuid(); opts.capped = true; opts.cappedSize = 1024 * 1024; createCollection(opCtx, nss, opts); @@ -493,7 +505,7 @@ TEST_F(StorageInterfaceImplTest, CreateCollectionWithIDIndexCommits) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - CollectionOptions opts; + CollectionOptions opts = generateOptionsWithUuid(); std::vector<BSONObj> indexes; auto loaderStatus = storage.createCollectionForBulkLoading(nss, opts, makeIdIndexSpec(nss), indexes); @@ -519,7 +531,7 @@ void _testDestroyUncommitedCollectionBulkLoader( std::vector<BSONObj> secondaryIndexes, stdx::function<void(std::unique_ptr<CollectionBulkLoader> loader)> destroyLoaderFn) { StorageInterfaceImpl storage; - CollectionOptions opts; + CollectionOptions opts = generateOptionsWithUuid(); auto loaderStatus = storage.createCollectionForBulkLoading(nss, opts, makeIdIndexSpec(nss), secondaryIndexes); ASSERT_OK(loaderStatus.getStatus()); @@ -590,7 +602,7 @@ TEST_F(StorageInterfaceImplTest, CreateCollectionThatAlreadyExistsFails) { NamespaceString nss("test.system.indexes"); createCollection(opCtx, nss); - const CollectionOptions opts{}; + const CollectionOptions opts = generateOptionsWithUuid(); const std::vector<BSONObj> indexes; const auto status = storage.createCollectionForBulkLoading(nss, opts, makeIdIndexSpec(nss), indexes); @@ -624,7 +636,7 @@ TEST_F(StorageInterfaceImplTest, ASSERT_FALSE(autoColl.getCollection()); } - auto status = storage.createCollection(opCtx, nss, CollectionOptions()); + auto status = storage.createCollection(opCtx, nss, generateOptionsWithUuid()); ASSERT_EQUALS(ErrorCodes::duplicateCodeForTest(28838), status); ASSERT_STRING_CONTAINS(status.reason(), "cannot create a non-capped oplog collection"); } @@ -637,13 +649,13 @@ TEST_F(StorageInterfaceImplTest, CreateCollectionFailsIfCollectionExists) { AutoGetCollectionForReadCommand autoColl(opCtx, nss); ASSERT_FALSE(autoColl.getCollection()); } - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); { AutoGetCollectionForReadCommand autoColl(opCtx, nss); ASSERT_TRUE(autoColl.getCollection()); ASSERT_EQ(nss.toString(), autoColl.getCollection()->ns().toString()); } - auto status = storage.createCollection(opCtx, nss, CollectionOptions()); + auto status = storage.createCollection(opCtx, nss, generateOptionsWithUuid()); ASSERT_EQUALS(ErrorCodes::NamespaceExists, status); ASSERT_STRING_CONTAINS(status.reason(), str::stream() << "Collection " << nss.ns() << " already exists"); @@ -689,7 +701,7 @@ TEST_F(StorageInterfaceImplTest, DropCollectionWorksWithSystemCollection) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; - ASSERT_OK(storage.createCollection(opCtx, nss, {})); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_TRUE(AutoGetCollectionForReadCommand(opCtx, nss).getCollection()); ASSERT_OK(storage.dropCollection(opCtx, nss)); @@ -717,7 +729,7 @@ TEST_F(StorageInterfaceImplTest, RenameCollectionWithStayTempFalseMakesItNotTemp StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto toNss = NamespaceString("local.toNs"); - CollectionOptions opts; + CollectionOptions opts = generateOptionsWithUuid(); opts.temp = true; createCollection(opCtx, nss, opts); @@ -736,7 +748,7 @@ TEST_F(StorageInterfaceImplTest, RenameCollectionWithStayTempTrueMakesItTemp) { StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto toNss = NamespaceString("local.toNs"); - CollectionOptions opts; + CollectionOptions opts = generateOptionsWithUuid(); opts.temp = true; createCollection(opCtx, nss, opts); @@ -820,7 +832,7 @@ TEST_F(StorageInterfaceImplTest, FindDocumentsReturnsIndexNotFoundIfIndexIsMissi StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "nonexistent"_sd; - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_EQUALS(ErrorCodes::IndexNotFound, storage .findDocuments(opCtx, @@ -844,7 +856,7 @@ TEST_F(StorageInterfaceImplTest, FindDocumentsReturnsIndexOptionsConflictIfIndex << "partialFilterExpression" << BSON("y" << 1))}; auto loader = unittest::assertGet(storage.createCollectionForBulkLoading( - nss, CollectionOptions(), makeIdIndexSpec(nss), indexes)); + nss, generateOptionsWithUuid(), makeIdIndexSpec(nss), indexes)); std::vector<BSONObj> docs = {BSON("_id" << 1), BSON("_id" << 1), BSON("_id" << 2)}; ASSERT_OK(loader->insertDocuments(docs.begin(), docs.end())); ASSERT_OK(loader->commit()); @@ -866,7 +878,7 @@ TEST_F(StorageInterfaceImplTest, FindDocumentsReturnsEmptyVectorIfCollectionIsEm StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "_id_"_sd; - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_TRUE(unittest::assertGet(storage.findDocuments(opCtx, nss, indexName, @@ -924,7 +936,7 @@ TEST_F(StorageInterfaceImplTest, StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "_id_"_sd; - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK(storage.insertDocuments( opCtx, nss, @@ -1061,7 +1073,7 @@ TEST_F(StorageInterfaceImplTest, StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "_id_"_sd; - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1177,7 +1189,7 @@ TEST_F(StorageInterfaceImplTest, auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1208,7 +1220,7 @@ TEST_F(StorageInterfaceImplTest, auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1233,7 +1245,7 @@ TEST_F(StorageInterfaceImplTest, FindDocumentsCollScanReturnsNoSuchKeyIfStartKey auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1257,7 +1269,7 @@ TEST_F(StorageInterfaceImplTest, auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1298,7 +1310,7 @@ TEST_F(StorageInterfaceImplTest, DeleteDocumentsReturnsIndexNotFoundIfIndexIsMis StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "nonexistent"_sd; - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_EQUALS(ErrorCodes::IndexNotFound, storage .deleteDocuments(opCtx, @@ -1316,7 +1328,7 @@ TEST_F(StorageInterfaceImplTest, DeleteDocumentsReturnsEmptyVectorIfCollectionIs StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "_id_"_sd; - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_TRUE( unittest::assertGet(storage.deleteDocuments(opCtx, nss, @@ -1334,7 +1346,7 @@ TEST_F(StorageInterfaceImplTest, StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "_id_"_sd; - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1445,7 +1457,7 @@ TEST_F(StorageInterfaceImplTest, StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "_id_"_sd; - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1555,7 +1567,7 @@ TEST_F(StorageInterfaceImplTest, auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1580,7 +1592,7 @@ TEST_F(StorageInterfaceImplTest, auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1604,7 +1616,7 @@ TEST_F(StorageInterfaceImplTest, DeleteDocumentsCollScanReturnsNoSuchKeyIfStartK auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1628,7 +1640,7 @@ TEST_F(StorageInterfaceImplTest, auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -1658,7 +1670,8 @@ TEST_F(StorageInterfaceImplTest, FindSingletonReturnsNamespaceNotFoundWhenCollec auto opCtx = getOperationContext(); StorageInterfaceImpl storage; NamespaceString nss("db.coll1"); - ASSERT_OK(storage.createCollection(opCtx, NamespaceString("db.coll2"), CollectionOptions())); + ASSERT_OK( + storage.createCollection(opCtx, NamespaceString("db.coll2"), generateOptionsWithUuid())); ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, storage.findSingleton(opCtx, nss).getStatus()); } @@ -1666,7 +1679,7 @@ TEST_F(StorageInterfaceImplTest, FindSingletonReturnsCollectionIsEmptyWhenCollec auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_EQUALS(ErrorCodes::CollectionIsEmpty, storage.findSingleton(opCtx, nss).getStatus()); } @@ -1675,7 +1688,7 @@ TEST_F(StorageInterfaceImplTest, auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc1 = BSON("_id" << 0 << "x" << 0); auto doc2 = BSON("_id" << 1 << "x" << 1); ASSERT_OK(storage.insertDocuments(opCtx, @@ -1690,7 +1703,7 @@ TEST_F(StorageInterfaceImplTest, FindSingletonReturnsDocumentWhenSingletonDocume auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc1 = BSON("_id" << 0 << "x" << 0); ASSERT_OK(storage.insertDocument(opCtx, nss, {doc1, Timestamp(0)}, OpTime::kUninitializedTerm)); ASSERT_BSONOBJ_EQ(doc1, unittest::assertGet(storage.findSingleton(opCtx, nss))); @@ -1712,7 +1725,7 @@ TEST_F(StorageInterfaceImplTest, PutSingletonReturnsNamespaceNotFoundWhenCollect auto opCtx = getOperationContext(); StorageInterfaceImpl storage; NamespaceString nss("db.coll1"); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); TimestampedBSONObj update; update.obj = BSON("$set" << BSON("_id" << 0 << "x" << 1)); @@ -1726,7 +1739,7 @@ TEST_F(StorageInterfaceImplTest, PutSingletonUpsertsDocumentsWhenCollectionIsEmp auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); TimestampedBSONObj update; update.obj = BSON("$set" << BSON("_id" << 0 << "x" << 1)); @@ -1742,7 +1755,7 @@ TEST_F(StorageInterfaceImplTest, PutSingletonUpdatesDocumentWhenCollectionIsNotE auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc1 = BSON("_id" << 0 << "x" << 0); ASSERT_OK(storage.insertDocument(opCtx, nss, {doc1, Timestamp(0)}, OpTime::kUninitializedTerm)); @@ -1760,7 +1773,7 @@ TEST_F(StorageInterfaceImplTest, PutSingletonUpdatesFirstDocumentWhenCollectionI auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc1 = BSON("_id" << 0 << "x" << 0); auto doc2 = BSON("_id" << 1 << "x" << 1); ASSERT_OK(storage.insertDocuments(opCtx, @@ -1780,7 +1793,7 @@ TEST_F(StorageInterfaceImplTest, UpdateSingletonNeverUpserts) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); TimestampedBSONObj update; update.obj = BSON("$set" << BSON("_id" << 0 << "x" << 1)); @@ -1795,7 +1808,7 @@ TEST_F(StorageInterfaceImplTest, UpdateSingletonUpdatesDocumentWhenCollectionIsN auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc1 = BSON("_id" << 0 << "x" << 0); ASSERT_OK( storage.insertDocument(opCtx, nss, {doc1, Timestamp::min()}, OpTime::kUninitializedTerm)); @@ -1823,7 +1836,7 @@ TEST_F(StorageInterfaceImplTest, FindByIdReturnsNoSuchKeyWhenCollectionIsEmpty) auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc = BSON("_id" << 0 << "x" << 0); ASSERT_EQUALS(ErrorCodes::NoSuchKey, storage.findById(opCtx, nss, doc["_id"]).getStatus()); } @@ -1832,7 +1845,7 @@ TEST_F(StorageInterfaceImplTest, FindByIdReturnsNoSuchKeyWhenDocumentIsNotFound) auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc1 = BSON("_id" << 0 << "x" << 0); auto doc2 = BSON("_id" << 1 << "x" << 1); auto doc3 = BSON("_id" << 2 << "x" << 2); @@ -1847,7 +1860,7 @@ TEST_F(StorageInterfaceImplTest, FindByIdReturnsDocumentWhenDocumentExists) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc1 = BSON("_id" << 0 << "x" << 0); auto doc2 = BSON("_id" << 1 << "x" << 1); auto doc3 = BSON("_id" << 2 << "x" << 2); @@ -1872,7 +1885,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByIdReturnsNoSuchKeyWhenCollectionIsEmpty auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc = BSON("_id" << 0 << "x" << 0); ASSERT_EQUALS(ErrorCodes::NoSuchKey, storage.deleteById(opCtx, nss, doc["_id"]).getStatus()); _assertDocumentsInCollectionEquals(opCtx, nss, std::vector<BSONObj>{}); @@ -1882,7 +1895,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByIdReturnsNoSuchKeyWhenDocumentIsNotFoun auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc1 = BSON("_id" << 0 << "x" << 0); auto doc2 = BSON("_id" << 1 << "x" << 1); auto doc3 = BSON("_id" << 2 << "x" << 2); @@ -1898,7 +1911,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByIdReturnsDocumentWhenDocumentExists) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc1 = BSON("_id" << 0 << "x" << 0); auto doc2 = BSON("_id" << 1 << "x" << 1); auto doc3 = BSON("_id" << 2 << "x" << 2); @@ -1928,7 +1941,7 @@ TEST_F(StorageInterfaceImplTest, StorageInterfaceImpl storage; NamespaceString nss("mydb.coll"); NamespaceString wrongColl(nss.db(), "wrongColl"_sd); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc = BSON("_id" << 0 << "x" << 1); auto status = storage.upsertById(opCtx, wrongColl, doc["_id"], doc); ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, status); @@ -1940,7 +1953,7 @@ TEST_F(StorageInterfaceImplTest, UpsertSingleDocumentReplacesExistingDocumentInC auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto originalDoc = BSON("_id" << 1 << "x" << 1); ASSERT_OK(storage.insertDocuments( @@ -1963,7 +1976,7 @@ TEST_F(StorageInterfaceImplTest, UpsertSingleDocumentInsertsNewDocumentInCollect auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK(storage.insertDocuments( opCtx, @@ -1991,7 +2004,7 @@ TEST_F(StorageInterfaceImplTest, auto opCtx = getOperationContext(); StorageInterfaceImpl storage; - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto originalDoc = BSON("_id" << 1 << "x" << 1); ASSERT_OK(storage.insertDocuments( @@ -2014,7 +2027,7 @@ TEST_F(StorageInterfaceImplTest, UpsertSingleDocumentReturnsFailedToParseOnNonSi auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto status = storage.upsertById( opCtx, nss, BSON("" << BSON("$gt" << 3)).firstElement(), BSON("x" << 100)); @@ -2025,7 +2038,7 @@ TEST_F(StorageInterfaceImplTest, UpsertSingleDocumentReturnsFailedToParseOnNonSi TEST_F(StorageInterfaceImplTest, UpsertSingleDocumentReturnsIndexNotFoundIfCollectionDoesNotHaveAnIdIndex) { - CollectionOptions options; + CollectionOptions options = generateOptionsWithUuid(); options.setNoIdIndex(); auto opCtx = getOperationContext(); @@ -2045,7 +2058,7 @@ TEST_F(StorageInterfaceImplTest, auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_THROWS_CODE_AND_WHAT(storage .upsertById(opCtx, @@ -2076,7 +2089,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterReturnsBadValueWhenFilterContains auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto filter = BSON("x" << BSON("$unknownFilterOp" << 1)); auto status = storage.deleteByFilter(opCtx, nss, filter); @@ -2088,7 +2101,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterReturnsIllegalOperationOnCappedCo auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - CollectionOptions options; + CollectionOptions options = generateOptionsWithUuid(); options.capped = true; options.cappedSize = 1024 * 1024; ASSERT_OK(storage.createCollection(opCtx, nss, options)); @@ -2106,7 +2119,7 @@ TEST_F( auto opCtx = getOperationContext(); StorageInterfaceImpl storage; NamespaceString nss("mydb.mycoll"); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc = BSON("_id" << 0 << "x" << 0); ASSERT_OK( @@ -2132,7 +2145,7 @@ TEST_F( auto opCtx = getOperationContext(); StorageInterfaceImpl storage; NamespaceString nss("mydb.mycoll"); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto doc = BSON("_id" << 0 << "x" << 0); ASSERT_OK( @@ -2157,7 +2170,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterReturnsNamespaceNotFoundWhenColle StorageInterfaceImpl storage; NamespaceString nss("mydb.coll"); NamespaceString wrongColl(nss.db(), "wrongColl"_sd); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto filter = BSON("x" << 1); auto status = storage.deleteByFilter(opCtx, wrongColl, filter); ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, status); @@ -2173,7 +2186,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterReturnsSuccessIfCollectionIsEmpty auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK(storage.deleteByFilter(opCtx, nss, {})); @@ -2184,7 +2197,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterLeavesCollectionUnchangedIfNoDocu auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); std::vector<TimestampedBSONObj> docs = {{BSON("_id" << 0 << "x" << 0), Timestamp(0)}, {BSON("_id" << 2 << "x" << 2), Timestamp(0)}}; @@ -2200,7 +2213,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterRemoveDocumentsThatMatchFilter) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); std::vector<TimestampedBSONObj> docs = {{BSON("_id" << 0 << "x" << 0), Timestamp(0)}, {BSON("_id" << 1 << "x" << 1), Timestamp(0)}, @@ -2219,7 +2232,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterExpandsDottedFieldNamesAsPaths) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); std::vector<TimestampedBSONObj> docs = { {BSON("_id" << 0 << "x" << BSON("y" << 0)), Timestamp::min()}, @@ -2239,7 +2252,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterUsesIdHackIfFilterContainsIdField auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); std::vector<TimestampedBSONObj> docs = {{BSON("_id" << 0 << "x" << 0), Timestamp(0)}, {BSON("_id" << 1 << "x" << 1), Timestamp(0)}}; @@ -2260,7 +2273,7 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterRemovesDocumentsInIllegalClientSy auto opCtx = getOperationContext(); StorageInterfaceImpl storage; - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); std::vector<TimestampedBSONObj> docs = {{BSON("_id" << 0 << "x" << 0), Timestamp(0)}, {BSON("_id" << 1 << "x" << 1), Timestamp(0)}, @@ -2282,7 +2295,7 @@ TEST_F(StorageInterfaceImplTest, auto nss = makeNamespace(_agent); // Create a collection using a case-insensitive collation. - CollectionOptions options; + CollectionOptions options = generateOptionsWithUuid(); options.collation = BSON("locale" << "en_US" << "strength" @@ -2328,7 +2341,7 @@ TEST_F(StorageInterfaceImplTest, StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); NamespaceString wrongColl(nss.db(), "wrongColl"_sd); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, storage.getCollectionCount(opCtx, wrongColl).getStatus()); } @@ -2337,7 +2350,7 @@ TEST_F(StorageInterfaceImplTest, GetCollectionCountReturnsZeroOnEmptyCollection) auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto count = unittest::assertGet(storage.getCollectionCount(opCtx, nss)); ASSERT_EQUALS(0UL, count); } @@ -2346,7 +2359,7 @@ TEST_F(StorageInterfaceImplTest, GetCollectionCountReturnsCollectionCount) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, @@ -2358,103 +2371,6 @@ TEST_F(StorageInterfaceImplTest, GetCollectionCountReturnsCollectionCount) { } TEST_F(StorageInterfaceImplTest, - GetCollectionUUIDReturnsNamespaceNotFoundWhenDatabaseDoesNotExist) { - auto opCtx = getOperationContext(); - StorageInterfaceImpl storage; - NamespaceString nss("nosuchdb.coll"); - ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, storage.getCollectionUUID(opCtx, nss).getStatus()); -} - -TEST_F(StorageInterfaceImplTest, - GetCollectionUUIDReturnsNamespaceNotFoundWhenCollectionDoesNotExist) { - auto opCtx = getOperationContext(); - StorageInterfaceImpl storage; - auto nss = makeNamespace(_agent); - NamespaceString wrongColl(nss.db(), "wrongColl"_sd); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); - ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, - storage.getCollectionUUID(opCtx, wrongColl).getStatus()); -} - -TEST_F(StorageInterfaceImplTest, GetCollectionUUIDReturnsBoostNoneWhenCollectionHasNoUUID) { - auto opCtx = getOperationContext(); - StorageInterfaceImpl storage; - auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); - auto uuid = unittest::assertGet(storage.getCollectionUUID(opCtx, nss)); - ASSERT_EQ(uuid, boost::none); -} - -TEST_F(StorageInterfaceImplTest, GetCollectionUUIDReturnsUUIDIfExists) { - auto opCtx = getOperationContext(); - StorageInterfaceImpl storage; - auto nss = makeNamespace(_agent); - CollectionOptions options; - options.uuid = UUID::gen(); - ASSERT_OK(storage.createCollection(opCtx, nss, options)); - auto uuid = unittest::assertGet(storage.getCollectionUUID(opCtx, nss)); - ASSERT_EQ(uuid, options.uuid); -} - -TEST_F(StorageInterfaceImplTest, UpgradeUUIDSchemaVersionNonReplicatedUpgradesLocalCollections) { - auto opCtx = getOperationContext(); - StorageInterfaceImpl storage; - auto nss = makeNamespace(_agent); - - // Create a collection on the local database with no UUID. - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); - auto uuid = unittest::assertGet(storage.getCollectionUUID(opCtx, nss)); - ASSERT_EQ(uuid, boost::none); - ASSERT_OK(storage.upgradeUUIDSchemaVersionNonReplicated(opCtx)); - - // Ensure a UUID now exists on the collection. - uuid = unittest::assertGet(storage.getCollectionUUID(opCtx, nss)); - ASSERT_NOT_EQUALS(uuid, boost::none); -} - -TEST_F(StorageInterfaceImplTest, UpgradeUUIDSchemaVersionNonReplicatedIgnoresUpgradedCollections) { - auto opCtx = getOperationContext(); - StorageInterfaceImpl storage; - auto nss = makeNamespace(_agent); - CollectionOptions options; - options.uuid = UUID::gen(); - - // Create a collection on the local database with a UUID. - ASSERT_OK(storage.createCollection(opCtx, nss, options)); - auto uuid = unittest::assertGet(storage.getCollectionUUID(opCtx, nss)); - ASSERT_EQ(uuid, options.uuid); - ASSERT_OK(storage.upgradeUUIDSchemaVersionNonReplicated(opCtx)); - - // Ensure the UUID has not changed after the upgrade. - uuid = unittest::assertGet(storage.getCollectionUUID(opCtx, nss)); - ASSERT_EQUALS(uuid, options.uuid); -} - -TEST_F(StorageInterfaceImplTest, UpgradeUUIDSchemaVersionNonReplicatedUpgradesSystemDotProfile) { - auto opCtx = getOperationContext(); - StorageInterfaceImpl storage; - const NamespaceString nss("testdb", "system.profile"); - - // Create a system.profile collection with no UUID. - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); - auto uuid = unittest::assertGet(storage.getCollectionUUID(opCtx, nss)); - ASSERT_EQ(uuid, boost::none); - - // Also create another collection on the same database that will not be assigned a UUID. - const NamespaceString noUUIDNss("testdb", "noUUIDCollection"); - ASSERT_OK(storage.createCollection(opCtx, noUUIDNss, CollectionOptions())); - auto noUUID = unittest::assertGet(storage.getCollectionUUID(opCtx, noUUIDNss)); - ASSERT_EQ(noUUID, boost::none); - ASSERT_OK(storage.upgradeUUIDSchemaVersionNonReplicated(opCtx)); - - // Ensure a UUID now exists on the system.profile collection but not noUUIDCollection. - uuid = unittest::assertGet(storage.getCollectionUUID(opCtx, nss)); - ASSERT_NOT_EQUALS(uuid, boost::none); - noUUID = unittest::assertGet(storage.getCollectionUUID(opCtx, noUUIDNss)); - ASSERT_EQ(noUUID, boost::none); -} - -TEST_F(StorageInterfaceImplTest, GetCollectionSizeReturnsNamespaceNotFoundWhenDatabaseDoesNotExist) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; @@ -2468,7 +2384,7 @@ TEST_F(StorageInterfaceImplTest, StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); NamespaceString wrongColl(nss.db(), "wrongColl"_sd); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, storage.getCollectionSize(opCtx, wrongColl).getStatus()); } @@ -2477,7 +2393,7 @@ TEST_F(StorageInterfaceImplTest, GetCollectionSizeReturnsZeroOnEmptyCollection) auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); auto size = unittest::assertGet(storage.getCollectionSize(opCtx, nss)); ASSERT_EQUALS(0UL, size); } @@ -2486,7 +2402,7 @@ TEST_F(StorageInterfaceImplTest, GetCollectionSizeReturnsCollectionSize) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); - ASSERT_OK(storage.createCollection(opCtx, nss, CollectionOptions())); + ASSERT_OK(storage.createCollection(opCtx, nss, generateOptionsWithUuid())); ASSERT_OK( storage.insertDocuments(opCtx, nss, diff --git a/src/mongo/db/server_options.h b/src/mongo/db/server_options.h index 719b57102ea..826f5760313 100644 --- a/src/mongo/db/server_options.h +++ b/src/mongo/db/server_options.h @@ -173,11 +173,11 @@ struct ServerGlobalParams { * entries use the 3.4 format, but existing entries may have * either the 3.4 or 3.6 format * - * kUnsetDefault34Behavior + * kUnsetDefault36Behavior * (Unset, Unset): This is the case on startup before the fCV document is * loaded into memory. isVersionInitialized() will return * false, and getVersion() will return the default - * (kFullyDowngradedTo34). + * (kFullyUpgradedTo36). * * TODO: update this comment to 3.6/4.0 when FCV 3.4 is removed (SERVER-32597). */ @@ -185,7 +185,7 @@ struct ServerGlobalParams { // The order of these enums matter, higher upgrades having higher values, so that // features can be active or inactive if the version is higher than some minimum or // lower than some maximum, respectively. - kUnsetDefault34Behavior = 0, + kUnsetDefault36Behavior = 0, kFullyDowngradedTo34 = 1, kDowngradingTo34 = 2, kUpgradingTo36 = 3, @@ -200,7 +200,7 @@ struct ServerGlobalParams { * exposes the actual state of the featureCompatibilityVersion if it is uninitialized. */ const bool isVersionInitialized() const { - return _version.load() != Version::kUnsetDefault34Behavior; + return _version.load() != Version::kUnsetDefault36Behavior; } /** @@ -209,11 +209,11 @@ struct ServerGlobalParams { */ const Version getVersion() const { Version v = _version.load(); - return (v == Version::kUnsetDefault34Behavior) ? Version::kFullyDowngradedTo34 : v; + return (v == Version::kUnsetDefault36Behavior) ? Version::kFullyUpgradedTo36 : v; } void reset() { - _version.store(Version::kFullyDowngradedTo34); + _version.store(Version::kUnsetDefault36Behavior); } void setVersion(Version version) { @@ -227,7 +227,7 @@ struct ServerGlobalParams { } private: - AtomicWord<Version> _version{Version::kUnsetDefault34Behavior}; + AtomicWord<Version> _version{Version::kUnsetDefault36Behavior}; } featureCompatibility; diff --git a/src/mongo/db/service_context_d_test_fixture.cpp b/src/mongo/db/service_context_d_test_fixture.cpp index c47e554b633..ab8939ed51f 100644 --- a/src/mongo/db/service_context_d_test_fixture.cpp +++ b/src/mongo/db/service_context_d_test_fixture.cpp @@ -33,12 +33,14 @@ #include "mongo/base/checked_cast.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder.h" +#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/curop.h" #include "mongo/db/db_raii.h" #include "mongo/db/logical_clock.h" #include "mongo/db/op_observer_noop.h" +#include "mongo/db/op_observer_registry.h" #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" #include "mongo/db/service_context_d.h" @@ -70,6 +72,16 @@ void ServiceContextMongoDTest::setUp() { serviceContext->initializeGlobalStorageEngine(); serviceContext->setOpObserver(stdx::make_unique<OpObserverNoop>()); } + + // Set up UUID Catalog observer. This is necessary because the Collection destructor contains an + // invariant to ensure the UUID corresponding to that Collection object is no longer associated + // with that Collection object in the UUIDCatalog. UUIDs may be registered in the UUIDCatalog + // directly in certain code paths, but they can only be removed from the UUIDCatalog via a + // UUIDCatalogObserver. It is therefore necessary to install the observer to ensure the + // invariant in the Collection destructor is not triggered. + auto observerRegistry = stdx::make_unique<OpObserverRegistry>(); + observerRegistry->addObserver(stdx::make_unique<UUIDCatalogObserver>()); + serviceContext->setOpObserver(std::unique_ptr<OpObserver>(observerRegistry.release())); } void ServiceContextMongoDTest::tearDown() { diff --git a/src/mongo/shell/shardingtest.js b/src/mongo/shell/shardingtest.js index 4dd72ef5705..60beac8b19f 100644 --- a/src/mongo/shell/shardingtest.js +++ b/src/mongo/shell/shardingtest.js @@ -1341,7 +1341,7 @@ var ShardingTest = function(params) { const configRS = this.configRS; if (_hasNewFeatureCompatibilityVersion() && _isMixedVersionCluster()) { function setFeatureCompatibilityVersion() { - assert.commandWorked(csrsPrimary.adminCommand({setFeatureCompatibilityVersion: '3.4'})); + assert.commandWorked(csrsPrimary.adminCommand({setFeatureCompatibilityVersion: '3.6'})); // Wait for the new featureCompatibilityVersion to propagate to all nodes in the CSRS // to ensure that older versions of mongos can successfully connect. |