diff options
author | Judah Schvimer <judah@mongodb.com> | 2015-11-10 09:52:53 -0500 |
---|---|---|
committer | Judah Schvimer <judah@mongodb.com> | 2015-11-10 09:52:53 -0500 |
commit | 904c99891b47935ff7c0856f4456303f32c04f11 (patch) | |
tree | aa2759fd498a09d0ef3b52ddafb8a533d9017e5d /jstests/concurrency | |
parent | c836472353e736424c9bb87868508c9e633b892d (diff) | |
download | mongo-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.js | 21 | ||||
-rw-r--r-- | jstests/concurrency/fsm_libs/runner.js | 28 | ||||
-rw-r--r-- | jstests/concurrency/fsm_libs/thread_mgr.js | 12 | ||||
-rw-r--r-- | jstests/concurrency/fsm_libs/worker_thread.js | 24 | ||||
-rw-r--r-- | jstests/concurrency/fsm_workloads/convert_to_capped_collection.js | 15 | ||||
-rw-r--r-- | jstests/concurrency/fsm_workloads/list_indexes.js | 6 | ||||
-rw-r--r-- | jstests/concurrency/fsm_workloads/remove_single_document.js | 9 | ||||
-rw-r--r-- | jstests/concurrency/fsm_workloads/update_inc.js | 6 | ||||
-rw-r--r-- | jstests/concurrency/fsm_workloads/update_multifield.js | 9 | ||||
-rw-r--r-- | jstests/concurrency/fsm_workloads/update_rename.js | 11 | ||||
-rw-r--r-- | jstests/concurrency/fsm_workloads/update_replace.js | 11 | ||||
-rw-r--r-- | jstests/concurrency/fsm_workloads/update_simple.js | 11 |
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 }; |