mongo/jstests/fail_point/fail_point.js

140 lines
5.2 KiB
JavaScript

// @tags: [requires_sharding]
/**
* Performs basic checks on the configureFailPoint and waitForFailPoint command.
* Also check mongo/util/fail_point_test.cpp for unit tests.
*
* @param adminDB {DB} the admin database database object
*/
import {kDefaultWaitForFailPointTimeout} from "jstests/libs/fail_point_util.js";
import {ShardingTest} from "jstests/libs/shardingtest.js";
function runBasicTest(adminDB) {
function expectFailPointState(fpState, expectedMode, expectedData) {
assert.eq(expectedMode, fpState.mode);
// Check that all expected data is present.
for (var field in expectedData) {
// Valid only for 1 level field checks
assert.eq(expectedData[field], fpState.data[field]);
}
// Check that all present data is expected.
for (field in fpState.data) {
assert.eq(expectedData[field], fpState.data[field]);
}
}
let res;
// A failpoint's state can be read through getParameter by prefixing its name with
// "failpoint"
// Test non-existing fail point
assert.commandFailed(adminDB.runCommand({configureFailPoint: "fpNotExist", mode: "alwaysOn", data: {x: 1}}));
// Test bad mode string
assert.commandFailed(adminDB.runCommand({configureFailPoint: "dummy", mode: "badMode", data: {x: 1}}));
res = adminDB.runCommand({getParameter: 1, "failpoint.dummy": 1});
assert.commandWorked(res);
expectFailPointState(res["failpoint.dummy"], 0, {});
// Test bad mode obj
assert.commandFailed(adminDB.runCommand({configureFailPoint: "dummy", mode: {foo: 3}, data: {x: 1}}));
res = adminDB.runCommand({getParameter: 1, "failpoint.dummy": 1});
assert.commandWorked(res);
expectFailPointState(res["failpoint.dummy"], 0, {});
// Test bad mode type
assert.commandFailed(adminDB.runCommand({configureFailPoint: "dummy", mode: true, data: {x: 1}}));
res = adminDB.runCommand({getParameter: 1, "failpoint.dummy": 1});
assert.commandWorked(res);
expectFailPointState(res["failpoint.dummy"], 0, {});
// Test bad data type
assert.commandFailed(adminDB.runCommand({configureFailPoint: "dummy", mode: "alwaysOn", data: "data"}));
res = adminDB.runCommand({getParameter: 1, "failpoint.dummy": 1});
assert.commandWorked(res);
expectFailPointState(res["failpoint.dummy"], 0, {});
// Test setting mode to off.
assert.commandWorked(adminDB.runCommand({configureFailPoint: "dummy", mode: "off"}));
res = adminDB.runCommand({getParameter: 1, "failpoint.dummy": 1});
assert.commandWorked(res);
expectFailPointState(res["failpoint.dummy"], 0, {});
// Test setting mode to skip.
assert.commandWorked(adminDB.runCommand({configureFailPoint: "dummy", mode: {skip: 2}}));
res = adminDB.runCommand({getParameter: 1, "failpoint.dummy": 1});
assert.commandWorked(res);
expectFailPointState(res["failpoint.dummy"], 4, {});
// Test good command w/ data
assert.commandWorked(adminDB.runCommand({configureFailPoint: "dummy", mode: "alwaysOn", data: {x: 1}}));
res = adminDB.runCommand({getParameter: 1, "failpoint.dummy": 1});
assert.commandWorked(res);
expectFailPointState(res["failpoint.dummy"], 1, {x: 1});
// Test that the timeout for waitForFailPoint can be set via maxTimeMS.
let configureFailPointRes = adminDB.runCommand({configureFailPoint: "dummy", mode: "alwaysOn"});
assert.commandWorked(configureFailPointRes);
assert.commandFailedWithCode(
adminDB.adminCommand({
waitForFailPoint: "dummy",
timesEntered: configureFailPointRes.count + 1,
maxTimeMS: 10,
}),
ErrorCodes.MaxTimeMSExpired,
);
// Test that waitForFailPoint throws an error when maxTimeMS is not provided.
assert.commandFailedWithCode(adminDB.adminCommand({waitForFailPoint: "dummy", timesEntered: 1}), [
ErrorCodes.FailedToParse,
ErrorCodes.IDLFailedToParse,
]);
}
// Test the parameter handling.
let conn = MongoRunner.runMongod();
runBasicTest(conn.getDB("admin"));
MongoRunner.stopMongod(conn);
let st = new ShardingTest({shards: 1});
runBasicTest(st.s.getDB("admin"));
// Test the functionality of the commands.
const testDB = st.shard0.getDB("test");
const testColl = testDB["user"];
const failPointName = "hangAfterCollectionInserts";
// Turn on the fail point and check that the returned count is 0.
let configureFailPointRes = assert.commandWorked(
testDB.adminCommand({
configureFailPoint: failPointName,
mode: "alwaysOn",
data: {collectionNS: testColl.getFullName()},
}),
);
assert.eq(0, configureFailPointRes.count);
const joinHungWrite = startParallelShell(() => {
assert.commandWorked(db.getSiblingDB("test").user.insert({_id: 0}));
}, st.rs0.getPrimary().port);
// Wait for the fail point to be entered.
assert.commandWorked(
testDB.adminCommand({
waitForFailPoint: failPointName,
timesEntered: 1,
maxTimeMS: kDefaultWaitForFailPointTimeout,
}),
);
// Turn off the fail point
configureFailPointRes = assert.commandWorked(testDB.adminCommand({configureFailPoint: failPointName, mode: "off"}));
assert.lte(1, configureFailPointRes.count);
joinHungWrite();
st.stop();