diff options
Diffstat (limited to 'src/mongo/db/repl/sync_tail_test.cpp')
| -rw-r--r-- | src/mongo/db/repl/sync_tail_test.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/mongo/db/repl/sync_tail_test.cpp b/src/mongo/db/repl/sync_tail_test.cpp index 30f0eeacad2..09953633f7e 100644 --- a/src/mongo/db/repl/sync_tail_test.cpp +++ b/src/mongo/db/repl/sync_tail_test.cpp @@ -47,6 +47,7 @@ #include "mongo/db/query/internal_plans.h" #include "mongo/db/repl/bgsync.h" #include "mongo/db/repl/oplog.h" +#include "mongo/db/repl/oplog_buffer_blocking_queue.h" #include "mongo/db/repl/oplog_interface_local.h" #include "mongo/db/repl/replication_coordinator_global.h" #include "mongo/db/repl/replication_coordinator_mock.h" @@ -56,6 +57,7 @@ #include "mongo/db/service_context.h" #include "mongo/db/service_context_d_test_fixture.h" #include "mongo/stdx/mutex.h" +#include "mongo/unittest/death_test.h" #include "mongo/unittest/unittest.h" #include "mongo/util/concurrency/old_thread_pool.h" #include "mongo/util/md5.hpp" @@ -1089,6 +1091,43 @@ TEST_F(SyncTailTest, ASSERT_EQUALS(ErrorCodes::CollectionIsEmpty, iter->next().getStatus()); } +namespace { + +class ReplicationCoordinatorSignalDrainCompleteThrows : public ReplicationCoordinatorMock { +public: + explicit ReplicationCoordinatorSignalDrainCompleteThrows(const ReplSettings& settings) + : ReplicationCoordinatorMock(settings) {} + bool isInPrimaryOrSecondaryState() const final { + return true; + } + void signalDrainComplete(OperationContext*, long long) final { + uasserted(ErrorCodes::OperationFailed, "failed to signal drain complete"); + } +}; + +} // namespace + +DEATH_TEST_F(SyncTailTest, + OplogApplicationLogsExceptionFromSignalDrainCompleteBeforeAborting, + "failed to signal drain complete") { + // Leave oplog buffer empty so that SyncTail calls + // ReplicationCoordinator::signalDrainComplete() during oplog application. + auto oplogBuffer = stdx::make_unique<OplogBufferBlockingQueue>(); + BackgroundSync bgsync(nullptr, // ReplicationCoordinatorExternalState. Not used. + std::move(oplogBuffer)); + + auto applyOperationFn = [](MultiApplier::OperationPtrs*, SyncTail*) { return Status::OK(); }; + SyncTail syncTail(&bgsync, applyOperationFn); + + auto currentReplCoord = ReplicationCoordinator::get(_opCtx.get()); + ReplicationCoordinatorSignalDrainCompleteThrows replCoord(currentReplCoord->getSettings()); + ASSERT_TRUE(replCoord.setFollowerMode(MemberState::RS_PRIMARY)); + + // SyncTail::oplogApplication() creates its own OperationContext in the current thread context. + _opCtx = {}; + syncTail.oplogApplication(&replCoord); +} + class IdempotencyTest : public SyncTailTest { protected: OplogEntry createCollection(); |
