summaryrefslogtreecommitdiff
path: root/jstests/concurrency
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/concurrency')
-rw-r--r--jstests/concurrency/fsm_libs/fsm.js5
-rw-r--r--jstests/concurrency/fsm_workload_helpers/set_parameter.js33
-rw-r--r--jstests/concurrency/fsm_workloads/agg_out.js75
-rw-r--r--jstests/concurrency/fsm_workloads/collection_uuid_sharded.js6
-rw-r--r--jstests/concurrency/fsm_workloads/insert_with_data_size_aware_balancing.js131
-rw-r--r--jstests/concurrency/fsm_workloads/query_stats_concurrent.js155
-rw-r--r--jstests/concurrency/fsm_workloads/query_stats_enable_disable.js133
-rw-r--r--jstests/concurrency/fsm_workloads/random_moveChunk_refine_collection_shard_key.js12
-rw-r--r--jstests/concurrency/fsm_workloads/random_moveChunk_timeseries_insert_many.js1
9 files changed, 356 insertions, 195 deletions
diff --git a/jstests/concurrency/fsm_libs/fsm.js b/jstests/concurrency/fsm_libs/fsm.js
index 29e4f5737eb..f252d70fd7a 100644
--- a/jstests/concurrency/fsm_libs/fsm.js
+++ b/jstests/concurrency/fsm_libs/fsm.js
@@ -132,7 +132,10 @@ var fsm = (function() {
fn.call(args.data, args.db, args.collName, connCache);
}
- var nextState = getWeightedRandomChoice(args.transitions[currentState], Random.rand());
+ assert(args.transitions.hasOwnProperty(currentState),
+ `No transitions defined for state: ${currentState}`);
+ const nextState =
+ getWeightedRandomChoice(args.transitions[currentState], Random.rand());
currentState = nextState;
}
diff --git a/jstests/concurrency/fsm_workload_helpers/set_parameter.js b/jstests/concurrency/fsm_workload_helpers/set_parameter.js
new file mode 100644
index 00000000000..f2422cedb9c
--- /dev/null
+++ b/jstests/concurrency/fsm_workload_helpers/set_parameter.js
@@ -0,0 +1,33 @@
+/**
+ * Changes the setParameter on each mongod and on each mongos (if any) for the given cluster.
+ *
+ * @returns the original value for the given parameter (which can be useful to reset the value after
+ * your workload is finshed).
+ *
+ * @param {Cluster} cluster - The FSM workload cluster - given in setup and teardown.
+ * @param {String} paramName - The name of the setParameter to change.
+ * @param {any} newValue - The new value to configure for the parameter.
+ * @param {Boolean} assertAllSettingsWereIdentical - whether to enforce that the settings were in
+ * sync across all nodes before this change is applied. All settings will be in sync after
+ * changes are applied.
+ */
+function setParameterOnAllNodes({cluster, paramName, newValue, assertAllSettingsWereIdentical}) {
+ let returnValue = null;
+ let lastSeenHost = null;
+ const setQueryStatsParams = (db) => {
+ const res = db.adminCommand({setParameter: 1, [paramName]: newValue});
+ assert.commandWorked(res);
+
+ if (returnValue != null && assertAllSettingsWereIdentical) {
+ assert.eq(
+ returnValue,
+ res.was,
+ `Expected all hosts to start with the same value for the parameter. Latest is: ${
+ db.getMongo().toString()}, last seen is: ${lastSeenHost}`);
+ }
+ returnValue = res.was;
+ };
+ cluster.executeOnMongodNodes(setQueryStatsParams);
+ cluster.executeOnMongosNodes(setQueryStatsParams);
+ return returnValue;
+}
diff --git a/jstests/concurrency/fsm_workloads/agg_out.js b/jstests/concurrency/fsm_workloads/agg_out.js
index d320676a167..86ebca8801a 100644
--- a/jstests/concurrency/fsm_workloads/agg_out.js
+++ b/jstests/concurrency/fsm_workloads/agg_out.js
@@ -37,11 +37,10 @@ var $config = extendWorkload($config, function($config, $super) {
$config.transitions = {
query: {
- query: 0.63,
+ query: 0.68,
createIndexes: 0.1,
dropIndex: 0.1,
collMod: 0.1,
- movePrimary: 0.05,
// Converting the target collection to a capped collection or a sharded collection will
// cause all subsequent aggregations to fail, so give these a low probability to make
// sure they don't happen too early in the test.
@@ -49,7 +48,6 @@ var $config = extendWorkload($config, function($config, $super) {
shardCollection: 0.01,
},
createIndexes: {query: 1},
- movePrimary: {query: 1},
dropIndex: {query: 1},
collMod: {query: 1},
convertToCapped: {query: 1},
@@ -60,7 +58,6 @@ var $config = extendWorkload($config, function($config, $super) {
* Runs an aggregate with a $out into '$config.data.outputCollName'.
*/
$config.states.query = function query(db, collName) {
- jsTestLog(`Running query: coll=${collName} out=${this.outputCollName}`);
const res = db[collName].runCommand({
aggregate: collName,
pipeline: [{$match: {flag: true}}, {$out: this.outputCollName}],
@@ -68,27 +65,15 @@ var $config = extendWorkload($config, function($config, $super) {
});
const allowedErrorCodes = [
- // Indexes of target collection changed during processing.
- ErrorCodes.CommandFailed,
- // $out is not supported to an existing *sharded* output collection.
- ErrorCodes.IllegalOperation,
- // Namespace is capped so it can't be used for $out.
- 17152,
- // $out collection cannot be sharded.
- 28769,
- // $out can't be executed while there is a move primary in progress.
- ErrorCodes.MovePrimaryInProgress,
- // (SERVER-78850) Move primary coordinator drops donor collections when it is done.
- // This invalidates non - snapshot cursors, which causes $out to fail.
- // Locally it fails with explicit collection dropped error. When doing remote reads,
- // it fails with cursor not found error.
- ErrorCodes.CursorNotFound,
+ ErrorCodes.CommandFailed, // indexes of target collection changed during processing.
+ ErrorCodes.IllegalOperation, // $out is not supported to an existing *sharded* output
+ // collection.
+ 17152, // namespace is capped so it can't be used for $out.
+ 28769, // $out collection cannot be sharded.
];
assertWhenOwnDB.commandWorkedOrFailedWithCode(res, allowedErrorCodes);
if (res.ok) {
- // No matter how many documents were in the original input stream, $out should never
- // return any results.
const cursor = new DBCommandCursor(db, res);
assertAlways.eq(0, cursor.itcount()); // No matter how many documents were in the
// original input stream, $out should never
@@ -102,10 +87,7 @@ var $config = extendWorkload($config, function($config, $super) {
*/
$config.states.createIndexes = function createIndexes(db, unusedCollName) {
for (var i = 0; i < this.indexSpecs; ++i) {
- const indexSpecs = this.indexSpecs[i];
- jsTestLog(`Running createIndex: coll=${this.outputCollName} indexSpec=${indexSpecs}`);
- assertWhenOwnDB.commandWorkedOrFailedWithCode(
- db[this.outputCollName].createIndex(indexSpecs), ErrorCodes.MovePrimaryInProgress);
+ assertWhenOwnDB.commandWorked(db[this.outputCollName].createIndex(this.indexSpecs[i]));
}
};
@@ -114,7 +96,6 @@ var $config = extendWorkload($config, function($config, $super) {
*/
$config.states.dropIndex = function dropIndex(db, unusedCollName) {
const indexSpec = this.indexSpecs[Random.randInt(this.indexSpecs.length)];
- jsTestLog(`Running dropIndex: coll=${this.outputCollName} indexSpec=${indexSpec}`);
db[this.outputCollName].dropIndex(indexSpec);
};
@@ -126,39 +107,20 @@ var $config = extendWorkload($config, function($config, $super) {
// Change the validation level.
const validationLevels = ['off', 'strict', 'moderate'];
const newValidationLevel = validationLevels[Random.randInt(validationLevels.length)];
- jsTestLog(`Running collMod: coll=${this.outputCollName} validationLevel=${
- newValidationLevel}`);
-
assertWhenOwnDB.commandWorkedOrFailedWithCode(
db.runCommand({collMod: this.outputCollName, validationLevel: newValidationLevel}),
- [ErrorCodes.ConflictingOperationInProgress, ErrorCodes.MovePrimaryInProgress]);
+ ErrorCodes.ConflictingOperationInProgress);
} else {
// Change the validation action.
- const validationAction = Random.rand() > 0.5 ? 'warn' : 'error';
- jsTestLog(`Running collMod: coll=${this.outputCollName} validationAction=${
- validationAction}`);
-
assertWhenOwnDB.commandWorkedOrFailedWithCode(
- db.runCommand({collMod: this.outputCollName, validationAction: validationAction}),
- [ErrorCodes.ConflictingOperationInProgress, ErrorCodes.MovePrimaryInProgress]);
+ db.runCommand({
+ collMod: this.outputCollName,
+ validationAction: Random.rand() > 0.5 ? 'warn' : 'error'
+ }),
+ ErrorCodes.ConflictingOperationInProgress);
}
};
- $config.states.movePrimary = function movePrimary(db, collName) {
- if (!isMongos(db)) {
- return;
- }
- const toShard = this.shards[Random.randInt(this.shards.length)];
- jsTestLog(`Running movePrimary: db=${db} to=${toShard}`);
-
- assert.commandWorkedOrFailedWithCode(
- db.adminCommand({movePrimary: db.getName(), to: toShard}), [
- // Caused by a concurrent movePrimary operation on the same database but a different
- // destination shard.
- ErrorCodes.ConflictingOperationInProgress,
- ]);
- };
-
/**
* Converts '$config.data.outputCollName' to a capped collection. This is never undone, and all
* subsequent $out's to this collection should fail.
@@ -168,10 +130,8 @@ var $config = extendWorkload($config, function($config, $super) {
return; // convertToCapped can't be run against a mongos.
}
- jsTestLog(`Running convertToCapped: coll=${this.outputCollName}`);
- assertWhenOwnDB.commandWorkedOrFailedWithCode(
- db.runCommand({convertToCapped: this.outputCollName, size: 100000}),
- ErrorCodes.MovePrimaryInProgress);
+ assertWhenOwnDB.commandWorked(
+ db.runCommand({convertToCapped: this.outputCollName, size: 100000}));
};
/**
@@ -182,7 +142,6 @@ var $config = extendWorkload($config, function($config, $super) {
*/
$config.states.shardCollection = function shardCollection(db, unusedCollName) {
if (isMongos(db) && this.tid === 0) {
- jsTestLog(`Running shardCollection: coll=${this.outputCollName} key=${this.shardKey}`);
assertWhenOwnDB.commandWorked(db.adminCommand({enableSharding: db.getName()}));
assertWhenOwnDB.commandWorked(db.adminCommand(
{shardCollection: db[this.outputCollName].getFullName(), key: {_id: 'hashed'}}));
@@ -198,10 +157,6 @@ var $config = extendWorkload($config, function($config, $super) {
// `shardCollection()` requires a shard key index to be in place on the output collection,
// as we may be sharding a non-empty collection.
assertWhenOwnDB.commandWorked(db[this.outputCollName].createIndex({_id: 'hashed'}));
-
- if (isMongos(db)) {
- this.shards = Object.keys(cluster.getSerializedCluster().shards);
- }
};
return $config;
diff --git a/jstests/concurrency/fsm_workloads/collection_uuid_sharded.js b/jstests/concurrency/fsm_workloads/collection_uuid_sharded.js
index 7fbaba0357f..40cc51e3219 100644
--- a/jstests/concurrency/fsm_workloads/collection_uuid_sharded.js
+++ b/jstests/concurrency/fsm_workloads/collection_uuid_sharded.js
@@ -34,7 +34,8 @@ var $config = extendWorkload($config, function($config, $super) {
let reshardCollectionCmd = {
reshardCollection: namespace,
key: {a: 1},
- collectionUUID: this.collUUID
+ collectionUUID: this.collUUID,
+ numInitialChunks: 1,
};
testCommand(db, namespace, "reshardCollection", reshardCollectionCmd, this);
@@ -56,7 +57,8 @@ var $config = extendWorkload($config, function($config, $super) {
reshardCollectionCmd = {
reshardCollection: namespace,
key: {_id: 1},
- collectionUUID: this.collUUID
+ collectionUUID: this.collUUID,
+ numInitialChunks: 1,
};
testCommand(db, namespace, "reshardCollection", reshardCollectionCmd, this);
}
diff --git a/jstests/concurrency/fsm_workloads/insert_with_data_size_aware_balancing.js b/jstests/concurrency/fsm_workloads/insert_with_data_size_aware_balancing.js
deleted file mode 100644
index 65315d99b36..00000000000
--- a/jstests/concurrency/fsm_workloads/insert_with_data_size_aware_balancing.js
+++ /dev/null
@@ -1,131 +0,0 @@
-'use strict';
-
-/**
- * - Shard several collections with different (random) configured maxChunkSize
- * - Perform continuous inserts of random amounts of data into the collections
- * - Verify that the balancer fairly redistributes data among available shards
- *
- * @tags: [
- * requires_sharding,
- * assumes_balancer_on,
- * featureFlagBalanceAccordingToDataSize,
- * requires_fcv_60,
- * ]
- */
-
-const bigString = 'X'.repeat(1024 * 1024 - 30); // Almost 1MB, to create documents of exactly 1MB
-const minChunkSizeMB = 1;
-const maxChunkSizeMB = 10;
-const dbNames = ['db0', 'db1'];
-const collNames = ['collA', 'collB', 'collC'];
-
-/*
- * Get a random db/coll name from the test lists.
- *
- * Using the thread id to introduce more randomness: it has been observed that concurrent calls to
- * Random.randInt(array.length) are returning too often the same number to different threads.
- */
-function getRandomDbName(tid) {
- return dbNames[Random.randInt(tid * tid) % dbNames.length];
-}
-function getRandomCollName(tid) {
- return collNames[Random.randInt(tid * tid) % collNames.length];
-}
-
-var $config = (function() {
- let states = {
- /*
- * Insert into a test collection a random amount of documents (up to 10MB per iteration)
- */
- insert: function(db, collName, connCache) {
- const dbName = getRandomDbName(this.tid);
- db = db.getSiblingDB(dbName);
- collName = getRandomCollName(this.tid);
- const coll = db[collName];
-
- const numDocs = Random.randInt(maxChunkSizeMB - 1) + 1;
- let insertBulkOp = coll.initializeUnorderedBulkOp();
- for (let i = 0; i < numDocs; ++i) {
- insertBulkOp.insert({s: bigString});
- }
-
- assertAlways.commandWorked(insertBulkOp.execute());
- },
- };
-
- /*
- * Create sharded collections with random maxChunkSizeMB (betwen 1MB and 10MB)
- */
- let setup = function(db, collName, cluster) {
- const mongos = cluster.getDB('config').getMongo();
- const shardNames = Object.keys(cluster.getSerializedCluster().shards);
- const numShards = shardNames.length;
-
- for (let i = 0; i < dbNames.length; i++) {
- // Initialize database
- const dbName = dbNames[i];
- const newDb = db.getSiblingDB(dbName);
- newDb.adminCommand({enablesharding: dbName, primaryShard: shardNames[i % numShards]});
-
- for (let j = 0; j < collNames.length; j++) {
- // Shard collection
- collName = collNames[j];
- const coll = newDb[collName];
- const ns = coll.getFullName();
- db.adminCommand({shardCollection: ns, key: {_id: 1}});
-
- // Configure random maxChunkSize
- const randomMaxChunkSizeMB = Random.randInt(maxChunkSizeMB - 1) + 1;
- assert.commandWorked(mongos.adminCommand({
- configureCollectionBalancing: ns,
- chunkSize: randomMaxChunkSizeMB,
- }));
- }
- }
- };
-
- /*
- * Verify that the balancer fairly redistributes data among available shards: the
- * collection size difference between two shards must be at most 2 * maxChunkSize
- */
- let teardown = function(db, collName, cluster) {
- const mongos = cluster.getDB('config').getMongo();
- // Sentinel variable to make sure not all collections have been skipped
- let testedAtLeastOneCollection = false;
- for (let i = 0; i < dbNames.length; i++) {
- const dbName = dbNames[i];
- for (let j = 0; j < collNames.length; j++) {
- collName = collNames[j];
- const ns = dbName + '.' + collName;
-
- const coll = mongos.getCollection(ns);
- if (coll.countDocuments({}) === 0) {
- // Skip empty collections
- continue;
- }
- testedAtLeastOneCollection = true;
-
- // Wait for collection to be considered balanced
- sh.awaitCollectionBalance(
- coll, 5 * 60000 /* 5min timeout */, 1000 /* 1s interval */);
- sh.verifyCollectionIsBalanced(coll);
- }
-
- assert(testedAtLeastOneCollection);
- }
- };
-
- let transitions = {insert: {insert: 1.0}};
-
- return {
- threadCount: 5,
- iterations: 8,
- startState: 'insert',
- states: states,
- transitions: transitions,
- data: {},
- setup: setup,
- teardown: teardown,
- passConnectionCache: true
- };
-})();
diff --git a/jstests/concurrency/fsm_workloads/query_stats_concurrent.js b/jstests/concurrency/fsm_workloads/query_stats_concurrent.js
new file mode 100644
index 00000000000..6d7b9456288
--- /dev/null
+++ b/jstests/concurrency/fsm_workloads/query_stats_concurrent.js
@@ -0,0 +1,155 @@
+'use strict';
+
+/**
+ * query_stats_concurrent.js
+ *
+ * Stresses $queryStats running concurrently with queries.
+ *
+ * @tags: [
+ * requires_fcv_60,
+ * does_not_support_causal_consistency,
+ * ]
+ *
+ *
+ */
+load("jstests/concurrency/fsm_workload_helpers/set_parameter.js");
+
+var $config = (function() {
+ var states = (function() {
+ function init(db, collName) {
+ }
+
+ function reInit(db, collName) {
+ }
+
+ // Runs one find query so that the queryStatsEntry is updated.
+ function findOneShape(db, collName) {
+ assertWhenOwnColl.gt(db[collName].find({i: {$lt: 50}}).itcount(), 0);
+ }
+
+ // Runs one agg query so that the queryStatsEntry is updated.
+ function aggOneShape(db, collName) {
+ assertWhenOwnColl.gt(db[collName].aggregate([{$match: {i: {$gt: 900}}}]).itcount(), 0);
+ }
+
+ // Runs many queries with different shapes to ensure eviction occurs in the queryStats
+ // store.
+ function multipleShapes(db, collName) {
+ for (var i = 0; i < 10000; i++) {
+ let query = {};
+ query["foo" + i] = "bar";
+ db[collName].aggregate([{$match: query}]).itcount();
+ }
+ const evictedAfter = db.serverStatus().metrics.queryStats.numEvicted;
+ assertAlways.gt(evictedAfter, 0);
+ }
+
+ // Runs queryStats with transformation.
+ function runQueryStatsWithHmac(db, collName) {
+ let response = db.adminCommand({
+ aggregate: 1,
+ pipeline: [{
+ $queryStats: {
+ transformIdentifiers: {
+ algorithm: "hmac-sha-256",
+ hmacKey: BinData(8, "MjM0NTY3ODkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjE=")
+ }
+ }
+ }],
+ // Use a small batch size to ensure these operations open up a cursor and use
+ // multiple getMores.
+ cursor: {batchSize: 1}
+ });
+ assertAlways.commandWorked(response);
+ const cursor = new DBCommandCursor(db.getSiblingDB("admin"), response);
+ assertAlways.gt(cursor.itcount(), 0);
+ }
+
+ // Runs queryStats without transformation.
+ function runQueryStatsWithoutHmac(db, collName) {
+ let response = db.adminCommand({
+ aggregate: 1,
+ pipeline: [{$queryStats: {}}],
+ // Use a small batch size to ensure these operations open up a cursor and use
+ // multiple getMores.
+ cursor: {batchSize: 1}
+ });
+ assertAlways.commandWorked(response);
+ const cursor = new DBCommandCursor(db.getSiblingDB("admin"), response);
+ assertAlways.gt(cursor.itcount(), 0);
+ }
+
+ return {
+ init: init,
+ reInit: reInit,
+ findOneShape: findOneShape,
+ multipleShapes: multipleShapes,
+ aggOneShape: aggOneShape,
+ runQueryStatsWithHmac: runQueryStatsWithHmac,
+ runQueryStatsWithoutHmac: runQueryStatsWithoutHmac
+ };
+ })();
+
+ var internalQueryStatsRateLimit;
+ var internalQueryStatsCacheSize;
+
+ let setup = function(db, collName, cluster) {
+ internalQueryStatsRateLimit = setParameterOnAllNodes(
+ {cluster: cluster, paramName: "internalQueryStatsRateLimit", newValue: -1});
+ internalQueryStatsCacheSize = setParameterOnAllNodes(
+ {cluster: cluster, paramName: "internalQueryStatsCacheSize", newValue: "1MB"});
+
+ assert.commandWorked(db[collName].createIndex({i: 1}));
+ const bulk = db[collName].initializeUnorderedBulkOp();
+ for (let i = 0; i < 1000; ++i) {
+ bulk.insert({i: i});
+ }
+ assert.commandWorked(bulk.execute());
+ };
+
+ let teardown = function(db, collName, cluster) {
+ setParameterOnAllNodes({
+ cluster: cluster,
+ paramName: "internalQueryStatsRateLimit",
+ newValue: internalQueryStatsRateLimit
+ });
+ setParameterOnAllNodes({
+ cluster: cluster,
+ paramName: "internalQueryStatsCacheSize",
+ newValue: internalQueryStatsCacheSize
+ });
+
+ db[collName].drop();
+ };
+
+ let transitions = {
+ // To start, add some $queryStats data so that it is never empty.
+ init: {
+ aggOneShape: 0.33,
+ findOneShape: 0.33,
+ multipleShapes: 0.34,
+ },
+ // From then on, choose evenly among all possibilities:
+ reInit: {
+ aggOneShape: 0.2,
+ findOneShape: 0.2,
+ multipleShapes: 0.2,
+ runQueryStatsWithHmac: 0.2,
+ runQueryStatsWithoutHmac: 0.2
+ },
+ findOneShape: {reInit: 1},
+ multipleShapes: {reInit: 1},
+ runQueryStatsWithHmac: {reInit: 1},
+ runQueryStatsWithoutHmac: {reInit: 1},
+ aggOneShape: {reInit: 1}
+ };
+
+ return {
+ threadCount: 10,
+ iterations: 10,
+ states: states,
+ setup: setup,
+ teardown: teardown,
+ transitions: transitions
+ };
+})();
diff --git a/jstests/concurrency/fsm_workloads/query_stats_enable_disable.js b/jstests/concurrency/fsm_workloads/query_stats_enable_disable.js
new file mode 100644
index 00000000000..ff22b26efb0
--- /dev/null
+++ b/jstests/concurrency/fsm_workloads/query_stats_enable_disable.js
@@ -0,0 +1,133 @@
+/**
+ * query_stats_enable_disable.js
+ *
+ * Stresses $queryStats being toggled on and off during execution.
+ *
+ * @tags: [
+ * requires_fcv_60,
+ * # Cannot read query stats entries from a different node than issued the query.
+ * does_not_support_causal_consistency,
+ * # setParameter is not persistent.
+ * does_not_support_stepdowns,
+ * # Changing the query stats parameters messes with the query stats test which expects to see
+ * # query stats results.
+ * incompatible_with_concurrency_simultaneous,
+ * ]
+ *
+ */
+
+load("jstests/concurrency/fsm_workload_helpers/set_parameter.js");
+
+var $config = (function() {
+ function setCacheSize(db, cacheSize) {
+ assert.commandWorked(
+ db.adminCommand({setParameter: 1, internalQueryStatsCacheSize: cacheSize}));
+ }
+
+ function setRateLimit(db, rateLimit) {
+ assert.commandWorked(
+ db.adminCommand({setParameter: 1, internalQueryStatsRateLimit: rateLimit}));
+ }
+
+ function runQueryStats({db, options}) {
+ try {
+ // Use a small batch size to ensure these operations open up a cursor and use
+ // multiple getMores - this will better stress odd concurrency states.
+ const cursor =
+ db.getSiblingDB("admin").aggregate([{$queryStats: options}], {batchSize: 1});
+ // Can't assert much in particular about the results.
+ assert.gte(cursor.itcount(), 0);
+ } catch (e) {
+ if (e.code === ErrorCodes.QueryFeatureNotAllowed) {
+ // This means query stats is disabled, which is expected to happen in this workload.
+ return;
+ }
+ throw e;
+ }
+ }
+
+ const hmacOptions = {
+ transformIdentifiers: {
+ algorithm: "hmac-sha-256",
+ hmacKey: BinData(8, "MjM0NTY3ODkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjE=")
+ }
+ };
+ const nDifferentShapes = 200;
+ const states = {
+ // The main operating states which toggle the feature on and off, since we've seen
+ // bugs like SERVER-84730 when this happens.
+ disableViaCacheSize: (db, collName) => setCacheSize(db, "0MB"),
+ enableViaCacheSize: (db, collName) => setCacheSize(db, "1MB"),
+ disableViaRateLimit: (db, collName) => setRateLimit(db, 0),
+ enableViaRateLimit: (db, collName) => setRateLimit(db, -1),
+
+ runOneQuery: function runOneQuery(db, collName) {
+ assert.eq(null,
+ db[collName].findOne({["field" + Random.randInt(nDifferentShapes)]: 42}));
+ },
+
+ runQueryStatsWithHmac: (db, collName) => runQueryStats({db: db, options: hmacOptions}),
+ runQueryStatsWithoutHmac: (db, collName) => runQueryStats({db: db, options: {}}),
+ init: (db, collName) => { /* no op */ },
+ };
+
+ const transitions = {
+ init: {
+ // Make the most common thing be running a query.
+ runOneQuery: 0.6,
+ // Followed by runing $queryStats, with half the probability.
+ runQueryStatsWithHmac: 0.15,
+ runQueryStatsWithoutHmac: 0.15,
+ // These sum up to 0.1:
+ disableViaCacheSize: 0.05,
+ disableViaRateLimit: 0.05,
+ },
+ runOneQuery: {init: 1},
+ runQueryStatsWithHmac: {init: 1},
+ runQueryStatsWithoutHmac: {init: 1},
+ // If you disable it, immediately re-enable it.
+ disableViaCacheSize: {enableViaCacheSize: 1},
+ enableViaCacheSize: {init: 1},
+ disableViaRateLimit: {enableViaRateLimit: 1},
+ enableViaRateLimit: {init: 1},
+ };
+
+ var internalQueryStatsRateLimit;
+ var internalQueryStatsCacheSize;
+
+ const setup = function(db, collName, cluster) {
+ // TODO SERVER-85405 Make this pattern easier and repeated throughout multiple workloads,
+ // not just the query stats ones.
+ internalQueryStatsRateLimit = setParameterOnAllNodes(
+ {cluster: cluster, paramName: "internalQueryStatsRateLimit", newValue: -1});
+ internalQueryStatsCacheSize = setParameterOnAllNodes(
+ {cluster: cluster, paramName: "internalQueryStatsCacheSize", newValue: "1MB"});
+ };
+
+ const teardown = function(db, collName, cluster) {
+ setParameterOnAllNodes({
+ cluster: cluster,
+ paramName: "internalQueryStatsRateLimit",
+ newValue: internalQueryStatsRateLimit,
+ // We were messing with the settings in this test by sending commands only to the
+ // primary. The secondaries are not expected to be involved and so cannot be expected to
+ // have the same settings.
+ assertAllSettingsWereIdentical: false,
+ });
+ setParameterOnAllNodes({
+ cluster: cluster,
+ paramName: "internalQueryStatsCacheSize",
+ newValue: internalQueryStatsCacheSize,
+ assertAllSettingsWereIdentical: false,
+ });
+ };
+
+ return {
+ threadCount: 10,
+ iterations: 10,
+ states: states,
+ setup: setup,
+ teardown: teardown,
+ transitions: transitions
+ };
+})();
diff --git a/jstests/concurrency/fsm_workloads/random_moveChunk_refine_collection_shard_key.js b/jstests/concurrency/fsm_workloads/random_moveChunk_refine_collection_shard_key.js
index d74d2454176..18fa771a945 100644
--- a/jstests/concurrency/fsm_workloads/random_moveChunk_refine_collection_shard_key.js
+++ b/jstests/concurrency/fsm_workloads/random_moveChunk_refine_collection_shard_key.js
@@ -57,7 +57,17 @@ var $config = extendWorkload($config, function($config, $super) {
// migrated back in. The particular error code is replaced with a more generic one, so this
// is identified by the failed migration's error message.
$config.data.isMoveChunkErrorAcceptable = (err) => {
- const codes = [ErrorCodes.LockBusy, ErrorCodes.ShardKeyNotFound, ErrorCodes.LockTimeout];
+ const codes = [
+ // TODO SERVER-68551: Remove lockbusy error since the balancer won't acquire anymore the
+ // DDL lock for migrations
+ ErrorCodes.LockBusy,
+ ErrorCodes.ShardKeyNotFound,
+ ErrorCodes.LockTimeout,
+ // The refienCollectionCoordinator interrupt all migrations by setting `allowMigration`
+ // to false
+ ErrorCodes.Interrupted,
+ ErrorCodes.OrphanedRangeCleanUpFailed,
+ ];
return (err.code && codes.includes(err.code)) ||
(err.message &&
(err.message.includes("CommandFailed") ||
diff --git a/jstests/concurrency/fsm_workloads/random_moveChunk_timeseries_insert_many.js b/jstests/concurrency/fsm_workloads/random_moveChunk_timeseries_insert_many.js
index 97b0cf8e5b4..80224a2725d 100644
--- a/jstests/concurrency/fsm_workloads/random_moveChunk_timeseries_insert_many.js
+++ b/jstests/concurrency/fsm_workloads/random_moveChunk_timeseries_insert_many.js
@@ -7,6 +7,7 @@
* assumes_balancer_off,
* requires_non_retryable_writes,
* does_not_support_transactions,
+ * requires_fcv_51,
* ]
*/
load('jstests/concurrency/fsm_workload_helpers/chunks.js'); // for chunk helpers