diff options
author | Benety Goh <benety@mongodb.com> | 2018-11-21 06:01:03 -0500 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2018-11-21 06:01:03 -0500 |
commit | f8de654b888ef3b9a9f210499b0b8f5d727dfffd (patch) | |
tree | 33c59555d11f534b9a451e0349fdbdbce3c387ef /src/mongo/db/catalog/multi_index_block_test.cpp | |
parent | 9cc66d04356cf7b542df77ebe9dbe94445308240 (diff) | |
download | mongo-f8de654b888ef3b9a9f210499b0b8f5d727dfffd.tar.gz |
SERVER-37763 add support for aborting MultiIndexBlock index builds
Diffstat (limited to 'src/mongo/db/catalog/multi_index_block_test.cpp')
-rw-r--r-- | src/mongo/db/catalog/multi_index_block_test.cpp | 204 |
1 files changed, 193 insertions, 11 deletions
diff --git a/src/mongo/db/catalog/multi_index_block_test.cpp b/src/mongo/db/catalog/multi_index_block_test.cpp index 4f09562a847..11dcd74502c 100644 --- a/src/mongo/db/catalog/multi_index_block_test.cpp +++ b/src/mongo/db/catalog/multi_index_block_test.cpp @@ -28,29 +28,211 @@ * it in the license file. */ -#include "mongo/db/catalog/multi_index_block.h" - -#include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/collection_mock.h" +#include "mongo/db/catalog/index_catalog_noop.h" #include "mongo/db/catalog/multi_index_block_impl.h" -#include "mongo/db/operation_context_noop.h" +#include "mongo/db/jsobj.h" +#include "mongo/db/repl/replication_coordinator_mock.h" +#include "mongo/db/service_context_test_fixture.h" #include "mongo/unittest/unittest.h" namespace mongo { namespace { /** - * Simple initialization test for MultiIndexBlock to check library dependencies. - * For greater test coverage, it may be necessary to make this test fixture inherit from + * Unit test for MultiIndexBlock to verify basic functionality. + * Using a mocked Collection object ensures that we are pulling in a minimal set of library + * dependencies. + * For integration tests, it may be necessary to make this test fixture inherit from * ServiceContextMongoDTest. */ -class MultiIndexBlockTest : public unittest::Test {}; +class MultiIndexBlockTest : public ServiceContextTest { +private: + void setUp() override; + void tearDown() override; + +protected: + OperationContext* getOpCtx() const; + Collection* getCollection() const; + MultiIndexBlockImpl* getIndexer() const; + +private: + ServiceContext::UniqueOperationContext _opCtx; + std::unique_ptr<Collection> _collection; + std::unique_ptr<MultiIndexBlockImpl> _indexer; +}; + +void MultiIndexBlockTest::setUp() { + ServiceContextTest::setUp(); + + auto service = getServiceContext(); + repl::ReplicationCoordinator::set(service, + std::make_unique<repl::ReplicationCoordinatorMock>(service)); + + _opCtx = makeOperationContext(); -TEST_F(MultiIndexBlockTest, Create) { - OperationContextNoop opCtx; NamespaceString nss("mydb.mycoll"); - Collection collection(std::make_unique<CollectionMock>(nss)); - MultiIndexBlockImpl(&opCtx, &collection); + auto collectionMock = + std::make_unique<CollectionMock>(nss, std::make_unique<IndexCatalogNoop>()); + _collection = std::make_unique<Collection>(std::move(collectionMock)); + + _indexer = std::make_unique<MultiIndexBlockImpl>(_opCtx.get(), _collection.get()); +} + +void MultiIndexBlockTest::tearDown() { + auto service = getServiceContext(); + repl::ReplicationCoordinator::set(service, {}); + + _indexer = {}; + + _collection = {}; + + _opCtx = {}; + + ServiceContextTest::tearDown(); +} + +OperationContext* MultiIndexBlockTest::getOpCtx() const { + return _opCtx.get(); +} + +Collection* MultiIndexBlockTest::getCollection() const { + return _collection.get(); +} + +MultiIndexBlockImpl* MultiIndexBlockTest::getIndexer() const { + return _indexer.get(); +} + +TEST_F(MultiIndexBlockTest, CommitWithoutInsertingDocuments) { + auto indexer = getIndexer(); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kUninitialized, indexer->getState_forTest()); + + auto specs = unittest::assertGet(indexer->init(std::vector<BSONObj>())); + ASSERT_EQUALS(0U, specs.size()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kRunning, indexer->getState_forTest()); + + ASSERT_OK(indexer->doneInserting()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kPreCommit, indexer->getState_forTest()); + + ASSERT_FALSE(indexer->isCommitted()); + { + WriteUnitOfWork wunit(getOpCtx()); + ASSERT_OK(indexer->commit()); + wunit.commit(); + } + ASSERT(indexer->isCommitted()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kCommitted, indexer->getState_forTest()); +} + +TEST_F(MultiIndexBlockTest, CommitAfterInsertingSingleDocument) { + auto indexer = getIndexer(); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kUninitialized, indexer->getState_forTest()); + + auto specs = unittest::assertGet(indexer->init(std::vector<BSONObj>())); + ASSERT_EQUALS(0U, specs.size()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kRunning, indexer->getState_forTest()); + + ASSERT_OK(indexer->insert({}, {}, nullptr)); + ASSERT_OK(indexer->doneInserting()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kPreCommit, indexer->getState_forTest()); + + ASSERT_FALSE(indexer->isCommitted()); + { + WriteUnitOfWork wunit(getOpCtx()); + ASSERT_OK(indexer->commit()); + wunit.commit(); + } + ASSERT(indexer->isCommitted()); + + // abort() should have no effect after the index build is committed. + indexer->abort("test"_sd); + ASSERT(indexer->isCommitted()); +} + +TEST_F(MultiIndexBlockTest, AbortWithoutCleanupAfterInsertingSingleDocument) { + auto indexer = getIndexer(); + auto specs = unittest::assertGet(indexer->init(std::vector<BSONObj>())); + ASSERT_EQUALS(0U, specs.size()); + ASSERT_OK(indexer->insert({}, {}, nullptr)); + indexer->abortWithoutCleanup(); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kAborted, indexer->getState_forTest()); + + ASSERT_FALSE(indexer->isCommitted()); +} + +TEST_F(MultiIndexBlockTest, InitFailsAfterAbort) { + auto indexer = getIndexer(); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kUninitialized, indexer->getState_forTest()); + + indexer->abort("test"_sd); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kAborted, indexer->getState_forTest()); + + ASSERT_EQUALS(ErrorCodes::IndexBuildAborted, indexer->init(std::vector<BSONObj>()).getStatus()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kAborted, indexer->getState_forTest()); + + ASSERT_FALSE(indexer->isCommitted()); +} + +TEST_F(MultiIndexBlockTest, InsertingSingleDocumentFailsAfterAbort) { + auto indexer = getIndexer(); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kUninitialized, indexer->getState_forTest()); + + auto specs = unittest::assertGet(indexer->init(std::vector<BSONObj>())); + ASSERT_EQUALS(0U, specs.size()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kRunning, indexer->getState_forTest()); + + indexer->abort("test"_sd); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kAborted, indexer->getState_forTest()); + + ASSERT_EQUALS(ErrorCodes::IndexBuildAborted, + indexer->insert(BSON("_id" << 123 << "a" << 456), {}, nullptr)); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kAborted, indexer->getState_forTest()); + + ASSERT_FALSE(indexer->isCommitted()); +} + +TEST_F(MultiIndexBlockTest, DoneInsertingFailsAfterAbort) { + auto indexer = getIndexer(); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kUninitialized, indexer->getState_forTest()); + + auto specs = unittest::assertGet(indexer->init(std::vector<BSONObj>())); + ASSERT_EQUALS(0U, specs.size()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kRunning, indexer->getState_forTest()); + + ASSERT_OK(indexer->insert(BSON("_id" << 123 << "a" << 456), {}, nullptr)); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kRunning, indexer->getState_forTest()); + + indexer->abort("test"_sd); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kAborted, indexer->getState_forTest()); + + ASSERT_EQUALS(ErrorCodes::IndexBuildAborted, indexer->doneInserting()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kAborted, indexer->getState_forTest()); + + ASSERT_FALSE(indexer->isCommitted()); +} + +TEST_F(MultiIndexBlockTest, CommitFailsAfterAbort) { + auto indexer = getIndexer(); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kUninitialized, indexer->getState_forTest()); + + auto specs = unittest::assertGet(indexer->init(std::vector<BSONObj>())); + ASSERT_EQUALS(0U, specs.size()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kRunning, indexer->getState_forTest()); + + ASSERT_OK(indexer->insert(BSON("_id" << 123 << "a" << 456), {}, nullptr)); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kRunning, indexer->getState_forTest()); + + ASSERT_OK(indexer->doneInserting()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kPreCommit, indexer->getState_forTest()); + + indexer->abort("test"_sd); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kAborted, indexer->getState_forTest()); + + ASSERT_EQUALS(ErrorCodes::IndexBuildAborted, indexer->commit()); + ASSERT_EQUALS(MultiIndexBlockImpl::State::kAborted, indexer->getState_forTest()); + + ASSERT_FALSE(indexer->isCommitted()); } } // namespace |