summaryrefslogtreecommitdiff
path: root/src/mongo/db/ops/write_ops_retryability_test.cpp
diff options
context:
space:
mode:
authorDaniel Gottlieb <daniel.gottlieb@mongodb.com>2020-11-24 20:56:33 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-11-25 02:47:05 +0000
commit8e7ad370f7d35501a9fdd563456b361cbb133d86 (patch)
tree914b7f742215aac4fb7fc73119303e807c1ced51 /src/mongo/db/ops/write_ops_retryability_test.cpp
parentcda3a52701fe4143b06bd981b98514e69d0a93eb (diff)
downloadmongo-8e7ad370f7d35501a9fdd563456b361cbb133d86.tar.gz
SERVER-52978: Correct ordered batch inserts code path for document validation errors.
Diffstat (limited to 'src/mongo/db/ops/write_ops_retryability_test.cpp')
-rw-r--r--src/mongo/db/ops/write_ops_retryability_test.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/mongo/db/ops/write_ops_retryability_test.cpp b/src/mongo/db/ops/write_ops_retryability_test.cpp
index 07cd5600dd8..fcdef0c6845 100644
--- a/src/mongo/db/ops/write_ops_retryability_test.cpp
+++ b/src/mongo/db/ops/write_ops_retryability_test.cpp
@@ -267,6 +267,71 @@ TEST_F(WriteOpsRetryability, PerformOrderedInsertsStopsAtError) {
ASSERT_EQ(ErrorCodes::DuplicateKey, result.results[1].getStatus());
}
+TEST_F(WriteOpsRetryability, PerformOrderedInsertsStopsAtBadDoc) {
+ auto opCtxRaii = makeOperationContext();
+ opCtxRaii->setLogicalSessionId({UUID::gen(), {}});
+ OperationContextSession session(opCtxRaii.get());
+ // Use an unreplicated write block to avoid setting up more structures.
+ repl::UnreplicatedWritesBlock unreplicated(opCtxRaii.get());
+ setUpReplication(getServiceContext());
+
+ write_ops::Insert insertOp(NamespaceString("foo.bar"));
+ insertOp.getWriteCommandBase().setOrdered(true);
+
+ // Setup documents such that the second cannot be successfully inserted.
+ auto largeBuffer = [](std::int32_t size) {
+ std::vector<char> buffer(size);
+ DataRange bufferRange(&buffer.front(), &buffer.back());
+ ASSERT_OK(bufferRange.writeNoThrow(LittleEndian<int32_t>(size)));
+
+ return buffer;
+ }(17 * 1024 * 1024);
+
+ insertOp.setDocuments({BSON("_id" << 0),
+ BSONObj(largeBuffer.data(), BSONObj::LargeSizeTrait{}),
+ BSON("_id" << 2)});
+ write_ops_exec::WriteResult result = write_ops_exec::performInserts(opCtxRaii.get(), insertOp);
+
+ // Assert that the third write is not attempted because this is an ordered insert.
+ ASSERT_EQ(2, result.results.size());
+ ASSERT_TRUE(result.results[0].isOK());
+ ASSERT_FALSE(result.results[1].isOK());
+ ASSERT_EQ(ErrorCodes::BadValue, result.results[1].getStatus());
+}
+
+TEST_F(WriteOpsRetryability, PerformUnorderedInsertsContinuesAtBadDoc) {
+ auto opCtxRaii = makeOperationContext();
+ opCtxRaii->setLogicalSessionId({UUID::gen(), {}});
+ OperationContextSession session(opCtxRaii.get());
+ // Use an unreplicated write block to avoid setting up more structures.
+ repl::UnreplicatedWritesBlock unreplicated(opCtxRaii.get());
+ setUpReplication(getServiceContext());
+
+ write_ops::Insert insertOp(NamespaceString("foo.bar"));
+ insertOp.getWriteCommandBase().setOrdered(false);
+
+ // Setup documents such that the second cannot be successfully inserted.
+ auto largeBuffer = [](std::int32_t size) {
+ std::vector<char> buffer(size);
+ DataRange bufferRange(&buffer.front(), &buffer.back());
+ ASSERT_OK(bufferRange.writeNoThrow(LittleEndian<int32_t>(size)));
+
+ return buffer;
+ }(17 * 1024 * 1024);
+
+ insertOp.setDocuments({BSON("_id" << 0),
+ BSONObj(largeBuffer.data(), BSONObj::LargeSizeTrait{}),
+ BSON("_id" << 2)});
+ write_ops_exec::WriteResult result = write_ops_exec::performInserts(opCtxRaii.get(), insertOp);
+
+ // Assert that the third write is attempted because this is an unordered insert.
+ ASSERT_EQ(3, result.results.size());
+ ASSERT_TRUE(result.results[0].isOK());
+ ASSERT_FALSE(result.results[1].isOK());
+ ASSERT_TRUE(result.results[2].isOK());
+ ASSERT_EQ(ErrorCodes::BadValue, result.results[1].getStatus());
+}
+
class FindAndModifyRetryability : public MockReplCoordServerFixture {
public: