summaryrefslogtreecommitdiff
path: root/jstests/replsets
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/replsets')
-rw-r--r--jstests/replsets/auth1.js11
-rw-r--r--jstests/replsets/auth2.js8
-rw-r--r--jstests/replsets/auth3.js69
-rw-r--r--jstests/replsets/capped_id.js145
-rw-r--r--jstests/replsets/cloneDb.js13
-rw-r--r--jstests/replsets/fastsync.js68
-rw-r--r--jstests/replsets/fsync_lock_read_secondaries.js61
-rw-r--r--jstests/replsets/getlasterror_w2.js36
-rw-r--r--jstests/replsets/groupAndMapReduce.js9
-rw-r--r--jstests/replsets/initSyncV1Index.js32
-rw-r--r--jstests/replsets/initial_sync1.js13
-rw-r--r--jstests/replsets/initial_sync2.js6
-rw-r--r--jstests/replsets/initial_sync3.js8
-rw-r--r--jstests/replsets/initial_sync4.js67
-rw-r--r--jstests/replsets/maintenance.js65
-rw-r--r--jstests/replsets/maintenance2.js63
-rw-r--r--jstests/replsets/majority.js6
-rw-r--r--jstests/replsets/reconfig.js22
-rw-r--r--jstests/replsets/reindex_secondary.js34
-rw-r--r--jstests/replsets/remove1.js56
-rw-r--r--jstests/replsets/replset1.js26
-rw-r--r--jstests/replsets/replset2.js6
-rw-r--r--jstests/replsets/replset4.js82
-rw-r--r--jstests/replsets/replset6.js52
-rw-r--r--jstests/replsets/replset7.js2
-rw-r--r--jstests/replsets/replset8.js61
-rw-r--r--jstests/replsets/replsetadd.js16
-rw-r--r--jstests/replsets/replsetfreeze.js6
-rw-r--r--jstests/replsets/replsethostnametrim.js21
-rw-r--r--jstests/replsets/replsetprio1.js2
-rw-r--r--jstests/replsets/replsetrestart1.js6
-rw-r--r--jstests/replsets/rollback.js39
-rw-r--r--jstests/replsets/rollback2.js14
-rwxr-xr-xjstests/replsets/rollback3.js19
-rw-r--r--jstests/replsets/rollback4.js14
-rw-r--r--jstests/replsets/rslib.js54
-rw-r--r--jstests/replsets/slaveDelay2.js28
-rw-r--r--jstests/replsets/slavedelay1.js66
-rw-r--r--jstests/replsets/stale_clustered.js4
-rw-r--r--jstests/replsets/stepdown.js19
-rw-r--r--jstests/replsets/sync2.js1
-rw-r--r--jstests/replsets/sync_passive2.js65
-rw-r--r--jstests/replsets/tags.js102
-rw-r--r--jstests/replsets/tags2.js15
44 files changed, 1190 insertions, 322 deletions
diff --git a/jstests/replsets/auth1.js b/jstests/replsets/auth1.js
index 40a131a3e44..0d0ca76d1c0 100644
--- a/jstests/replsets/auth1.js
+++ b/jstests/replsets/auth1.js
@@ -8,9 +8,7 @@ var path = "jstests/libs/";
print("try starting mongod with auth");
-var pargs = new MongodRunner( port[4], "/data/db/wrong-auth", false, false,
- ["--auth"], {no_bind : true} );
-var m = pargs.start();
+var m = MongoRunner.runMongod({auth : "", port : port[4], dbpath : "/data/db/wrong-auth"});
assert.eq(m.getDB("local").auth("__system", ""), 0);
@@ -25,8 +23,9 @@ run("chmod", "644", path+"key2");
print("try starting mongod");
m = runMongoProgram( "mongod", "--keyFile", path+"key1", "--port", port[0], "--dbpath", "/data/db/" + name);
+
print("should fail with wrong permissions");
-assert.eq(m, 2, "mongod should exit w/ 2: permissions too open");
+assert.eq(m, _isWindows()? 100 : 2, "mongod should exit w/ 2: permissions too open");
stopMongod(port[0]);
@@ -43,6 +42,7 @@ print("make sure user is written before shutting down");
m.getDB("test").getLastError();
stopMongod(port[0]);
+if ( !_isWindows() ) { // SERVER-5024
print("start up rs");
var rs = new ReplSetTest({"name" : name, "nodes" : 3, "startPort" : port[0]});
@@ -160,7 +160,7 @@ conn.start();
master.getSisterDB("admin").auth("foo", "bar");
var config = master.getSisterDB("local").system.replset.findOne();
-config.members.push({_id : 3, host : getHostName()+":"+port[3]});
+config.members.push({_id : 3, host : rs.host+":"+port[3]});
config.version++;
try {
master.adminCommand({replSetReconfig:config});
@@ -214,3 +214,4 @@ assert.soon(function() {
}
return true;
});
+ } // !isWindows \ No newline at end of file
diff --git a/jstests/replsets/auth2.js b/jstests/replsets/auth2.js
index 0fe1ae404de..4a38c387aee 100644
--- a/jstests/replsets/auth2.js
+++ b/jstests/replsets/auth2.js
@@ -1,3 +1,4 @@
+if ( !_isWindows() ) { //SERVER-5024
var name = "rs_auth2";
var port = allocatePorts(3);
var path = "jstests/libs/";
@@ -40,6 +41,7 @@ var checkInvalidAuthStates = function() {
assert.soon(function() {
try {
var result = m.getDB("admin").runCommand({isMaster: 1});
+ printjson(result);
return !result.ismaster && !result.secondary;
}
catch ( e ) {
@@ -53,6 +55,7 @@ var checkInvalidAuthStates = function() {
assert.soon(function() {
var result = m.getDB("admin").runCommand({isMaster: 1});
+ printjson(result);
return !result.ismaster && !result.secondary;
});
@@ -61,6 +64,7 @@ var checkInvalidAuthStates = function() {
assert.soon(function() {
var result = m.getDB("admin").runCommand({isMaster: 1});
+ printjson(result);
return result.secondary;
});
@@ -71,6 +75,7 @@ var checkInvalidAuthStates = function() {
var checkValidAuthState = function() {
assert.soon(function() {
var result = m.getDB("admin").runCommand({isMaster : 1});
+ printjson(result);
return result.secondary;
});
};
@@ -79,7 +84,7 @@ var rs = setupReplSet();
var master = rs.getMaster();
print("add an admin user");
-master.getDB("admin").addUser("foo","bar");
+master.getDB("admin").addUser("foo","bar",false,3);
m = rs.nodes[0];
print("starting 1 and 2 with key file");
@@ -101,3 +106,4 @@ rs.stop(0);
m = rs.restart(0, {"keyFile" : path+"key1"});
print("0 becomes a secondary");
+} // !_isWindows() \ No newline at end of file
diff --git a/jstests/replsets/auth3.js b/jstests/replsets/auth3.js
new file mode 100644
index 00000000000..7408e8a34a5
--- /dev/null
+++ b/jstests/replsets/auth3.js
@@ -0,0 +1,69 @@
+if ( !_isWindows() ) { // SERVER-5024
+var path = "jstests/libs/";
+
+var rs = new ReplSetTest({"nodes" : {node0 : {}, node1 : {}, arbiter : {}}, keyFile : path+"key1"});
+rs.startSet();
+rs.initiate();
+
+master = rs.getMaster();
+print("adding user");
+master.getDB("admin").addUser("foo", "bar", false, 2);
+
+var checkValidState = function(i) {
+ assert.soon(function() {
+ var result = rs.nodes[i].getDB("admin").runCommand({isMaster : 1});
+ printjson(result);
+ return result.secondary || result.ismaster;
+ });
+};
+
+var safeInsert = function() {
+ master = rs.getMaster();
+ master.getDB("admin").auth("foo", "bar");
+ master.getDB("foo").bar.insert({x:1});
+ var insertWorked = master.getDB("foo").runCommand({getlasterror:1});
+ printjson(insertWorked);
+ assert.eq(insertWorked.ok, 1);
+}
+
+print("authing");
+assert.soon(function() {
+ for (var i=0; i<2; i++) {
+ checkValidState(i);
+
+ // if this is run before initial sync finishes, we won't be logged in
+ var res = rs.nodes[i].getDB("admin").auth("foo", "bar");
+ if (res != 1) {
+ print("couldn't log into "+rs.nodes[i].host);
+ return false;
+ }
+ }
+ return true;
+});
+
+print("make common point");
+
+safeInsert();
+rs.awaitReplication();
+
+print("write stuff to 0&2")
+rs.stop(1);
+
+master = rs.getMaster();
+master.getDB("foo").bar.drop();
+print("last op: "+tojson(master.getDB("local").oplog.rs.find().sort({$natural:-1}).limit(1).next()));
+
+print("write stuff to 1&2")
+rs.stop(0);
+rs.restart(1);
+
+safeInsert();
+print("last op: "+tojson(master.getDB("local").oplog.rs.find().sort({$natural:-1}).limit(1).next()));
+
+rs.restart(0);
+
+print("doing rollback!");
+
+checkValidState(0);
+checkValidState(1);
+} // !_isWindows() \ No newline at end of file
diff --git a/jstests/replsets/capped_id.js b/jstests/replsets/capped_id.js
new file mode 100644
index 00000000000..2fd3369e277
--- /dev/null
+++ b/jstests/replsets/capped_id.js
@@ -0,0 +1,145 @@
+// Check that capped collections get an _id index when replicated
+
+// Test #
+// 0) create capped collection on replset, check _id index appears on secondary
+// 1) create normal collection, then convertToCapped, check _id index on secondaries
+// 2) create capped collection, do updates instead of inserts, check _id index on secondaries
+// 3) create capped collection with autoIndexId=false. make sure no _id index. then create one
+// and check it got created on secondaries.
+
+// Create a new replica set test with name 'testSet' and 3 members
+var replTest = new ReplSetTest( {name: 'testSet', nodes: 3} );
+
+// call startSet() to start each mongod in the replica set
+// this returns a list of nodes
+var nodes = replTest.startSet();
+
+// Call initiate() to send the replSetInitiate command
+// This will wait for initiation
+replTest.initiate();
+
+// Call getMaster to return a reference to the node that's been
+// elected master
+var master = replTest.getMaster();
+
+// wait for secondaries to be up, since we'll be reading from them
+replTest.awaitSecondaryNodes();
+// And get the slaves from the liveNodes
+var slave1 = replTest.liveNodes.slaves[0];
+var slave2 = replTest.liveNodes.slaves[1];
+
+// Calling getMaster made available the liveNodes structure,
+// which looks like this:
+// liveNodes = {master: masterNode, slaves: [slave1, slave2] }
+printjson( replTest.liveNodes );
+
+// define db names to use for this test
+var dbname = "dbname";
+var masterdb = master.getDB( dbname );
+var slave1db = slave1.getDB( dbname );
+var slave2db = slave2.getDB( dbname );
+
+var numtests = 4;
+for( testnum=0; testnum < numtests; testnum++ ){
+
+ //define collection name
+ coll = "coll" + testnum;
+
+ // drop the coll on the master (just in case it already existed)
+ // and wait for the drop to replicate
+ masterdb.getCollection( coll ).drop();
+ replTest.awaitReplication();
+
+ if ( testnum == 0 ){
+ // create a capped collection on the master
+ // insert a bunch of things in it
+ // wait for it to replicate
+ masterdb.runCommand( {create : coll , capped : true , size : 1024} );
+ for(i=0; i < 500 ; i++){
+ masterdb.getCollection( coll ).insert( {a: 1000} );
+ }
+ replTest.awaitReplication();
+ }
+ else if ( testnum == 1 ){
+ // create a non-capped collection on the master
+ // insert a bunch of things in it
+ // wait for it to replicate
+ masterdb.runCommand( {create : coll } );
+ for(i=0; i < 500 ; i++){
+ masterdb.getCollection( coll ).insert( {a: 1000} );
+ }
+ replTest.awaitReplication();
+
+ // make sure _id index exists on primary
+ assert.eq( 1 ,
+ masterdb.system.indexes.find( { key:{"_id" : 1}, ns: dbname + "." + coll } ).count() ,
+ "master does not have _id index on normal collection");
+
+ // then convert it to capped
+ masterdb.runCommand({convertToCapped: coll , size: 1024 } );
+ replTest.awaitReplication();
+ }
+ else if ( testnum == 2 ){
+ // similar to first test, but check that a bunch of updates instead
+ // of inserts triggers the _id index creation on secondaries.
+ masterdb.runCommand( {create : coll , capped : true , size : 1024} );
+ masterdb.getCollection( coll ).insert( {a : 0} );
+ for(i=0; i < 500 ; i++){
+ masterdb.getCollection( coll ).update( {} , {$inc : {a : 1} } );
+ }
+ replTest.awaitReplication();
+ }
+ else if ( testnum == 3 ){
+ // explicitly set autoIndexId : false
+ masterdb.runCommand( {create : coll , capped : true , size : 1024 , autoIndexId : false } )
+ for(i=0; i < 500 ; i++){
+ masterdb.getCollection( coll ).insert( {a: 1000} );
+ }
+ replTest.awaitReplication();
+
+ assert.eq( 0 ,
+ masterdb.system.indexes.find( { key:{"_id" : 1}, ns: dbname + "." + coll } ).count() ,
+ "master has an _id index on capped collection when autoIndexId is false");
+ assert.eq( 0 ,
+ slave1db.system.indexes.find( { key:{"_id" : 1}, ns: dbname + "." + coll } ).count() ,
+ "slave1 has an _id index on capped collection when autoIndexId is false");
+ assert.eq( 0 ,
+ slave2db.system.indexes.find( { key:{"_id" : 1}, ns: dbname + "." + coll } ).count() ,
+ "slave2 has an _id index on capped collection when autoIndexId is false");
+
+ // now create the index and make sure it works
+ masterdb.getCollection( coll ).ensureIndex( { "_id" : 1 } );
+ replTest.awaitReplication();
+ }
+
+ // what indexes do we have?
+ print("**********Master indexes:**********");
+ masterdb.system.indexes.find().forEach(printjson);
+ print("");
+
+ print("**********Slave1 indexes:**********");
+ slave1db.system.indexes.find().forEach(printjson);
+ print("");
+
+ print("**********Slave2 indexes:**********");
+ slave2db.system.indexes.find().forEach(printjson);
+ print("");
+
+ // insure all nodes have _id index
+ assert.eq( 1 ,
+ masterdb.system.indexes.find( { key:{"_id" : 1}, ns: dbname + "." + coll } ).count() ,
+ "master has an _id index on capped collection");
+ assert.eq( 1 ,
+ slave1db.system.indexes.find( { key:{"_id" : 1}, ns: dbname + "." + coll } ).count() ,
+ "slave1 does not have _id index on capped collection");
+ assert.eq( 1 ,
+ slave2db.system.indexes.find( { key:{"_id" : 1}, ns: dbname + "." + coll } ).count() ,
+ "slave2 does not have _id index on capped collection");
+
+ print("capped_id.js Test # " + testnum + " SUCCESS");
+}
+
+//Finally, stop set
+replTest.stopSet();
+
+
diff --git a/jstests/replsets/cloneDb.js b/jstests/replsets/cloneDb.js
index 2519c09b42b..d6356031e2c 100644
--- a/jstests/replsets/cloneDb.js
+++ b/jstests/replsets/cloneDb.js
@@ -19,7 +19,10 @@ doTest = function( signal ) {
print("Insert data");
for (var i = 0; i < N; i++) {
db1['foo'].insert({x: i, text: Text})
- db1.getLastError(2) // wait to be copied to at least one secondary
+ var le = db1.getLastErrorObj(2, 1000); // wait to be copied to at least one secondary
+ if (le.err) {
+ printjson(le);
+ }
}
print("Create single server");
@@ -50,5 +53,9 @@ doTest = function( signal ) {
repset.stopSet( signal )
}
-doTest( 15 );
-print("replsets/cloneDb.js SUCCESS");
+if (jsTest.options().keyFile) {
+ print("Skipping test because clone command doesn't work with authentication enabled: SERVER-4245")
+} else {
+ doTest( 15 );
+ print("replsets/cloneDb.js SUCCESS");
+}
diff --git a/jstests/replsets/fastsync.js b/jstests/replsets/fastsync.js
index 1c9c2152ebb..06da6a8d82b 100644
--- a/jstests/replsets/fastsync.js
+++ b/jstests/replsets/fastsync.js
@@ -97,9 +97,21 @@ var startSlave = function(n) {
config.version++;
config.members.push({_id:n, host:hostname+":"+ports[n]});
- result = admin.runCommand({replSetReconfig : config});
- printjson(result);
- assert(result.ok, "reconfig worked");
+ // When the slave is started, it'll try to load the config and find that it's
+ // not in the config and close all connections in preparation for transitioning
+ // to "removed" state. If the reconfig adding it to the set happens to occur at
+ // this point, the heartbeat request's connection will be cut off, causing the
+ // reconfig to fail..
+ assert.soon(function() {
+ try {
+ result = admin.runCommand({replSetReconfig : config});
+ }
+ catch (e) {
+ print("failed to reconfig: "+e);
+ return false;
+ }
+ return result.ok;
+ });
reconnect(p);
print("4");
@@ -132,10 +144,16 @@ var startSlave = function(n) {
admin.foo.insert({x:1});
assert.soon(function() {
- var last = local.oplog.rs.find().sort({$natural:-1}).limit(1).next();
- var cur = conn.getDB("local").oplog.rs.find().sort({$natural:-1}).limit(1).next();
- print("last: "+tojson(last)+" cur: "+tojson(cur));
- return cur != null && last != null && cur.ts.t == last.ts.t && cur.ts.i == last.ts.i;
+ try {
+ var last = local.oplog.rs.find().sort({$natural:-1}).limit(1).next();
+ var cur = conn.getDB("local").oplog.rs.find().sort({$natural:-1}).limit(1).next();
+ print("last: "+tojson(last)+" cur: "+tojson(cur));
+ return cur != null && last != null && cur.ts.t == last.ts.t && cur.ts.i == last.ts.i;
+ }
+ catch (e) {
+ print(e);
+ }
+ return false;
});
return conn;
@@ -143,10 +161,19 @@ var startSlave = function(n) {
var s1 = startSlave(1);
-var me1 = s1.getDB("local").me.findOne();
+var me1 = null;
+
+// local.me will not be populated until the secondary reports back to the
+// primary that it is syncing
+assert.soon(function() {
+ me1 = s1.getDB("local").me.findOne();
+ if (me1 == null) {
+ return false;
+ }
-print("me: " +me1._id);
-assert(me1._id != null);
+ print("me: " +me1._id);
+ return me1._id != null;
+});
print("5");
s1.getDB("admin").runCommand( {fsync:1,lock:1} );
@@ -172,14 +199,25 @@ sleep(10000);
pargs = new MongodRunner( ports[ 3 ], basePath + "-p", false, false,
["--replSet", basename, "--oplogSize", 2],
{no_bind : true} );
-p = pargs.start(true);
+pargs.start(true);
-printjson(p.getDB("admin").runCommand({replSetGetStatus:1}));
+p = new Mongo("localhost:"+ports[3]);
-p.getDB("admin").runCommand({replSetReconfig : {
- _id : basename,
- members : [{_id:0, host : hostname+":"+ports[3]}]
+// initFromConfig will keep closing sockets, so we'll a couple of times
+assert.soon(function() {
+ try {
+ p.getDB("admin").runCommand({replSetReconfig : {
+ _id : basename,
+ members : [{_id:0, host : hostname+":"+ports[3]}]
}, force : true});
+ }
+ catch (e) {
+ print(e);
+ return false;
+ }
+
+ return true;
+});
print("start waiting for primary...");
assert.soon(function() {
diff --git a/jstests/replsets/fsync_lock_read_secondaries.js b/jstests/replsets/fsync_lock_read_secondaries.js
new file mode 100644
index 00000000000..b89c01dd52c
--- /dev/null
+++ b/jstests/replsets/fsync_lock_read_secondaries.js
@@ -0,0 +1,61 @@
+/* @file : jstests/fsync_lock_read_secondaries.js
+ *
+ * SERVER 4243 : If there is a pending write due to an fsync lock, all reads are blocked
+ *
+ * This test validates part of SERVER-4243 ticket. Allow reading on secondaries with fsyncLock
+ * mode enabled. Previously oplog application would cause blocking.
+ * The corresponding commit :
+ * https://github.com/mongodb/mongo/commit/73aa870d129bd7d51de946b91c16cc056aaacbc7
+ */
+
+/*
+ * 1) Create a replica set.
+ * 2) Add some documents to master.
+ * 3) Wait until the secondary nodes are in state "SECONDARY".
+ * 4) Set slaveOk on secondary.
+ * 5) Take the fsync lock on a secondary. This will stop replication.
+ * 6) Insert some more documents to master.
+ * 7) Expect to be able to read from the secondary; the count of documents should
+ * be equal to the number of documents added in step 2.
+ * 8) Release the fsync lock. This will resume replication.
+ * 9) Soon, the secondary should be applying the oplog again, which we should
+ * witness as an increase in the count of documents stored on the secondary.
+ */
+
+// Load utility methods for replica set tests
+load("jstests/replsets/rslib.js");
+
+var replTest = new ReplSetTest({name: 'testSet', nodes: 2, oplogSize: 5});
+// Start each mongod in the replica set. Returns a list of nodes
+var nodes = replTest.startSet();
+// This will wait for initiation
+replTest.initiate();
+var master = replTest.getMaster();
+var docNum = 100;
+for(var i=0; i<docNum; i++) {
+ master.getDB("foo").bar.save({a: i});
+}
+waitForAllMembers(master.getDB("foo"));
+
+// Calling getMaster also makes available the liveNodes structure, which looks like this:
+// liveNodes = {master: masterNode, slaves: [slave1, slave2] }
+var slaves = replTest.liveNodes.slaves;
+slaves[0].setSlaveOk();
+
+assert.commandWorked(slaves[0].getDB("admin").runCommand({fsync:1, lock: 1}));
+var docNum = 1000;
+for (var i=0; i<docNum; i++) {
+ master.getDB("foo").bar.save({a: i});
+}
+// Issue a read query on the secondary while holding the fsync lock.
+// This is what we are testing. Previously this would block. After the fix
+// this should work just fine.
+var slave0count = slaves[0].getDB("foo").bar.count();
+assert.eq(slave0count, 100, "Doc count in fsync lock wrong. Expected (=100), found " + slave0count);
+assert(slaves[0].getDB("admin").$cmd.sys.unlock.findOne().ok);
+
+// The secondary should have equal or more documents than what it had before.
+assert.soon(function() {
+ return slaves[0].getDB("foo").bar.count() > 100
+ }, "count of documents stored on the secondary did not increase");
+replTest.stopSet();
diff --git a/jstests/replsets/getlasterror_w2.js b/jstests/replsets/getlasterror_w2.js
deleted file mode 100644
index 795e6671d46..00000000000
--- a/jstests/replsets/getlasterror_w2.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// BUG: [SERVER-1768] replica set getlasterror {w: 2} after 2000
-// inserts hangs while secondary servers log "replSet error RS102 too stale to catch up" every once in a while
-
-function newReplicaSet (name, numServers) {
- var rs = new ReplSetTest({name: name, nodes: numServers})
- rs.startSet()
- rs.initiate()
- rs.awaitReplication()
- return rs
-}
-
-function go() {
-var N = 2000
-
-// ~1KB string
-var Text = ''
-for (var i = 0; i < 40; i++)
- Text += 'abcdefghijklmnopqrstuvwxyz'
-
-// Create replica set of 3 servers
-var repset = newReplicaSet('repset', 3)
-var conn = repset.getMaster()
-var db = conn.getDB('test')
-
-// Add data to it
-for (var i = 0; i < N; i++)
- db['foo'].insert({x: i, text: Text})
-
-// wait to be copied to at least one secondary (BUG hangs here)
-db.getLastError(2)
-
-print('getlasterror_w2.js SUCCESS')
-}
-
-// turn off until fixed
-//go();
diff --git a/jstests/replsets/groupAndMapReduce.js b/jstests/replsets/groupAndMapReduce.js
index 539fe44b264..a60ce82f5f8 100644
--- a/jstests/replsets/groupAndMapReduce.js
+++ b/jstests/replsets/groupAndMapReduce.js
@@ -1,3 +1,5 @@
+load("jstests/replsets/rslib.js");
+
doTest = function( signal ) {
// Test basic replica set functionality.
@@ -26,11 +28,10 @@ doTest = function( signal ) {
master.getDB("foo").foo.save({a: i});
}
+ waitForAllMembers(master.getDB("foo"));
// This method will check the oplogs of the master
// and slaves in the set and wait until the change has replicated.
replTest.awaitReplication();
- print("Sleeping 10s for slaves to go to secondary state");
- sleep(10000);
slaves = replTest.liveNodes.slaves;
assert( slaves.length == 2, "Expected 2 slaves but length was " + slaves.length );
@@ -101,5 +102,5 @@ doTest = function( signal ) {
replTest.stopSet( signal );
}
-doTest( 15 );
-print("SUCCESS");
+doTest( 15 );
+print("SUCCESS");
diff --git a/jstests/replsets/initSyncV1Index.js b/jstests/replsets/initSyncV1Index.js
new file mode 100644
index 00000000000..deec0177382
--- /dev/null
+++ b/jstests/replsets/initSyncV1Index.js
@@ -0,0 +1,32 @@
+// Create {v:0} index on primary. Add new secondary. Make sure same index on secondary is {v:1} - SERVER-3852
+
+var rs = new ReplSetTest( {name: 'rs', nodes: 1, host: 'localhost'} );
+rs.startSet();
+rs.initiate();
+var r1 = rs.getMaster();
+var db1 = r1.getDB('test');
+
+var t = '';
+for (var i = 0; i < 1000; i++) t += 'a';
+for (var i = 0; i < 10000; i++) db1.foo.insert( {_id:i, x:i%1000, t:t} );
+db1.foo.createIndex( {x:1}, {v: 0} );
+
+var r2 = rs.add();
+rs.reInitiate();
+rs.awaitSecondaryNodes();
+var db2 = r2.getDB('test');
+r2.setSlaveOk();
+
+var idx = db2.system.indexes.findOne( {key: {x:1}} );
+assert.eq (idx.v, 1, 'expected all indexes generated on Mongo version >= 2.0 to be {v:1}. See SERVER-3852');
+
+// add another new node, make sure ports _aren't_ closed SERVER-4315
+r1 = rs.getMaster();
+rs.add();
+var c = r1.getDB("local").system.replset.findOne();
+var config = rs.getReplSetConfig();
+config.version = c.version+1;
+var result = r1.getDB("admin").runCommand({replSetReconfig:config});
+assert.eq(result.ok, 1);
+
+rs.stopSet(15);
diff --git a/jstests/replsets/initial_sync1.js b/jstests/replsets/initial_sync1.js
index 4cfd606ec9c..e2d415d75bb 100644
--- a/jstests/replsets/initial_sync1.js
+++ b/jstests/replsets/initial_sync1.js
@@ -50,17 +50,14 @@ var ports = allocatePorts( 3 );
var basePath = "/data/db/" + basename;
var hostname = getHostName();
-var sargs = new MongodRunner( ports[ 2 ], basePath, false, false,
- ["--replSet", basename, "--oplogSize", 2],
- {no_bind : true} );
-var slave2 = sargs.start();
+var slave2 = startMongodTest (ports[2], basename, false, {replSet : basename, oplogSize : 2} )
+
var local_s2 = slave2.getDB("local");
var admin_s2 = slave2.getDB("admin");
var config = replTest.getReplSetConfig();
config.version = 2;
config.members.push({_id:2, host:hostname+":"+ports[2]});
-
try {
admin.runCommand({replSetReconfig:config});
}
@@ -123,3 +120,9 @@ for (var i=0; i<10000; i++) {
print("11. Everyone happy eventually");
replTest.awaitReplication(300000);
+
+print("13. Check hbmsg");
+master.getDB("admin").runCommand({replSetTest:1, sethbmsg:"foo bar baz"});
+var status = master.getDB("admin").runCommand({replSetGetStatus:1});
+printjson(status);
+assert.eq(status.members[0].errmsg, "foo bar baz");
diff --git a/jstests/replsets/initial_sync2.js b/jstests/replsets/initial_sync2.js
index 3ad39725834..cc5237a7fb3 100644
--- a/jstests/replsets/initial_sync2.js
+++ b/jstests/replsets/initial_sync2.js
@@ -54,10 +54,8 @@ var ports = allocatePorts( 3 );
var basePath = "/data/db/" + basename;
var hostname = getHostName();
-var sargs = new MongodRunner( ports[ 2 ], basePath, false, false,
- ["--replSet", basename, "--oplogSize", 2],
- {no_bind : true} );
-var slave2 = sargs.start();
+var slave2 = startMongodTest (ports[2], basename, false, {replSet : basename, oplogSize : 2} )
+
var local_s2 = slave2.getDB("local");
var admin_s2 = slave2.getDB("admin");
diff --git a/jstests/replsets/initial_sync3.js b/jstests/replsets/initial_sync3.js
index ef45581d618..f63e79b868b 100644
--- a/jstests/replsets/initial_sync3.js
+++ b/jstests/replsets/initial_sync3.js
@@ -3,6 +3,7 @@
* Make sure member can't sync from a member with a different buildIndexes setting.
*/
+
load("jstests/replsets/rslib.js");
var name = "initialsync3";
var host = getHostName();
@@ -33,7 +34,6 @@ replTest.start(1);
print("make sure 1 does not become a secondary (because it cannot clone from 2)");
sleep(10000);
-reconnect(nodes[1]);
var result = nodes[1].getDB("admin").runCommand({isMaster : 1});
assert(!result.ismaster, tojson(result));
assert(!result.secondary, tojson(result));
@@ -66,7 +66,7 @@ try {
master.getDB("admin").runCommand({replSetReconfig : config});
}
catch(e) {
- print("trying to reconfigure: "+e);
+ assert((e.message || e) == "error doing query: failed");
}
// wait for a heartbeat, too, just in case sync happens before hb
@@ -93,8 +93,10 @@ rs2.partition(0, 2);
master.getDB("foo").bar.baz.insert({x:1});
rs2.awaitReplication();
+master = rs2.getMaster();
+
master.getDB("foo").bar.baz.insert({x:2});
-var x = master.getDB("foo").runCommand({getLastError : 1, w : 3, wtimeout : 5000});
+var x = master.getDB("foo").runCommand({getLastError : 1, w : 3, wtimeout : 60000});
printjson(x);
assert.eq(null, x.err);
diff --git a/jstests/replsets/initial_sync4.js b/jstests/replsets/initial_sync4.js
new file mode 100644
index 00000000000..efcc8e435ed
--- /dev/null
+++ b/jstests/replsets/initial_sync4.js
@@ -0,0 +1,67 @@
+// Test update modifier uassert during initial sync. SERVER-4781
+
+if( 0 ) { // SERVER-4781
+
+load("jstests/replsets/rslib.js");
+basename = "jstests_initsync4";
+
+print("1. Bring up set");
+replTest = new ReplSetTest( {name: basename, nodes: 1} );
+replTest.startSet();
+replTest.initiate();
+
+m = replTest.getMaster();
+md = m.getDB("d");
+mc = m.getDB("d")["c"];
+
+print("2. Insert some data");
+N = 500000;
+for( i = 0; i < N; ++i ) {
+ mc.save( {_id:i,a:{}} );
+}
+md.getLastError();
+
+print("3. Make sure synced");
+replTest.awaitReplication();
+
+print("4. Bring up a new node");
+ports = allocatePorts( 3 );
+basePath = "/data/db/" + basename;
+hostname = getHostName();
+
+s = startMongodTest (ports[2], basename, false, {replSet : basename, oplogSize : 2} );
+
+var config = replTest.getReplSetConfig();
+config.version = 2;
+config.members.push({_id:2, host:hostname+":"+ports[2]});
+try {
+ m.getDB("admin").runCommand({replSetReconfig:config});
+}
+catch(e) {
+ print(e);
+}
+reconnect(s);
+
+print("5. Wait for new node to start cloning");
+
+s.setSlaveOk();
+sc = s.getDB("d")["c"];
+
+wait( function() { printjson( sc.stats() ); return sc.stats().count > 0; } );
+
+print("6. Start updating documents on primary");
+for( i = N-1; i >= N-10000; --i ) {
+ // If the document is cloned as {a:1}, the {$set:{'a.b':1}} modifier will uassert.
+ mc.update( {_id:i}, {$set:{'a.b':1}} );
+ mc.update( {_id:i}, {$set:{a:1}} );
+}
+
+print("7. Wait for new node to become SECONDARY");
+wait(function() {
+ var status = s.getDB("admin").runCommand({replSetGetStatus:1});
+ printjson(status);
+ return status.members &&
+ (status.members[1].state == 2);
+ });
+
+} \ No newline at end of file
diff --git a/jstests/replsets/maintenance.js b/jstests/replsets/maintenance.js
index 5b068cd3d8e..65b1ccfd851 100644
--- a/jstests/replsets/maintenance.js
+++ b/jstests/replsets/maintenance.js
@@ -1,6 +1,6 @@
-var replTest = new ReplSetTest( {name: 'unicomplex', nodes: 3} );
+var replTest = new ReplSetTest( {name: 'unicomplex', nodes: 2} );
var conns = replTest.startSet();
replTest.initiate();
@@ -12,21 +12,70 @@ for (i=0;i<1000; i++) { master.getDB("bar").foo.update({y:i},{$push :{foo : "bar
replTest.awaitReplication();
-assert.soon(function() { return conns[2].getDB("admin").isMaster().secondary; });
+assert.soon(function() { return conns[1].getDB("admin").isMaster().secondary; });
-join = startParallelShell( "db.getSisterDB('bar').runCommand({compact : 'foo'});", replTest.ports[2] );
-
-print("check secondary goes to recovering");
-assert.soon(function() { return !conns[2].getDB("admin").isMaster().secondary; });
+join = startParallelShell( "db.getSisterDB('bar').runCommand({compact : 'foo'});", replTest.ports[1] );
print("joining");
join();
print("check secondary becomes a secondary again");
+var secondarySoon = function() {
+ var x = 0;
+ assert.soon(function() {
+ var im = conns[1].getDB("admin").isMaster();
+ if (x++ % 5 == 0) printjson(im);
+ return im.secondary;
+ });
+};
+
+secondarySoon();
+
+print("make sure compact works on a secondary (SERVER-3923)");
+master.getDB("foo").bar.drop();
+replTest.awaitReplication();
+var result = conns[1].getDB("foo").runCommand({compact : "bar"});
+assert.eq(result.ok, 0, tojson(result));
+
+secondarySoon();
+
+print("use replSetMaintenance command to go in/out of maintence mode");
+
+print("primary cannot go into maintence mode");
+result = master.getDB("admin").runCommand({replSetMaintenance : 1});
+assert.eq(result.ok, 0, tojson(result));
+
+print("check getMore works on a secondary, not on a recovering node");
+var cursor = conns[1].getDB("bar").foo.find();
+for (var i=0; i<50; i++) {
+ cursor.next();
+}
+
+print("secondary can");
+result = conns[1].getDB("admin").runCommand({replSetMaintenance : 1});
+assert.eq(result.ok, 1, tojson(result));
+
+print("make sure secondary goes into recovering");
var x = 0;
assert.soon(function() {
- var im = conns[2].getDB("admin").isMaster();
+ var im = conns[1].getDB("admin").isMaster();
if (x++ % 5 == 0) printjson(im);
- return im.secondary;
+ return !im.secondary && !im.ismaster;
});
+print("now getmore shouldn't work");
+lastDoc = null;
+while (cursor.hasNext()) {
+ lastDoc = cursor.next();
+}
+
+print("the shell is currently stupid and won't throw once it's returned any query results");
+printjson(lastDoc);
+assert("$err" in lastDoc);
+assert.eq(lastDoc.code, 13436);
+
+result = conns[1].getDB("admin").runCommand({replSetMaintenance : 0});
+assert.eq(result.ok, 1, tojson(result));
+
+secondarySoon();
+
diff --git a/jstests/replsets/maintenance2.js b/jstests/replsets/maintenance2.js
new file mode 100644
index 00000000000..463f6c78a4e
--- /dev/null
+++ b/jstests/replsets/maintenance2.js
@@ -0,0 +1,63 @@
+function shouldFail( f ) {
+ e = assert.throws( function() {
+ f();
+ if( db.getLastError() ) {
+ throw db.getLastError();
+ }
+ } );
+}
+
+doTest = function( signal ) {
+ // Test that certain operations fail in recovery mode
+
+ // Replica set testing API
+ // Create a new replica set test. Specify set name and the number of nodes you want.
+ var replTest = new ReplSetTest( {name: 'testSet', nodes: 3} );
+
+ // call startSet() to start each mongod in the replica set
+ // this returns a list of nodes
+ var nodes = replTest.startSet();
+
+ // Call initiate() to send the replSetInitiate command
+ // This will wait for initiation
+ replTest.initiate();
+
+ // Call getMaster to return a reference to the node that's been
+ // elected master.
+ var master = replTest.getMaster();
+
+ // save some records
+ var len = 100
+ for (var i = 0; i < len; ++i) {
+ master.getDB("foo").foo.save({a: i});
+ }
+
+ // This method will check the oplogs of the master
+ // and slaves in the set and wait until the change has replicated.
+ // replTest.awaitReplication();
+
+ slaves = replTest.liveNodes.slaves;
+ assert( slaves.length == 2, "Expected 2 slaves but length was " + slaves.length );
+
+ slaves.forEach(function(slave) {
+ // put slave into maintenance (recovery) mode
+ slave.getDB("foo").adminCommand({replSetMaintenance:1});
+
+ stats = slave.getDB("foo").adminCommand({replSetGetStatus:1});
+ assert.eq(stats.myState, 3, "Slave should be in recovering state.");
+
+ print("group should fail in recovering state...");
+ slave.slaveOk = true;
+ shouldFail( function() { slave.getDB("foo").foo.group({initial: {n:0}, reduce: function(obj,out){out.n++;}}); } );
+
+ print("count should fail in recovering state...");
+ slave.slaveOk = true;
+ shouldFail( function() { slave.getDB("foo").foo.count(); } );
+ });
+
+ // Shut down the set and finish the test.
+ replTest.stopSet( signal );
+}
+
+doTest( 15 );
+print("SUCCESS");
diff --git a/jstests/replsets/majority.js b/jstests/replsets/majority.js
index 5bb3cde33f0..a763dcc9641 100644
--- a/jstests/replsets/majority.js
+++ b/jstests/replsets/majority.js
@@ -1,3 +1,5 @@
+if (!_isWindows()) {
+
var testInsert = function() {
master.getDB("foo").bar.insert({x:1});
var result = master.getDB("foo").runCommand({getLastError:1, w:"majority", wtimeout:timeout});
@@ -8,7 +10,7 @@ var testInsert = function() {
var num = 7;
var host = getHostName();
var name = "tags";
-var timeout = 10000;
+var timeout = 60000;
var replTest = new ReplSetTest( {name: name, nodes: num, startPort:31000} );
var nodes = replTest.startSet();
@@ -94,3 +96,5 @@ master = replTest.getMaster();
print("make sure majority works");
assert.eq(testInsert().err, null);
+replTest.stopSet();
+} \ No newline at end of file
diff --git a/jstests/replsets/reconfig.js b/jstests/replsets/reconfig.js
index 7d43720b5ad..aba5c5b6519 100644
--- a/jstests/replsets/reconfig.js
+++ b/jstests/replsets/reconfig.js
@@ -11,13 +11,21 @@ print("initial sync");
master.getDB("foo").bar.insert({X:1});
replTest.awaitReplication();
+print("invalid reconfig");
+var config = master.getDB("local").system.replset.findOne();
+config.version++;
+config.members.push({_id : 5, host : "localhost:12345, votes:0"});
+var result = master.adminCommand({replSetReconfig : config});
+printjson(result);
+assert.eq(result.ok, 0);
+
print("stopping 3 & 4");
replTest.stop(3);
replTest.stop(4);
print("reconfiguring");
master = replTest.getMaster();
-var config = master.getDB("local").system.replset.findOne();
+config = master.getDB("local").system.replset.findOne();
var oldVersion = config.version++;
config.members[0].votes = 2;
config.members[3].votes = 2;
@@ -28,8 +36,16 @@ catch(e) {
print(e);
}
-var config = master.getDB("local").system.replset.findOne();
-assert.eq(oldVersion+1, config.version);
+assert.soon(function() {
+ try {
+ var config = master.getDB("local").system.replset.findOne();
+ return oldVersion+1 == config.version;
+ }
+ catch (e) {
+ print("Query failed: "+e);
+ return false;
+ }
+});
print("0 & 3 up; 1, 2, 4 down");
diff --git a/jstests/replsets/reindex_secondary.js b/jstests/replsets/reindex_secondary.js
new file mode 100644
index 00000000000..d0fd5d71123
--- /dev/null
+++ b/jstests/replsets/reindex_secondary.js
@@ -0,0 +1,34 @@
+var replTest = new ReplSetTest( {name: 'reindexTest', nodes: 2} );
+
+var nodes = replTest.startSet();
+
+replTest.initiate();
+
+var master = replTest.getMaster();
+replTest.awaitSecondaryNodes()
+
+var slaves = replTest.liveNodes.slaves;
+assert( slaves.length == 1, "Expected 1 slave but length was " + slaves.length );
+slave = slaves[0];
+
+db = master.getDB("reindexTest");
+slaveDb = slave.getDB("reindexTest");
+
+// Setup index
+db.foo.insert({a:1000});
+
+db.foo.ensureIndex({a:1});
+
+replTest.awaitReplication();
+
+assert.eq(2, db.system.indexes.count(), "Master didn't have proper indexes before reindex");
+assert.eq(2, slaveDb.system.indexes.count(), "Slave didn't have proper indexes before reindex");
+
+
+// Try to reindex secondary
+slaveDb.foo.reIndex();
+
+assert.eq(2, db.system.indexes.count(), "Master didn't have proper indexes after reindex");
+assert.eq(2, slaveDb.system.indexes.count(), "Slave didn't have proper indexes after reindex");
+
+replTest.stopSet(15); \ No newline at end of file
diff --git a/jstests/replsets/remove1.js b/jstests/replsets/remove1.js
index f93fe9eb071..a1bbc75b99d 100644
--- a/jstests/replsets/remove1.js
+++ b/jstests/replsets/remove1.js
@@ -1,53 +1,54 @@
/* test removing a node from a replica set
*
- * Start set with three nodes
+ * Start set with two nodes
* Initial sync
- * Remove slave1
- * Remove slave2
- * Bring slave1 back up
- * Bring slave2 back up
- * Add them back as slave
- * Make sure everyone's secondary
+ * Remove secondary
+ * Bring secondary back up
+ * Add it back as secondary
+ * Make sure both nodes are either primary or secondary
*/
load("jstests/replsets/rslib.js");
var name = "removeNodes";
var host = getHostName();
-
-print("Start set with three nodes");
+print("Start set with two nodes");
var replTest = new ReplSetTest( {name: name, nodes: 2} );
var nodes = replTest.startSet();
replTest.initiate();
var master = replTest.getMaster();
-
print("Initial sync");
master.getDB("foo").bar.baz.insert({x:1});
replTest.awaitReplication();
-
-print("Remove slaves");
+print("Remove secondary");
var config = replTest.getReplSetConfig();
config.members.pop();
config.version = 2;
+
+assert.eq(replTest.nodes[1].getDB("admin").runCommand({ping:1}).ok, 1, "we are connected to node[1]");
+
+try {
+ master.getDB("admin").runCommand({replSetReconfig:config});
+}
+catch(e) {
+ print(e);
+}
+
+assert.throws(replTest.nodes[1].getDB("admin").runCommand({ping:1}).ok, 1, "we are not connected to node[1]");
+assert.eq(replTest.nodes[1].getDB("admin").runCommand({ping:1}).ok, 1, "we are connected to node[1]");
+
+reconnect(master);
+
assert.soon(function() {
- try {
- master.getDB("admin").runCommand({replSetReconfig:config});
- }
- catch(e) {
- print(e);
- }
-
- reconnect(master);
- reconnect(replTest.nodes[1]);
var c = master.getDB("local").system.replset.findOne();
return c.version == 2;
- });
+});
-print("Add it back as a slave");
+print("Add it back as a secondary");
config.members.push({_id:1, host : host+":"+replTest.getPort(1)});
config.version = 3;
printjson(config);
@@ -67,8 +68,7 @@ wait(function() {
return newConfig.version == 3;
} , "wait1" );
-
-print("Make sure everyone's secondary");
+print("Make sure both nodes are either primary or secondary");
wait(function() {
var status = master.getDB("admin").runCommand({replSetGetStatus:1});
occasionally(function() {
@@ -87,7 +87,6 @@ wait(function() {
return true;
} , "wait2" );
-
print("reconfig with minority");
replTest.stop(1);
@@ -98,7 +97,7 @@ assert.soon(function() {
catch(e) {
print("trying to get master: "+e);
}
-});
+},"waiting for primary to step down",(60*1000),1000);
config.version = 4;
config.members.pop();
@@ -112,11 +111,10 @@ catch(e) {
reconnect(master);
assert.soon(function() {
return master.getDB("admin").runCommand({isMaster : 1}).ismaster;
-});
+},"waiting for old primary to accept reconfig and step up",(60*1000),1000);
config = master.getDB("local").system.replset.findOne();
printjson(config);
assert(config.version > 4);
replTest.stopSet();
-
diff --git a/jstests/replsets/replset1.js b/jstests/replsets/replset1.js
index 6387c5d8624..4b48f980cef 100644
--- a/jstests/replsets/replset1.js
+++ b/jstests/replsets/replset1.js
@@ -1,3 +1,5 @@
+load("jstests/replsets/rslib.js")
+
doTest = function( signal ) {
// Test basic replica set functionality.
@@ -43,7 +45,7 @@ doTest = function( signal ) {
var temp = replTest.getURL();
temp = temp.substring( 0 , temp.lastIndexOf( "," ) );
temp = new Mongo( temp ).getDB( "foo" );
- assert.eq( 1000 , temp.foo.findOne().a , "cppconn 1" );
+ assert.eq( 1000 , temp.foo.findOne().a , "cppconn 1" );
}
@@ -59,16 +61,8 @@ doTest = function( signal ) {
assert( master_id != new_master_id, "Old master shouldn't be equal to new master." );
- {
- // this may fail since it has to reconnect
- try {
- cppconn.foo.findOne()
- }
- catch ( e ){
- }
- assert.eq( 1000 , cppconn.foo.findOne().a , "cppconn 2" );
-
- }
+ reconnect(cppconn);
+ assert.eq( 1000 , cppconn.foo.findOne().a , "cppconn 2" );
// Now let's write some documents to the new master
for(var i=0; i<1000; i++) {
@@ -121,7 +115,11 @@ doTest = function( signal ) {
t.save({a: 1000});
t.ensureIndex( { a : 1 } )
- db.getLastError( 3 , 30000 )
+ result = db.runCommand({getLastError : 1, w: 3 , wtimeout :30000 })
+ printjson(result);
+ lastOp = result.lastOp;
+ lastOplogOp = master.getDB("local").oplog.rs.find().sort({$natural : -1}).limit(1).next();
+ assert.eq(lastOplogOp['ts'], lastOp);
ts.forEach( function(z){ assert.eq( 2 , z.getIndexKeys().length , "A " + z.getMongo() ); } )
@@ -134,5 +132,5 @@ doTest = function( signal ) {
replTest.stopSet( signal );
}
-doTest( 15 );
-print("replset1.js SUCCESS");
+doTest( 15 );
+print("replset1.js SUCCESS");
diff --git a/jstests/replsets/replset2.js b/jstests/replsets/replset2.js
index 484962036ef..9588567ea50 100644
--- a/jstests/replsets/replset2.js
+++ b/jstests/replsets/replset2.js
@@ -1,4 +1,4 @@
-print("\n\nreplset2.js BEGIN");
+load("jstests/replsets/rslib.js");
doTest = function (signal) {
@@ -28,8 +28,8 @@ doTest = function (signal) {
// Wait for replication to a single node
master.getDB(testDB).bar.insert({ n: 1 });
- // Wait for initial sync
- replTest.awaitReplication();
+ // Wait for states to become PRI,SEC,SEC
+ waitForAllMembers(master.getDB(testDB));
var slaves = replTest.liveNodes.slaves;
slaves.forEach(function (slave) { slave.setSlaveOk(); });
diff --git a/jstests/replsets/replset4.js b/jstests/replsets/replset4.js
index 9b1f2e9e1f9..2b06567cfff 100644
--- a/jstests/replsets/replset4.js
+++ b/jstests/replsets/replset4.js
@@ -1,44 +1,44 @@
-doTest = function (signal) {
-
- // Test orphaned master steps down
- var replTest = new ReplSetTest({ name: 'testSet', nodes: 3 });
-
- replTest.startSet();
- replTest.initiate();
-
- var master = replTest.getMaster();
-
- // Kill both slaves, simulating a network partition
- var slaves = replTest.liveNodes.slaves;
- for (var i = 0; i < slaves.length; i++) {
- var slave_id = replTest.getNodeId(slaves[i]);
- replTest.stop(slave_id);
- }
-
- print("replset4.js 1");
-
- var result = master.getDB("admin").runCommand({ ismaster: 1 });
-
- print("replset4.js 2");
- printjson(result);
-
- assert.soon(
- function () {
- try {
- var result = master.getDB("admin").runCommand({ ismaster: 1 });
- return (result['ok'] == 1 && result['ismaster'] == false);
- } catch (e) {
- print("replset4.js caught " + e);
- return false;
- }
- },
- "Master fails to step down when orphaned."
- );
-
- print("replset4.js worked, stopping");
- replTest.stopSet(signal);
-}
-
+doTest = function (signal) {
+
+ // Test orphaned master steps down
+ var replTest = new ReplSetTest({ name: 'testSet', nodes: 3 });
+
+ replTest.startSet();
+ replTest.initiate();
+
+ var master = replTest.getMaster();
+
+ // Kill both slaves, simulating a network partition
+ var slaves = replTest.liveNodes.slaves;
+ for (var i = 0; i < slaves.length; i++) {
+ var slave_id = replTest.getNodeId(slaves[i]);
+ replTest.stop(slave_id);
+ }
+
+ print("replset4.js 1");
+
+ var result = master.getDB("admin").runCommand({ ismaster: 1 });
+
+ print("replset4.js 2");
+ printjson(result);
+
+ assert.soon(
+ function () {
+ try {
+ var result = master.getDB("admin").runCommand({ ismaster: 1 });
+ return (result['ok'] == 1 && result['ismaster'] == false);
+ } catch (e) {
+ print("replset4.js caught " + e);
+ return false;
+ }
+ },
+ "Master fails to step down when orphaned."
+ );
+
+ print("replset4.js worked, stopping");
+ replTest.stopSet(signal);
+}
+
print("replset4.js");
doTest( 15 );
print("replset4.js SUCCESS");
diff --git a/jstests/replsets/replset6.js b/jstests/replsets/replset6.js
new file mode 100644
index 00000000000..f9111e28dbd
--- /dev/null
+++ b/jstests/replsets/replset6.js
@@ -0,0 +1,52 @@
+
+// Test replication of collection renaming
+
+baseName = "jstests_replsets_replset6";
+
+var rt = new ReplSetTest({ name : "replset6tests" , nodes: 2 });
+var nodes = rt.startSet();
+rt.initiate();
+var m = rt.getMaster();
+rt.awaitSecondaryNodes();
+var slaves = rt.liveNodes.slaves;
+s = slaves[0];
+s.setSlaveOk();
+admin = m.getDB( "admin" );
+
+debug = function( foo ) {} // print( foo ); }
+
+// rename within db
+
+m.getDB( baseName ).one.save( { a: 1 } );
+assert.soon( function() { v = s.getDB( baseName ).one.findOne(); return v && 1 == v.a } );
+
+assert.commandWorked( admin.runCommand( {renameCollection:"jstests_replsets_replset6.one", to:"jstests_replsets_replset6.two"} ) );
+assert.soon( function() {
+ if ( -1 == s.getDB( baseName ).getCollectionNames().indexOf( "two" ) ) {
+ debug( "no two coll" );
+ debug( tojson( s.getDB( baseName ).getCollectionNames() ) );
+ return false;
+ }
+ if ( !s.getDB( baseName ).two.findOne() ) {
+ debug( "no two object" );
+ return false;
+ }
+ return 1 == s.getDB( baseName ).two.findOne().a; });
+assert.eq( -1, s.getDB( baseName ).getCollectionNames().indexOf( "one" ) );
+
+// rename to new db
+
+first = baseName + "_first";
+second = baseName + "_second";
+
+m.getDB( first ).one.save( { a: 1 } );
+assert.soon( function() { return s.getDB( first ).one.findOne() && 1 == s.getDB( first ).one.findOne().a; } );
+
+assert.commandWorked( admin.runCommand( {renameCollection:"jstests_replsets_replset6_first.one", to:"jstests_replsets_replset6_second.two"} ) );
+assert.soon( function() {
+ return -1 != s.getDBNames().indexOf( second ) &&
+ -1 != s.getDB( second ).getCollectionNames().indexOf( "two" ) &&
+ s.getDB( second ).two.findOne() &&
+ 1 == s.getDB( second ).two.findOne().a; } );
+assert.eq( -1, s.getDB( first ).getCollectionNames().indexOf( "one" ) );
+
diff --git a/jstests/replsets/replset7.js b/jstests/replsets/replset7.js
index f29c1fbb953..0c4cbe2b841 100644
--- a/jstests/replsets/replset7.js
+++ b/jstests/replsets/replset7.js
@@ -11,7 +11,7 @@ var md = master.getDB( 'd' );
var mdc = md[ 'c' ];
// prep the data
-var doccount = 100000;
+var doccount = 50000;
for( i = 0; i < doccount; ++i ) {
mdc.insert( { _id:i, x:i } );
}
diff --git a/jstests/replsets/replset8.js b/jstests/replsets/replset8.js
new file mode 100644
index 00000000000..cc900195cde
--- /dev/null
+++ b/jstests/replsets/replset8.js
@@ -0,0 +1,61 @@
+
+// test for SERVER-6303 - if documents move backward during an initial sync.
+
+var rt = new ReplSetTest( { name : "replset8tests" , nodes: 1 } );
+
+var nodes = rt.startSet();
+rt.initiate();
+var master = rt.getMaster();
+var bigstring = "a";
+var md = master.getDB( 'd' );
+var mdc = md[ 'c' ];
+
+// prep the data
+
+// idea: create x documents of increasing size, then create x documents of size n.
+// delete first x documents. start initial sync (cloner). update all remaining
+// documents to be increasing size.
+// this should result in the updates moving the docs backwards.
+
+var doccount = 10000;
+// Avoid empty extent issues
+mdc.insert( { _id:-1, x:"dummy" } );
+
+print ("inserting bigstrings");
+for( i = 0; i < doccount; ++i ) {
+ mdc.insert( { _id:i, x:bigstring } );
+ bigstring += "a";
+}
+md.getLastError();
+
+print ("inserting x");
+for( i = doccount; i < doccount*2; ++i ) {
+ mdc.insert( { _id:i, x:i } );
+}
+md.getLastError();
+
+print ("deleting bigstrings");
+for( i = 0; i < doccount; ++i ) {
+ mdc.remove( { _id:i } );
+}
+md.getLastError();
+
+// add a secondary
+var slave = rt.add();
+rt.reInitiate();
+print ("initiation complete!");
+var sc = slave.getDB( 'd' )[ 'c' ];
+slave.setSlaveOk();
+sleep(25000);
+print ("updating documents backwards");
+// Move all documents to the beginning by growing them to sizes that should
+// fit the holes we made in phase 1
+for (i = doccount*2; i > doccount; --i) {
+ mdc.update( { _id:i, x:i }, { _id:i, x:bigstring } );
+ md.getLastError();
+ bigstring = bigstring.slice(0, -1); // remove last char
+}
+print ("finished");
+// Wait for replication to catch up.
+rt.awaitSecondaryNodes();
+assert.eq(doccount+1, slave.getDB( 'd' )['c'].count());
diff --git a/jstests/replsets/replsetadd.js b/jstests/replsets/replsetadd.js
index 44ef7c61fdf..711a173931b 100644
--- a/jstests/replsets/replsetadd.js
+++ b/jstests/replsets/replsetadd.js
@@ -22,7 +22,9 @@ doTest = function( signal ) {
return result['ok'] == 1;
});
- replTest.getMaster();
+ db = replTest.getMaster().getDB( "test");
+ db.foo.insert( { x : 1} );
+ db.foo.ensureIndex( { x : 1 } );
// Start a second node
var second = replTest.add();
@@ -50,8 +52,16 @@ doTest = function( signal ) {
print("trying reconfig that shouldn't work");
var result = master.getDB("admin").runCommand({replSetReconfig: config});
- assert.eq(result.ok, 0);
- assert.eq(result.assertionCode, 13645);
+ assert.eq(result.ok, 0, tojson(result));
+ assert.eq(result.code, 13645, tojson(result));
+
+ replTest.awaitReplication();
+
+ hashes = replTest.getHashes( "test" );
+ printjson( hashes );
+ for ( i=0; i<hashes.slaves.length; i++ ) {
+ assert.eq( hashes.master.collections.foo , hashes.slaves[i].collections.foo );
+ }
replTest.stopSet( signal );
}
diff --git a/jstests/replsets/replsetfreeze.js b/jstests/replsets/replsetfreeze.js
index 70963497a0d..03e9f724f8a 100644
--- a/jstests/replsets/replsetfreeze.js
+++ b/jstests/replsets/replsetfreeze.js
@@ -49,7 +49,9 @@ var config = {"_id" : "unicomplex", "members" : [
{"_id" : 2, "host" : nodes[2], "arbiterOnly" : true}]};
var r = replTest.initiate(config);
var master = replTest.getMaster();
+var secondary = replTest.getSecondary();
+replTest.awaitSecondaryNodes();
print("2: step down m1");
try {
@@ -59,14 +61,16 @@ catch(e) {
print(e);
}
reconnect(master);
+printjson( master.getDB("admin").runCommand({replSetGetStatus: 1}) );
print("3: freeze set for 30 seconds");
+secondary.getDB("admin").runCommand({replSetFreeze : 30});
master.getDB("admin").runCommand({replSetFreeze : 30});
print("4: check no one is master for 30 seconds");
var start = (new Date()).getTime();
-while ((new Date()).getTime() - start < 30000) {
+while ((new Date()).getTime() - start < (28 * 1000) ) { // we need less 30 since it takes some time to return... hacky
var result = master.getDB("admin").runCommand({isMaster:1});
assert.eq(result.ismaster, false);
assert.eq(result.primary, undefined);
diff --git a/jstests/replsets/replsethostnametrim.js b/jstests/replsets/replsethostnametrim.js
new file mode 100644
index 00000000000..44f4c7b2320
--- /dev/null
+++ b/jstests/replsets/replsethostnametrim.js
@@ -0,0 +1,21 @@
+// try reconfiguring with space at the end of the host:port
+
+var replTest = new ReplSetTest({ name: 'testSet', nodes: 1 });
+var nodes = replTest.startSet();
+replTest.initiate();
+
+var master = replTest.getMaster();
+var config = master.getDB("local").system.replset.findOne();
+config.version++;
+var origHost = config.members[0].host;
+config.members[0].host = origHost + " ";
+var result = master.adminCommand({replSetReconfig : config});
+assert.eq(result.ok, 1, tojson(result));
+//print("current (bad) config:"); printjson(config);
+
+//check new config to make sure it doesn't have a space in the hostname
+config = master.getDB("local").system.replset.findOne();
+assert.eq(origHost, config.members[0].host);
+//print("current (good) config:"); printjson(config);
+
+replTest.stopSet(); \ No newline at end of file
diff --git a/jstests/replsets/replsetprio1.js b/jstests/replsets/replsetprio1.js
index aeeb7494a0b..218bbc04314 100644
--- a/jstests/replsets/replsetprio1.js
+++ b/jstests/replsets/replsetprio1.js
@@ -47,7 +47,7 @@ doTest = function( signal ) {
print(e);
}
return false;
- }, 'node 2 is master again');
+ }, 'node 2 is master again', 60000);
// make sure nothing was rolled back
master = replTest.getMaster();
diff --git a/jstests/replsets/replsetrestart1.js b/jstests/replsets/replsetrestart1.js
index d9f5093783d..212bf783e1d 100644
--- a/jstests/replsets/replsetrestart1.js
+++ b/jstests/replsets/replsetrestart1.js
@@ -52,18 +52,18 @@ doTest = function( signal ) {
assert.soon(function() {
stat = master.getDB("admin").runCommand({replSetGetStatus: 1});
return stat.myState == 1;
- });
+ }, "checking master", 3 * 60 * 1000, 1000 );
// Slaves to be set to 2 (secondary)
assert.soon(function() {
stat = slaves[0].getDB("admin").runCommand({replSetGetStatus: 1});
return stat.myState == 2;
- });
+ }, "checking slave 0", 3 * 60 * 1000, 1000 );
assert.soon(function() {
stat = slaves[1].getDB("admin").runCommand({replSetGetStatus: 1});
return stat.myState == 2;
- });
+ }, "checking slave 1", 3 * 60 * 1000, 1000 );
}
doTest( 15 );
diff --git a/jstests/replsets/rollback.js b/jstests/replsets/rollback.js
index 6370e4173c6..7ec3810fbdc 100644
--- a/jstests/replsets/rollback.js
+++ b/jstests/replsets/rollback.js
@@ -1,12 +1,24 @@
// test rollback in replica sets
// try running as :
-//
+//
// mongo --nodb rollback.js | tee out | grep -v ^m31
//
var debugging = 0;
+function ifReady(db, f) {
+ var stats = db.adminCommand({ replSetGetStatus: 1 });
+
+
+ // only eval if state isn't recovery
+ if (stats && stats.myState != 3) {
+ return f();
+ }
+
+ return false;
+}
+
function pause(s) {
print(s);
while (debugging) {
@@ -15,10 +27,10 @@ function pause(s) {
}
}
-function deb(obj) {
+function deb(obj) {
if( debugging ) {
print("\n\n\n" + obj + "\n\n");
- }
+ }
}
w = 0;
@@ -105,7 +117,7 @@ doTest = function (signal) {
assert(a.bar.count() == 3, "t.count");
// wait for secondary to get this data
- wait(function () { return b.bar.count() == 3; });
+ wait(function () { return ifReady(b, function() { return b.bar.count() == 3 }); });
A.runCommand({ replSetTest: 1, blind: true });
reconnect(a,b);
@@ -126,7 +138,7 @@ doTest = function (signal) {
print("*************** B ****************");
wait(function () { try { return !B.isMaster().ismaster; } catch(e) { return false; } });
print("*************** A ****************");
- reconnect(a,b);
+ reconnect(a,b);
wait(function () {
try {
return A.isMaster().ismaster;
@@ -151,17 +163,22 @@ doTest = function (signal) {
// A is 1 2 3 7 8
// B is 1 2 3 4 5 6
- // bring B back online
+ // bring B back online
B.runCommand({ replSetTest: 1, blind: false });
reconnect(a,b);
- wait(function () { return B.isMaster().ismaster || B.isMaster().secondary; });
+ assert.soon(function() {
+ return (A.isMaster().ismaster || A.isMaster().secondary) &&
+ (B.isMaster().ismaster || B.isMaster().secondary);
+ });
- // everyone is up here...
- assert(A.isMaster().ismaster || A.isMaster().secondary, "A up");
- assert(B.isMaster().ismaster || B.isMaster().secondary, "B up");
replTest.awaitReplication();
+ assert.soon(function() {
+ return (A.isMaster().ismaster || A.isMaster().secondary) &&
+ (B.isMaster().ismaster || B.isMaster().secondary);
+ });
+
friendlyEqual(a.bar.find().sort({ _id: 1 }).toArray(), b.bar.find().sort({ _id: 1 }).toArray(), "server data sets do not match");
pause("rollback.js SUCCESS");
@@ -170,7 +187,7 @@ doTest = function (signal) {
var reconnect = function(a,b) {
- wait(function() {
+ wait(function() {
try {
a.bar.stats();
b.bar.stats();
diff --git a/jstests/replsets/rollback2.js b/jstests/replsets/rollback2.js
index 7ab3c6bf4ee..d80e7b7349e 100644
--- a/jstests/replsets/rollback2.js
+++ b/jstests/replsets/rollback2.js
@@ -7,6 +7,18 @@
var debugging = 0;
+function ifReady(db, f) {
+ var stats = db.adminCommand({ replSetGetStatus: 1 });
+
+
+ // only eval if state isn't recovery
+ if (stats && stats.myState != 3) {
+ return f();
+ }
+
+ return false;
+}
+
function pause(s) {
print(s);
while (debugging) {
@@ -165,7 +177,7 @@ doTest = function (signal) {
doInitialWrites(a);
// wait for secondary to get this data
- wait(function () { return b.bar.count() == a.bar.count(); });
+ wait(function () { return ifReady(a, function() { return ifReady(b, function() { return b.bar.count() == a.bar.count(); }); }); });
wait(function () {
var status = A.runCommand({replSetGetStatus : 1});
return status.members[1].state == 2;
diff --git a/jstests/replsets/rollback3.js b/jstests/replsets/rollback3.js
index fa923d87a46..188394a1263 100755
--- a/jstests/replsets/rollback3.js
+++ b/jstests/replsets/rollback3.js
@@ -4,9 +4,22 @@
//
// mongo --nodb rollback.js | tee out | grep -v ^m31
//
+load("jstests/replsets/rslib.js");
var debugging = 0;
+function ifReady(db, f) {
+ var stats = db.adminCommand({ replSetGetStatus: 1 });
+
+
+ // only eval if state isn't recovery
+ if (stats && stats.myState != 3) {
+ return f();
+ }
+
+ return false;
+}
+
function pause(s) {
print(s);
while (debugging) {
@@ -185,7 +198,7 @@ doTest = function (signal) {
doInitialWrites(a);
// wait for secondary to get this data
- wait(function () { return b.bar.count() == a.bar.count(); });
+ wait(function () { return ifReady(a, function() { return ifReady(b, function() { return b.bar.count() == a.bar.count(); }); }); });
A.runCommand({ replSetTest: 1, blind: true });
reconnect(a,b);
@@ -220,7 +233,9 @@ doTest = function (signal) {
assert(A.isMaster().ismaster || A.isMaster().secondary, "A up");
assert(B.isMaster().ismaster || B.isMaster().secondary, "B up");
replTest.awaitReplication();
-
+
+ assert.soon(function() { return B.isMaster().secondary; });
+
assert( dbs_match(a,b), "server data sets do not match after rollback, something is wrong");
pause("rollback3.js SUCCESS");
diff --git a/jstests/replsets/rollback4.js b/jstests/replsets/rollback4.js
index 5d3299b130b..2fc1386a66f 100644
--- a/jstests/replsets/rollback4.js
+++ b/jstests/replsets/rollback4.js
@@ -97,7 +97,18 @@ replTest.unPartition(2,5)
replTest.unPartition(2,6)
printjson({endUnPartition: new Date()});
-printjson(master2.adminCommand({getLastError:1, w:7, wtimeout:30*1000}));
+assert.soon(function() {
+ try {
+ printjson(master2.adminCommand({getLastError:1, w:7, wtimeout:30*1000}));
+ return true;
+ }
+ catch (e) {
+ print("getLastError returned an exception; retrying");
+ print(e);
+ return false;
+ }
+});
+
printjson(master2.adminCommand("replSetGetStatus"));
assert.soon(function() {return master.adminCommand('isMaster').ismaster},
@@ -114,4 +125,3 @@ replTest.stopSet();
}
-
diff --git a/jstests/replsets/rslib.js b/jstests/replsets/rslib.js
index 19271c9e13d..562f6e8c4ed 100644
--- a/jstests/replsets/rslib.js
+++ b/jstests/replsets/rslib.js
@@ -38,10 +38,14 @@ var reconnect = function(a) {
try {
// make this work with either dbs or connections
if (typeof(a.getDB) == "function") {
- a.getDB("foo").bar.stats();
+ db = a.getDB('foo');
}
else {
- a.bar.stats();
+ db = a;
+ }
+ db.bar.stats();
+ if (jsTest.options().keyFile) { // SERVER-4241: Shell connections don't re-authenticate on reconnect
+ return jsTest.authenticate(db.getMongo());
}
return true;
} catch(e) {
@@ -63,26 +67,36 @@ var getLatestOp = function(server) {
};
-var waitForAllMembers = function(master) {
- var ready = false;
- var count = 0;
-
- outer:
- while (count < 60) {
- count++;
- var state = master.getSisterDB("admin").runCommand({replSetGetStatus:1});
- occasionally(function() { printjson(state); }, 10);
+var waitForAllMembers = function(master, timeout) {
+ var failCount = 0;
- for (var m in state.members) {
- if (state.members[m].state != 2 && state.members[m].state != 1) {
- sleep(1000);
- continue outer;
- }
- }
- return;
- }
+ assert.soon( function() {
+ var state = null
+ try {
+ state = master.getSisterDB("admin").runCommand({replSetGetStatus:1});
+ failCount = 0;
+ } catch ( e ) {
+ // Connection can get reset on replica set failover causing a socket exception
+ print( "Calling replSetGetStatus failed" );
+ printjson( e );
+ failCount++;
+ assert.lt( failCount, 3, "replSetGetStatus failed 3 times in a row" );
+ return false;
+ }
+ occasionally(function() { printjson(state); }, 10);
+
+ for (var m in state.members) {
+ if (state.members[m].state != 1 && // PRIMARY
+ state.members[m].state != 2 && // SECONDARY
+ state.members[m].state != 7) { // ARBITER
+ return false;
+ }
+ }
+ printjson( state );
+ return true;
+ }, "not all members ready", timeout || 60000);
- assert(false, "all members not ready");
+ print( "All members are now in state PRIMARY, SECONDARY, or ARBITER" );
};
var reconfig = function(rs, config) {
diff --git a/jstests/replsets/slaveDelay2.js b/jstests/replsets/slaveDelay2.js
index 2d9dd1ff15b..3ef968f3a53 100644
--- a/jstests/replsets/slaveDelay2.js
+++ b/jstests/replsets/slaveDelay2.js
@@ -1,27 +1,8 @@
+load("jstests/replsets/rslib.js");
var name = "slaveDelay2";
var host = getHostName();
-var waitForAllMembers = function(master) {
- var ready = false;
-
- outer:
- while (true) {
- var state = master.getSisterDB("admin").runCommand({replSetGetStatus:1});
-
- for (var m in state.members) {
- if (state.members[m].state != 2 && state.members[m].state != 1) {
- sleep(10000);
- continue outer;
- }
- }
-
- printjson(state);
- print("okay, everyone is primary or secondary");
- return;
- }
-};
-
var initialize = function() {
var replTest = new ReplSetTest( {name: name, nodes: 1} );
@@ -57,7 +38,8 @@ doTest = function( signal ) {
* initializing. Make sure it syncs all of these writes before going into
* syncDelay.
*/
- var conn = startMongodTest(31008, name + "-sd", 0, { useHostname: true, replSet: name });
+ var conn = MongoRunner.runMongod({port : 31008, dbpath : name + "-sd", useHostname: true,
+ replSet: name, oplogSize : 128});
conn.setSlaveOk();
config = master.getSisterDB("local").system.replset.findOne();
@@ -67,7 +49,7 @@ doTest = function( signal ) {
assert.eq(ok.ok,1);
// do inserts during initial sync
- count = 0;
+ var count = 0;
while (count < 10) {
for (var i = 100*count; i<100*(count+1); i++) {
master.foo.insert({x:i});
@@ -91,7 +73,7 @@ doTest = function( signal ) {
}
// wait a bit for the syncs to be applied
- waitForAllMembers(master);
+ waitForAllMembers(master);
for (var i=0; i<(100*count); i++) {
var obj = conn.getDB(name).foo.findOne({x : i});
diff --git a/jstests/replsets/slavedelay1.js b/jstests/replsets/slavedelay1.js
index 9301c8ebb8a..13c6adfcdf3 100644
--- a/jstests/replsets/slavedelay1.js
+++ b/jstests/replsets/slavedelay1.js
@@ -4,7 +4,7 @@ doTest = function( signal ) {
var name = "slaveDelay";
var host = getHostName();
-
+
var replTest = new ReplSetTest( {name: name, nodes: 3} );
var nodes = replTest.startSet();
@@ -13,7 +13,7 @@ doTest = function( signal ) {
var config = replTest.getReplSetConfig();
config.members[2].priority = 0;
config.members[2].slaveDelay = 10;
-
+
replTest.initiate(config);
var master = replTest.getMaster().getDB(name);
@@ -26,14 +26,14 @@ doTest = function( signal ) {
}
waitForAllMembers(master);
-
+
// insert a record
master.foo.insert({x:1});
master.runCommand({getlasterror:1, w:2});
-
+
var doc = master.foo.findOne();
assert.eq(doc.x, 1);
-
+
// make sure slave has it
var doc = slave[0].foo.findOne();
assert.eq(doc.x, 1);
@@ -45,18 +45,18 @@ doTest = function( signal ) {
assert.eq(slave[1].foo.findOne(), null);
sleep(1000);
}
-
+
// now delayed slave should have it
assert.soon(function() {
var z = slave[1].foo.findOne();
return z && z.x == 1;
});
-
+
/************* Part 2 *******************/
// how about non-initial sync?
-
+
for (var i=0; i<100; i++) {
master.foo.insert({_id : i, "foo" : "bar"});
}
@@ -70,26 +70,26 @@ doTest = function( signal ) {
assert.eq(slave[1].foo.findOne({_id:99}), null);
sleep(1000);
}
-
+
assert.soon(function() {
var z = slave[1].foo.findOne({_id : 99});
return z && z.foo == "bar";
});
-
+
/************* Part 3 *******************/
// how about if we add a new server? will it sync correctly?
- var conn = startMongodTest( 31007 , name+"-part3" , 0 , {useHostname : true, replSet : name} );
-
+ conn = replTest.add();
+
config = master.getSisterDB("local").system.replset.findOne();
printjson(config);
config.version++;
- config.members.push({_id : 3, host : host+":31007",priority:0, slaveDelay:10});
+ config.members.push({_id : 3, host : host+":"+replTest.ports[replTest.ports.length-1],priority:0, slaveDelay:10});
master = reconfig(replTest, config);
master = master.getSisterDB(name);
-
+
// it should be all caught up now
master.foo.insert({_id : 123, "x" : "foo"});
@@ -101,39 +101,43 @@ doTest = function( signal ) {
assert.eq(conn.getDB(name).foo.findOne({_id:123}), null);
sleep(1000);
}
-
+
assert.soon(function() {
var z = conn.getDB(name).foo.findOne({_id:123});
return z != null && z.x == "foo"
- });
-
+ });
+
/************* Part 4 ******************/
-
+
print("reconfigure slavedelay");
-
+
config.version++;
config.members[3].slaveDelay = 15;
- master = reconfig(replTest, config);
- master = master.getSisterDB(name);
+ reconfig(replTest, config);
+ master = replTest.getMaster().getDB(name);
assert.soon(function() {
return conn.getDB("local").system.replset.findOne().version == config.version;
});
-
+
+ assert.soon(function() {
+ var result = conn.getDB("admin").isMaster();
+ printjson(result);
+ return result.secondary;
+ });
+
+ print("testing insert");
master.foo.insert({_id : 124, "x" : "foo"});
-
+ assert(master.foo.findOne({_id:124}) != null);
+
for (var i=0; i<13; i++) {
assert.eq(conn.getDB(name).foo.findOne({_id:124}), null);
sleep(1000);
}
-
- assert.soon(function() {
- var z = conn.getDB(name).foo.findOne({_id:124});
- return z != null && z.x == "foo"
- });
-
-
- replTest.stopSet();
+
+ replTest.awaitReplication();
+
+ replTest.stopSet();
}
doTest(15);
diff --git a/jstests/replsets/stale_clustered.js b/jstests/replsets/stale_clustered.js
index 457231eb838..916a0647750 100644
--- a/jstests/replsets/stale_clustered.js
+++ b/jstests/replsets/stale_clustered.js
@@ -79,7 +79,7 @@ prt("6: stop non-overflowed secondary")
rsA.stop( goodSec, undefined, true )
-prt("7: check our regular and slaveok query")
+prt("7: check our regular and slaveOk query")
assert.eq( coll.find().itcount(), collSOk.find().itcount() )
@@ -91,7 +91,7 @@ prt("9: wait for recovery")
rsA.waitForState( rsA.getSecondaries(), rsA.SECONDARY, 5 * 60 * 1000 )
-prt("10: check our regular and slaveok query")
+prt("10: check our regular and slaveOk query")
assert.eq( coll.find().itcount(), collSOk.find().itcount() )
diff --git a/jstests/replsets/stepdown.js b/jstests/replsets/stepdown.js
index 67f10f9bcfd..f21772785ea 100644
--- a/jstests/replsets/stepdown.js
+++ b/jstests/replsets/stepdown.js
@@ -108,13 +108,26 @@ catch (e) {
print(e);
}
-print("\nsleeping");
-sleep(2000);
+master = replTest.getMaster();
+assert.soon(function() {
+ var result = master.getDB("admin").runCommand({replSetGetStatus:1});
+ for (var i in result.members) {
+ if (result.members[i].self) {
+ continue;
+ }
+
+ return result.members[i].health == 0;
+ }
+
+}, 'make sure master knows that slave is down before proceeding');
+
print("\nrunning shutdown without force on master: "+master);
-result = replTest.getMaster().getDB("admin").runCommand({shutdown : 1, timeoutSecs : 3});
+// this should fail because the master can't reach an up-to-date secondary (because the only
+// secondary is down)
+result = master.getDB("admin").runCommand({shutdown : 1, timeoutSecs : 3});
assert.eq(result.ok, 0);
print("\nsend shutdown command");
diff --git a/jstests/replsets/sync2.js b/jstests/replsets/sync2.js
index 9f6c20550d0..eabd4b89ce1 100644
--- a/jstests/replsets/sync2.js
+++ b/jstests/replsets/sync2.js
@@ -46,3 +46,4 @@ replTest.awaitReplication();
result = master.getDB("admin").runCommand({getLastError:1,w:5,wtimeout:1000});
assert.eq(null, result.err, tojson(result));
+replTest.stopSet(); \ No newline at end of file
diff --git a/jstests/replsets/sync_passive2.js b/jstests/replsets/sync_passive2.js
index 230d71c65ad..63a1e58e63e 100644
--- a/jstests/replsets/sync_passive2.js
+++ b/jstests/replsets/sync_passive2.js
@@ -19,6 +19,10 @@ var config = replTest.getReplSetConfig();
config.members[1].arbiterOnly = true;
for (i=2; i<config.members.length; i++) {
config.members[i].priority = 0;
+ if (i == 4) {
+ config.members[i].buildIndexes = false;
+ config.members[i].hidden = true;
+ }
}
replTest.initiate(config);
@@ -118,3 +122,64 @@ wait(function() {
friendlyEqual(status.members[3].optime, status.members[4].optime) &&
friendlyEqual(status.members[2].optime, status.members[4].optime);
});
+
+
+print("force sync from various members");
+master = replTest.getMaster();
+
+print("sync from self: error");
+var result = replTest.nodes[3].getDB("admin").runCommand({replSetSyncFrom: replTest.host+":"+replTest.ports[3]});
+printjson(result);
+assert.eq(result.ok, 0);
+assert.eq(result.errmsg, "I cannot sync from myself");
+
+print("sync from arbiter: error");
+result = replTest.nodes[3].getDB("admin").runCommand({replSetSyncFrom: replTest.host+":"+replTest.ports[1]});
+printjson(result);
+assert.eq(result.ok, 0);
+
+print("sync arbiter from someone: error");
+result = replTest.nodes[1].getDB("admin").runCommand({replSetSyncFrom: replTest.host+":"+replTest.ports[3]});
+printjson(result);
+assert.eq(result.ok, 0);
+
+print("sync from non-index-building member: error");
+result = replTest.nodes[3].getDB("admin").runCommand({replSetSyncFrom: replTest.host+":"+replTest.ports[4]});
+printjson(result)
+assert.eq(result.ok, 0);
+
+var checkSyncingFrom = function(node, target) {
+ var status = node.getDB("admin").runCommand({replSetGetStatus:1});
+ occasionally(function() {
+ printjson(status);
+ });
+ return status.syncingTo == target;
+}
+
+print("sync from primary");
+result = replTest.nodes[3].getDB("admin").runCommand({replSetSyncFrom: replTest.host+":"+replTest.ports[0]});
+printjson(result)
+assert.eq(result.ok, 1);
+assert.soon(function() {
+ return checkSyncingFrom(nodes[3], replTest.host+":"+replTest.ports[0])
+});
+
+print("sync from another passive");
+result = replTest.nodes[3].getDB("admin").runCommand({replSetSyncFrom: replTest.host+":"+replTest.ports[2]});
+printjson(result)
+assert.eq(result.ok, 1);
+assert.soon(function() {
+ return checkSyncingFrom(nodes[3], replTest.host+":"+replTest.ports[2])
+});
+
+/**
+ * Test forcing a primary to sync from another member
+ */
+
+print("sync a primary from another member: error");
+result = replTest.nodes[0].getDB("admin").runCommand({replSetSyncFrom: replTest.host+":"+replTest.ports[2]});
+printjson(result);
+assert.eq(result.ok, 0);
+assert.eq(result.errmsg, "primaries don't sync");
+
+replTest.stopSet();
diff --git a/jstests/replsets/tags.js b/jstests/replsets/tags.js
index 4e738862afe..f7e843848f3 100644
--- a/jstests/replsets/tags.js
+++ b/jstests/replsets/tags.js
@@ -1,3 +1,7 @@
+if (!_isWindows()) {
+function myprint( x ) {
+ print( "tags output: " + x );
+}
var num = 5;
var host = getHostName();
@@ -16,8 +20,8 @@ replTest.initiate({_id : name, members :
],
settings : {
getLastErrorModes : {
- "important" : {"dc" : 2, "server" : 3},
- "a machine" : {"server" : 1}
+ "2 dc and 3 server" : {"dc" : 2, "server" : 3},
+ "1 and 2" : {"server" : 1}
}
}});
@@ -28,54 +32,61 @@ var config = master.getDB("local").system.replset.findOne();
printjson(config);
var modes = config.settings.getLastErrorModes;
assert.eq(typeof modes, "object");
-assert.eq(modes.important.dc, 2);
-assert.eq(modes.important.server, 3);
-assert.eq(modes["a machine"]["server"], 1);
+assert.eq(modes["2 dc and 3 server"].dc, 2);
+assert.eq(modes["2 dc and 3 server"].server, 3);
+assert.eq(modes["1 and 2"]["server"], 1);
config.version++;
config.members[1].priority = 1.5;
config.members[2].priority = 2;
-modes.rack = {"sf" : 1};
-modes.niceRack = {"sf" : 2};
-modes["a machine"]["2"] = 1;
-modes.on2 = {"2" : 1}
+modes["3 or 4"] = {"sf" : 1};
+modes["3 and 4"] = {"sf" : 2};
+modes["1 and 2"]["2"] = 1;
+modes["2"] = {"2" : 1}
try {
master.getDB("admin").runCommand({replSetReconfig : config});
}
catch(e) {
- print(e);
+ myprint(e);
}
replTest.awaitReplication();
-print("primary should now be 2");
+myprint("primary should now be 2");
master = replTest.getMaster();
config = master.getDB("local").system.replset.findOne();
printjson(config);
modes = config.settings.getLastErrorModes;
assert.eq(typeof modes, "object");
-assert.eq(modes.important.dc, 2);
-assert.eq(modes.important.server, 3);
-assert.eq(modes["a machine"]["server"], 1);
-assert.eq(modes.rack["sf"], 1);
-assert.eq(modes.niceRack["sf"], 2);
+assert.eq(modes["2 dc and 3 server"].dc, 2);
+assert.eq(modes["2 dc and 3 server"].server, 3);
+assert.eq(modes["1 and 2"]["server"], 1);
+assert.eq(modes["3 or 4"]["sf"], 1);
+assert.eq(modes["3 and 4"]["sf"], 2);
-print("bridging");
+myprint("bridging");
replTest.bridge();
-
+myprint("bridge 1");
replTest.partition(0, 3);
+myprint("bridge 2");
replTest.partition(0, 4);
+myprint("bridge 3");
replTest.partition(1, 3);
+myprint("bridge 4");
replTest.partition(1, 4);
+myprint("bridge 5");
replTest.partition(2, 3);
+myprint("bridge 6");
replTest.partition(2, 4);
+myprint("bridge 7");
replTest.partition(3, 4);
-print("done bridging");
+myprint("done bridging");
-print("test1");
-print("2 should be primary");
+myprint("paritions: [0-1-2-0] [3] [4]")
+myprint("test1");
+myprint("2 should be primary");
master = replTest.getMaster();
printjson(master.getDB("admin").runCommand({replSetGetStatus:1}));
@@ -83,51 +94,56 @@ printjson(master.getDB("admin").runCommand({replSetGetStatus:1}));
var timeout = 20000;
master.getDB("foo").bar.insert({x:1});
-var result = master.getDB("foo").runCommand({getLastError:1,w:"rack",wtimeout:timeout});
+var result = master.getDB("foo").runCommand({getLastError:1,w:"3 or 4",wtimeout:timeout});
printjson(result);
assert.eq(result.err, "timeout");
replTest.unPartition(1,4);
-print("test2");
+myprint("partitions: [1-4] [0-1-2-0] [3]");
+myprint("test2");
master.getDB("foo").bar.insert({x:1});
-result = master.getDB("foo").runCommand({getLastError:1,w:"rack",wtimeout:timeout});
+result = master.getDB("foo").runCommand({getLastError:1,w:"3 or 4",wtimeout:timeout});
printjson(result);
assert.eq(result.err, null);
-print("test3");
-result = master.getDB("foo").runCommand({getLastError:1,w:"niceRack",wtimeout:timeout});
+myprint("partitions: [1-4] [0-1-2-0] [3]");
+myprint("test3");
+result = master.getDB("foo").runCommand({getLastError:1,w:"3 and 4",wtimeout:timeout});
printjson(result);
assert.eq(result.err, "timeout");
replTest.unPartition(3,4);
-print("test4");
-result = master.getDB("foo").runCommand({getLastError:1,w:"niceRack",wtimeout:timeout});
+myprint("partitions: [0-4-3] [0-1-2-0]");
+myprint("31004 should sync from 31001 (31026)");
+myprint("31003 should sync from 31004 (31024)");
+myprint("test4");
+result = master.getDB("foo").runCommand({getLastError:1,w:"3 and 4",wtimeout:timeout});
printjson(result);
assert.eq(result.err, null);
-print("non-existent w");
+myprint("non-existent w");
result = master.getDB("foo").runCommand({getLastError:1,w:"blahblah",wtimeout:timeout});
printjson(result);
-assert.eq(result.assertionCode, 14830);
+assert.eq(result.code, 14830);
assert.eq(result.ok, 0);
-print("test on2");
+myprint("test mode 2");
master.getDB("foo").bar.insert({x:1});
-result = master.getDB("foo").runCommand({getLastError:1,w:"on2",wtimeout:0});
+result = master.getDB("foo").runCommand({getLastError:1,w:"2",wtimeout:0});
printjson(result);
assert.eq(result.err, null);
-print("test two on the primary");
+myprint("test two on the primary");
master.getDB("foo").bar.insert({x:1});
-result = master.getDB("foo").runCommand({getLastError:1,w:"a machine",wtimeout:0});
+result = master.getDB("foo").runCommand({getLastError:1,w:"1 and 2",wtimeout:0});
printjson(result);
assert.eq(result.err, null);
-print("test5");
+myprint("test5");
master.getDB("foo").bar.insert({x:1});
-result = master.getDB("foo").runCommand({getLastError:1,w:"important",wtimeout:timeout});
+result = master.getDB("foo").runCommand({getLastError:1,w:"2 dc and 3 server",wtimeout:timeout});
printjson(result);
assert.eq(result.err, null);
@@ -137,18 +153,22 @@ replTest.partition(2, 0);
replTest.partition(2, 1);
replTest.stop(2);
-print("1 must become primary here because otherwise the other members will take too long timing out their old sync threads");
+myprint("1 must become primary here because otherwise the other members will take too long timing out their old sync threads");
master = replTest.getMaster();
-print("test6");
+myprint("test6");
master.getDB("foo").bar.insert({x:1});
-result = master.getDB("foo").runCommand({getLastError:1,w:"niceRack",wtimeout:timeout});
+result = master.getDB("foo").runCommand({getLastError:1,w:"3 and 4",wtimeout:timeout});
printjson(result);
assert.eq(result.err, null);
-print("test on2");
+myprint("test mode 2");
master.getDB("foo").bar.insert({x:1});
-result = master.getDB("foo").runCommand({getLastError:1,w:"on2",wtimeout:timeout});
+result = master.getDB("foo").runCommand({getLastError:1,w:"2",wtimeout:timeout});
printjson(result);
assert.eq(result.err, "timeout");
+replTest.stopSet();
+myprint("\n\ntags.js SUCCESS\n\n");
+
+}
diff --git a/jstests/replsets/tags2.js b/jstests/replsets/tags2.js
index 16dfcdf4983..068574bc9c9 100644
--- a/jstests/replsets/tags2.js
+++ b/jstests/replsets/tags2.js
@@ -1,16 +1,27 @@
// Change a getLastErrorMode from 2 to 3 servers
var host = getHostName();
-var replTest = new ReplSetTest( {name: "rstag", nodes: 3, startPort: 31000} );
+var replTest = new ReplSetTest( {name: "rstag", nodes: 4, startPort: 31000} );
var nodes = replTest.startSet();
var ports = replTest.ports;
var conf = {_id : "rstag", version: 1, members : [
{_id : 0, host : host+":"+ports[0], tags : {"backup" : "A"}},
{_id : 1, host : host+":"+ports[1], tags : {"backup" : "B"}},
- {_id : 2, host : host+":"+ports[2], tags : {"backup" : "C"}} ],
+ {_id : 2, host : host+":"+ports[2], tags : {"backup" : "C"}},
+ {_id : 3, host : host+":"+ports[3], tags : {"backup" : "D"}, arbiterOnly : true}],
settings : {getLastErrorModes : {
backedUp : {backup : 2} }} };
+
+print("arbiters can't have tags");
+var result = nodes[0].getDB("admin").runCommand({replSetInitiate : conf});
+printjson(result);
+assert.eq(result.ok, 0);
+
+conf.members.pop();
+replTest.stop(3);
+replTest.remove(3);
replTest.initiate( conf );
+
replTest.awaitReplication();
master = replTest.getMaster();