summaryrefslogtreecommitdiff
path: root/jstests/replsets/drop_collections_two_phase_rename_drop_target.js
blob: e0c2aabadb61563644fd0bcddbdbcef46bfa080b (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
/**
 * Test to ensure that the two phase drop behavior is applied to the target collection of a
 * renameCollection command when dropTarget is set to true.
 */

(function() {
    'use strict';

    load('jstests/replsets/libs/two_phase_drops.js');  // For TwoPhaseDropCollectionTest.
    load('jstests/libs/check_log.js');                 // For checkLog.contains().

    // Set up a two phase drop test.
    let testName = 'drop_collection_two_phase_rename_drop_target';
    let dbName = testName;
    let fromCollName = 'collToRename';
    let toCollName = 'collToDrop';
    let twoPhaseDropTest = new TwoPhaseDropCollectionTest(testName, dbName);

    // Initialize replica set.
    let replTest = twoPhaseDropTest.initReplSet();

    // Create the collections that will be renamed and dropped.
    twoPhaseDropTest.createCollection(fromCollName);
    twoPhaseDropTest.createCollection(toCollName);

    // Insert documents into both collections so that we can tell them apart.
    const primary = replTest.getPrimary();
    const testDb = primary.getDB(dbName);
    const fromColl = testDb.getCollection(fromCollName);
    const toColl = testDb.getCollection(toCollName);
    assert.writeOK(fromColl.insert({_id: 'from'}));
    assert.writeOK(toColl.insert({_id: 'to'}));
    replTest.awaitReplication();

    // Prevent renameCollection from being applied on the secondary so that we can examine the state
    // of the primary after target collection has been dropped.
    jsTestLog('Pausing oplog application on the secondary node.');
    const secondary = replTest.getSecondary();
    twoPhaseDropTest.pauseOplogApplication(secondary);

    // This logs each operation being applied.
    const previousLogLevel =
        assert.commandWorked(primary.setLogLevel(1, 'storage')).was.replication.verbosity;

    try {
        // When the target collection exists, the renameCollection command should fail if dropTarget
        // flag is set to false or is omitted.
        jsTestLog(
            'Checking renameCollection error handling when dropTarget is set to false and target collection exists.');
        let dropTarget = false;
        assert.commandFailedWithCode(fromColl.renameCollection(toCollName, dropTarget),
                                     ErrorCodes.NamespaceExists);

        // Rename collection with dropTarget set to true. Check collection contents after rename.
        jsTestLog('Renaming collection ' + fromColl.getFullName() + ' to ' + toColl.getFullName() +
                  ' with dropTarget set to true.');
        dropTarget = true;
        assert.commandWorked(fromColl.renameCollection(toColl.getName(), dropTarget));
        assert(!twoPhaseDropTest.collectionExists(fromCollName));
        assert(twoPhaseDropTest.collectionExists(toCollName));
        assert.eq({_id: 'from'}, toColl.findOne());

        // Confirm that original target collection is now a drop-pending collection.
        assert(twoPhaseDropTest.collectionIsPendingDrop(toCollName));

        // COMMIT collection drop.
        twoPhaseDropTest.resumeOplogApplication(secondary);
        replTest.awaitReplication();
        assert.soonNoExcept(function() {
            return !twoPhaseDropTest.collectionIsPendingDrop(toCollName);
        });

        // Confirm in the logs that the renameCollection dropped the target collection on the
        // secondary using two phase collection drop.
        checkLog.contains(secondary, 'dropCollection: ' + toColl.getFullName());

        // Rename target collection back to source collection. This helps to ensure the collection
        // metadata is updated correctly on both primary and secondary.
        assert.commandWorked(toColl.renameCollection(fromCollName + '_roundtrip'));
        replTest.awaitReplication();
    } finally {
        // Reset log level.
        primary.setLogLevel(previousLogLevel, 'storage');

        twoPhaseDropTest.stop();
    }
}());