summaryrefslogtreecommitdiff
path: root/jstests/replsets/apply_ops_create_indexes.js
blob: ea97ce5fd9d8a0f9658a14263b3e3de7e1ef2c00 (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
 * This test ensures that indexes created by running applyOps are both successful and replicated
 * correctly (see SERVER-31435).
 */
(function() {
    "use strict";
    let ensureIndexExists = function(testDB, collName, indexName, expectedNumIndexes) {
        let cmd = {listIndexes: collName};
        let res = testDB.runCommand(cmd);
        assert.commandWorked(res, "could not run " + tojson(cmd));
        let indexes = new DBCommandCursor(testDB, res).toArray();

        assert.eq(indexes.length, expectedNumIndexes);

        let foundIndex = false;
        for (let i = 0; i < indexes.length; ++i) {
            if (indexes[i].name == indexName) {
                foundIndex = true;
            }
        }
        assert(foundIndex,
               "did not find the index '" + indexName + "' amongst the collection indexes: " +
                   tojson(indexes));
    };

    let ensureOplogEntryExists = function(localDB, indexName) {
        // Make sure the oplog entry for index creation exists in the oplog.
        let cmd = {find: "oplog.rs"};
        let res = localDB.runCommand(cmd);
        assert.commandWorked(res, "could not run " + tojson(cmd));
        let cursor = new DBCommandCursor(localDB, res);
        let errMsg =
            "expected more data from command " + tojson(cmd) + ", with result " + tojson(res);
        assert(cursor.hasNext(), errMsg);
        let oplog = localDB.getCollection("oplog.rs");
        let query = {$and: [{"o.createIndexes": {$exists: true}}, {"o.name": indexName}]};
        let resCursor = oplog.find(query);
        assert.eq(resCursor.count(),
                  1,
                  "Expected the query " + tojson(query) + " to return exactly 1 document");
    };

    let rst = new ReplSetTest({nodes: 3});
    rst.startSet();
    rst.initiate();

    let collName = "create_indexes_col";
    let dbName = "create_indexes_db";

    let primaryTestDB = rst.getPrimary().getDB(dbName);
    let cmd = {"create": collName};
    let res = primaryTestDB.runCommand(cmd);
    assert.commandWorked(res, "could not run " + tojson(cmd));
    rst.awaitReplication();

    // Create an index via the applyOps command with the createIndexes command format and make sure
    // it exists.
    let uuid = primaryTestDB.getCollectionInfos()[0].info.uuid;
    let cmdFormatIndexNameA = "a_1";
    cmd = {
        applyOps: [{
            op: "c",
            ns: dbName + "." + collName,
            ui: uuid,
            o: {createIndexes: collName, v: 2, key: {a: 1}, name: cmdFormatIndexNameA}
        }]
    };
    res = primaryTestDB.runCommand(cmd);
    assert.commandWorked(res, "could not run " + tojson(cmd));
    rst.awaitReplication();
    ensureIndexExists(primaryTestDB, collName, cmdFormatIndexNameA, 2);

    // Same as directly above, but ensure that applyOps createIndexes can work without a uuid.
    let cmdFormatIndexNameB = "b_1";
    cmd = {
        applyOps: [{
            op: "c",
            ns: dbName + "." + collName,
            o: {createIndexes: collName, v: 2, key: {b: 1}, name: cmdFormatIndexNameB}
        }]
    };
    res = primaryTestDB.runCommand(cmd);
    assert.commandWorked(res, "could not run " + tojson(cmd));
    rst.awaitReplication();
    ensureIndexExists(primaryTestDB, collName, cmdFormatIndexNameB, 3);

    // Test with a background index.
    let cmdFormatIndexNameC = "c_1";
    cmd = {
        applyOps: [{
            op: "c",
            ns: dbName + "." + collName,
            ui: uuid,
            o: {
                createIndexes: collName,
                v: 2,
                key: {c: 1},
                name: cmdFormatIndexNameC,
                background: true
            }
        }]
    };
    assert.commandWorked(primaryTestDB.runCommand(cmd));
    rst.awaitReplication();
    ensureIndexExists(primaryTestDB, collName, cmdFormatIndexNameC, 4);

    let localDB = rst.getPrimary().getDB("local");
    ensureOplogEntryExists(localDB, cmdFormatIndexNameA);
    ensureOplogEntryExists(localDB, cmdFormatIndexNameB);
    ensureOplogEntryExists(localDB, cmdFormatIndexNameC);

    // Make sure the indexes were replicated to the secondaries.
    rst.waitForAllIndexBuildsToFinish(dbName, collName);
    let secondaries = rst.getSecondaries();
    for (let j = 0; j < secondaries.length; j++) {
        let secondaryTestDB = secondaries[j].getDB(dbName);
        ensureIndexExists(secondaryTestDB, collName, cmdFormatIndexNameA, 4);
        ensureIndexExists(secondaryTestDB, collName, cmdFormatIndexNameB, 4);
        ensureIndexExists(secondaryTestDB, collName, cmdFormatIndexNameC, 4);
    }

    rst.stopSet();
}());