summaryrefslogtreecommitdiff
path: root/jstests/core/killop_drop_collection.js
blob: 621b5c4ace9a46e8deb310e683c88a964685892a (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
/**
 * A killOp command issued against a collection drop should not interfere with the drop and allow it
 * to complete. Interrupting a collection drop could leave the database in an inconsistent state.
 * This test confirms that killOp won't interrupt a collection drop, and that the drop occurs
 * successfully.
 *
 * @tags: [
 *   assumes_superuser_permissions,
 *   # Uses index building in background
 *   requires_background_index,
 * ]
 */
(function() {
    "use strict";

    var collectionName = "killop_drop";
    let collection = db.getCollection(collectionName);
    collection.drop();
    for (let i = 0; i < 1000; i++) {
        assert.writeOK(collection.insert({x: i}));
    }
    assert.writeOK(collection.createIndex({x: 1}, {background: true}));

    // Attempt to fsyncLock the database, aborting early if the storage engine doesn't support it.
    const storageEngine = jsTest.options().storageEngine;
    let fsyncRes = db.fsyncLock();
    if (!fsyncRes.ok) {
        assert.commandFailedWithCode(fsyncRes, ErrorCodes.CommandNotSupported);
        jsTest.log("Skipping test on storage engine " + storageEngine +
                   ", which does not support fsyncLock.");
        return;
    }

    // Kick off a drop on the collection.
    const useDefaultPort = null;
    const noConnect = false;
    // The drop will occasionally, and legitimately be interrupted by killOp (and not succeed).
    let awaitDropCommand = startParallelShell(function() {
        let res = db.getSiblingDB("test").runCommand({drop: "killop_drop"});
        let collectionFound = db.getCollectionNames().includes("killop_drop");
        if (res.ok == 1) {
            // Ensure that the collection has been dropped.
            assert(
                !collectionFound,
                "Expected collection to not appear in listCollections output after being dropped");
        } else {
            // Ensure that the collection hasn't been dropped.
            assert(collectionFound,
                   "Expected collection to appear in listCollections output after drop failed");
        }
    }, useDefaultPort, noConnect);

    // Wait for the drop operation to appear in the db.currentOp() output.
    let dropCommandOpId = null;
    assert.soon(function() {
        let dropOpsInProgress = db.currentOp().inprog.filter(
            op => op.command && op.command.drop === collection.getName());
        if (dropOpsInProgress.length > 0) {
            dropCommandOpId = dropOpsInProgress[0].opid;
        }
        return dropCommandOpId;
    });

    // Issue a killOp for the drop command, then unlock the server. We expect that the drop
    // operation was *not* killed, and that the collection was dropped successfully.
    assert.commandWorked(db.killOp(dropCommandOpId));
    let unlockRes = assert.commandWorked(db.fsyncUnlock());
    assert.eq(0,
              unlockRes.lockCount,
              "Expected the number of fsyncLocks to be zero after issuing fsyncUnlock");

    awaitDropCommand();

}());