mongo/jstests/noPassthrough/validate/validate_multikey_failures.js

78 lines
3.2 KiB
JavaScript

/**
* Test that validate detects and properly reports multikey inconsistencies and fix multikey.
*/
const baseName = "validate_multikey_failures";
const dbpath = MongoRunner.dataPath + baseName + "/";
let conn = MongoRunner.runMongod({dbpath: dbpath});
let coll = conn.getDB("test").getCollection("corrupt");
const resetCollection = () => {
coll.drop();
coll.createIndex({"a.b": 1});
};
const disableMultikeyUpdate = () => {
assert.commandWorked(conn.adminCommand({configureFailPoint: "skipUpdateIndexMultikey", mode: "alwaysOn"}));
};
const enableMultikeyUpdate = () => {
assert.commandWorked(conn.adminCommand({configureFailPoint: "skipUpdateIndexMultikey", mode: "off"}));
};
function checkValidateLogs() {
assert(
checkLog.checkContainsWithAtLeastCountJson(
conn,
7463100,
{"spec": {"v": 2, "key": {"_id": 1}, "name": "_id_"}},
1,
),
);
}
// Test that multiple keys suggest index should be marked multikey.
resetCollection();
disableMultikeyUpdate();
assert.commandWorked(coll.insert({a: {b: [1, 2]}}));
enableMultikeyUpdate();
let res = coll.validate({fixMultikey: true});
assert.commandWorked(res);
assert(!res.valid);
assert.eq(res.indexDetails["a.b_1"].errors.length, 1);
assert(res.indexDetails["a.b_1"].errors[0].startsWith("Index a.b_1 is not multikey"));
assert(res.indexDetails["a.b_1"].errors[0].includes("2 key(s)"));
assert(checkLog.checkContainsWithAtLeastCountJson(conn, 7556100, {"indexName": "a.b_1"}, 1));
assert(checkLog.checkContainsWithAtLeastCountJson(conn, 7556101, {"indexKey": {"a.b": 1}}, 1));
assert(checkLog.checkContainsWithAtLeastCountJson(conn, 7556101, {"indexKey": {"a.b": 2}}, 1));
// Test that a single-entry array suggests index should be marked multikey.
resetCollection();
disableMultikeyUpdate();
assert.commandWorked(coll.insert({a: {b: [3]}}));
enableMultikeyUpdate();
res = coll.validate({fixMultikey: true});
assert.commandWorked(res);
assert(!res.valid);
assert.eq(res.indexDetails["a.b_1"].errors.length, 1);
assert(res.indexDetails["a.b_1"].errors[0].startsWith("Index a.b_1 is not multikey"));
assert(res.indexDetails["a.b_1"].errors[0].includes("1 key(s)"));
assert(checkLog.checkContainsWithAtLeastCountJson(conn, 7556100, {"indexName": "a.b_1"}, 1));
assert(checkLog.checkContainsWithAtLeastCountJson(conn, 7556101, {"indexKey": {"a.b": 3}}, 1));
// Test that a mis-match in multikey paths should be marked multikey.
resetCollection();
assert.commandWorked(coll.insert({a: [{b: 4}, {b: 5}]}));
disableMultikeyUpdate();
assert.commandWorked(coll.insert({a: {b: [6]}}));
enableMultikeyUpdate();
res = coll.validate({fixMultikey: true});
assert.commandWorked(res);
assert(!res.valid);
assert.eq(res.indexDetails["a.b_1"].errors.length, 1);
assert(res.indexDetails["a.b_1"].errors[0].startsWith("Index a.b_1 multikey paths do not cover a document"));
assert(checkLog.checkContainsWithAtLeastCountJson(conn, 7556100, {"indexName": "a.b_1"}, 1));
assert(checkLog.checkContainsWithAtLeastCountJson(conn, 7556101, {"indexKey": {"a.b": 6}}, 1));
assert(checkLog.checkContainsWithAtLeastCountJson(conn, 5367500, {"index": "a.b_1"}, 1));
MongoRunner.stopMongod(conn, null, {skipValidation: true});