summaryrefslogtreecommitdiff
path: root/jstests/concurrency
diff options
context:
space:
mode:
authorJudah Schvimer <judah@mongodb.com>2015-11-10 09:52:53 -0500
committerJudah Schvimer <judah@mongodb.com>2015-11-10 09:52:53 -0500
commit904c99891b47935ff7c0856f4456303f32c04f11 (patch)
treeaa2759fd498a09d0ef3b52ddafb8a533d9017e5d /jstests/concurrency
parentc836472353e736424c9bb87868508c9e633b892d (diff)
downloadmongo-904c99891b47935ff7c0856f4456303f32c04f11.tar.gz
SERVER-21310 Inject iterations and threadCount into data object in fsm workloads
Diffstat (limited to 'jstests/concurrency')
-rw-r--r--jstests/concurrency/fsm_libs/parse_config.js21
-rw-r--r--jstests/concurrency/fsm_libs/runner.js28
-rw-r--r--jstests/concurrency/fsm_libs/thread_mgr.js12
-rw-r--r--jstests/concurrency/fsm_libs/worker_thread.js24
-rw-r--r--jstests/concurrency/fsm_workloads/convert_to_capped_collection.js15
-rw-r--r--jstests/concurrency/fsm_workloads/list_indexes.js6
-rw-r--r--jstests/concurrency/fsm_workloads/remove_single_document.js9
-rw-r--r--jstests/concurrency/fsm_workloads/update_inc.js6
-rw-r--r--jstests/concurrency/fsm_workloads/update_multifield.js9
-rw-r--r--jstests/concurrency/fsm_workloads/update_rename.js11
-rw-r--r--jstests/concurrency/fsm_workloads/update_replace.js11
-rw-r--r--jstests/concurrency/fsm_workloads/update_simple.js11
12 files changed, 103 insertions, 60 deletions
diff --git a/jstests/concurrency/fsm_libs/parse_config.js b/jstests/concurrency/fsm_libs/parse_config.js
index d1aef30c545..1b53f42841c 100644
--- a/jstests/concurrency/fsm_libs/parse_config.js
+++ b/jstests/concurrency/fsm_libs/parse_config.js
@@ -24,13 +24,15 @@ function parseConfig(config) {
'; valid parameters are: ' + tojson(allowedKeys));
});
- assert.eq('number', typeof config.threadCount);
- // TODO: assert that the thread count is positive
- // TODO: assert that the thread count is an integer
+ assert(Number.isInteger(config.threadCount),
+ 'expected number of threads to be an integer');
+ assert.gt(config.threadCount, 0,
+ 'expected number of threads to be positive');
- assert.eq('number', typeof config.iterations);
- // TODO: assert that the number of iterations is positive
- // TODO: assert that the number of iterations is an integer
+ assert(Number.isInteger(config.iterations),
+ 'expected number of iterations to be an integer');
+ assert.gt(config.iterations, 0,
+ 'expected number of iterations to be positive');
config.startState = config.startState || 'init';
assert.eq('string', typeof config.startState);
@@ -78,7 +80,12 @@ function parseConfig(config) {
config.data = config.data || {};
assert.eq('object', typeof config.data);
- // TODO: assert that 'tid' is not a key of 'config.data'
+ assert.eq(false, config.data.hasOwnProperty('tid'),
+ 'data object cannot redefine "tid"');
+ assert.eq(false, config.data.hasOwnProperty('iterations'),
+ 'data object cannot redefine "iterations"');
+ assert.eq(false, config.data.hasOwnProperty('threadCount'),
+ 'data object cannot redefine "threadCount"');
config.passConnectionCache = config.passConnectionCache || false;
assert.eq('boolean', typeof config.passConnectionCache);
diff --git a/jstests/concurrency/fsm_libs/runner.js b/jstests/concurrency/fsm_libs/runner.js
index 0e96112c0cb..5b53bfb0979 100644
--- a/jstests/concurrency/fsm_libs/runner.js
+++ b/jstests/concurrency/fsm_libs/runner.js
@@ -344,6 +344,30 @@ var runner = (function() {
config.teardown.call(config.data, myDB, collName, cluster);
}
+ function setIterations(config, iterationMultiplier) {
+ config.iterations = config.iterations * iterationMultiplier;
+
+ // This property must be enumerable because of SERVER-21338, which prevents
+ // objects with non-enumerable properties from being serialized properly in
+ // ScopedThreads.
+ Object.defineProperty(config.data, 'iterations', {
+ enumerable: true,
+ value: config.iterations
+ });
+ }
+
+ function setThreadCount(config, threadMultiplier) {
+ config.threadCount = config.threadCount * threadMultiplier;
+
+ // This property must be enumerable because of SERVER-21338, which prevents
+ // objects with non-enumerable properties from being serialized properly in
+ // ScopedThreads.
+ Object.defineProperty(config.data, 'threadCount', {
+ enumerable: true,
+ value: config.threadCount
+ });
+ }
+
function runWorkloads(workloads,
clusterOptions,
executionMode,
@@ -385,9 +409,11 @@ var runner = (function() {
load(workload); // for $config
assert.neq('undefined', typeof $config, '$config was not defined by ' + workload);
context[workload] = { config: parseConfig($config) };
+ setIterations(context[workload].config, executionOptions.iterationMultiplier);
+ setThreadCount(context[workload].config, executionOptions.threadMultiplier);
});
- var threadMgr = new ThreadManager(clusterOptions, executionMode, executionOptions);
+ var threadMgr = new ThreadManager(clusterOptions, executionMode);
var cluster = new Cluster(clusterOptions);
cluster.setup();
diff --git a/jstests/concurrency/fsm_libs/thread_mgr.js b/jstests/concurrency/fsm_libs/thread_mgr.js
index d9e4e66b50f..45a5287b008 100644
--- a/jstests/concurrency/fsm_libs/thread_mgr.js
+++ b/jstests/concurrency/fsm_libs/thread_mgr.js
@@ -7,9 +7,9 @@ load('jstests/concurrency/fsm_libs/worker_thread.js'); // for workerThread
* Helper for spawning and joining worker threads.
*/
-var ThreadManager = function(clusterOptions, executionMode, executionOptions) {
+var ThreadManager = function(clusterOptions, executionMode) {
if (!(this instanceof ThreadManager)) {
- return new ThreadManager(clusterOptions, executionMode, executionOptions);
+ return new ThreadManager(clusterOptions, executionMode);
}
function makeThread(workloads, args, options) {
@@ -59,7 +59,7 @@ var ThreadManager = function(clusterOptions, executionMode, executionOptions) {
workloads.forEach(function(workload) {
var config = context[workload].config;
- threadCounts[workload] = config.threadCount * executionOptions.threadMultiplier;
+ threadCounts[workload] = config.threadCount;
});
var requestedNumThreads = computeNumThreads();
@@ -95,12 +95,9 @@ var ThreadManager = function(clusterOptions, executionMode, executionOptions) {
}
var workloadData = {};
- _workloads.forEach(function(workload) {
- workloadData[workload] = _context[workload].config.data;
- });
-
var tid = 0;
_workloads.forEach(function(workload) {
+ workloadData[workload] = _context[workload].config.data;
var workloads = [workload]; // worker thread only needs to load 'workload'
if (executionMode.composed) {
workloads = _workloads; // worker thread needs to load all workloads
@@ -116,7 +113,6 @@ var ThreadManager = function(clusterOptions, executionMode, executionOptions) {
collName: _context[workload].collName,
cluster: cluster.getSerializedCluster(),
clusterOptions: clusterOptions,
- iterationMultiplier: executionOptions.iterationMultiplier,
seed: Random.randInt(1e13), // contains range of Date.getTime()
globalAssertLevel: globalAssertLevel
};
diff --git a/jstests/concurrency/fsm_libs/worker_thread.js b/jstests/concurrency/fsm_libs/worker_thread.js
index 30b9986f030..f4491098279 100644
--- a/jstests/concurrency/fsm_libs/worker_thread.js
+++ b/jstests/concurrency/fsm_libs/worker_thread.js
@@ -15,7 +15,6 @@ var workerThread = (function() {
// args.collName = the collection name
// args.cluster = connection strings for all cluster nodes (see cluster.js for format)
// args.clusterOptions = the configuration of the cluster
- // args.iterationMultiplier = number to multiply the number of iterations by
// args.seed = seed for the random number generator
// args.globalAssertLevel = the global assertion level to use
// run = callback that takes a map of workloads to their associated $config
@@ -58,17 +57,36 @@ var workerThread = (function() {
var data = Object.extend({}, args.data[workload], true);
data = Object.extend(data, config.data, true);
+ // Object.extend() defines all properties added to the destination object as
+ // configurable, enumerable, and writable. To prevent workloads from changing
+ // the iterations and threadCount properties in their state functions, we redefine
+ // them here as non-configurable, non-enumerable, and non-writable.
+ Object.defineProperties(data, {
+ 'iterations': {
+ configurable: false,
+ enumerable: false,
+ writable: false,
+ value: data.iterations
+ },
+ 'threadCount': {
+ configurable: false,
+ enumerable: false,
+ writable: false,
+ value: data.threadCount
+ }
+ });
+
data.tid = args.tid;
configs[workload] = {
data: data,
db: myDB,
collName: args.collName,
cluster: args.cluster,
+ iterations: data.iterations,
passConnectionCache: config.passConnectionCache,
startState: config.startState,
states: config.states,
- transitions: config.transitions,
- iterations: config.iterations * args.iterationMultiplier
+ transitions: config.transitions
};
});
diff --git a/jstests/concurrency/fsm_workloads/convert_to_capped_collection.js b/jstests/concurrency/fsm_workloads/convert_to_capped_collection.js
index ef575b17849..9f28512a837 100644
--- a/jstests/concurrency/fsm_workloads/convert_to_capped_collection.js
+++ b/jstests/concurrency/fsm_workloads/convert_to_capped_collection.js
@@ -12,12 +12,9 @@
load('jstests/concurrency/fsm_workload_helpers/drop_utils.js');
var $config = (function() {
- var iter = 20;
+ // TODO: This workload may fail if an iteration multiplier is specified.
var data = {
- prefix: 'convert_to_capped_collection',
-
- // initial size should not be a power of 256
- size: Math.pow(2, iter + 5) + 1
+ prefix: 'convert_to_capped_collection'
};
var states = (function() {
@@ -76,6 +73,11 @@ var $config = (function() {
convertToCapped: { convertToCapped: 1 }
};
+ function setup(db, collName, cluster) {
+ // Initial size should not be a power of 256.
+ this.size = Math.pow(2, this.iterations + 5) + 1;
+ }
+
function teardown(db, collName, cluster) {
var pattern = new RegExp('^' + this.prefix + '_\\d+$');
dropCollections(db, pattern);
@@ -83,10 +85,11 @@ var $config = (function() {
return {
threadCount: 10,
- iterations: iter,
+ iterations: 20,
data: data,
states: states,
transitions: transitions,
+ setup: setup,
teardown: teardown
};
diff --git a/jstests/concurrency/fsm_workloads/list_indexes.js b/jstests/concurrency/fsm_workloads/list_indexes.js
index 4b422cc6f3d..6ab3a8c28b9 100644
--- a/jstests/concurrency/fsm_workloads/list_indexes.js
+++ b/jstests/concurrency/fsm_workloads/list_indexes.js
@@ -8,8 +8,6 @@
*/
var $config = (function() {
- var threadCount = 10;
-
var states = (function() {
// Picks a random index to drop and recreate.
function modifyIndices(db, collName) {
@@ -42,7 +40,7 @@ var $config = (function() {
function setup(db, collName) {
// Create indices {fooi: 1}.
- for (var i = 0; i < threadCount; ++i) {
+ for (var i = 0; i < this.threadCount; ++i) {
var spec = {};
spec['foo' + i] = 1;
assertAlways.commandWorked(db[collName].ensureIndex(spec));
@@ -50,7 +48,7 @@ var $config = (function() {
}
return {
- threadCount: threadCount,
+ threadCount: 10,
iterations: 20,
states: states,
startState: 'modifyIndices',
diff --git a/jstests/concurrency/fsm_workloads/remove_single_document.js b/jstests/concurrency/fsm_workloads/remove_single_document.js
index c54cf02ec85..75442919f2d 100644
--- a/jstests/concurrency/fsm_workloads/remove_single_document.js
+++ b/jstests/concurrency/fsm_workloads/remove_single_document.js
@@ -33,12 +33,9 @@ var $config = (function() {
remove: { remove: 1 }
};
- var threadCount = 10;
- var iterations = 20;
-
function setup(db, collName, cluster) {
// insert enough documents so that each thread can remove exactly one per iteration
- var num = threadCount * iterations;
+ var num = this.threadCount * this.iterations;
for (var i = 0; i < num; ++i) {
db[collName].insert({ i: i, rand: Random.rand() });
}
@@ -46,8 +43,8 @@ var $config = (function() {
}
return {
- threadCount: threadCount,
- iterations: iterations,
+ threadCount: 10,
+ iterations: 20,
states: states,
transitions: transitions,
setup: setup,
diff --git a/jstests/concurrency/fsm_workloads/update_inc.js b/jstests/concurrency/fsm_workloads/update_inc.js
index 6ecb1ff522d..32dca107456 100644
--- a/jstests/concurrency/fsm_workloads/update_inc.js
+++ b/jstests/concurrency/fsm_workloads/update_inc.js
@@ -68,20 +68,18 @@ var $config = (function() {
find: { update: 1 }
};
- var threadCount = 5;
-
function setup(db, collName, cluster) {
var doc = { _id: this.id };
// Pre-populate the fields we need to avoid size change for capped collections.
- for (var i = 0; i < threadCount; ++i) {
+ for (var i = 0; i < this.threadCount; ++i) {
doc['t' + i] = 0;
}
db[collName].insert(doc);
}
return {
- threadCount: threadCount,
+ threadCount: 5,
iterations: 10,
data: data,
states: states,
diff --git a/jstests/concurrency/fsm_workloads/update_multifield.js b/jstests/concurrency/fsm_workloads/update_multifield.js
index 6df238051bf..f04f347d262 100644
--- a/jstests/concurrency/fsm_workloads/update_multifield.js
+++ b/jstests/concurrency/fsm_workloads/update_multifield.js
@@ -67,6 +67,10 @@ var $config = (function() {
assertAlways.commandWorked(db[collName].ensureIndex({ z: 1 }));
assertAlways.commandWorked(db[collName].ensureIndex({ x: 1, y: 1, z: 1 }));
+ // numDocs should be much less than threadCount, to make more threads use the same docs.
+ this.numDocs = Math.floor(this.threadCount / 3);
+ assertAlways.gt(this.numDocs, 0, 'numDocs should be a positive number');
+
for (var i = 0; i < this.numDocs; ++i) {
var res = db[collName].insert({ _id: i });
assertWhenOwnColl.writeOK(res);
@@ -74,9 +78,8 @@ var $config = (function() {
}
}
- var threadCount = 10;
return {
- threadCount: threadCount,
+ threadCount: 10,
iterations: 10,
startState: 'update',
states: states,
@@ -105,8 +108,6 @@ var $config = (function() {
},
multi: false,
isolated: false,
- // numDocs should be much less than threadCount, to make more threads use the same docs
- numDocs: Math.floor(threadCount / 3)
},
setup: setup
};
diff --git a/jstests/concurrency/fsm_workloads/update_rename.js b/jstests/concurrency/fsm_workloads/update_rename.js
index c4ebaa3e812..c74a657f312 100644
--- a/jstests/concurrency/fsm_workloads/update_rename.js
+++ b/jstests/concurrency/fsm_workloads/update_rename.js
@@ -47,6 +47,10 @@ var $config = (function() {
assertAlways.commandWorked(db[collName].ensureIndex(indexSpec));
});
+ // numDocs should be much less than threadCount, to make more threads use the same docs.
+ this.numDocs = Math.floor(this.threadCount / 5);
+ assertAlways.gt(this.numDocs, 0, 'numDocs should be a positive number');
+
for (var i = 0; i < this.numDocs; ++i) {
var fieldName = fieldNames[i % fieldNames.length];
var doc = {};
@@ -57,17 +61,12 @@ var $config = (function() {
}
}
- var threadCount = 20;
return {
- threadCount: threadCount,
+ threadCount: 20,
iterations: 20,
startState: 'update',
states: states,
transitions: transitions,
- data: {
- // numDocs should be much less than threadCount, to make more threads use the same docs
- numDocs: Math.floor(threadCount / 5)
- },
setup: setup
};
diff --git a/jstests/concurrency/fsm_workloads/update_replace.js b/jstests/concurrency/fsm_workloads/update_replace.js
index 25a35d5255d..9776d6f31da 100644
--- a/jstests/concurrency/fsm_workloads/update_replace.js
+++ b/jstests/concurrency/fsm_workloads/update_replace.js
@@ -54,6 +54,10 @@ var $config = (function() {
assertAlways.commandWorked(db[collName].ensureIndex({ y: 1 }));
// no index on z
+ // numDocs should be much less than threadCount, to make more threads use the same docs.
+ this.numDocs = Math.floor(this.threadCount / 3);
+ assertAlways.gt(this.numDocs, 0, 'numDocs should be a positive number');
+
for (var i = 0; i < this.numDocs; ++i) {
var res = db[collName].insert({ _id: i });
assertWhenOwnColl.writeOK(res);
@@ -63,17 +67,12 @@ var $config = (function() {
assertWhenOwnColl.eq(this.numDocs, db[collName].find().itcount());
}
- var threadCount = 10;
return {
- threadCount: threadCount,
+ threadCount: 10,
iterations: 10,
startState: 'update',
states: states,
transitions: transitions,
- data: {
- // numDocs should be much less than threadCount, to make more threads use the same docs
- numDocs: Math.floor(threadCount / 3)
- },
setup: setup
};
diff --git a/jstests/concurrency/fsm_workloads/update_simple.js b/jstests/concurrency/fsm_workloads/update_simple.js
index 9b116f40c23..7e3c00de390 100644
--- a/jstests/concurrency/fsm_workloads/update_simple.js
+++ b/jstests/concurrency/fsm_workloads/update_simple.js
@@ -36,6 +36,11 @@ var $config = (function() {
function setup(db, collName, cluster) {
// index on 'value', the field being updated
assertAlways.commandWorked(db[collName].ensureIndex({ value: 1 }));
+
+ // numDocs should be much less than threadCount, to make more threads use the same docs.
+ this.numDocs = Math.floor(this.threadCount / 5);
+ assertAlways.gt(this.numDocs, 0, 'numDocs should be a positive number');
+
for (var i = 0; i < this.numDocs; ++i) {
// make sure the inserted docs have a 'value' field, so they won't need
// to grow when this workload runs against a capped collection
@@ -45,9 +50,8 @@ var $config = (function() {
}
}
- var threadCount = 20;
return {
- threadCount: threadCount,
+ threadCount: 20,
iterations: 20,
startState: 'set',
states: states,
@@ -91,9 +95,6 @@ var $config = (function() {
doUpdate: function doUpdate(db, collName, query, updater) {
return db[collName].update(query, updater);
},
-
- // numDocs should be much less than threadCount, to make more threads use the same docs
- numDocs: Math.floor(threadCount / 5)
},
setup: setup
};