summaryrefslogtreecommitdiff
path: root/jstests/noPassthroughWithMongod/replReads.js
blob: d093d6551e58b2c722df92ee865f186dbbf1bf8e (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
// Test that doing secondaryOk reads from secondaries hits all the secondaries evenly
// @tags: [requires_sharding]

function testReadLoadBalancing(numReplicas) {
    var s =
        new ShardingTest({shards: {rs0: {nodes: numReplicas}}, verbose: 2, other: {chunkSize: 1}});

    s.adminCommand({enablesharding: "test"});
    s.config.settings.find().forEach(printjson);

    s.adminCommand({shardcollection: "test.foo", key: {_id: 1}});

    s.getDB("test").foo.insert({a: 123});

    let primary = s.rs0.getPrimary();
    let secondaries = s.rs0.getSecondaries();

    function rsStats() {
        return s.getDB("admin").runCommand("connPoolStats")["replicaSets"][s.rs0.name];
    }

    assert.eq(numReplicas, rsStats().hosts.length);

    function isPrimaryOrSecondary(info) {
        if (!info.ok)
            return false;
        if (info.ismaster)
            return true;
        return info.secondary && !info.hidden;
    }

    assert.soon(function() {
        var x = rsStats().hosts;
        printjson(x);
        for (var i = 0; i < x.length; i++)
            if (!isPrimaryOrSecondary(x[i]))
                return false;
        return true;
    });

    for (var i = 0; i < secondaries.length; i++) {
        assert.soon(function() {
            return secondaries[i].getDB("test").foo.count() > 0;
        });
        secondaries[i].getDB('test').setProfilingLevel(2);
    }
    // Primary may change with reconfig
    primary.getDB('test').setProfilingLevel(2);

    // Store references to the connection so they won't be garbage collected.
    var connections = [];

    for (var i = 0; i < secondaries.length * 10; i++) {
        let conn = new Mongo(s._mongos[0].host);
        conn.setSecondaryOk();
        conn.getDB('test').foo.findOne();
        connections.push(conn);
    }

    var profileCriteria = {op: 'query', ns: 'test.foo'};

    for (var i = 0; i < secondaries.length; i++) {
        var profileCollection = secondaries[i].getDB('test').system.profile;
        assert.eq(10,
                  profileCollection.find(profileCriteria).count(),
                  "Wrong number of read queries sent to secondary " + i + " " +
                      tojson(profileCollection.find().toArray()));
    }

    db = primary.getDB("test");

    printjson(rs.status());
    let c = rs.conf();
    print("config before: " + tojson(c));
    for (i = 0; i < c.members.length; i++) {
        if (c.members[i].host == db.runCommand("hello").primary)
            continue;
        c.members[i].hidden = true;
        c.members[i].priority = 0;
        break;
    }
    rs.reconfig(c);
    print("config after: " + tojson(rs.conf()));

    assert.soon(function() {
        var x = rsStats();
        printjson(x);
        var numOk = 0;
        // Now wait until the host disappears, since now we actually update our
        // replica sets via isMaster in mongos
        if (x.hosts.length == c["members"].length - 1)
            return true;
        /*
        for ( var i=0; i<x.hosts.length; i++ )
            if ( x.hosts[i].hidden )
                return true;
        */
        return false;
    }, "one secondary not ok", 180000, 5000);

    // Secondaries may change here
    secondaries = s.rs0.getSecondaries();

    for (var i = 0; i < secondaries.length * 10; i++) {
        let conn = new Mongo(s._mongos[0].host);
        conn.setSecondaryOk();
        conn.getDB('test').foo.findOne();
        connections.push(conn);
    }

    var counts = [];
    for (var i = 0; i < secondaries.length; i++) {
        var profileCollection = secondaries[i].getDB('test').system.profile;
        counts.push(profileCollection.find(profileCriteria).count());
    }

    counts = counts.sort();
    assert.eq(20, Math.abs(counts[1] - counts[0]), "counts wrong: " + tojson(counts));

    s.stop();
}

// for (var i = 1; i < 10; i++) {
//    testReadLoadBalancing(i)
//}

// Is there a way that this can be run multiple times with different values?
// Disabled until SERVER-11956 is solved
// testReadLoadBalancing(3)