summaryrefslogtreecommitdiff
path: root/jstests/noPassthroughWithMongod/replReads.js
blob: 45e0a4d49a66cd0b6a0ff2e98aa47dffb1b751f1 (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
// Test that doing slaveOk reads from secondaries hits all the secondaries evenly

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});

    primary = s._rs[0].test.liveNodes.master;
    secondaries = s._rs[0].test.liveNodes.slaves;

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

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

    function isMasterOrSecondary(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 (!isMasterOrSecondary(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++) {
        conn = new Mongo(s._mongos[0].host);
        conn.setSlaveOk();
        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());
    c = rs.conf();
    print("config before: " + tojson(c));
    for (i = 0; i < c.members.length; i++) {
        if (c.members[i].host == db.runCommand("ismaster").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 slave not ok", 180000, 5000);

    // Secondaries may change here
    secondaries = s._rs[0].test.liveNodes.slaves;

    for (var i = 0; i < secondaries.length * 10; i++) {
        conn = new Mongo(s._mongos[0].host);
        conn.setSlaveOk();
        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)