summaryrefslogtreecommitdiff
path: root/jstests/replsets/oplog_format_create_indexes.js
blob: 9b3b9e25749df8369c0b31b0228949611a1622f2 (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
/**
 * Tests that the index's full specification is included in the oplog entry corresponding to its
 * creation.
 */
(function() {
"use strict";

load("jstests/libs/get_index_helpers.js");

const rst = new ReplSetTest({nodes: 1});
rst.startSet();
rst.initiate();

const primary = rst.getPrimary();

const testDB = primary.getDB("test");
const oplogColl = primary.getDB("local").oplog.rs;

function testOplogEntryContainsIndexInfoObj(coll, keyPattern, indexOptions) {
    assert.commandWorked(coll.createIndex(keyPattern, indexOptions));
    const allIndexes = coll.getIndexes();
    const indexSpec = GetIndexHelpers.findByKeyPattern(allIndexes, keyPattern);

    assert.neq(
        null,
        indexSpec,
        "Index with key pattern " + tojson(keyPattern) + " not found: " + tojson(allIndexes));

    const indexCreationOplogQuery = {
        op: "c",
        ns: testDB.getName() + ".$cmd",
        "o.startIndexBuild": coll.getName(),
    };

    const allOplogEntries = oplogColl.find(indexCreationOplogQuery).toArray();

    // Preserve the JSON version of the originals, as we're going to delete fields.
    const allOplogEntriesJson = tojson(allOplogEntries);
    const indexSpecJson = tojson(indexSpec);

    const found = allOplogEntries.filter((entry) => {
        const entrySpec = entry.o;

        // startIndexes oplog entry contains an array of index specs.
        if (entry.o.indexes) {
            assert.eq(1, entry.o.indexes.length);
            if (indexSpec.name !== entry.o.indexes[0].name) {
                return false;
            }
            // We use assert.docEq() here rather than bsonWoCompare() because we cannot expect the
            // field order in the embedded startIndexBuild index spec to match the original index
            // spec.
            assert.docEq(indexSpec, entry.o.indexes[0]);
            return true;
        }

        delete entrySpec.ns;
        delete entrySpec.createIndexes;
        return bsonWoCompare(indexSpec, entrySpec) === 0;
    });
    assert.eq(1,
              found.length,
              "Failed to find full index specification " + indexSpecJson +
                  " in any oplog entry from index creation: " + allOplogEntriesJson);

    assert.commandWorked(coll.dropIndex(keyPattern));
}

// Insert document into collection to avoid optimization for index creation on an empty collection.
assert.commandWorked(testDB.oplog_format.insert({a: 1}));

// Test that options both explicitly included in the command and implicitly filled in with
// defaults by the server are serialized into the corresponding oplog entry.
testOplogEntryContainsIndexInfoObj(testDB.oplog_format, {withoutAnyOptions: 1});
testOplogEntryContainsIndexInfoObj(testDB.oplog_format, {withV1: 1}, {v: 1});
testOplogEntryContainsIndexInfoObj(
    testDB.oplog_format, {partialIndex: 1}, {partialFilterExpression: {field: {$exists: true}}});

// Test that the representation of an index's collation in the oplog on a collection with a
// non-simple default collation exactly matches that of the index's full specification.
assert.commandWorked(
    testDB.runCommand({create: "oplog_format_collation", collation: {locale: "fr"}}));

// Insert document into collection to avoid optimization for index creation on an empty collection.
assert.commandWorked(testDB.oplog_format_collation.insert({a: 1}));

testOplogEntryContainsIndexInfoObj(testDB.oplog_format_collation, {withDefaultCollation: 1});
testOplogEntryContainsIndexInfoObj(
    testDB.oplog_format_collation, {withNonDefaultCollation: 1}, {collation: {locale: "en"}});
testOplogEntryContainsIndexInfoObj(testDB.oplog_format_collation, {withV1: 1}, {v: 1});
testOplogEntryContainsIndexInfoObj(
    testDB.oplog_format_collation, {withSimpleCollation: 1}, {collation: {locale: "simple"}});

rst.stopSet();
})();