diff options
author | Denis Grebennicov <denis.grebennicov@mongodb.com> | 2021-09-23 16:42:26 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-09-23 17:20:04 +0000 |
commit | 9af446967575222fcfe87a24f2971adfd3935d8f (patch) | |
tree | c6ea17ed88db2f090ba770f2e48365c06e8ff0ef /src/mongo/db/op_observer_impl_test.cpp | |
parent | 3cfd58313f40c5fa881028632d7685e509373ce5 (diff) | |
download | mongo-9af446967575222fcfe87a24f2971adfd3935d8f.tar.gz |
SERVER-58686 Implement writing of pre-images for non-transactional update/replace operations
Diffstat (limited to 'src/mongo/db/op_observer_impl_test.cpp')
-rw-r--r-- | src/mongo/db/op_observer_impl_test.cpp | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/src/mongo/db/op_observer_impl_test.cpp b/src/mongo/db/op_observer_impl_test.cpp index 1cc220d3746..150a8f4313f 100644 --- a/src/mongo/db/op_observer_impl_test.cpp +++ b/src/mongo/db/op_observer_impl_test.cpp @@ -43,6 +43,7 @@ #include "mongo/db/logical_time_validator.h" #include "mongo/db/op_observer_impl.h" #include "mongo/db/op_observer_registry.h" +#include "mongo/db/pipeline/change_stream_preimage_gen.h" #include "mongo/db/read_write_concern_defaults.h" #include "mongo/db/read_write_concern_defaults_cache_lookup_mock.h" #include "mongo/db/repl/image_collection_entry_gen.h" @@ -1637,12 +1638,15 @@ TEST_F(OpObserverTest, TestFundamentalOnUpdateOutputs) { {StoreDocOption::PostImage, kRecordPreImages, RetryableOptions::WithOplog, 3}, {StoreDocOption::PostImage, kRecordPreImages, RetryableOptions::WithSideCollection, 2}}; - for (std::size_t testIdx = 0; testIdx < cases.size(); ++testIdx) { - const auto& testCase = cases[testIdx]; + const auto testFunc = [&](CollectionUpdateArgs& updateArgs, + const UpdateTestCase& testCase, + const int testIdx) { LOGV2(5739902, "UpdateTestCase", "ImageType"_attr = testCase.getImageTypeStr(), - "AlwaysRecordPreImages"_attr = testCase.alwaysRecordPreImages, + "PreImageRecording"_attr = updateArgs.preImageRecordingEnabledForCollection, + "ChangeStreamPreAndPostImagesEnabled"_attr = + updateArgs.changeStreamPreAndPostImagesEnabledForCollection, "RetryableOptions"_attr = testCase.getRetryableOptionsStr(), "ExpectedOplogEntries"_attr = testCase.numOutputOplogs); @@ -1653,7 +1657,6 @@ TEST_F(OpObserverTest, TestFundamentalOnUpdateOutputs) { boost::optional<MongoDOperationContextSession> contextSession; boost::optional<TransactionParticipant::Participant> txnParticipant; - CollectionUpdateArgs updateArgs; switch (testCase.retryableOptions) { case RetryableOptions::NotRetryable: updateArgs.stmtIds = {kUninitializedStmtId}; @@ -1690,7 +1693,6 @@ TEST_F(OpObserverTest, TestFundamentalOnUpdateOutputs) { BSON("$set" << BSON("postImage" << true) << "$unset" << BSON("preImage" << 1)); updateArgs.criteria = BSON("_id" << 0); updateArgs.storeDocOption = testCase.imageType; - updateArgs.preImageRecordingEnabledForCollection = testCase.alwaysRecordPreImages; OplogUpdateEntryArgs update(std::move(updateArgs), nss, uuid); // Phase 2: Call the code we're testing. @@ -1706,7 +1708,7 @@ TEST_F(OpObserverTest, TestFundamentalOnUpdateOutputs) { // Entries are returned in ascending timestamp order. const OplogEntry& actualOp = assertGet(OplogEntry::parse(oplogs.back())); - const bool checkPreImageInOplog = testCase.alwaysRecordPreImages || + const bool checkPreImageInOplog = update.updateArgs.preImageRecordingEnabledForCollection || (testCase.imageType == StoreDocOption::PreImage && testCase.retryableOptions == RetryableOptions::WithOplog); if (checkPreImageInOplog) { @@ -1729,11 +1731,11 @@ TEST_F(OpObserverTest, TestFundamentalOnUpdateOutputs) { bool checkSideCollection = testCase.imageType != StoreDocOption::None && testCase.retryableOptions == RetryableOptions::WithSideCollection; - if (checkSideCollection && testCase.alwaysRecordPreImages && + if (checkSideCollection && update.updateArgs.preImageRecordingEnabledForCollection && testCase.imageType == StoreDocOption::PreImage) { - // When `alwaysRecordPreImages` is enabled for a collection, we always store an image in - // the oplog. To avoid unnecessary writes, we won't also store an image in the side - // collection. + // When `alwaysRecordPreImages` is enabled for a collection, we always store an + // image in the oplog. To avoid unnecessary writes, we won't also store an image + // in the side collection. checkSideCollection = false; } @@ -1750,6 +1752,50 @@ TEST_F(OpObserverTest, TestFundamentalOnUpdateOutputs) { ASSERT(imageEntry.getImageKind() == repl::RetryImageEnum::kPostImage); } } + + if (update.updateArgs.changeStreamPreAndPostImagesEnabledForCollection) { + const Timestamp preImageOpTime = actualOp.getOpTime().getTimestamp(); + ChangeStreamPreImageId preImageId(uuid, preImageOpTime, 0); + AutoGetCollection preImagesCollection( + opCtx, NamespaceString::kChangeStreamPreImagesNamespace, LockMode::MODE_IS); + const auto preImage = Helpers::findOneForTesting( + opCtx, preImagesCollection.getCollection(), BSON("_id" << preImageId.toBSON())); + const auto changeStreamPreImage = + ChangeStreamPreImage::parse(IDLParserErrorContext("pre-image"), preImage); + const BSONObj& expectedImage = update.updateArgs.preImageDoc.get(); + ASSERT_BSONOBJ_EQ(expectedImage, changeStreamPreImage.getPreImage()); + ASSERT_EQ(actualOp.getWallClockTime(), changeStreamPreImage.getOperationTime()); + } + }; + + for (std::size_t testIdx = 0; testIdx < cases.size(); ++testIdx) { + auto& testCase = cases[testIdx]; + + // In case when 'alwaysRecordPreImages' is set to true, run the test for both + // 'preImageRecordingEnabledForCollection' and + // 'changeStreamPreAndPostImagesEnabledForCollection' cases. + CollectionUpdateArgs updateArgs; + if (testCase.alwaysRecordPreImages) { + updateArgs.preImageRecordingEnabledForCollection = testCase.alwaysRecordPreImages; + updateArgs.changeStreamPreAndPostImagesEnabledForCollection = + !testCase.alwaysRecordPreImages; + testFunc(updateArgs, testCase, testIdx); + + const auto numOutputOplogs = (testCase.imageType == StoreDocOption::PreImage && + testCase.retryableOptions == RetryableOptions::WithOplog) + ? testCase.numOutputOplogs + : testCase.numOutputOplogs - 1; + updateArgs.preImageRecordingEnabledForCollection = !testCase.alwaysRecordPreImages; + updateArgs.changeStreamPreAndPostImagesEnabledForCollection = + testCase.alwaysRecordPreImages; + testCase.numOutputOplogs = numOutputOplogs; + testFunc(updateArgs, testCase, testIdx); + } else { + updateArgs.preImageRecordingEnabledForCollection = testCase.alwaysRecordPreImages; + updateArgs.changeStreamPreAndPostImagesEnabledForCollection = + testCase.alwaysRecordPreImages; + testFunc(updateArgs, testCase, testIdx); + } } } |