summaryrefslogtreecommitdiff
path: root/src/mongo/db/storage/record_store_test_updatewithdamages.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/storage/record_store_test_updatewithdamages.cpp')
-rw-r--r--src/mongo/db/storage/record_store_test_updatewithdamages.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/mongo/db/storage/record_store_test_updatewithdamages.cpp b/src/mongo/db/storage/record_store_test_updatewithdamages.cpp
index 59d41042885..a166499d4a2 100644
--- a/src/mongo/db/storage/record_store_test_updatewithdamages.cpp
+++ b/src/mongo/db/storage/record_store_test_updatewithdamages.cpp
@@ -376,5 +376,120 @@ TEST(RecordStoreTestHarness, UpdateWithDamagesScalar) {
}
}
+// Insert a record with nested documents and try to perform updates on it.
+TEST(RecordStoreTestHarness, UpdateWithDamagesNested) {
+ const auto harnessHelper(newRecordStoreHarnessHelper());
+ unique_ptr<RecordStore> rs(harnessHelper->newNonCappedRecordStore());
+
+ if (!rs->updateWithDamagesSupported())
+ return;
+
+ BSONObj obj0 = fromjson(
+ "{a: 0, "
+ " b: {p: 1, q: 1, r: 2}, "
+ " c: 3, "
+ " d: {p: {x: {i: 1}, y: {q: 1}}}}");
+ BSONObj obj1 = fromjson(
+ "{a: 0, "
+ " b: {p: 1, r: 2, q: 1}, "
+ " c: '3', "
+ " d: {p: {x: {j: '1'}, y: {q: 1}}}}");
+
+ RecordId loc;
+ const RecordData obj0Rec(obj0.objdata(), obj0.objsize());
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ {
+ WriteUnitOfWork uow(opCtx.get());
+ StatusWith<RecordId> res =
+ rs->insertRecord(opCtx.get(), obj0Rec.data(), obj0Rec.size(), Timestamp());
+ ASSERT_OK(res.getStatus());
+ loc = res.getValue();
+ uow.commit();
+ }
+ }
+
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ ASSERT(obj0.binaryEqual(rs->dataFor(opCtx.get(), loc).toBson()));
+ }
+
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ {
+ WriteUnitOfWork uow(opCtx.get());
+ // {u: {c: "3"}, sb: {i: {q: 1}}, sd: {sp: {u: {x: {j: "1"}}}}}
+ auto diffOutput = doc_diff::computeDiff(obj0, obj1, 0, nullptr);
+ ASSERT(diffOutput);
+ auto [_, damageSource, damages] =
+ doc_diff::computeDamages(obj0, diffOutput->diff, true);
+ auto newRecStatus1 =
+ rs->updateWithDamages(opCtx.get(), loc, obj0Rec, damageSource.get(), damages);
+ ASSERT_OK(newRecStatus1.getStatus());
+ ASSERT(obj1.binaryEqual(newRecStatus1.getValue().toBson()));
+ uow.commit();
+ }
+ }
+
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ ASSERT(obj1.binaryEqual(rs->dataFor(opCtx.get(), loc).toBson()));
+ }
+}
+
+// Insert a record with nested arrays and try to perform updates on it.
+TEST(RecordStoreTestHarness, UpdateWithDamagesArray) {
+ const auto harnessHelper(newRecordStoreHarnessHelper());
+ unique_ptr<RecordStore> rs(harnessHelper->newNonCappedRecordStore());
+
+ if (!rs->updateWithDamagesSupported())
+ return;
+
+ BSONObj obj0 =
+ fromjson("{field1: 'abcd', field2: [1, 2, 3, [1, 'longString', [2], 4, 5, 6], 5, 5, 5]}");
+ BSONObj obj1 = fromjson("{field1: 'abcd', field2: [1, 2, 3, [1, 'longString', [4], 4], 5, 6]}");
+
+ RecordId loc;
+ const RecordData obj0Rec(obj0.objdata(), obj0.objsize());
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ {
+ WriteUnitOfWork uow(opCtx.get());
+ StatusWith<RecordId> res =
+ rs->insertRecord(opCtx.get(), obj0Rec.data(), obj0Rec.size(), Timestamp());
+ ASSERT_OK(res.getStatus());
+ loc = res.getValue();
+ uow.commit();
+ }
+ }
+
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ ASSERT(obj0.binaryEqual(rs->dataFor(opCtx.get(), loc).toBson()));
+ }
+
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ {
+ WriteUnitOfWork uow(opCtx.get());
+ // {sfield2: {a: true, l: 6, 's3': {a: true, l: 4, 'u2': [4]}, 'u5': 6}}
+ auto diffOutput = doc_diff::computeDiff(obj0, obj1, 0, nullptr);
+ ASSERT(diffOutput);
+ auto [_, damageSource, damages] =
+ doc_diff::computeDamages(obj0, diffOutput->diff, true);
+ auto newRecStatus1 =
+ rs->updateWithDamages(opCtx.get(), loc, obj0Rec, damageSource.get(), damages);
+ ASSERT_OK(newRecStatus1.getStatus());
+ ASSERT(obj1.binaryEqual(newRecStatus1.getValue().toBson()));
+ uow.commit();
+ }
+ }
+
+ {
+ ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
+ ASSERT(obj1.binaryEqual(rs->dataFor(opCtx.get(), loc).toBson()));
+ }
+}
+
} // namespace
} // namespace mongo