diff options
author | Bobby Morck <bobby.morck@mongodb.com> | 2021-09-25 17:34:13 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-10-08 19:45:19 +0000 |
commit | fedd7fa7eaf29751d3573ff39f18c3f09abbf06c (patch) | |
tree | 570b1cdca9fb07785b231557f15c90aa45d61bd6 /src/mongo/s/shard_key_pattern_test.cpp | |
parent | 230477b7740ec1aa111ce5035a5f8f6a1cd2dd7e (diff) | |
download | mongo-fedd7fa7eaf29751d3573ff39f18c3f09abbf06c.tar.gz |
SERVER-56127 Fixing retryable writes on update and delete commands to not execute more than once
Diffstat (limited to 'src/mongo/s/shard_key_pattern_test.cpp')
-rw-r--r-- | src/mongo/s/shard_key_pattern_test.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/mongo/s/shard_key_pattern_test.cpp b/src/mongo/s/shard_key_pattern_test.cpp index c67f9958378..2809ff17d86 100644 --- a/src/mongo/s/shard_key_pattern_test.cpp +++ b/src/mongo/s/shard_key_pattern_test.cpp @@ -62,6 +62,36 @@ protected: OperationContext* _opCtx; }; +/** + * Creates OplogEntry with given field values. + */ +repl::OplogEntry makeOplogEntry(repl::OpTime opTime, + repl::OpTypeEnum opType, + NamespaceString nss, + BSONObj oField, + boost::optional<BSONObj> o2Field = boost::none) { + return { + repl::DurableOplogEntry(opTime, // optime + boost::none, // hash + opType, // opType + nss, // namespace + boost::none, // uuid + boost::none, // fromMigrate + repl::OplogEntry::kOplogVersion, // version + oField, // o + o2Field, // o2 + {}, // sessionInfo + boost::none, // upsert + Date_t(), // wall clock time + {}, // statement ids + boost::none, // optime of previous write within same transaction + boost::none, // pre-image optime + boost::none, // post-image optime + boost::none, // ShardId of resharding recipient + boost::none, // _id + boost::none)}; // needsRetryImage +} + TEST_F(ShardKeyPatternTest, SingleFieldShardKeyPatternsValidityCheck) { ShardKeyPattern s1(BSON("a" << 1)); ShardKeyPattern s2(BSON("a" << 1.0f)); @@ -145,6 +175,10 @@ static BSONObj docKey(const ShardKeyPattern& pattern, const BSONObj& doc) { return pattern.extractShardKeyFromDoc(doc); } +static BSONObj docKeyFromOplog(const ShardKeyPattern& pattern, const repl::OplogEntry& entry) { + return pattern.extractShardKeyFromOplogEntry(entry); +} + TEST_F(ShardKeyPatternTest, ExtractDocShardKeySingle) { // // Single field ShardKeyPatterns @@ -236,6 +270,76 @@ TEST_F(ShardKeyPatternTest, ExtractDocShardKeyNested) { ASSERT_BSONOBJ_EQ(docKey(pattern, fromjson("{a:{b:[10, 20]}, c:30}")), BSONObj()); } +TEST_F(ShardKeyPatternTest, ExtractShardKeyFromOplogUnnested) { + // + // Unnested ShardKeyPatterns from oplog entries with CRUD operation + // + + ShardKeyPattern pattern(BSON("a" << 1)); + auto deleteOplog = makeOplogEntry(repl::OpTime(Timestamp(50, 10), 1), // optime + repl::OpTypeEnum::kDelete, // op type + NamespaceString("a"), // namespace + BSON("_id" << 1 << "a" << 5)); // o + auto insertOplog = makeOplogEntry(repl::OpTime(Timestamp(60, 10), 1), // optime + repl::OpTypeEnum::kInsert, // op type + NamespaceString("a"), // namespace + BSON("_id" << 2 << "a" << 6)); // o + auto updateOplog = makeOplogEntry(repl::OpTime(Timestamp(70, 10), 1), // optime + repl::OpTypeEnum::kUpdate, // op type + NamespaceString("a"), // namespace + BSON("_id" << 3), // o + BSON("_id" << 3 << "a" << 7)); // o2 + + ASSERT_BSONOBJ_EQ(docKeyFromOplog(pattern, deleteOplog), fromjson("{a: 5}")); + ASSERT_BSONOBJ_EQ(docKeyFromOplog(pattern, insertOplog), fromjson("{a: 6}")); + ASSERT_BSONOBJ_EQ(docKeyFromOplog(pattern, updateOplog), fromjson("{a: 7}")); +} + +TEST_F(ShardKeyPatternTest, ExtractShardKeyFromOplogNested) { + // + // Nested ShardKeyPatterns from oplog entries with CRUD operation + // + + ShardKeyPattern pattern(BSON("a.b" << 1)); + auto deleteOplog = makeOplogEntry(repl::OpTime(Timestamp(50, 10), 1), // optime + repl::OpTypeEnum::kDelete, // op type + NamespaceString("a.b"), // namespace + BSON("_id" << 1 << "a.b" << 5)); // o + auto insertOplog = makeOplogEntry(repl::OpTime(Timestamp(60, 10), 1), // optime + repl::OpTypeEnum::kInsert, // op type + NamespaceString("a.b"), // namespace + BSON("_id" << 2 << "a" << BSON("b" << 6))); // o + auto updateOplog = makeOplogEntry(repl::OpTime(Timestamp(70, 10), 1), // optime + repl::OpTypeEnum::kUpdate, // op type + NamespaceString("a.b"), // namespace + BSON("_id" << 3), // o + BSON("_id" << 3 << "a.b" << 7)); // o2 + + ASSERT_BSONOBJ_EQ(docKeyFromOplog(pattern, deleteOplog), fromjson("{'a.b': 5}")); + ASSERT_BSONOBJ_EQ(docKeyFromOplog(pattern, insertOplog), fromjson("{'a.b': 6}")); + ASSERT_BSONOBJ_EQ(docKeyFromOplog(pattern, updateOplog), fromjson("{'a.b': 7}")); +} + +TEST_F(ShardKeyPatternTest, ExtractShardKeyFromOplogNonCRUD) { + // + // Oplogs with non-CRUD op types + // + + ShardKeyPattern pattern(BSON("a.b" << 1)); + auto noopOplog = makeOplogEntry(repl::OpTime(Timestamp(50, 10), 1), // optime + repl::OpTypeEnum::kNoop, // op type + NamespaceString("a.b"), // namespace + BSON("_id" << 1 << "a.b" << 5)); // o + auto commandOplog = makeOplogEntry(repl::OpTime(Timestamp(60, 10), 1), // optime + repl::OpTypeEnum::kCommand, // op type + NamespaceString("a.b"), // namespace + BSON("create" + << "c")); // o + + ASSERT_BSONOBJ_EQ(docKeyFromOplog(pattern, noopOplog), BSONObj()); + ASSERT_BSONOBJ_EQ(docKeyFromOplog(pattern, commandOplog), BSONObj()); +} + TEST_F(ShardKeyPatternTest, ExtractDocShardKeyDeepNested) { // // Deeply nested ShardKeyPatterns |