summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorGeert Bosch <geert@mongodb.com>2016-11-09 18:27:14 -0500
committerGeert Bosch <geert@mongodb.com>2016-11-18 15:41:48 -0500
commit27071b2f3e476737f0f86b07ae997617748f6848 (patch)
tree9fe5f3507ff72915ca7b2c5db6f947648ee6b6a1 /jstests
parentee84af83abda81bdd5c1fdf2d831c4979d739f8c (diff)
downloadmongo-27071b2f3e476737f0f86b07ae997617748f6848.tar.gz
SERVER-24563 Fix race in check for DB names that differ in case only
Diffstat (limited to 'jstests')
-rw-r--r--jstests/concurrency/fsm_all_sharded_replication.js1
-rw-r--r--jstests/concurrency/fsm_all_sharded_replication_with_balancer.js1
-rw-r--r--jstests/concurrency/fsm_workloads/create_database.js133
3 files changed, 135 insertions, 0 deletions
diff --git a/jstests/concurrency/fsm_all_sharded_replication.js b/jstests/concurrency/fsm_all_sharded_replication.js
index bd732c0d0ed..b74fb1f18d5 100644
--- a/jstests/concurrency/fsm_all_sharded_replication.js
+++ b/jstests/concurrency/fsm_all_sharded_replication.js
@@ -9,6 +9,7 @@ var blacklist = [
'distinct.js', // SERVER-13116 distinct isn't sharding aware
'distinct_noindex.js', // SERVER-13116 distinct isn't sharding aware
'distinct_projection.js', // SERVER-13116 distinct isn't sharding aware
+ 'create_database.js', // SERVER-17397 Drops of sharded namespaces may not fully succeed
'drop_database.js', // SERVER-17397 Drops of sharded namespaces may not fully succeed
// Disabled due to SERVER-3645, '.count() can be wrong on sharded collections'.
diff --git a/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js b/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js
index ad1bef53c86..b44bd3f6a2e 100644
--- a/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js
+++ b/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js
@@ -9,6 +9,7 @@ var blacklist = [
'distinct.js', // SERVER-13116 distinct isn't sharding aware
'distinct_noindex.js', // SERVER-13116 distinct isn't sharding aware
'distinct_projection.js', // SERVER-13116 distinct isn't sharding aware
+ 'create_database.js', // SERVER-17397 Drops of sharded namespaces may not fully succeed
'drop_database.js', // SERVER-17397 Drops of sharded namespaces may not fully succeed
'remove_where.js', // SERVER-14669 Multi-removes that use $where miscount removed documents
diff --git a/jstests/concurrency/fsm_workloads/create_database.js b/jstests/concurrency/fsm_workloads/create_database.js
new file mode 100644
index 00000000000..490cd8f1854
--- /dev/null
+++ b/jstests/concurrency/fsm_workloads/create_database.js
@@ -0,0 +1,133 @@
+'use strict';
+
+/**
+ * create_database.js
+ *
+ * Repeatedly creates and drops a database, with the focus on creation using different name casing.
+ * Create using all different methods, implicitly by inserting, creating views/indexes etc.
+ *
+ * Each thread uses its own database, though sometimes threads may try to create databases with
+ * names that only differ in case, expecting the appriopriate error code.
+ */
+var $config = (function() {
+
+ let data = {
+ checkCommandResult: function checkCommandResult(mayFailWithDatabaseDifferCase, res) {
+ if (mayFailWithDatabaseDifferCase && !res.ok)
+ assertAlways.commandFailedWithCode(res, ErrorCodes.DatabaseDifferCase);
+ else
+ assertAlways.commandWorked(res);
+ return res;
+ },
+
+ checkWriteResult: function checkWriteResult(mayFailWithDatabaseDifferCase, res) {
+ if (mayFailWithDatabaseDifferCase && res.hasWriteError())
+ assertAlways.writeErrorWithCode(res, ErrorCodes.DatabaseDifferCase);
+ else
+ assertAlways.writeOK(res);
+ return res;
+ }
+ };
+
+ let states = {
+ init: function init(db, collName) {
+ let uniqueNr = this.tid;
+ let semiUniqueNr = Math.floor(uniqueNr / 2);
+
+ // The semiUniqueDBName may clash and result in a DatabaseDifferCas error on creation,
+ // while the uniqueDBName does not clash. The unique and created variables track this.
+ this.semiUniqueDBName =
+ (this.tid % 2 ? 'create_database' : 'CREATE_DATABASE') + semiUniqueNr;
+ this.uniqueDBName = 'CreateDatabase' + uniqueNr;
+ this.myDB = db.getSiblingDB(this.uniqueDBName);
+ this.created = false;
+ this.unique = true;
+
+ },
+
+ useSemiUniqueDBName: function useSemiUniqueDBName(db, collName) {
+ this.myDB = db.getSiblingDB(this.semiUniqueDBName);
+ this.unique = false;
+ },
+
+ createView: function createView(db, collName) {
+ this.created =
+ this.checkCommandResult(!this.unique, this.myDB.createView(collName, "nil", [])).ok;
+ },
+
+ createCollection: function createCollection(db, collName) {
+ this.created =
+ this.checkCommandResult(!this.unique, this.myDB.createCollection(collName)).ok;
+ },
+
+ createIndex: function createIndex(db, collName) {
+ let background = Math.random > 0.5;
+ let res = this.myDB.getCollection(collName).createIndex({x: 1}, {background});
+ this.created |=
+ this.checkCommandResult(!this.unique, res).createdCollectionAutomatically;
+ },
+
+ insert: function insert(db, collName) {
+ this.created |= this.checkWriteResult(!this.created && !this.unique,
+ this.myDB.getCollection(collName).insert({x: 1}))
+ .nInserted == 1;
+ },
+
+ upsert: function upsert(db, collName) {
+ this.created |= this.checkWriteResult(!this.created && !this.unique,
+ this.myDB.getCollection(collName).update(
+ {x: 1}, {x: 2}, {upsert: 1}))
+ .nUpserted == 1;
+ },
+
+ drop: function drop(db, collName) {
+ if (this.created)
+ assertAlways(this.myDB.getCollection(collName).drop());
+ },
+
+ dropDatabase: function dropDatabase(db, collName) {
+ if (this.created)
+ assertAlways.commandWorked(this.myDB.dropDatabase());
+ },
+
+ listDatabases: function listDatabases(db, collName) {
+ for (let database of db.adminCommand({listDatabases: 1}).databases) {
+ let res = db.getSiblingDB(database.name).runCommand({listCollections: 1});
+ assertAlways.commandWorked(res);
+ assertAlways.neq(database.name, this.myDB.toString(), "this DB shouldn't exist");
+ }
+ },
+ };
+
+ var transitions = {
+ init: {
+ useSemiUniqueDBName: 0.25,
+ createView: 0.25,
+ createCollection: 0.125,
+ createIndex: 0.125,
+ insert: 0.125,
+ upsert: 0.125
+ },
+ useSemiUniqueDBName: {createCollection: 0.75, createView: 0.25},
+ createView: {dropDatabase: 0.5, drop: 0.5},
+ createCollection: {dropDatabase: 0.25, createIndex: 0.25, insert: 0.25, upsert: 0.25},
+ createIndex: {insert: 0.25, upsert: 0.25, dropDatabase: 0.5},
+ insert: {dropDatabase: 0.2, drop: 0.05, insert: 0.5, upsert: 0.25},
+ upsert: {dropDatabase: 0.2, drop: 0.05, insert: 0.25, upsert: 0.5},
+ drop: {dropDatabase: 0.75, init: 0.25}, // OK to leave the empty database behind sometimes
+ dropDatabase: {init: 0.75, listDatabases: 0.25},
+ listDatabases: {init: 0.75, listDatabases: 0.25},
+ };
+
+ return {
+ data,
+ // We only run a few iterations to reduce the amount of data cumulatively
+ // written to disk by mmapv1. For example, setting 10 threads and 180
+ // iterations (with an expected 6 transitions per create/drop roundtrip)
+ // causes this workload to write at least 32MB (.ns and .0 files) * 10 threads
+ // * 30 iterations worth of data to disk, or about 10GB, which can be slow on
+ // test hosts.
+ threadCount: 10,
+ iterations: 180, states, transitions,
+ };
+})();