summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Midvidy <amidvidy@gmail.com>2016-02-26 16:33:23 -0500
committerAdam Midvidy <amidvidy@gmail.com>2016-03-10 11:03:15 -0500
commit6efa681435ec30467ca88edc449b241bb2c326bf (patch)
tree41f788b7cb9f2058247266f0f51f3b7947fa267b
parent947307dbf80d59313e8c154eea1612fedb01a321 (diff)
downloadmongo-6efa681435ec30467ca88edc449b241bb2c326bf.tar.gz
SERVER-22356 add read_only_sharded suite
-rw-r--r--buildscripts/resmokeconfig/suites/read_only.yml3
-rw-r--r--buildscripts/resmokeconfig/suites/read_only_sharded.yml14
-rw-r--r--etc/evergreen.yml30
-rw-r--r--jstests/readonly/aggregate.js14
-rw-r--r--jstests/readonly/geo.js16
-rw-r--r--jstests/readonly/lib/read_only_test.js122
-rw-r--r--src/mongo/shell/shardingtest.js50
7 files changed, 198 insertions, 51 deletions
diff --git a/buildscripts/resmokeconfig/suites/read_only.yml b/buildscripts/resmokeconfig/suites/read_only.yml
index 7ae7cd5286a..f5c3a373fd9 100644
--- a/buildscripts/resmokeconfig/suites/read_only.yml
+++ b/buildscripts/resmokeconfig/suites/read_only.yml
@@ -7,5 +7,8 @@ executor:
js_test:
config:
shell_options:
+ global_vars:
+ TestData:
+ fixture: standalone
readMode: commands
nodb: ""
diff --git a/buildscripts/resmokeconfig/suites/read_only_sharded.yml b/buildscripts/resmokeconfig/suites/read_only_sharded.yml
new file mode 100644
index 00000000000..58ab7df836e
--- /dev/null
+++ b/buildscripts/resmokeconfig/suites/read_only_sharded.yml
@@ -0,0 +1,14 @@
+selector:
+ js_test:
+ roots:
+ - jstests/readonly/*.js
+
+executor:
+ js_test:
+ config:
+ shell_options:
+ global_vars:
+ TestData:
+ fixture: sharded
+ readMode: commands
+ nodb: ""
diff --git a/etc/evergreen.yml b/etc/evergreen.yml
index b581b4691a5..c9229e595ea 100644
--- a/etc/evergreen.yml
+++ b/etc/evergreen.yml
@@ -1719,6 +1719,24 @@ tasks:
resmoke_args: --suites=read_only --storageEngine=wiredTiger
run_multiple_jobs: true
+- <<: *task_template
+ name: read_only_sharded
+ commands:
+ - func: "do setup"
+ - func: "run tests"
+ vars:
+ resmoke_args: --suites=read_only_sharded --storageEngine=mmapv1
+ run_multiple_jobs: true
+
+- <<: *task_template
+ name: read_only_sharded_WT
+ commands:
+ - func: "do setup"
+ - func: "run tests"
+ vars:
+ resmoke_args: --suites=read_only_sharded --storageEngine=wiredTiger
+ run_multiple_jobs: true
+
- name: push
patchable: false
depends_on:
@@ -2239,6 +2257,8 @@ buildvariants:
- name: read_concern_majority_passthrough_WT
- name: read_only
- name: read_only_WT
+ - name: read_only_sharded
+ - name: read_only_sharded_WT
- name: replicasets
- name: replicasets_WT
- name: replicasets_auth
@@ -3258,6 +3278,8 @@ buildvariants:
- name: read_concern_majority_passthrough_WT
- name: read_only
- name: read_only_WT
+ - name: read_only_sharded
+ - name: read_only_sharded_WT
- name: replicasets
- name: replicasets_WT
- name: replication
@@ -3927,6 +3949,8 @@ buildvariants:
- name: read_concern_majority_passthrough_WT
- name: read_only
- name: read_only_WT
+ - name: read_only_sharded
+ - name: read_only_sharded_WT
- name: replicasets
- name: replicasets_WT
- name: replicasets_WT_ese
@@ -4531,6 +4555,10 @@ buildvariants:
- name: parallel_compatibility
- name: parallel_compatibility_WT
- name: read_concern_majority_passthrough_WT
+ - name: read_only
+ - name: read_only_WT
+ - name: read_only_sharded
+ - name: read_only_sharded_WT
- name: replicasets
- name: replicasets_WT
- name: replicasets_WT_ese
@@ -5604,6 +5632,8 @@ buildvariants:
- name: read_concern_majority_passthrough_WT
- name: read_only
- name: read_only_WT
+ - name: read_only_sharded
+ - name: read_only_sharded_WT
- name: replicasets
- name: replicasets_WT
- name: replicasets_WT_ese
diff --git a/jstests/readonly/aggregate.js b/jstests/readonly/aggregate.js
index 9f74f739c4d..aba6a7aa3a3 100644
--- a/jstests/readonly/aggregate.js
+++ b/jstests/readonly/aggregate.js
@@ -69,13 +69,17 @@ runReadOnlyTest(function() {
// Find titles nominated for the most awards.
var mostAwardsPipeline = [
{$unwind: "$nominations"},
- {$group: {_id: "$nominations.title", count: {$sum: 1}}},
- {$sort: {count: -1}},
- {$limit: 2}
+ {$group: {
+ _id: "$nominations.title",
+ count: {$sum: 1}}},
+ {$sort: {count: -1, _id: 1}},
+ {$limit: 2},
];
- assert.docEq(readableCollection.aggregate(mostAwardsPipeline).toArray(),
- [{_id: "The Revenant", count: 3}, {_id: "Spotlight", count: 3}]);
+ assert.docEq(readableCollection.aggregate(mostAwardsPipeline).toArray(), [
+ {_id: "Spotlight", count: 3},
+ {_id: "The Revenant", count: 3}
+ ]);
// Check that pipelines fail with allowDiskUse true. We use runCommand manually because
// the helper has conflicting error handling logic.
diff --git a/jstests/readonly/geo.js b/jstests/readonly/geo.js
index 367cb89be96..f8113dabb06 100644
--- a/jstests/readonly/geo.js
+++ b/jstests/readonly/geo.js
@@ -33,11 +33,17 @@ runReadOnlyTest(function() {
writableCollection.insertMany(locDocs);
},
exec: function(readableCollection) {
- var res = readableCollection.find({
- loc:
- {$near: {$geometry: {type: "Point", coordinates: [40.7211404, -73.9591494]}}}
- }).limit(1).toArray();
- assert.eq(res[0].name, "The Counting Room");
+ var res = readableCollection.runCommand({
+ geoNear: readableCollection.getName(),
+ near: {
+ type: "Point",
+ coordinates: [40.7211404, -73.9591494]
+ },
+ spherical: true,
+ limit: 1
+ });
+ assert.commandWorked(res);
+ assert.eq(res.results[0].obj.name, "The Counting Room", printjson(res));
}
};
}());
diff --git a/jstests/readonly/lib/read_only_test.js b/jstests/readonly/lib/read_only_test.js
index 55af207a399..c0ee79a7370 100644
--- a/jstests/readonly/lib/read_only_test.js
+++ b/jstests/readonly/lib/read_only_test.js
@@ -1,4 +1,4 @@
-'use_strict';
+"use_strict";
function makeDirectoryReadOnly(dir) {
if (_isWindows()) {
@@ -16,44 +16,114 @@ function makeDirectoryWritable(dir) {
}
}
-function runReadOnlyTest(test) {
- printjson(test);
+function StandaloneFixture() {
+}
+
+StandaloneFixture.prototype.runLoadPhase = function runLoadPhase(test) {
+ this.mongod = MongoRunner.runMongod({});
+ this.dbpath = this.mongod.dbpath;
+
+ test.load(this.mongod.getDB("test")[test.name]);
+ MongoRunner.stopMongod(this.mongod);
+};
+
+StandaloneFixture.prototype.runExecPhase = function runExecPhase(test) {
+ try {
+ makeDirectoryReadOnly(this.dbpath);
- assert.eq(typeof(test.exec), 'function');
- assert.eq(typeof(test.load), 'function');
- assert.eq(typeof(test.name), 'string');
+ var options = {
+ readOnly: "",
+ noCleanData: true,
+ dbpath: this.dbpath
+ };
+
+ this.mongod = MongoRunner.runMongod(options);
+
+ test.exec(this.mongod.getDB("test")[test.name]);
+
+ MongoRunner.stopMongod(this.mongod);
+ } finally {
+ makeDirectoryWritable(this.dbpath);
+ }
+};
+
+function ShardedFixture() {
+ this.nShards = 3;
+}
- var options = {
- storageEngine: TestData.storageEngine,
- nopreallocj: ''
- };
+ShardedFixture.prototype.runLoadPhase = function runLoadPhase(test) {
+ this.shardingTest = new ShardingTest({
+ nopreallocj: true,
+ mongos: 1,
+ shards: this.nShards
+ });
- var writableMongod = MongoRunner.runMongod(options);
- var dbpath = writableMongod.dbpath;
+ this.paths = this.shardingTest.getDBPaths();
- jsTest.log('starting load phase for test: ' + test.name);
- test.load(writableMongod.getDB('test')[test.name]);
+ jsTest.log("sharding test collection...");
- MongoRunner.stopMongod(writableMongod);
+ // Use a hashed shard key so we actually hit multiple shards.
+ this.shardingTest.shardColl(test.name, {_id: "hashed"});
- makeDirectoryReadOnly(dbpath);
+ test.load(this.shardingTest.getDB("test")[test.name]);
+};
+ShardedFixture.prototype.runExecPhase = function runExecPhase(test) {
+ jsTest.log("restarting shards...");
try {
- var readOnlyOptions =
- Object.extend(options, {readOnly: '', dbpath: dbpath, noCleanData: true});
+ for (var i = 0; i < this.nShards; ++i) {
+ var opts = {
+ readOnly: "",
+ dbpath: this.paths[i]
+ };
+
+ this.shardingTest.restartMongod(i, opts, () => {
+ makeDirectoryReadOnly(this.paths[i]);
+ });
+ }
+
+ jsTest.log("restarting mongos...");
- var readOnlyMongod = MongoRunner.runMongod(readOnlyOptions);
+ this.shardingTest.restartMongos(0);
- jsTest.log('starting execution phase for test: ' + test.name);
- test.exec(readOnlyMongod.getDB('test')[test.name]);
+ test.exec(this.shardingTest.getDB("test")[test.name]);
- // We need to make the directory writable so that MongoRunner can clean the dbpath.
- makeDirectoryWritable(dbpath);
- MongoRunner.stopMongod(readOnlyMongod);
+ this.paths.forEach((path) => {
+ makeDirectoryWritable(path);
+ });
+
+ this.shardingTest.stop();
} finally {
- // One last time, just in case.
- makeDirectoryWritable(dbpath);
+ this.paths.forEach((path) => {
+ makeDirectoryWritable(path);
+ });
+ }
+};
+
+function runReadOnlyTest(test) {
+
+ printjson(test);
+
+ assert.eq(typeof(test.exec), "function");
+ assert.eq(typeof(test.load), "function");
+ assert.eq(typeof(test.name), "string");
+
+ var fixtureType = TestData.fixture || "standalone";
+
+ var fixture = null;
+ if (fixtureType === "standalone") {
+ fixture = new StandaloneFixture();
+ } else if (fixtureType === "sharded") {
+ fixture = new ShardedFixture();
+ } else {
+ throw new Error("fixtureType must be one of either 'standalone' or 'sharded'");
}
+
+ jsTest.log("starting load phase for test: " + test.name);
+ fixture.runLoadPhase(test);
+
+ jsTest.log("starting execution phase for test: " + test.name);
+ fixture.runExecPhase(test);
}
function * cycleN(arr, N) {
diff --git a/src/mongo/shell/shardingtest.js b/src/mongo/shell/shardingtest.js
index 4d38aa88544..6651057143e 100644
--- a/src/mongo/shell/shardingtest.js
+++ b/src/mongo/shell/shardingtest.js
@@ -369,6 +369,12 @@ var ShardingTest = function(params) {
(timeMillis / 1000) + " seconds ***");
};
+ this.getDBPaths = function() {
+ return _alldbpaths.map((path) => {
+ return MongoRunner.dataPath + path;
+ });
+ };
+
this.adminCommand = function(cmd) {
var res = this.admin.runCommand(cmd);
if (res && res.ok == 1)
@@ -820,11 +826,14 @@ var ShardingTest = function(params) {
* Stops and restarts a shard mongod process.
*
* If opts is specified, the new mongod is started using those options. Otherwise, it is started
- * with its previous parameters.
+ * with its previous parameters. The 'beforeRestartCallback' parameter is an optional function
+ * that will be run after the MongoD is stopped, but before it is restarted. The intended uses
+ * of the callback are modifications to the dbpath of the mongod that must be made while it is
+ * stopped.
*
* Warning: Overwrites the old dn/shardn member variables.
*/
- this.restartMongod = function(n) {
+ this.restartMongod = function(n, opts, beforeRestartCallback) {
var mongod;
if (otherParams.useBridge) {
@@ -833,26 +842,37 @@ var ShardingTest = function(params) {
mongod = this["d" + n];
}
+ opts = opts || mongod;
+ opts.port = opts.port || mongod.port;
+
this.stopMongod(n);
if (otherParams.useBridge) {
- var bridgeOptions =
- Object.merge(otherParams.bridgeOptions, mongod.fullOptions.bridgeOptions || {});
- bridgeOptions = Object.merge(
- bridgeOptions,
- {
- hostName: otherParams.useHostname ? hostName : "localhost",
- port: this._connections[n].port,
- // The mongod processes identify themselves to mongobridge as host:port, where the
- // host is the actual hostname of the machine and not localhost.
- dest: hostName + ":" + mongod.port,
- });
+ var bridgeOptions = (opts !== mongod) ? opts.bridgeOptions
+ : mongod.fullOptions.bridgeOptions;
+ bridgeOptions = Object.merge(otherParams.bridgeOptions, bridgeOptions || {});
+ bridgeOptions = Object.merge(bridgeOptions, {
+ hostName: otherParams.useHostname ? hostName : "localhost",
+ port: this._connections[n].port,
+ // The mongod processes identify themselves to mongobridge as host:port, where the
+ // host is the actual hostname of the machine and not localhost.
+ dest: hostName + ":" + opts.port,
+ });
this._connections[n] = new MongoBridge(bridgeOptions);
}
- mongod.restart = true;
- var newConn = MongoRunner.runMongod(mongod);
+ if (arguments.length >= 3) {
+ if (typeof(beforeRestartCallback) !== "function") {
+ throw new Error("beforeRestartCallback must be a function but was of type " +
+ typeof(beforeRestartCallback));
+ }
+ beforeRestartCallback();
+ }
+
+ opts.restart = true;
+
+ var newConn = MongoRunner.runMongod(opts);
if (!newConn) {
throw new Error("Failed to restart shard " + n);
}