summaryrefslogtreecommitdiff
path: root/jstests/noPassthroughWithMongod/index_retry.js
blob: cb33de4b95b81ff8e4bebf662595554131e07556 (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
// Check index rebuild when MongoDB is killed.
//
// This test requires persistence beacuase it assumes data/indices will survive a restart.
// @tags: [requires_persistence]
(function() {
    'use strict';
    var baseName = 'index_retry';
    var dbpath = MongoRunner.dataPath + baseName;

    var conn = MongoRunner.runMongod({dbpath: dbpath, journal: ''});

    var test = conn.getDB("test");

    var name = 'jstests_slownightly_' + baseName;
    var t = test.getCollection(name);
    t.drop();

    // Insert a large number of documents, enough to ensure that an index build on these documents
    // can be interrupted before complete.
    var bulk = t.initializeUnorderedBulkOp();
    for (var i = 0; i < 5e5; ++i) {
        bulk.insert({a: i});
        if (i % 10000 == 0) {
            print("i: " + i);
        }
    }
    assert.writeOK(bulk.execute());

    function debug(x) {
        printjson(x);
    }

    /**
     * @return if there's a current running index build
     */
    function indexBuildInProgress() {
        var inprog = test.currentOp().inprog;
        debug(inprog);
        var indexBuildOpId = -1;
        inprog.forEach(function(op) {
            // Identify the index build as a createIndexes command.
            // It is assumed that no other clients are concurrently
            // accessing the 'test' database.
            if ((op.op == 'query' || op.op == 'command') && 'createIndexes' in op.query) {
                debug(op.opid);
                var idxSpec = op.query.indexes[0];
                // SERVER-4295 Make sure the index details are there
                // we can't assert these things, since there is a race in reporting
                // but we won't count if they aren't
                if ("a_1" == idxSpec.name && 1 == idxSpec.key.a && idxSpec.background &&
                    op.progress && (op.progress.done / op.progress.total) > 0.20) {
                    indexBuildOpId = op.opid;
                }
            }
        });
        return indexBuildOpId != -1;
    }

    function abortDuringIndexBuild(options) {
        var createIdx = startParallelShell(
            'db.' + name + '.createIndex({ a: 1 }, { background: true });', conn.port);

        // Wait for the index build to start.
        var times = 0;
        assert.soon(function() {
            return indexBuildInProgress() && times++ >= 2;
        });

        print("killing the mongod");
        MongoRunner.stopMongod(conn.port, /* signal */ 9);

        var exitCode = createIdx({checkExitSuccess: false});
        assert.neq(0, exitCode, "expected shell to exit abnormally due to mongod being terminated");
    }

    abortDuringIndexBuild();

    conn = MongoRunner.runMongod({dbpath: dbpath, journal: '', restart: true});
    test = conn.getDB("test");
    t = test.getCollection(name);

    assert.eq({a: 42},
              t.find({a: 42}, {_id: 0}).hint({a: 1}).next(),
              'index {a: 1} was rebuilt on startup');

    var indexes = t.getIndexes();
    assert.eq(2,
              indexes.length,
              'unexpected number of indexes in listIndexes result: ' + tojson(indexes));

    print("Index built");

    MongoRunner.stopMongod(conn.port);
    print("SUCCESS!");
}());