summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/multi_index_block_test.cpp
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2018-11-21 06:01:03 -0500
committerBenety Goh <benety@mongodb.com>2018-11-21 06:01:03 -0500
commitf8de654b888ef3b9a9f210499b0b8f5d727dfffd (patch)
tree33c59555d11f534b9a451e0349fdbdbce3c387ef /src/mongo/db/catalog/multi_index_block_test.cpp
parent9cc66d04356cf7b542df77ebe9dbe94445308240 (diff)
downloadmongo-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.cpp204
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