diff options
author | Benety Goh <benety@mongodb.com> | 2021-06-17 14:53:02 -0400 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2021-06-24 16:34:57 -0400 |
commit | c6ebda4b612b0f1da93e1892a3765c9581f3dc62 (patch) | |
tree | 044f2a0e692d99686c97b23f795500c103644d71 | |
parent | e2162a7e9258a7e7e85e1413c0395c5526d00e32 (diff) | |
download | mongo-c6ebda4b612b0f1da93e1892a3765c9581f3dc62.tar.gz |
SERVER-57775 add tests for Collection::setIndexIsMultikey()
(cherry picked from commit 360823520e1ba097d9f7afedc20863124ddaccf6)
-rw-r--r-- | src/mongo/db/catalog/collection_test.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/mongo/db/catalog/collection_test.cpp b/src/mongo/db/catalog/collection_test.cpp index 334040436c7..8e99ae81037 100644 --- a/src/mongo/db/catalog/collection_test.cpp +++ b/src/mongo/db/catalog/collection_test.cpp @@ -37,10 +37,12 @@ #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/collection_mock.h" #include "mongo/db/catalog/collection_validation.h" +#include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/db_raii.h" #include "mongo/db/repl/storage_interface_impl.h" #include "mongo/stdx/thread.h" #include "mongo/unittest/unittest.h" +#include "mongo/util/fail_point.h" #define ASSERT_ID_EQ(EXPR, ID) \ [](boost::optional<Record> record, RecordId id) { \ @@ -55,6 +57,7 @@ using namespace mongo; class CollectionTest : public CatalogTestFixture { protected: void makeCapped(NamespaceString nss, long long cappedSize = 8192); + void makeCollectionForMultikey(NamespaceString nss, StringData indexName); }; void CollectionTest::makeCapped(NamespaceString nss, long long cappedSize) { @@ -214,6 +217,123 @@ TEST_F(CollectionTest, AsynchronouslyNotifyCappedWaitersIfNeeded) { ASSERT_EQ(notifier->getVersion(), thisVersion); } +void CollectionTest::makeCollectionForMultikey(NamespaceString nss, StringData indexName) { + auto opCtx = operationContext(); + { + AutoGetCollection autoColl(opCtx, nss, MODE_IX); + auto db = autoColl.ensureDbExists(); + WriteUnitOfWork wuow(opCtx); + ASSERT(db->createCollection(opCtx, nss)); + wuow.commit(); + } + + { + AutoGetCollection autoColl(opCtx, nss, MODE_X); + WriteUnitOfWork wuow(opCtx); + auto collWriter = autoColl.getWritableCollection(); + ASSERT_OK(collWriter->getIndexCatalog()->createIndexOnEmptyCollection( + opCtx, collWriter, BSON("v" << 2 << "name" << indexName << "key" << BSON("a" << 1)))); + wuow.commit(); + } +} + +TEST_F(CollectionTest, SetIndexIsMultikey) { + NamespaceString nss("test.t"); + auto indexName = "myindex"_sd; + makeCollectionForMultikey(nss, indexName); + + auto opCtx = operationContext(); + AutoGetCollection autoColl(opCtx, nss, MODE_IX); + const auto& coll = autoColl.getCollection(); + ASSERT(coll); + MultikeyPaths paths = {{0}}; + { + WriteUnitOfWork wuow(opCtx); + ASSERT(coll->setIndexIsMultikey(opCtx, indexName, paths)); + wuow.commit(); + } + { + WriteUnitOfWork wuow(opCtx); + ASSERT_FALSE(coll->setIndexIsMultikey(opCtx, indexName, paths)); + wuow.commit(); + } +} + +TEST_F(CollectionTest, SetIndexIsMultikeyRemovesUncommittedChangesOnRollback) { + NamespaceString nss("test.t"); + auto indexName = "myindex"_sd; + makeCollectionForMultikey(nss, indexName); + + auto opCtx = operationContext(); + AutoGetCollection autoColl(opCtx, nss, MODE_IX); + const auto& coll = autoColl.getCollection(); + ASSERT(coll); + MultikeyPaths paths = {{0}}; + + { + FailPointEnableBlock failPoint("EFTAlwaysThrowWCEOnWrite"); + WriteUnitOfWork wuow(opCtx); + ASSERT_THROWS(coll->setIndexIsMultikey(opCtx, indexName, paths), WriteConflictException); + } + + // After rolling back the above WUOW, we should succeed in retrying setIndexIsMultikey(). + { + WriteUnitOfWork wuow(opCtx); + ASSERT_FALSE(coll->setIndexIsMultikey(opCtx, indexName, paths)); + wuow.commit(); + } +} + +TEST_F(CollectionTest, ForceSetIndexIsMultikey) { + NamespaceString nss("test.t"); + auto indexName = "myindex"_sd; + makeCollectionForMultikey(nss, indexName); + + auto opCtx = operationContext(); + AutoGetCollection autoColl(opCtx, nss, MODE_IX); + const auto& coll = autoColl.getCollection(); + ASSERT(coll); + MultikeyPaths paths = {{0}}; + { + WriteUnitOfWork wuow(opCtx); + auto desc = coll->getIndexCatalog()->findIndexByName(opCtx, indexName); + coll->forceSetIndexIsMultikey(opCtx, desc, true, paths); + wuow.commit(); + } + { + WriteUnitOfWork wuow(opCtx); + ASSERT_FALSE(coll->setIndexIsMultikey(opCtx, indexName, paths)); + wuow.commit(); + } +} + +TEST_F(CollectionTest, ForceSetIndexIsMultikeyRemovesUncommittedChangesOnRollback) { + NamespaceString nss("test.t"); + auto indexName = "myindex"_sd; + makeCollectionForMultikey(nss, indexName); + + auto opCtx = operationContext(); + AutoGetCollection autoColl(opCtx, nss, MODE_IX); + const auto& coll = autoColl.getCollection(); + ASSERT(coll); + MultikeyPaths paths = {{0}}; + + { + FailPointEnableBlock failPoint("EFTAlwaysThrowWCEOnWrite"); + WriteUnitOfWork wuow(opCtx); + auto desc = coll->getIndexCatalog()->findIndexByName(opCtx, indexName); + ASSERT_THROWS(coll->forceSetIndexIsMultikey(opCtx, desc, true, paths), + WriteConflictException); + } + + // After rolling back the above WUOW, we should succeed in retrying setIndexIsMultikey(). + { + WriteUnitOfWork wuow(opCtx); + ASSERT_FALSE(coll->setIndexIsMultikey(opCtx, indexName, paths)); + wuow.commit(); + } +} + TEST_F(CatalogTestFixture, CollectionPtrNoYieldTag) { CollectionMock mock(NamespaceString("test.t")); |