summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/index_version_autoupgrade.js
blob: 5f1c309c1ba570c72c794f3ca476e633e0874c42 (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
/**
 * Tests whether various MongoDB commands automatically upgrade the index version of existing
 * indexes when they are rebuilt on a collection.
 */
(function() {
"use strict";

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

var conn = MongoRunner.runMongod({});
assert.neq(null, conn, "mongod was unable to start up");

var testDB = conn.getDB("test");
assert.commandWorked(testDB.runCommand({create: "index_version_autoupgrade"}));
var allIndexes = testDB.index_version_autoupgrade.getIndexes();
var spec = IndexCatalogHelpers.findByKeyPattern(allIndexes, {_id: 1});
assert.neq(null, spec, "Index with key pattern {_id: 1} not found: " + tojson(allIndexes));
var defaultIndexVersion = spec.v;
assert.lte(2, defaultIndexVersion, "Expected the defaultIndexVersion to be at least v=2");

/**
 * Tests whether the execution of the 'commandFn' function automatically upgrades the index
 * version of existing indexes.
 *
 * The 'commandFn' function takes a single argument of the collection to act on and returns a
 * collection to validate the index versions of. Most often the 'commandFn' function returns
 * its input collection, but is able to return a reference to a different collection to support
 * testing the effects of cloning commands.
 *
 * If 'doesAutoUpgrade' is true, then this function verifies that the indexes on the returned
 * collection have been upgraded to the 'defaultIndexVersion'. If 'doesAutoUpgrade' is false,
 * then this function verifies that the indexes on the returned collection are unchanged.
 */
function testIndexVersionAutoUpgrades(commandFn, doesAutoUpgrade) {
    testDB.dropDatabase();
    var coll = testDB.index_version_autoupgrade;

    // Create a v=1 _id index.
    assert.commandWorked(testDB.createCollection("index_version_autoupgrade",
                                                 {idIndex: {key: {_id: 1}, name: "_id_", v: 1}}));
    var allIndexes = coll.getIndexes();
    var spec = IndexCatalogHelpers.findByKeyPattern(allIndexes, {_id: 1});
    assert.neq(null, spec, "Index with key pattern {_id: 1} not found: " + tojson(allIndexes));
    assert.eq(1, spec.v, "Expected a v=1 index to be built: " + tojson(spec));

    assert.commandWorked(coll.createIndex({withoutAnyOptions: 1}));
    allIndexes = coll.getIndexes();
    spec = IndexCatalogHelpers.findByKeyPattern(allIndexes, {withoutAnyOptions: 1});
    assert.neq(null,
               spec,
               "Index with key pattern {withoutAnyOptions: 1} not found: " + tojson(allIndexes));
    assert.eq(defaultIndexVersion,
              spec.v,
              "Expected an index with the default version to be built: " + tojson(spec));

    assert.commandWorked(coll.createIndex({withV1: 1}, {v: 1}));
    allIndexes = coll.getIndexes();
    spec = IndexCatalogHelpers.findByKeyPattern(allIndexes, {withV1: 1});
    assert.neq(null, spec, "Index with key pattern {withV1: 1} not found: " + tojson(allIndexes));
    assert.eq(1, spec.v, "Expected a v=1 index to be built: " + tojson(spec));

    assert.commandWorked(coll.createIndex({withV2: 1}, {v: 2}));
    allIndexes = coll.getIndexes();
    spec = IndexCatalogHelpers.findByKeyPattern(allIndexes, {withV2: 1});
    assert.neq(null, spec, "Index with key pattern {withV2: 1} not found: " + tojson(allIndexes));
    assert.eq(2, spec.v, "Expected a v=2 index to be built: " + tojson(spec));

    var collToVerify = commandFn(coll);
    var expectedResults;

    if (doesAutoUpgrade) {
        expectedResults = [
            {keyPattern: {_id: 1}, version: defaultIndexVersion},
            {keyPattern: {withoutAnyOptions: 1}, version: defaultIndexVersion},
            {keyPattern: {withV1: 1}, version: defaultIndexVersion},
            {keyPattern: {withV2: 1}, version: defaultIndexVersion},
        ];

    } else {
        expectedResults = [
            {keyPattern: {_id: 1}, version: 1},
            {keyPattern: {withoutAnyOptions: 1}, version: defaultIndexVersion},
            {keyPattern: {withV1: 1}, version: 1},
            {keyPattern: {withV2: 1}, version: 2},
        ];
    }

    expectedResults.forEach(function(expected) {
        var allIndexes = collToVerify.getIndexes();
        var spec = IndexCatalogHelpers.findByKeyPattern(allIndexes, expected.keyPattern);
        assert.neq(null,
                   spec,
                   "Index with key pattern " + tojson(expected.keyPattern) +
                       " not found: " + tojson(allIndexes));
        assert.eq(expected.version,
                  spec.v,
                  "Expected index to be rebuilt with " +
                      (doesAutoUpgrade ? "the default" : "its original") +
                      " version: " + tojson(spec));
    });
}

// Test that the "reIndex" command upgrades all existing indexes to the latest version.
testIndexVersionAutoUpgrades(function(coll) {
    assert.commandWorked(coll.getDB().runCommand({reIndex: coll.getName()}));
    return coll;
}, true);

// Test that the "compact" command doesn't upgrade existing indexes to the latest version.
testIndexVersionAutoUpgrades(function(coll) {
    var res = coll.getDB().runCommand({compact: coll.getName()});
    if (res.ok === 0) {
        // Ephemeral storage engines don't support the "compact" command. The existing indexes
        // should remain unchanged.
        assert.commandFailedWithCode(res, ErrorCodes.CommandNotSupported);
    } else {
        assert.commandWorked(res);
    }
    return coll;
}, false);

MongoRunner.stopMongod(conn);
})();