summaryrefslogtreecommitdiff
path: root/src/mongo/s/shard_key_pattern_test.cpp
diff options
context:
space:
mode:
authorBobby Morck <bobby.morck@mongodb.com>2021-09-25 17:34:13 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-10-08 19:45:19 +0000
commitfedd7fa7eaf29751d3573ff39f18c3f09abbf06c (patch)
tree570b1cdca9fb07785b231557f15c90aa45d61bd6 /src/mongo/s/shard_key_pattern_test.cpp
parent230477b7740ec1aa111ce5035a5f8f6a1cd2dd7e (diff)
downloadmongo-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.cpp104
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