summaryrefslogtreecommitdiff
path: root/jstests/serial_run
diff options
context:
space:
mode:
authorEric Milkie <milkie@10gen.com>2016-03-14 13:56:45 -0400
committerEric Milkie <milkie@10gen.com>2016-03-15 13:28:47 -0400
commit61fd8eefb0fd8e563014b82b2d928d9b0bafda7b (patch)
treed6facaff9a0f0382bff93fd9ac5a52e9ebe80a65 /jstests/serial_run
parenta40991b77d885ceb3048b9eaf3b5100e259234b9 (diff)
downloadmongo-61fd8eefb0fd8e563014b82b2d928d9b0bafda7b.tar.gz
SERVER-23111 isolate election_timing.js and memory.js by creating new serial_run suite
Diffstat (limited to 'jstests/serial_run')
-rw-r--r--jstests/serial_run/README2
-rw-r--r--jstests/serial_run/election_timing.js151
-rw-r--r--jstests/serial_run/memory.js57
3 files changed, 210 insertions, 0 deletions
diff --git a/jstests/serial_run/README b/jstests/serial_run/README
new file mode 100644
index 00000000000..73bc3344f1d
--- /dev/null
+++ b/jstests/serial_run/README
@@ -0,0 +1,2 @@
+This suite contains tests that are unusually susceptible to availability of machine resources;
+therefore, this suite is always run with --jobs=1 via Evergreen config. \ No newline at end of file
diff --git a/jstests/serial_run/election_timing.js b/jstests/serial_run/election_timing.js
new file mode 100644
index 00000000000..2fe83be02ed
--- /dev/null
+++ b/jstests/serial_run/election_timing.js
@@ -0,0 +1,151 @@
+// Run a small set of tests using the ElectionTimingTest framework. While this
+// reports the timing of the election, we are using it to check if any errors happen
+// during different election cycles.
+(function() {
+ "use strict";
+ load("jstests/libs/election_timing_test.js");
+ var testStart = Date.now();
+
+ var testCases = [
+ {
+ name: "testV1Stop",
+ description: "protocolVersion 1, primary is stopped",
+ protocolVersion: 1,
+ // testRuns is the number of times a new ReplSetTest will be used.
+ testRuns: 1,
+ // testCycles is the number of election cycles that will be run per ReplSetTest lifespan.
+ testCycles: 5,
+ // testSetup is run after the replSet is initiated.
+ // Function.prototype is the default.
+ testSetup: Function.prototype,
+ // Trigger an election by stepping down, stopping, or partitioning the primary.
+ // stopPrimary is the default.
+ electionTrigger: ElectionTimingTest.prototype.stopPrimary,
+ // After the election has completed, make the old primary available again.
+ // stopPrimaryReset is the default.
+ testReset: ElectionTimingTest.prototype.stopPrimaryReset
+ },
+
+ /*
+ This test case is flakey since waiting for the old primary to shutdown can take longer than
+ the
+ allowed timeout, even if a new primary was elected during the shutdown time.
+
+ {
+ name: "testV1StopTimeout1500",
+ description: "protocolVersion 1, primary is stopped, electionTimeoutMillis set to 1500",
+ protocolVersion: 1,
+ testRuns: 1,
+ testCycles: 5,
+ // The settings object is merged into the replset config settings object.
+ settings: {electionTimeoutMillis: 1500}
+ },
+ */
+
+ {
+ name: "testV1StepDown",
+ description: "protocolVersion 1, primary is stepped down",
+ protocolVersion: 1,
+ testRuns: 1,
+ testCycles: 5,
+ electionTrigger: ElectionTimingTest.prototype.stepDownPrimary,
+ testReset: ElectionTimingTest.prototype.stepDownPrimaryReset,
+ },
+
+ {
+ name: "testV1StepDown1500",
+ description: "protocolVersion 1, primary is stepped down",
+ protocolVersion: 1,
+ testRuns: 1,
+ testCycles: 5,
+ electionTrigger: ElectionTimingTest.prototype.stepDownPrimary,
+ testReset: ElectionTimingTest.prototype.stepDownPrimaryReset,
+ // The settings object is merged into the replset config settings object.
+ settings: {electionTimeoutMillis: 1500}
+ },
+
+ {
+ name: "testV1StepDownLargeCluster",
+ description: "protocolVersion 1, primary is stepped down, 7 electable nodes",
+ protocolVersion: 1,
+ nodes: 7,
+ testRuns: 1,
+ testCycles: 5,
+ electionTrigger: ElectionTimingTest.prototype.stepDownPrimary,
+ testReset: function() {},
+ waitForNewPrimary: function(rst, secondary) {
+ rst.getPrimary();
+ }
+ },
+
+ {
+ name: "testV0Stop",
+ description: "protocolVersion 0, primary is stopped",
+ protocolVersion: 0,
+ testRuns: 1,
+ testCycles: 1
+ },
+
+ {
+ name: "testV0StepDown",
+ description: "protocolVersion 0, primary is stepped down",
+ protocolVersion: 0,
+ testRuns: 1,
+ testCycles: 2,
+ stepDownGuardTime: 30,
+ // There is a guard time in pv0 that prevents an election right
+ // after initiating.
+ testSetup: function() {
+ sleep(30 * 1000);
+ },
+ electionTrigger: ElectionTimingTest.prototype.stepDownPrimary,
+ testReset: ElectionTimingTest.prototype.stepDownPrimaryReset
+ },
+
+ ];
+
+ testCases.forEach(function(tc) {
+ var testRun = new ElectionTimingTest(tc);
+ tc.testResults = testRun.testResults;
+ tc.electionTimeoutLimitMillis = testRun.electionTimeoutLimitMillis;
+
+ if (testRun.testErrors.length) {
+ // Stop tests if we encounter an error.
+ // Dump available information for debugging.
+ jsTestLog("Errors from: " + tc.name);
+ printjson(tc);
+ printjson(testRun.testErrors);
+ throw new Error(testRun.testErrors[0].status);
+ }
+ // Print results of current test in case
+ // we need to analyze a failed test later.
+ jsTestLog("Raw Results: " + tc.name);
+ printjson(tc.testResults);
+ });
+
+ testCases.forEach(function(tc) {
+ var allResults = [];
+ tc.testResults.forEach(function(tr) {
+ allResults = allResults.concat(tr.results);
+ });
+
+ var resAvg = Array.avg(allResults);
+ var resMin = Math.min(... allResults);
+ var resMax = Math.max(... allResults);
+ var resStdDev = Array.stdDev(allResults);
+
+ jsTestLog("Results: " + tc.name + " Average over " + allResults.length + " runs: " +
+ resAvg + " Min: " + resMin + " Max: " + resMax + " Limit: " +
+ tc.electionTimeoutLimitMillis / 1000 + " StdDev: " + resStdDev.toFixed(4));
+
+ allResults.forEach(function(failoverElapsedMillis) {
+ assert.lte(failoverElapsedMillis,
+ tc.electionTimeoutLimitMillis / 1000,
+ tc.name + ': failover (' + failoverElapsedMillis +
+ ' sec) took too long. limit: ' + tc.electionTimeoutLimitMillis / 1000 +
+ ' sec');
+ });
+ });
+
+ jsTestLog("Tests completed in: " + (Date.now() - testStart) / 1000 + " seconds");
+}());
diff --git a/jstests/serial_run/memory.js b/jstests/serial_run/memory.js
new file mode 100644
index 00000000000..9d67aa7aab6
--- /dev/null
+++ b/jstests/serial_run/memory.js
@@ -0,0 +1,57 @@
+var col = db.memoryTest;
+
+// test creating many collections to make sure no internal cache goes OOM
+for (var i = 0; i < 10000; ++i) {
+ name = "memoryTest" + i;
+ if ((i % 1000) == 0)
+ print("Processing " + name);
+ db.eval(function(col) {
+ for (var i = 0; i < 100; ++i) {
+ db[col + "_" + i].find();
+ }
+ }, name);
+}
+
+// test recovery of JS engine after out of memory
+db.system.js.save({
+ "_id": "f1",
+ "value": function(n) {
+ a = [];
+ b = [];
+ c = [];
+ for (i = 0; i < n; i++) {
+ a.push(Math.random());
+ b.push(Math.random());
+ c.push(Math.random());
+ }
+ }
+});
+
+// do mix of calls to make sure OOM is handled with no permanent damage
+db.eval("f1(10)");
+assert.throws(function() {
+ db.eval("f1(100000000)");
+});
+db.eval("f1(10)");
+assert.throws(function() {
+ db.eval("f1(1000000000)");
+});
+db.eval("f1(1000000)");
+db.eval("f1(1000000)");
+db.eval("f1(1000000)");
+assert.throws(function() {
+ db.eval("f1(100000000)");
+});
+db.eval("f1(10)");
+db.eval("f1(1000000)");
+db.eval("f1(1000000)");
+db.eval("f1(1000000)");
+
+// also test $where
+col.drop();
+col.insert({a: 1});
+col.findOne({$where: "var arr = []; for (var i = 0; i < 1000000; ++i) {arr.push(0);}"});
+assert.throws(function() {
+ col.findOne({$where: "var arr = []; for (var i = 0; i < 1000000000; ++i) {arr.push(0);}"});
+});
+col.findOne({$where: "var arr = []; for (var i = 0; i < 1000000; ++i) {arr.push(0);}"});