13
13
var NODES = SEC_TAGS.length + 1;
15
var st = new ShardingTest({ shards: { rs0: { nodes: NODES, oplogSize: 10,
16
useHostName: true }}});
17
var replTest = st.rs0;
18
var primaryNode = replTest.getMaster();
20
var setupConf = function(){
21
var replConf = primaryNode.getDB( 'local' ).system.replset.findOne();
22
replConf.version = (replConf.version || 0) + 1;
25
for ( var x = 0; x < NODES; x++ ){
26
var node = replConf.members[x];
28
if ( node.host == primaryNode.name ){
15
var doTest = function(useDollarQuerySyntax) {
16
var st = new ShardingTest({ shards: { rs0: { nodes: NODES, oplogSize: 10,
17
useHostName: true }}});
18
var replTest = st.rs0;
19
var primaryNode = replTest.getMaster();
21
var setupConf = function(){
22
var replConf = primaryNode.getDB( 'local' ).system.replset.findOne();
23
replConf.version = (replConf.version || 0) + 1;
26
for ( var x = 0; x < NODES; x++ ){
27
var node = replConf.members[x];
29
if ( node.host == primaryNode.name ){
33
node.tags = SEC_TAGS[secIdx++];
39
primaryNode.getDB( 'admin' ).runCommand({ replSetReconfig: replConf });
41
jsTest.log('Exception expected because reconfiguring would close all conn, got ' + x);
47
var checkTag = function( nodeToCheck, tag ){
48
for ( var idx = 0; idx < NODES; idx++ ){
49
var node = replConf.members[idx];
51
if ( node.host == nodeToCheck ){
52
jsTest.log( 'node[' + node.host + '], Tag: ' + tojson( node['tags'] ));
53
jsTest.log( 'tagToCheck: ' + tojson( tag ));
55
var nodeTag = node['tags'];
57
for ( var key in tag ){
58
assert.eq( tag[key], nodeTag[key] );
65
assert( false, 'node ' + nodeToCheck + ' not part of config!' );
68
var replConf = setupConf();
72
// Wait until the ReplicaSetMonitor refreshes its view and see the tags
73
ReplSetTest.awaitRSClientHosts( conn, primaryNode,
74
{ ok: true, tags: PRI_TAG }, replTest.name );
75
replTest.awaitReplication();
77
jsTest.log('New rs config: ' + tojson(primaryNode.getDB('local').system.replset.findOne()));
78
jsTest.log( 'connpool: ' + tojson(conn.getDB('admin').runCommand({ connPoolStats: 1 })));
80
var coll = conn.getDB( 'test' ).user;
82
assert.soon(function() {
83
coll.insert({ x: 1 });
84
var err = coll.getDB().getLastError(NODES);
88
// Transient transport errors may be expected b/c of the replSetReconfig
89
if (err.indexOf("transport error") == -1) {
96
var getExplain = function(readPrefMode, readPrefTags) {
97
if (useDollarQuerySyntax) {
103
readPrefObj.tags = readPrefTags;
106
return coll.find({ $query: {}, $readPreference: readPrefObj,
107
$explain: true }).limit(-1).next();
32
node.tags = SEC_TAGS[secIdx++];
37
primaryNode.getDB( 'admin' ).runCommand({ replSetReconfig: replConf });
39
jsTest.log( 'Exception expected because reconfiguring would close all conn, got ' + x );
45
var replConf = setupConf();
46
jsTest.log( 'New rs config: ' + tojson( primaryNode.getDB( 'local' ).system.replset.findOne() ));
50
// Wait until the ReplicaSetMonitor refreshes its view and see the tags
51
ReplSetTest.awaitRSClientHosts( conn, primaryNode,
52
{ ok: true, tags: PRI_TAG }, replTest.name );
54
jsTest.log( 'connpool: ' + tojson(conn.getDB('admin').runCommand({ connPoolStats: 1 })));
56
var coll = conn.getDB( 'test' ).user;
58
coll.insert({ x: 1 });
59
assert.eq( null, coll.getDB().getLastError( NODES ));
61
// Read pref should work without slaveOk
62
var explain = coll.find().readPref( "secondary" ).explain();
63
assert.neq( primaryNode.name, explain.server );
67
// It should also work with slaveOk
68
explain = coll.find().readPref( "secondary" ).explain();
69
assert.neq( primaryNode.name, explain.server );
71
// Check that $readPreference does not influence the actual query
72
assert.eq( 1, explain.n );
74
var checkTag = function( nodeToCheck, tag ){
75
for ( var idx = 0; idx < NODES; idx++ ){
76
var node = replConf.members[idx];
78
if ( node.host == nodeToCheck ){
79
jsTest.log( 'node[' + node.host + '], Tag: ' + tojson( node['tags'] ));
80
jsTest.log( 'tagToCheck: ' + tojson( tag ));
82
var nodeTag = node['tags'];
84
for ( var key in tag ){
85
assert.eq( tag[key], nodeTag[key] );
92
assert( false, 'node ' + nodeToCheck + ' not part of config!' );
95
explain = coll.find().readPref( "secondaryPreferred", [{ s: "2" }] ).explain();
96
checkTag( explain.server, { s: "2" });
97
assert.eq( 1, explain.n );
99
// Cannot use tags with primaryOnly
100
assert.throws( function() {
101
coll.find().readPref( "primaryOnly", [] ).explain();
104
// Check that mongos will try the next tag if nothing matches the first
105
explain = coll.find().readPref( "secondary", [{ z: "3" }, { dc: "jp" }] ).explain();
106
checkTag( explain.server, { dc: "jp" });
107
assert.eq( 1, explain.n );
109
// Check that mongos will fallback to primary if none of tags given matches
110
explain = coll.find().readPref( "secondaryPreferred", [{ z: "3" }, { dc: "ph" }] ).explain();
111
assert.eq( primaryNode.name, explain.server );
112
assert.eq( 1, explain.n );
114
// Kill all members except one
115
var stoppedNodes = [];
116
for ( var x = 0; x < NODES - 1; x++ ){
118
stoppedNodes.push( replTest.nodes[x] );
121
// Wait for ReplicaSetMonitor to realize nodes are down
122
ReplSetTest.awaitRSClientHosts( conn, stoppedNodes, { ok: false }, replTest.name );
124
// Wait for the last node to be in steady state -> secondary (not recovering)
125
var lastNode = replTest.nodes[NODES - 1];
126
ReplSetTest.awaitRSClientHosts( conn, lastNode,
127
{ ok: true, secondary: true }, replTest.name );
129
jsTest.log( 'connpool: ' + tojson(conn.getDB('admin').runCommand({ connPoolStats: 1 })));
131
// Test to make sure that connection is ok, in prep for priOnly test
132
explain = coll.find().readPref( "nearest" ).explain();
133
assert.eq( explain.server, replTest.nodes[NODES - 1].name );
134
assert.eq( 1, explain.n );
136
// Should assert if request with priOnly but no primary
137
assert.throws( function(){
138
coll.find().readPref( "primary" ).explain();
110
return coll.find().readPref(readPrefMode, readPrefTags).explain();
114
// Read pref should work without slaveOk
115
var explain = getExplain("secondary");
116
assert.neq( primaryNode.name, explain.server );
120
// It should also work with slaveOk
121
explain = getExplain("secondary");
122
assert.neq( primaryNode.name, explain.server );
124
// Check that $readPreference does not influence the actual query
125
assert.eq( 1, explain.n );
127
explain = getExplain("secondaryPreferred", [{ s: "2" }]);
128
checkTag( explain.server, { s: "2" });
129
assert.eq( 1, explain.n );
131
// Cannot use tags with primaryOnly
132
assert.throws( function() {
133
getExplain("primary", [{ s: "2" }]);
136
// Ok to use empty tags on primaryOnly
137
explain = coll.find().readPref("primary", [{}]).explain();
138
assert.eq(primaryNode.name, explain.server);
140
explain = coll.find().readPref("primary", []).explain();
141
assert.eq(primaryNode.name, explain.server);
143
// Check that mongos will try the next tag if nothing matches the first
144
explain = getExplain("secondary", [{ z: "3" }, { dc: "jp" }]);
145
checkTag( explain.server, { dc: "jp" });
146
assert.eq( 1, explain.n );
148
// Check that mongos will fallback to primary if none of tags given matches
149
explain = getExplain("secondaryPreferred", [{ z: "3" }, { dc: "ph" }]);
150
// Call getPrimary again since the primary could have changed after the restart.
151
assert.eq(replTest.getPrimary().name, explain.server);
152
assert.eq( 1, explain.n );
154
// Kill all members except one
155
var stoppedNodes = [];
156
for ( var x = 0; x < NODES - 1; x++ ){
158
stoppedNodes.push( replTest.nodes[x] );
161
// Wait for ReplicaSetMonitor to realize nodes are down
162
ReplSetTest.awaitRSClientHosts( conn, stoppedNodes, { ok: false }, replTest.name );
164
// Wait for the last node to be in steady state -> secondary (not recovering)
165
var lastNode = replTest.nodes[NODES - 1];
166
ReplSetTest.awaitRSClientHosts( conn, lastNode,
167
{ ok: true, secondary: true }, replTest.name );
169
jsTest.log( 'connpool: ' + tojson(conn.getDB('admin').runCommand({ connPoolStats: 1 })));
171
// Test to make sure that connection is ok, in prep for priOnly test
172
explain = getExplain("nearest");
173
assert.eq( explain.server, replTest.nodes[NODES - 1].name );
174
assert.eq( 1, explain.n );
176
// Should assert if request with priOnly but no primary
177
assert.throws( function(){
178
getExplain("primary");