142 lines
5.2 KiB
JavaScript
142 lines
5.2 KiB
JavaScript
// 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
|
|
},
|
|
|
|
{
|
|
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");
|
|
}());
|