... and simplify ReplCoordTestFixture ReplicationCoordinatorImpl consults the storage engine's isDurable flag for two purposes: 1. To choose whether to present the durable or applied optime when standing for election in pv1 2. To decide how to interpret w:majority without an explicit j field when waiting for write concern. In the first case, it is unnecessary to choose which optime to apply based on the isDurable flag. It is always safe and correct to present the applied optime, because if the node presenting it wins election, it will attempt to commit that applied optime. That means that voters may safely vote for that node. In the second case, using the value of the local node's storage engine's isDurable flag to adjust the meaning of w:majority is out of spec. Whether w:majority writes wait for journaling is a function only of the writeConcernMajorityJournalDefault flag when a write concern omits the "j" field. This patch removes the unnecessary consultation of the isDurable flag, and uses the opportunity to simplify the constructor of ReplicationCoordinatorImpl and its test fixture.
261 lines
7.4 KiB
JavaScript
261 lines
7.4 KiB
JavaScript
/*
|
|
* Tests that resource pattern matching rules work as expected.
|
|
*/
|
|
|
|
function setup_users(granter) {
|
|
var admindb = granter.getSiblingDB("admin");
|
|
admindb.runCommand({
|
|
createUser: "admin",
|
|
pwd: "admin",
|
|
roles: [
|
|
"userAdminAnyDatabase",
|
|
"dbAdminAnyDatabase",
|
|
"clusterAdmin",
|
|
"readWriteAnyDatabase"
|
|
]
|
|
});
|
|
|
|
admindb.auth("admin", "admin");
|
|
|
|
printjson(admindb.runCommand({createRole: "test_role", privileges: [], roles: []}));
|
|
|
|
printjson(admindb.runCommand({createUser: "test_user", pwd: "password", roles: ["test_role"]}));
|
|
}
|
|
|
|
function setup_dbs_and_cols(db) {
|
|
var test_db_a = db.getSiblingDB("a");
|
|
var test_db_b = db.getSiblingDB("b");
|
|
|
|
test_db_a.dropDatabase();
|
|
test_db_b.dropDatabase();
|
|
|
|
test_db_a.createCollection("a");
|
|
test_db_a.createCollection("b");
|
|
|
|
test_db_b.createCollection("a");
|
|
test_db_b.createCollection("b");
|
|
|
|
db.getLastError('majority');
|
|
}
|
|
|
|
function grant_privileges(granter, privileges) {
|
|
var admindb = granter.getSiblingDB("admin");
|
|
|
|
admindb.auth("admin", "admin");
|
|
|
|
var result = admindb.runCommand({
|
|
grantPrivilegesToRole: "test_role",
|
|
privileges: privileges,
|
|
writeConcern: {w: 'majority'}
|
|
});
|
|
|
|
admindb.logout();
|
|
|
|
return result;
|
|
}
|
|
|
|
function revoke_privileges(granter, privileges) {
|
|
var admindb = granter.getSiblingDB("admin");
|
|
|
|
admindb.auth("admin", "admin");
|
|
|
|
var result = admindb.runCommand({
|
|
revokePrivilegesFromRole: "test_role",
|
|
privileges: privileges,
|
|
writeConcern: {w: 'majority'}
|
|
});
|
|
|
|
admindb.logout();
|
|
|
|
return result;
|
|
}
|
|
|
|
function invalidateUserCache(verifier) {
|
|
var admindb = verifier.getSiblingDB("admin");
|
|
admindb.auth('admin', 'admin');
|
|
admindb.runCommand("invalidateUserCache");
|
|
admindb.logout();
|
|
}
|
|
|
|
function run_test(name, granter, verifier, privileges, collections) {
|
|
print("\n=== testing " + name + "() ===\n");
|
|
|
|
grant_privileges(granter, privileges);
|
|
invalidateUserCache(verifier);
|
|
|
|
verifier.getSiblingDB('admin').auth("test_user", "password");
|
|
|
|
for (var key in collections) {
|
|
var parts = key.split(".");
|
|
var testdb = verifier.getSiblingDB(parts[0]);
|
|
var col = testdb.getCollection(parts[1]);
|
|
|
|
var cb = collections[key];
|
|
|
|
cb(testdb, col);
|
|
}
|
|
|
|
revoke_privileges(granter, privileges);
|
|
}
|
|
|
|
function run_test_bad_resource(name, granter, resource) {
|
|
print("\n=== testing resource fail " + name + "() ===\n");
|
|
var admindb = granter.getSiblingDB("admin");
|
|
assert.commandFailed(grant_privileges(granter, [{resource: resource, actions: ["find"]}]));
|
|
}
|
|
|
|
function should_insert(testdb, testcol) {
|
|
assert.doesNotThrow(function() {
|
|
testcol.insert({a: "b"});
|
|
});
|
|
}
|
|
|
|
function should_fail_insert(testdb, testcol) {
|
|
assert.throws(function() {
|
|
testcol.insert({a: "b"});
|
|
});
|
|
}
|
|
|
|
function should_find(testdb, testcol) {
|
|
assert.doesNotThrow(function() {
|
|
testcol.findOne();
|
|
});
|
|
}
|
|
|
|
function should_fail_find(testdb, testcol) {
|
|
assert.throws(function() {
|
|
testcol.findOne();
|
|
});
|
|
}
|
|
|
|
function run_tests(granter, verifier) {
|
|
setup_users(granter);
|
|
setup_dbs_and_cols(granter);
|
|
|
|
run_test("specific",
|
|
granter,
|
|
verifier,
|
|
[{resource: {db: "a", collection: "a"}, actions: ["find"]}],
|
|
{
|
|
"a.a": should_find,
|
|
"a.b": should_fail_find,
|
|
"b.a": should_fail_find,
|
|
"b.b": should_fail_find
|
|
});
|
|
|
|
run_test(
|
|
"glob_collection",
|
|
granter,
|
|
verifier,
|
|
[{resource: {db: "a", collection: ""}, actions: ["find"]}],
|
|
{"a.a": should_find, "a.b": should_find, "b.a": should_fail_find, "b.b": should_fail_find});
|
|
|
|
run_test(
|
|
"glob_database",
|
|
granter,
|
|
verifier,
|
|
[{resource: {db: "", collection: "a"}, actions: ["find"]}],
|
|
{"a.a": should_find, "a.b": should_fail_find, "b.a": should_find, "b.b": should_fail_find});
|
|
|
|
run_test("glob_all",
|
|
granter,
|
|
verifier,
|
|
[{resource: {db: "", collection: ""}, actions: ["find"]}],
|
|
{"a.a": should_find, "a.b": should_find, "b.a": should_find, "b.b": should_find});
|
|
|
|
run_test(
|
|
"any_resource", granter, verifier, [{resource: {anyResource: true}, actions: ["find"]}], {
|
|
"a.a": should_find,
|
|
"a.b": should_find,
|
|
"b.a": should_find,
|
|
"b.b": should_find,
|
|
"c.a": should_find
|
|
});
|
|
|
|
run_test("no_global_access",
|
|
granter,
|
|
verifier,
|
|
[{resource: {db: "$", collection: "cmd"}, actions: ["find"]}],
|
|
{
|
|
"a.a": function(testdb, testcol) {
|
|
var r = testdb.stats();
|
|
|
|
if (r["ok"])
|
|
throw("db.$.cmd shouldn't give a.stats()");
|
|
}
|
|
});
|
|
|
|
run_test_bad_resource("empty_resource", granter, {});
|
|
run_test_bad_resource("users_collection_any_db", granter, {collection: "users"});
|
|
run_test_bad_resource("bad_key", granter, {myResource: "users"});
|
|
run_test_bad_resource("extra_key", granter, {db: "test", collection: "users", cluster: true});
|
|
run_test_bad_resource("bad_value_type", granter, {cluster: "false"});
|
|
run_test_bad_resource("bad_collection", granter, {db: "test", collection: "$$$$"});
|
|
|
|
run_test("mixed_find_write",
|
|
granter,
|
|
verifier,
|
|
[
|
|
{resource: {db: "a", collection: "a"}, actions: ["find"]},
|
|
{resource: {db: "", collection: ""}, actions: ["insert"]}
|
|
],
|
|
{
|
|
"a.a": function(testdb, testcol) {
|
|
should_insert(testdb, testcol);
|
|
should_find(testdb, testcol);
|
|
},
|
|
"a.b": function(testdb, testcol) {
|
|
should_insert(testdb, testcol);
|
|
should_fail_find(testdb, testcol);
|
|
},
|
|
"b.a": function(testdb, testcol) {
|
|
should_insert(testdb, testcol);
|
|
should_fail_find(testdb, testcol);
|
|
},
|
|
"b.b": function(testdb, testcol) {
|
|
should_insert(testdb, testcol);
|
|
should_fail_find(testdb, testcol);
|
|
},
|
|
});
|
|
}
|
|
|
|
var keyfile = "jstests/libs/key1";
|
|
|
|
print('--- standalone node test ---');
|
|
var conn = MongoRunner.runMongod({auth: null, keyFile: keyfile});
|
|
run_tests(conn.getDB('test'), conn.getDB('test'));
|
|
MongoRunner.stopMongod(conn);
|
|
print('--- done standalone node test ---');
|
|
|
|
print('--- replica set test ---');
|
|
var rst = new ReplSetTest({
|
|
name: 'testset',
|
|
nodes: 2,
|
|
nodeOptions: {'auth': null, 'httpinterface': null},
|
|
keyFile: keyfile
|
|
});
|
|
|
|
rst.startSet();
|
|
rst.initiate();
|
|
var primary = rst.getPrimary().getDB('admin');
|
|
rst.awaitSecondaryNodes();
|
|
var secondary = rst.getSecondaries()[0].getDB('admin');
|
|
run_tests(primary, secondary);
|
|
rst.stopSet();
|
|
print('--- done with the rs tests ---');
|
|
|
|
print('--- sharding test ---');
|
|
var st = new ShardingTest({
|
|
mongos: 2,
|
|
shard: 1,
|
|
keyFile: keyfile,
|
|
other: {
|
|
mongosOptions: {'auth': null, 'httpinterface': null},
|
|
configOptions: {'auth': null, 'httpinterface': null},
|
|
shardOptions: {'auth': null, 'httpinterface': null}
|
|
}
|
|
});
|
|
run_tests(st.s0.getDB('admin'), st.s1.getDB('admin'));
|
|
st.stop();
|
|
print('--- sharding test done ---');
|