summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/validate_multikey_failures.js
blob: be3d3010b30ca73b906eed8d3da3ff92f4768418 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
 * Test that validate detects and properly reports multikey inconsistencies.
 */
(function() {
"use strict";

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();
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();
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();
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});
})();