summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorBilly Donahue <billy.donahue@mongodb.com>2021-06-23 18:25:42 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-12-08 23:14:24 +0000
commit1fd786804af6a5b3967c3cacf9fe1e23567569bb (patch)
tree41208daf6f7911255693b28f907e76d9319c9517 /jstests
parent7ba62a29745f518e2a7b37c75b7a067813e0bcac (diff)
downloadmongo-1fd786804af6a5b3967c3cacf9fe1e23567569bb.tar.gz
SERVER-57772 suppress state-change rewrite when `writeConcernError` is injected by `failCommand`.
(cherry picked from commit 7396af4803b0b9b729c457f54defca0c4c51b61f)
Diffstat (limited to 'jstests')
-rw-r--r--jstests/sharding/rewrite_state_change_errors.js72
1 files changed, 72 insertions, 0 deletions
diff --git a/jstests/sharding/rewrite_state_change_errors.js b/jstests/sharding/rewrite_state_change_errors.js
new file mode 100644
index 00000000000..8fccc0e366b
--- /dev/null
+++ b/jstests/sharding/rewrite_state_change_errors.js
@@ -0,0 +1,72 @@
+/**
+ * Check that state change errors are suppressed by mongos.
+ * Those injected by the failCommand FailPoint are left alone.
+ *
+ * A naturally-occurring state-change error `ShutdownInProgress` in the
+ * `code` or `writeConcernError` of a response would be rewritten by a mongos, but
+ * because it was injected by a mongos failCommand failpoint, it should be
+ * left alone.
+ *
+ * This behavior can be overridden by adding the bool `allowRewriteStateChange`
+ * to the failpoint's configuration object.
+ */
+
+(function() {
+'use strict';
+
+var st = new ShardingTest({shards: 1, mongos: 1});
+var mongos = st.s;
+var db = mongos.getDB("test");
+
+const doesRewrite = ErrorCodes.probeMongosRewrite(mongos);
+
+const injected = ErrorCodes.ShutdownInProgress;
+
+function merge(x, y) {
+ for (const k in y)
+ x[k] = y[k];
+}
+
+function runInsertScenarios(injectCodeField, extractCode, message) {
+ for (const testCase of [
+ [{}, false, "Not rewritten by default."],
+ [{allowRewriteStateChange: false}, false, "Explicitly disallowing rewrites."],
+ [{allowRewriteStateChange: true}, true, "Explicitly allowing rewrites."],
+ ]) {
+ const [allowConfigFields, rewriteAllowed, desc] = testCase;
+ const summary = message + ": " + desc;
+
+ jsTestLog(summary);
+
+ var fpData = {failCommands: ["insert"]};
+
+ injectCodeField(fpData, injected);
+ merge(fpData, allowConfigFields);
+
+ mongos.adminCommand({
+ configureFailPoint: "failCommand",
+ mode: {times: 1},
+ data: fpData,
+ });
+ const res = db.runCommand({insert: db.coll.getName(), documents: [{x: 1}]});
+ assert.eq(
+ extractCode(res),
+ rewriteAllowed ? ErrorCodes.doMongosRewrite(mongos, injected, doesRewrite) : injected,
+ summary + ": " + tojson(testCase) + ": " + tojson(res));
+ }
+}
+
+runInsertScenarios((obj, ec) => {
+ obj.errorCode = ec;
+}, res => res.code, "Injected errorCode");
+
+// The code site where failCommand controls the injection of writeConcernError
+// is separated from the place where failCommand controls the injection of
+// more basic command errors, so it is tested separately here.
+
+runInsertScenarios((obj, ec) => {
+ obj.writeConcernError = {code: ec, errmsg: "Injected by failCommand"};
+}, res => res.writeConcernError.code, "Injected writeConcernError");
+
+st.stop();
+})();