summaryrefslogtreecommitdiff
path: root/jstests/replsets/rollback_collmods.js
blob: 75c9af51d9628b057c6e7faf2cd8b10e7521ddaf (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
/**
 * Tests that collMod commands during every stage of rollback are tracked correctly.
 * This especially targets collection validators that begin partially or fully uninitialized.
 *
 * @tags: [requires_fcv_53]
 */

(function() {
"use strict";

load("jstests/replsets/libs/rollback_test_deluxe.js");

const testName = "rollback_collmods";
const dbName = testName;

var coll1Name = "NoInitialValidationAtAll";
var coll2Name = "NoInitialValidationAction";
var coll3Name = "NoInitialValidator";
var coll4Name = "NoInitialValidationLevel";

function printCollectionOptionsForNode(node, time) {
    let opts = assert.commandWorked(node.getDB(dbName).runCommand({"listCollections": 1}));
    jsTestLog("Collection options " + time + " on " + node.host + ": " + tojson(opts));
}

function printCollectionOptions(rollbackTest, time) {
    printCollectionOptionsForNode(rollbackTest.getPrimary(), time);
    rollbackTest.getSecondaries().forEach(node => printCollectionOptionsForNode(node, time));
}

// Operations that will be present on both nodes, before the common point.
let CommonOps = (node) => {
    let testDb = node.getDB(dbName);
    assert.commandWorked(testDb[coll1Name].insert({a: 1, b: 1}));
    assert.commandWorked(testDb[coll2Name].insert({a: 2, b: 2}));
    assert.commandWorked(testDb[coll3Name].insert({a: 3, b: 3}));
    assert.commandWorked(testDb[coll4Name].insert({a: 4, b: 4}));

    // Start with no validation action.
    assert.commandWorked(testDb.runCommand({
        collMod: coll2Name,
        validator: {a: 1},
        validationLevel: "moderate",
    }));

    // Start with no validator.
    assert.commandWorked(testDb.runCommand(
        {collMod: coll3Name, validationLevel: "moderate", validationAction: "warn"}));

    // Start with no validation level.
    assert.commandWorked(
        testDb.runCommand({collMod: coll4Name, validator: {a: 1}, validationAction: "warn"}));
};

// Operations that will be performed on the rollback node past the common point.
let RollbackOps = (node) => {
    let testDb = node.getDB(dbName);

    // Set everything on the rollback node.
    assert.commandWorked(testDb.runCommand({
        collMod: coll1Name,
        validator: {a: 1},
        validationLevel: "moderate",
        validationAction: "warn"
    }));

    // Only modify the action, and never modify it again so it needs to be reset to empty.
    assert.commandWorked(testDb.runCommand({collMod: coll2Name, validationAction: "error"}));

    // Only modify the validator, and never modify it again so it needs to be reset to empty.
    assert.commandWorked(testDb.runCommand({collMod: coll3Name, validator: {b: 1}}));

    // Only modify the level, and never modify it again so it needs to be reset to empty.
    assert.commandWorked(testDb.runCommand({
        collMod: coll4Name,
        validationLevel: "moderate",
    }));
};

// Operations that will be performed on the sync source node after rollback.
let SteadyStateOps = (node) => {
    let testDb = node.getDB(dbName);

    assert.commandWorked(testDb.runCommand({collMod: coll2Name, validator: {b: 1}}));
    assert.commandWorked(testDb.runCommand({collMod: coll3Name, validationAction: "error"}));
    assert.commandWorked(testDb.runCommand({collMod: coll4Name, validationAction: "error"}));
};

// Set up Rollback Test.
let rollbackTest = new RollbackTestDeluxe(testName);
CommonOps(rollbackTest.getPrimary());

let rollbackNode = rollbackTest.transitionToRollbackOperations();
printCollectionOptions(rollbackTest, "before branch");
RollbackOps(rollbackNode);

rollbackTest.transitionToSyncSourceOperationsBeforeRollback();
printCollectionOptions(rollbackTest, "before rollback");
// No ops on the sync source.

// Wait for rollback to finish.
rollbackTest.transitionToSyncSourceOperationsDuringRollback();
rollbackTest.transitionToSteadyStateOperations();
printCollectionOptions(rollbackTest, "after rollback");

SteadyStateOps(rollbackTest.getPrimary());
printCollectionOptions(rollbackTest, "at completion");

rollbackTest.stop();
})();