summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/wt_index_option_defaults.js
blob: ce4f1a1c78dac9a3fe6b98d877b40a518b05113f (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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
 * Tests that different values for the same configuration string key have the following order of
 * preference:
 *   1. index-specific options specified to createIndex().
 *   2. collection-wide options specified as "indexOptionDefaults" to createCollection().
 *   3. system-wide options specified by --wiredTigerIndexConfigString or by
 *     inMemoryIndexConfigString.
 */
(function() {
'use strict';

var engine = 'wiredTiger';
if (jsTest.options().storageEngine) {
    engine = jsTest.options().storageEngine;
}

// Skip this test if not running with the right storage engine.
if (engine !== 'wiredTiger' && engine !== 'inMemory') {
    jsTest.log('Skipping test because storageEngine is not "wiredTiger" or "inMemory"');
    return;
}

// Skip this test when 'xxxIndexConfigString' is already set in TestData.
// TODO: This test can be enabled when MongoRunner supports combining WT config strings with
// commas.
if (jsTest.options()[engine + 'IndexConfigString']) {
    jsTest.log('Skipping test because system-wide defaults for index options are already set');
    return;
}

// Use different values for the same configuration string key to test that index-specific
// options override collection-wide options, and that collection-wide options override
// system-wide options.
var systemWideConfigString = 'split_pct=70,';
var collectionWideConfigString = 'split_pct=75,';
var indexSpecificConfigString = 'split_pct=80,';

// Start up a mongod with system-wide defaults for index options and create a collection without
// any additional options. Tests than an index without any additional options should take on the
// system-wide defaults, whereas an index with additional options should override the
// system-wide defaults.
runTest({});

// Start up a mongod with system-wide defaults for index options and create a collection with
// additional options. Tests than an index without any additional options should take on the
// collection-wide defaults, whereas an index with additional options should override the
// collection-wide defaults.
runTest({indexOptionDefaults: collectionWideConfigString});

function runTest(collOptions) {
    var hasIndexOptionDefaults = collOptions.hasOwnProperty('indexOptionDefaults');

    var dbpath = MongoRunner.dataPath + 'wt_index_option_defaults';
    resetDbpath(dbpath);

    // Start a mongod with system-wide defaults for engine-specific index options.
    var conn = MongoRunner.runMongod({
        dbpath: dbpath,
        noCleanData: true,
        [engine + 'IndexConfigString']: systemWideConfigString,
    });
    assert.neq(null, conn, 'mongod was unable to start up');

    var testDB = conn.getDB('test');
    var cmdObj = {create: 'coll'};

    // Apply collection-wide defaults for engine-specific index options if any were
    // specified.
    if (hasIndexOptionDefaults) {
        cmdObj.indexOptionDefaults = {
            storageEngine: {[engine]: {configString: collOptions.indexOptionDefaults}}
        };
    }
    assert.commandWorked(testDB.runCommand(cmdObj));

    // Create an index that does not specify any engine-specific options.
    assert.commandWorked(testDB.coll.createIndex({a: 1}, {name: 'without_options'}));

    // Create an index that specifies engine-specific index options.
    assert.commandWorked(testDB.coll.createIndex({b: 1}, {
        name: 'with_options',
        storageEngine: {[engine]: {configString: indexSpecificConfigString}}
    }));

    var collStats = testDB.runCommand({collStats: 'coll'});
    assert.commandWorked(collStats);

    checkIndexWithoutOptions(collStats.indexDetails);
    checkIndexWithOptions(collStats.indexDetails);

    MongoRunner.stopMongod(conn);

    function checkIndexWithoutOptions(indexDetails) {
        var indexSpec = getIndexSpecByName(testDB.coll, 'without_options');
        assert(!indexSpec.hasOwnProperty('storageEngine'),
               'no storage engine options should have been set in the index spec: ' +
                   tojson(indexSpec));

        var creationString = indexDetails.without_options.creationString;
        if (hasIndexOptionDefaults) {
            assert.eq(-1,
                      creationString.indexOf(systemWideConfigString),
                      'system-wide index option present in the creation string even though a ' +
                          'collection-wide option was specified: ' + creationString);
            assert.lte(0,
                       creationString.indexOf(collectionWideConfigString),
                       'collection-wide index option not present in the creation string: ' +
                           creationString);
        } else {
            assert.lte(
                0,
                creationString.indexOf(systemWideConfigString),
                'system-wide index option not present in the creation string: ' + creationString);
            assert.eq(-1,
                      creationString.indexOf(collectionWideConfigString),
                      'collection-wide index option present in creation string even though ' +
                          'it was not specified: ' + creationString);
        }

        assert.eq(-1,
                  creationString.indexOf(indexSpecificConfigString),
                  'index-specific option present in creation string even though it was not' +
                      ' specified: ' + creationString);
    }

    function checkIndexWithOptions(indexDetails) {
        var indexSpec = getIndexSpecByName(testDB.coll, 'with_options');
        assert(
            indexSpec.hasOwnProperty('storageEngine'),
            'storage engine options should have been set in the index spec: ' + tojson(indexSpec));
        assert.docEq({[engine]: {configString: indexSpecificConfigString}},
                     indexSpec.storageEngine,
                     engine + ' index options not present in the index spec');

        var creationString = indexDetails.with_options.creationString;
        assert.eq(-1,
                  creationString.indexOf(systemWideConfigString),
                  'system-wide index option present in the creation string even though an ' +
                      'index-specific option was specified: ' + creationString);
        assert.eq(-1,
                  creationString.indexOf(collectionWideConfigString),
                  'system-wide index option present in the creation string even though an ' +
                      'index-specific option was specified: ' + creationString);
        assert.lte(0,
                   creationString.indexOf(indexSpecificConfigString),
                   'index-specific option not present in the creation string: ' + creationString);
    }
}

function getIndexSpecByName(coll, indexName) {
    var indexes = coll.getIndexes().filter(function(spec) {
        return spec.name === indexName;
    });
    assert.eq(1, indexes.length, 'index "' + indexName + '" not found');
    return indexes[0];
}
})();