summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Seyster <justin.seyster@mongodb.com>2019-12-17 23:43:45 +0000
committerevergreen <evergreen@mongodb.com>2019-12-17 23:43:45 +0000
commitd379a124bd3f22e0970d4ec3028a67f724f25b31 (patch)
tree73b94e19cb333ea283609734d506c68fbc12fedd
parentf33f96be206f921079114a3e6e92e213a6644da3 (diff)
downloadmongo-d379a124bd3f22e0970d4ec3028a67f724f25b31.tar.gz
SERVER-36865 Improved kill_rooted_or.js and kill_aggregation.js
Backports the original version of this commit (on branch v4.2), so that we don't get CannotImplicitlyCreateCollection errors when testing v4.0. Unlike in the original commit, this backport does not add a function to repopulate the test collection after dropping it. The v4.0 version of this test does not populate the collection in the first place. We would have to backport that functionality as well if we wanted to backport the populateCollection function. (cherry picked from commit 369a2e0432c27b20b106056e2f2e0849cab617f0)
-rw-r--r--jstests/concurrency/fsm_workloads/kill_aggregation.js23
-rw-r--r--jstests/concurrency/fsm_workloads/kill_rooted_or.js46
2 files changed, 46 insertions, 23 deletions
diff --git a/jstests/concurrency/fsm_workloads/kill_aggregation.js b/jstests/concurrency/fsm_workloads/kill_aggregation.js
index cd16fbcce20..466b2769034 100644
--- a/jstests/concurrency/fsm_workloads/kill_aggregation.js
+++ b/jstests/concurrency/fsm_workloads/kill_aggregation.js
@@ -14,13 +14,13 @@ load('jstests/concurrency/fsm_libs/extend_workload.js'); // for extendWorkl
load('jstests/concurrency/fsm_workloads/kill_rooted_or.js'); // for $config
var $config = extendWorkload($config, function($config, $super) {
-
// Use the workload name as the collection name, since the workload name is assumed to be
- // unique.
+ // unique. Note that we choose our own collection name instead of using the collection provided
+ // by the concurrency framework, because this workload drops its collection.
$config.data.collName = 'kill_aggregation';
- $config.states.query = function query(db, collName) {
- var res = db.runCommand({
+ $config.states.query = function query(db, collNameUnused) {
+ const aggResult = db.runCommand({
aggregate: this.collName,
// We use a rooted $or query to cause plan selection to use the subplanner and thus
// yield.
@@ -28,16 +28,25 @@ var $config = extendWorkload($config, function($config, $super) {
cursor: {}
});
- if (!res.ok) {
+ if (!aggResult.ok) {
+ // We expect to see errors caused by the plan executor being killed, because of the
+ // collection getting dropped on another thread.
+ assertAlways.contains(aggResult.code,
+ [ErrorCodes.OperationFailed, ErrorCodes.QueryPlanKilled],
+ aggResult);
return;
}
- var cursor = new DBCommandCursor(db, res);
+ var cursor = new DBCommandCursor(db, aggResult);
try {
// No documents are ever inserted into the collection.
assertAlways.eq(0, cursor.itcount());
} catch (e) {
- // Ignore errors due to the plan executor being killed.
+ // We expect to see errors caused by the plan executor being killed, because of the
+ // collection getting dropped on another thread.
+ if (ErrorCodes.QueryPlanKilled != e.code) {
+ throw e;
+ }
}
};
diff --git a/jstests/concurrency/fsm_workloads/kill_rooted_or.js b/jstests/concurrency/fsm_workloads/kill_rooted_or.js
index c74e3b05e87..ee69bfd7bdd 100644
--- a/jstests/concurrency/fsm_workloads/kill_rooted_or.js
+++ b/jstests/concurrency/fsm_workloads/kill_rooted_or.js
@@ -10,9 +10,9 @@
* This workload was designed to reproduce SERVER-24761.
*/
var $config = (function() {
-
// Use the workload name as the collection name, since the workload name is assumed to be
- // unique.
+ // unique. Note that we choose our own collection name instead of using the collection provided
+ // by the concurrency framework, because this workload drops its collection.
var uniqueCollectionName = 'kill_rooted_or';
var data = {
@@ -26,34 +26,38 @@ var $config = (function() {
};
var states = {
- query: function query(db, collName) {
+ query: function query(db, collNameUnused) {
var cursor = db[this.collName].find({$or: [{a: 0}, {b: 0}]});
try {
// No documents are ever inserted into the collection.
assertAlways.eq(0, cursor.itcount());
} catch (e) {
- // Ignore errors due to the plan executor being killed.
+ // We expect to see errors caused by the plan executor being killed, because of the
+ // collection getting dropped on another thread.
+ if (ErrorCodes.QueryPlanKilled != e.code) {
+ throw e;
+ }
}
},
- dropCollection: function dropCollection(db, collName) {
+ dropCollection: function dropCollection(db, collNameUnused) {
db[this.collName].drop();
- // Recreate all of the indexes on the collection.
- this.indexSpecs.forEach(indexSpec => {
- assertAlways.commandWorked(db[this.collName].createIndex(indexSpec));
- });
+ // Restore the collection.
+ populateIndexes(db[this].collName, this.indexSpecs);
},
- dropIndex: function dropIndex(db, collName) {
+ dropIndex: function dropIndex(db, collNameUnused) {
var indexSpec = this.indexSpecs[Random.randInt(this.indexSpecs.length)];
// We don't assert that the command succeeded when dropping an index because it's
// possible another thread has already dropped this index.
db[this.collName].dropIndex(indexSpec);
- // Recreate the index that was dropped.
- assertAlways.commandWorked(db[this.collName].createIndex(indexSpec));
+ // Recreate the index that was dropped. (See populateIndexes() for why we ignore the
+ // CannotImplicitlyCreateCollection error.)
+ assertAlways.commandWorkedOrFailedWithCode(db[this.collName].createIndex(indexSpec),
+ ErrorCodes.CannotImplicitlyCreateCollection);
}
};
@@ -63,12 +67,23 @@ var $config = (function() {
dropIndex: {query: 1}
};
- function setup(db, collName, cluster) {
- this.indexSpecs.forEach(indexSpec => {
- assertAlways.commandWorked(db[this.collName].createIndex(indexSpec));
+ function populateIndexes(coll, indexSpecs) {
+ indexSpecs.forEach(indexSpec => {
+ // In sharded configurations, there's a limit to how many times mongos can retry an
+ // operation that fails because it wants to implicitly create a collection that is
+ // concurrently dropped. Normally, that's fine, but if some jerk keeps dropping our
+ // collection (as in the 'dropCollection' state of this test), then we run out of
+ // retries and get a CannotImplicitlyCreateCollection error once in a while, which we
+ // have to ignore.
+ assertAlways.commandWorkedOrFailedWithCode(coll.createIndex(indexSpec),
+ ErrorCodes.CannotImplicitlyCreateCollection);
});
}
+ function setup(db, collNameUnused, cluster) {
+ populateIndexes(db[this.collName], this.indexSpecs);
+ }
+
return {
threadCount: 10,
iterations: 50,
@@ -78,5 +93,4 @@ var $config = (function() {
transitions: transitions,
setup: setup
};
-
})();