summaryrefslogtreecommitdiff
path: root/jstests/sharding/mongos_no_replica_set_refresh.js
blob: b9080f950fc1eb84efc4bbb892b70f53ed3f7cf8 (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
// Tests that mongos and the shard discover changes to the shard's replica set membership.
load("jstests/replsets/rslib.js");

(function() {
'use strict';

var five_minutes = 5 * 60 * 1000;

var numRSHosts = function() {
    var result = assert.commandWorked(rsObj.nodes[0].adminCommand({ismaster: 1}));
    return result.hosts.length + result.passives.length;
};

var numMongosHosts = function() {
    var commandResult = assert.commandWorked(mongos.adminCommand("connPoolStats"));
    var result = commandResult.replicaSets[rsObj.name];
    return result.hosts.length;
};

var configServerURL = function() {
    var result = config.shards.find().toArray()[0];
    return result.host;
};

var checkNumHosts = function(expectedNumHosts) {
    jsTest.log("Waiting for the shard to discover that it now has " + expectedNumHosts + " hosts.");
    var numHostsSeenByShard;

    // Use a high timeout (5 minutes) because replica set refreshes are only done every 30
    // seconds.
    assert.soon(
        function() {
            numHostsSeenByShard = numRSHosts();
            return numHostsSeenByShard === expectedNumHosts;
        },
        function() {
            return ("Expected shard to see " + expectedNumHosts + " hosts but found " +
                    numHostsSeenByShard);
        },
        five_minutes);

    jsTest.log("Waiting for the mongos to discover that the shard now has " + expectedNumHosts +
               " hosts.");
    var numHostsSeenByMongos;

    // Use a high timeout (5 minutes) because replica set refreshes are only done every 30
    // seconds.
    assert.soon(
        function() {
            numHostsSeenByMongos = numMongosHosts();
            return numHostsSeenByMongos === expectedNumHosts;
        },
        function() {
            return ("Expected mongos to see " + expectedNumHosts + " hosts on shard but found " +
                    numHostsSeenByMongos);
        },
        five_minutes);
};

var st = new ShardingTest({
    name: 'mongos_no_replica_set_refresh',
    shards: 1,
    mongos: 1,
    other: {
        rs0: {
            nodes: [
                {},
                {rsConfig: {priority: 0}},
                {rsConfig: {priority: 0}},
            ],
        }
    }
});

var rsObj = st.rs0;
assert.commandWorked(rsObj.nodes[0].adminCommand({
    replSetTest: 1,
    waitForMemberState: ReplSetTest.State.PRIMARY,
    timeoutMillis: 60 * 1000,
}),
                     'node 0 ' + rsObj.nodes[0].host + ' failed to become primary');

var mongos = st.s;
var config = mongos.getDB("config");

printjson(mongos.getCollection("foo.bar").findOne());

jsTestLog("Removing a node from the shard's replica set.");

var rsConfig = rsObj.getReplSetConfigFromNode(0);

var removedNode = rsConfig.members.pop();
rsConfig.version++;
reconfig(rsObj, rsConfig);

// Wait for the election round to complete
rsObj.getPrimary();

checkNumHosts(rsConfig.members.length);

jsTest.log("Waiting for config.shards to reflect that " + removedNode.host + " has been removed.");
assert.soon(
    function() {
        return configServerURL().indexOf(removedNode.host) < 0;
    },
    function() {
        return (removedNode.host + " was removed from " + rsObj.name +
                ", but is still seen in config.shards");
    });

jsTestLog("Adding the node back to the shard's replica set.");

config.shards.update({_id: rsObj.name}, {$set: {host: rsObj.name + "/" + rsObj.nodes[0].host}});
printjson(config.shards.find().toArray());

rsConfig.members.push(removedNode);
rsConfig.version++;
reconfig(rsObj, rsConfig);

checkNumHosts(rsConfig.members.length);

jsTest.log("Waiting for config.shards to reflect that " + removedNode.host + " has been re-added.");
assert.soon(
    function() {
        return configServerURL().indexOf(removedNode.host) >= 0;
    },
    function() {
        return (removedNode.host + " was re-added to " + rsObj.name +
                ", but is not seen in config.shards");
    });

st.stop();
}());