summaryrefslogtreecommitdiff
path: root/jstests/replsets/sessions_collection_auto_healing.js
blob: f8240fc58d673ae329434708605bcf5c68d9be3f (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
load('jstests/libs/sessions_collection.js');

(function() {
"use strict";

// This test makes assertions about the number of sessions, which are not compatible with
// implicit sessions.
TestData.disableImplicitSessions = true;

var replTest = new ReplSetTest({
    name: 'refresh',
    nodes: [
        {/* primary */},
        {/* secondary */ rsConfig: {priority: 0}},
        {/* arbiter */ rsConfig: {arbiterOnly: true}}
    ]
});
var nodes = replTest.startSet();

replTest.initiate();
var primary = replTest.getPrimary();
var primaryAdmin = primary.getDB("admin");

replTest.awaitSecondaryNodes();
var secondary = replTest.getSecondary();
var secondaryAdmin = secondary.getDB("admin");

let arbiter = replTest.getArbiter();

const refreshErrorMsgRegex =
    new RegExp("Failed to refresh session cache, will try again at the next refresh interval");

// Get the current value of the TTL index so that we can verify it's being properly applied.
let res = assert.commandWorked(
    primary.adminCommand({getParameter: 1, localLogicalSessionTimeoutMinutes: 1}));
let timeoutMinutes = res.localLogicalSessionTimeoutMinutes;

// Test that we can use sessions on the primary before the sessions collection exists.
{
    validateSessionsCollection(primary, false, false, timeoutMinutes);

    assert.commandWorked(primaryAdmin.runCommand({startSession: 1}));

    validateSessionsCollection(primary, false, false, timeoutMinutes);
}

// Test that we can use sessions on secondaries before the sessions collection exists.
{
    validateSessionsCollection(primary, false, false, timeoutMinutes);

    replTest.awaitReplication();
    validateSessionsCollection(secondary, false, false, timeoutMinutes);

    assert.commandWorked(secondaryAdmin.runCommand({startSession: 1}));

    validateSessionsCollection(primary, false, false, timeoutMinutes);

    replTest.awaitReplication();
    validateSessionsCollection(secondary, false, false, timeoutMinutes);
}

// Test that a refresh on a secondary does not create the sessions collection.
{
    validateSessionsCollection(primary, false, false, timeoutMinutes);

    replTest.awaitReplication();
    validateSessionsCollection(secondary, false, false, timeoutMinutes);

    assert.commandWorked(secondaryAdmin.runCommand({refreshLogicalSessionCacheNow: 1}));

    validateSessionsCollection(primary, false, false, timeoutMinutes);

    replTest.awaitReplication();
    validateSessionsCollection(secondary, false, false, timeoutMinutes);
}

// Test that a refresh on an arbiter does not create the sessions collection.
{
    validateSessionsCollection(primary, false, false, timeoutMinutes);

    assert.commandWorked(arbiter.adminCommand({clearLog: 'global'}));
    assert.commandWorked(arbiter.adminCommand({refreshLogicalSessionCacheNow: 1}));

    validateSessionsCollection(primary, false, false, timeoutMinutes);

    if (!jsTest.options().useRandomBinVersionsWithinReplicaSet) {
        // Verify that the arbiter did not try to set up the session collection or refresh.
        assert.eq(false, checkLog.checkContainsOnce(arbiter, refreshErrorMsgRegex));
    }
}

// Test that a refresh on the primary creates the sessions collection.
{
    validateSessionsCollection(primary, false, false, timeoutMinutes);

    replTest.awaitReplication();
    validateSessionsCollection(secondary, false, false, timeoutMinutes);

    assert.commandWorked(primaryAdmin.runCommand({refreshLogicalSessionCacheNow: 1}));

    validateSessionsCollection(primary, true, true, timeoutMinutes);
}

// Test that a refresh on a secondary will not create the TTL index on the sessions collection.
{
    assert.commandWorked(primary.getDB("config").system.sessions.dropIndex({lastUse: 1}));

    validateSessionsCollection(primary, true, false, timeoutMinutes);

    assert.commandWorked(secondaryAdmin.runCommand({refreshLogicalSessionCacheNow: 1}));

    validateSessionsCollection(primary, true, false, timeoutMinutes);
}

// Test that a refresh on an arbiter will not create the TTL index on the sessions collection.
{
    validateSessionsCollection(primary, true, false, timeoutMinutes);

    assert.commandWorked(arbiter.adminCommand({refreshLogicalSessionCacheNow: 1}));

    validateSessionsCollection(primary, true, false, timeoutMinutes);
}

// Test that a refresh on the primary will create the TTL index on the sessions collection.
{
    validateSessionsCollection(primary, true, false, timeoutMinutes);

    assert.commandWorked(primaryAdmin.runCommand({refreshLogicalSessionCacheNow: 1}));

    validateSessionsCollection(primary, true, true, timeoutMinutes);
}

timeoutMinutes = 4;

replTest.restart(
    0, {startClean: false, setParameter: "localLogicalSessionTimeoutMinutes=" + timeoutMinutes});

primary = replTest.getPrimary();
primaryAdmin = primary.getDB("admin");
secondary = replTest.getSecondary();

// Test that a change to the TTL index expiration on restart will generate a collMod to change
// the expiration time.
{
    assert.commandWorked(primaryAdmin.runCommand({refreshLogicalSessionCacheNow: 1}));

    validateSessionsCollection(primary, true, true, timeoutMinutes);

    replTest.awaitReplication();
    validateSessionsCollection(secondary, true, true, timeoutMinutes);
}

replTest.stopSet();
})();