summaryrefslogtreecommitdiff
path: root/jstests/sharding/mongos_not_mark_nodes_as_down_when_reads_or_pings_fail.js
blob: 74341987cec8f05a9a9dbc1102337445340a2291 (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
/*
 * Tests that mongos does not mark nodes as down when reads or pings fail.
 */
(function() {
'use strict';

load("jstests/libs/fail_point_util.js");
load("jstests/replsets/rslib.js");

/*
 * Configures failCommand to force the given command to fail with the given error code when run
 * on the given namespace, and returns the resulting fail point.
 */
function configureFailCommand(nodeConn, command, ns, error) {
    return configureFailPoint(
        nodeConn,
        "failCommand",
        {failInternalCommands: true, errorCode: error, failCommands: [command], namespace: ns});
}

const st = new ShardingTest({shards: 1, rs: {nodes: [{}, {rsConfig: {priority: 0}}]}});
const kDbName = "foo";
const kCollName = "bar";
const kNs = kDbName + "." + kCollName;
const kErrorCode = ErrorCodes.HostUnreachable;
const kPingWaitTimeMS = 12 * 1000;  // streamable ReplicaSetMonitor's ping interval is 10 seconds.
const testDB = st.s.getDB(kDbName);

assert.commandWorked(st.s.adminCommand({enableSharding: kDbName}));
assert.commandWorked(st.s.adminCommand({shardCollection: kNs, key: {x: 1}}));

jsTest.log("Test that mongos does not mark the primary node as down when reads fail");
(() => {
    const cmdObj = {
        count: kCollName,
        query: {x: {$gte: 0}},
        $readPreference: {mode: "primary"},
    };

    // Make the command fail on the primary node with HostUnreachable.
    const failPoint = configureFailCommand(st.rs0.nodes[0], "count", kNs, kErrorCode);
    assert.commandFailedWithCode(testDB.runCommand(cmdObj), kErrorCode);
    failPoint.off();

    // Verify that the node was not marked as down (i.e. it is still the primary node and the
    // command with readPreference "primary" works).
    awaitRSClientHosts(st.s, st.rs0.nodes[0], {ok: true, ismaster: true});
    assert.commandWorked(testDB.runCommand(cmdObj));
})();

jsTest.log("Test that mongos does not mark the secondary node as down when reads fail");
(() => {
    const cmdObj = {
        count: kCollName,
        query: {x: {$gte: 0}},
        $readPreference: {mode: "secondary"},
    };

    // Make the command fail on the secondary node.
    const failPoint = configureFailCommand(st.rs0.nodes[1], "count", kNs, kErrorCode);
    assert.commandFailedWithCode(testDB.runCommand(cmdObj), kErrorCode);
    failPoint.off();

    // Verify that the node was not marked as down (i.e. it is still the secondary node and the
    // command with readPreference "secondary" works).
    awaitRSClientHosts(st.s, st.rs0.nodes[1], {ok: true, secondary: true});
    assert.commandWorked(testDB.runCommand(cmdObj));
})();

jsTest.log("Test that mongos does not mark the primary node as down when pings fail");
(() => {
    // Make ping commands fail on the primary node with HostUnreachable. Sleep for some
    // time to allow the ServerPingMonitor to send out pings.
    const failPoint = configureFailPoint(
        st.s, "serverPingMonitorFailWithHostUnreachable", {hostAndPort: st.rs0.nodes[0].host});
    sleep(kPingWaitTimeMS);

    // Verify that the node was not marked as down (i.e. it is still the primary node and
    // we can run commands with readPreference "primary").
    awaitRSClientHosts(st.s, st.rs0.nodes[0], {ok: true, ismaster: true});
    const cmdObj = {
        count: kCollName,
        query: {x: {$gte: 0}},
        $readPreference: {mode: "primary"},
    };
    assert.commandWorked(testDB.runCommand(cmdObj));

    failPoint.off();
})();

jsTest.log("Test that mongos does not mark the secondary node as down when pings fail");
(() => {
    // Make ping commands fail on the secondary node with HostUnreachable. Sleep for some
    // time to allow the ServerPingMonitor to send out pings.
    const failPoint = configureFailPoint(
        st.s, "serverPingMonitorFailWithHostUnreachable", {hostAndPort: st.rs0.nodes[1].host});
    sleep(kPingWaitTimeMS);

    // Verify that the node was not marked as down (i.e. it is still the secondary node and
    // we can run commands with readPreference "secondary").
    awaitRSClientHosts(st.s, st.rs0.nodes[1], {ok: true, secondary: true});
    const cmdObj = {
        count: kCollName,
        query: {x: {$gte: 0}},
        $readPreference: {mode: "secondary"},
    };
    assert.commandWorked(testDB.runCommand(cmdObj));

    failPoint.off();
})();

st.stop();
})();