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