diff --git a/src/mongo/db/storage/inmemory/SConscript b/src/mongo/db/storage/inmemory/SConscript index 07ce2ed1009cd..4fbef3b7885be 100644 --- a/src/mongo/db/storage/inmemory/SConscript +++ b/src/mongo/db/storage/inmemory/SConscript @@ -48,6 +48,7 @@ if inmemory: '$BUILD_DIR/mongo/db/repl/repl_coordinator_interface', '$BUILD_DIR/mongo/db/repl/replmocks', '$BUILD_DIR/mongo/db/storage/kv/kv_engine_test_harness', + '$BUILD_DIR/mongo/db/storage/storage_engine_impl', '$BUILD_DIR/mongo/db/storage/wiredtiger/storage_wiredtiger_core', ], ) diff --git a/src/mongo/db/storage/inmemory/inmemory_kv_engine_test.cpp b/src/mongo/db/storage/inmemory/inmemory_kv_engine_test.cpp index fc75e09464e81..cf748f00f11a6 100644 --- a/src/mongo/db/storage/inmemory/inmemory_kv_engine_test.cpp +++ b/src/mongo/db/storage/inmemory/inmemory_kv_engine_test.cpp @@ -32,10 +32,12 @@ Copyright (C) 2018-present Percona and/or its affiliates. All rights reserved. #include "mongo/db/storage/kv/kv_engine_test_harness.h" #include "mongo/base/init.h" +#include "mongo/db/global_settings.h" #include "mongo/db/repl/repl_settings.h" #include "mongo/db/repl/replication_coordinator_mock.h" #include "mongo/db/service_context.h" #include "mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h" +#include "mongo/db/storage/storage_engine_impl.h" #include "mongo/unittest/temp_dir.h" #include "mongo/util/clock_source_mock.h" @@ -48,47 +50,62 @@ namespace { class InMemoryKVHarnessHelper : public KVHarnessHelper { public: - InMemoryKVHarnessHelper(ServiceContext* svcCtx) : _dbpath("inmem-kv-harness") { + InMemoryKVHarnessHelper(ServiceContext* svcCtx) : _dbpath("inmem-kv-harness"), _svcCtx(svcCtx) { if (!hasGlobalServiceContext()) setGlobalServiceContext(ServiceContext::make()); auto client = svcCtx->getService()->makeClient("opCtx"); auto opCtx = client->makeOperationContext(); - _engine.reset(new WiredTigerKVEngine(kInMemoryEngineName, - _dbpath.path(), - _cs.get(), - "in_memory=true," - "log=(enabled=false)," - "file_manager=(close_idle_time=0)," - "checkpoint=(wait=0,log_size=0)", - 100, - 0, - true, - false)); + auto kv = std::make_unique(kInMemoryEngineName, + _dbpath.path(), + _cs.get(), + "in_memory=true," + "log=(enabled=false)," + "file_manager=(close_idle_time=0)," + "checkpoint=(wait=0,log_size=0)", + 100, + 0, + true, + false); + + // Simulate being in replica set mode for timestamping tests + repl::ReplSettings replSettings; + replSettings.setReplSetString("i am a replica set"); + setGlobalReplSettings(replSettings); repl::ReplicationCoordinator::set( - svcCtx, - std::unique_ptr( - new repl::ReplicationCoordinatorMock(svcCtx, repl::ReplSettings()))); - _engine->notifyStorageStartupRecoveryComplete(); + svcCtx, std::make_unique(svcCtx, replSettings)); + + StorageEngineOptions options; + _svcCtx->setStorageEngine( + std::make_unique(opCtx.get(), std::move(kv), options)); + + getWiredTigerKVEngine()->notifyStorageStartupRecoveryComplete(); } - virtual ~InMemoryKVHarnessHelper() { - _engine.reset(NULL); + ~InMemoryKVHarnessHelper() override { + getWiredTigerKVEngine()->cleanShutdown(true); + _svcCtx->clearStorageEngine(); } virtual KVEngine* restartEngine() { // Don't reset the engine since it doesn't persist anything // and all the data will be lost. - return _engine.get(); + return getEngine(); } - virtual KVEngine* getEngine() { - return _engine.get(); + KVEngine* getEngine() override { + return _svcCtx->getStorageEngine()->getEngine(); } private: + WiredTigerKVEngine* getWiredTigerKVEngine() { + auto engine = dynamic_cast(_svcCtx->getStorageEngine()->getEngine()); + invariant(engine); + return engine; + } + const std::unique_ptr _cs = std::make_unique(); unittest::TempDir _dbpath; - std::unique_ptr _engine; + ServiceContext* _svcCtx; }; std::unique_ptr makeHelper(ServiceContext* svcCtx) { diff --git a/src/mongo/db/storage/kv/kv_engine_test_harness.cpp b/src/mongo/db/storage/kv/kv_engine_test_harness.cpp index 3e108458f1346..c63266086b85b 100644 --- a/src/mongo/db/storage/kv/kv_engine_test_harness.cpp +++ b/src/mongo/db/storage/kv/kv_engine_test_harness.cpp @@ -389,7 +389,15 @@ TEST_F(KVEngineTestHarness, TemporaryRecordStoreSimple) { engine->checkpoint(); WriteUnitOfWork wuow(opCtx.get()); - ASSERT_OK(engine->dropIdent(shard_role_details::getRecoveryUnit(opCtx.get()), ident)); + + // Drop the temporary record store in a loop in case it returns ErrorCodes::ObjectIsBusy + Status status = Status::OK(); + do { + std::this_thread::yield(); + status = engine->dropIdent(shard_role_details::getRecoveryUnit(opCtx.get()), ident); + ASSERT(status.isOK() || status == ErrorCodes::ObjectIsBusy); + } while (status == ErrorCodes::ObjectIsBusy); + wuow.commit(); } } @@ -1040,7 +1048,13 @@ TEST_F(KVEngineTestHarness, RollingBackToLastStable) { ASSERT(!engine->getLastStableRecoveryTimestamp()); ASSERT_EQUALS(engine->getAllDurableTimestamp(), Timestamp(1, 1)); engine->setStableTimestamp(Timestamp(1, 1), false); - ASSERT(!engine->getLastStableRecoveryTimestamp()); + + if (engine->isEphemeral()) { + // Ephemeral storage engines set the last stable timestamp immediately. + ASSERT_EQ(engine->getLastStableRecoveryTimestamp(), Timestamp(1, 1)); + } else { + ASSERT(!engine->getLastStableRecoveryTimestamp()); + } // Force a checkpoint to be taken. This should advance the last stable timestamp. auto opCtx = _makeOperationContext(engine); @@ -1113,7 +1127,13 @@ DEATH_TEST_REGEX_F(KVEngineTestHarness, CommitBehindStable, "Fatal assertion.*39 // Set the stable timestamp to (2, 2). ASSERT(!engine->getLastStableRecoveryTimestamp()); engine->setStableTimestamp(Timestamp(2, 2), false); - ASSERT(!engine->getLastStableRecoveryTimestamp()); + + if (engine->isEphemeral()) { + // Ephemeral storage engines set the last stable timestamp immediately. + ASSERT_EQ(engine->getLastStableRecoveryTimestamp(), Timestamp(2, 2)); + } else { + ASSERT(!engine->getLastStableRecoveryTimestamp()); + } // Force a checkpoint to be taken. This should advance the last stable timestamp. auto opCtx = _makeOperationContext(engine); @@ -1238,8 +1258,7 @@ TEST_F(DurableCatalogTest, Idx1) { md.nss = NamespaceString::createNamespaceString_forTest(boost::none, "a.b"); BSONCollectionCatalogEntry::IndexMetaData imd; - imd.spec = BSON("name" - << "foo"); + imd.spec = BSON("name" << "foo"); imd.ready = false; imd.multikey = false; imd.isBackgroundSecondaryBuild = false; @@ -1273,8 +1292,7 @@ TEST_F(DurableCatalogTest, Idx1) { putMetaData(opCtx, catalog.get(), catalogId, md); // remove index BSONCollectionCatalogEntry::IndexMetaData imd; - imd.spec = BSON("name" - << "foo"); + imd.spec = BSON("name" << "foo"); imd.ready = false; imd.multikey = false; imd.isBackgroundSecondaryBuild = false; @@ -1335,8 +1353,7 @@ TEST_F(DurableCatalogTest, DirectoryPerDb1) { md.nss = NamespaceString::createNamespaceString_forTest(boost::none, "a.b"); BSONCollectionCatalogEntry::IndexMetaData imd; - imd.spec = BSON("name" - << "foo"); + imd.spec = BSON("name" << "foo"); imd.ready = false; imd.multikey = false; imd.isBackgroundSecondaryBuild = false; @@ -1394,8 +1411,7 @@ TEST_F(DurableCatalogTest, Split1) { md.nss = NamespaceString::createNamespaceString_forTest(boost::none, "a.b"); BSONCollectionCatalogEntry::IndexMetaData imd; - imd.spec = BSON("name" - << "foo"); + imd.spec = BSON("name" << "foo"); imd.ready = false; imd.multikey = false; imd.isBackgroundSecondaryBuild = false; @@ -1453,8 +1469,7 @@ TEST_F(DurableCatalogTest, DirectoryPerAndSplit1) { md.nss = NamespaceString::createNamespaceString_forTest(boost::none, "a.b"); BSONCollectionCatalogEntry::IndexMetaData imd; - imd.spec = BSON("name" - << "foo"); + imd.spec = BSON("name" << "foo"); imd.ready = false; imd.multikey = false; imd.isBackgroundSecondaryBuild = false; @@ -1517,10 +1532,7 @@ DEATH_TEST_REGEX_F(DurableCatalogTest, uow.commit(); } - IndexDescriptor desc("", - BSON("v" - << "1" - << "key" << BSON("a" << 1))); + IndexDescriptor desc("", BSON("v" << "1" << "key" << BSON("a" << 1))); std::unique_ptr sorted; { auto clientAndCtx = makeClientAndCtx("opCtx");