From 5d342a758c6095b4d30aba0750b54f13b8916f51 Mon Sep 17 00:00:00 2001 From: Antonin Kral Date: Wed, 14 Sep 2011 17:08:06 +0200 Subject: Imported Upstream version 2.0.0 --- jstests/replsets/auth1.js | 35 +++- jstests/replsets/cloneDb.js | 18 +- jstests/replsets/config1.js | 21 -- jstests/replsets/downstream.js | 36 ++++ jstests/replsets/fastsync.js | 151 ++++++++++---- jstests/replsets/initial_sync1.js | 5 +- jstests/replsets/initial_sync3.js | 37 +++- jstests/replsets/key1 | 1 - jstests/replsets/key2 | 1 - jstests/replsets/maintenance.js | 32 +++ jstests/replsets/majority.js | 60 ++++++ jstests/replsets/randomcommands1.js | 29 --- jstests/replsets/reconfig.js | 69 +++++++ jstests/replsets/remove1.js | 130 ++++++------ jstests/replsets/replset1.js | 22 ++ jstests/replsets/replset3.js | 2 +- jstests/replsets/replset5.js | 88 ++++---- jstests/replsets/replsetadd.js | 34 +++- jstests/replsets/replsetarb1.js | 33 --- jstests/replsets/replsetarb2.js | 13 +- jstests/replsets/replsetarb3.js | 144 ------------- jstests/replsets/replsetfreeze.js | 4 +- jstests/replsets/replsetrestart1.js | 14 +- jstests/replsets/replsetrestart2.js | 8 +- jstests/replsets/rollback2.js | 19 +- jstests/replsets/rollback4.js | 117 +++++++++++ jstests/replsets/rslib.js | 44 +++- jstests/replsets/slavedelay1.js | 104 +++++----- jstests/replsets/stale_clustered.js | 101 +++++++++ jstests/replsets/stepdown.js | 142 +++++++++++++ jstests/replsets/stepdown2.js | 139 +++++++++++++ jstests/replsets/sync1.js | 396 +++++++++++++++++++----------------- jstests/replsets/sync2.js | 48 +++++ jstests/replsets/tags.js | 154 ++++++++++++++ jstests/replsets/tags2.js | 44 ++++ jstests/replsets/toostale.js | 34 ++-- jstests/replsets/twosets.js | 35 ---- 37 files changed, 1660 insertions(+), 704 deletions(-) delete mode 100644 jstests/replsets/config1.js create mode 100755 jstests/replsets/downstream.js delete mode 100644 jstests/replsets/key1 delete mode 100644 jstests/replsets/key2 create mode 100644 jstests/replsets/maintenance.js create mode 100644 jstests/replsets/majority.js delete mode 100644 jstests/replsets/randomcommands1.js create mode 100644 jstests/replsets/reconfig.js delete mode 100644 jstests/replsets/replsetarb1.js delete mode 100644 jstests/replsets/replsetarb3.js create mode 100644 jstests/replsets/rollback4.js create mode 100644 jstests/replsets/stale_clustered.js create mode 100644 jstests/replsets/stepdown.js create mode 100755 jstests/replsets/stepdown2.js create mode 100644 jstests/replsets/sync2.js create mode 100644 jstests/replsets/tags.js create mode 100644 jstests/replsets/tags2.js delete mode 100644 jstests/replsets/twosets.js (limited to 'jstests/replsets') diff --git a/jstests/replsets/auth1.js b/jstests/replsets/auth1.js index 60e4b95..71ab2d9 100644 --- a/jstests/replsets/auth1.js +++ b/jstests/replsets/auth1.js @@ -3,17 +3,27 @@ load("jstests/replsets/rslib.js"); var name = "rs_auth1"; -var port = allocatePorts(4); -var path = "jstests/replsets/"; +var port = allocatePorts(5); +var path = "jstests/libs/"; + + +print("try starting mongod with auth"); +var m = runMongoProgram( "mongod", "--auth", "--port", port[4], "--dbpath", "/data/db/wrong-auth"); + +assert.throws(function() { + m.getDB("local").auth("__system", ""); +}); + +stopMongod(port[4]); + - print("reset permissions"); run("chmod", "644", path+"key1"); run("chmod", "644", path+"key2"); print("try starting mongod"); -var m = runMongoProgram( "mongod", "--keyFile", path+"key1", "--port", port[0], "--dbpath", "/data/db/" + name); +m = runMongoProgram( "mongod", "--keyFile", path+"key1", "--port", port[0], "--dbpath", "/data/db/" + name); print("should fail with wrong permissions"); @@ -81,6 +91,10 @@ function doQueryOn(p) { doQueryOn(slave); master.adminCommand({logout:1}); + +print("unauthorized:"); +printjson(master.adminCommand({replSetGetStatus : 1})); + doQueryOn(master); @@ -125,11 +139,12 @@ master.auth("bar", "baz"); for (var i=0; i<1000; i++) { master.foo.insert({x:i, foo : "bar"}); } -master.runCommand({getlasterror:1, w:3, wtimeout:60000}); +var result = master.runCommand({getlasterror:1, w:2, wtimeout:60000}); +printjson(result); print("resync"); -rs.restart(0); +rs.restart(0, {"keyFile" : path+"key1"}); print("add some more data 2"); @@ -159,7 +174,7 @@ master.getSisterDB("admin").auth("foo", "bar"); print("shouldn't ever sync"); -for (var i = 0; i<30; i++) { +for (var i = 0; i<10; i++) { print("iteration: " +i); var results = master.adminCommand({replSetGetStatus:1}); printjson(results); @@ -177,9 +192,15 @@ conn = new MongodRunner(port[3], "/data/db/"+name+"-3", null, null, ["--replSet" conn.start(); wait(function() { + try { var results = master.adminCommand({replSetGetStatus:1}); printjson(results); return results.members[3].state == 2; + } + catch (e) { + print(e); + } + return false; }); print("make sure it has the config, too"); diff --git a/jstests/replsets/cloneDb.js b/jstests/replsets/cloneDb.js index 6d2d0f3..2519c09 100644 --- a/jstests/replsets/cloneDb.js +++ b/jstests/replsets/cloneDb.js @@ -6,34 +6,36 @@ doTest = function( signal ) { var N = 2000 - // ~1KB string + print("~1KB string"); var Text = '' for (var i = 0; i < 40; i++) Text += 'abcdefghijklmnopqrstuvwxyz' - // Create replica set + print("Create replica set"); var repset = new ReplicaSet ('testSet', 3) .begin() var master = repset.getMaster() var db1 = master.getDB('test') - // Insert data + 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 } - // Create single server + print("Create single server"); var solo = new Server ('singleTarget') var soloConn = solo.begin() + soloConn.getDB("admin").runCommand({setParameter:1,logLevel:5}); + var db2 = soloConn.getDB('test') - // Clone db from replica set to single server + print("Clone db from replica set to single server"); db2.cloneDatabase (repset.getURL()) - // Confirm clone worked + print("Confirm clone worked"); assert.eq (Text, db2['foo'] .findOne({x: N-1}) ['text'], 'cloneDatabase failed (test1)') - // Now test the reverse direction + print("Now test the reverse direction"); db1 = master.getDB('test2') db2 = soloConn.getDB('test2') for (var i = 0; i < N; i++) { @@ -43,7 +45,7 @@ doTest = function( signal ) { db1.cloneDatabase (solo.host()) assert.eq (Text, db2['foo'] .findOne({x: N-1}) ['text'], 'cloneDatabase failed (test2)') - // Shut down replica set and single server + print("Shut down replica set and single server"); solo.end() repset.stopSet( signal ) } diff --git a/jstests/replsets/config1.js b/jstests/replsets/config1.js deleted file mode 100644 index 748ce8f..0000000 --- a/jstests/replsets/config1.js +++ /dev/null @@ -1,21 +0,0 @@ -doTest = function( signal ) { - var name = 'config1'; - - var replTest = new ReplSetTest( {name: name, nodes: 3} ); - var nodes = replTest.startSet(); - - var config = replTest.getReplSetConfig(); - config.settings = {"heartbeatSleep" : .5, heartbeatTimeout : .8}; - - replTest.initiate(config); - - // Call getMaster to return a reference to the node that's been - // elected master. - var master = replTest.getMaster(); - - config = master.getDB("local").system.replset.findOne(); - assert.eq(config.settings.heartbeatSleep, .5); - assert.eq(config.settings.heartbeatTimeout, .8); -}; - -doTest(15); diff --git a/jstests/replsets/downstream.js b/jstests/replsets/downstream.js new file mode 100755 index 0000000..795e667 --- /dev/null +++ b/jstests/replsets/downstream.js @@ -0,0 +1,36 @@ +// 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/fastsync.js b/jstests/replsets/fastsync.js index d7c3905..1c9c215 100644 --- a/jstests/replsets/fastsync.js +++ b/jstests/replsets/fastsync.js @@ -22,7 +22,7 @@ var wait = function(f) { } var reconnect = function(a) { - wait(function() { + wait(function() { try { a.getDB("foo").bar.stats(); return true; @@ -33,7 +33,7 @@ var reconnect = function(a) { }); }; -ports = allocatePorts( 3 ); +ports = allocatePorts( 4 ); var basename = "jstests_fastsync"; var basePath = "/data/db/" + basename; @@ -48,7 +48,7 @@ var admin = p.getDB("admin"); var foo = p.getDB("foo"); var local = p.getDB("local"); -var config = {_id : basename, members : [{_id : 0, host : hostname+":"+ports[0]}]}; +var config = {_id : basename, members : [{_id : 0, host : hostname+":"+ports[0], priority:2}]}; printjson(config); var result = admin.runCommand({replSetInitiate : config}); print("result:"); @@ -59,10 +59,19 @@ while (count < 10 && result.ok != 1) { count++; sleep(2000); result = admin.runCommand({replSetInitiate : config}); -} +} assert(result.ok, tojson(result)); -assert.soon(function() { return admin.runCommand({isMaster:1}).ismaster; }); +assert.soon(function() { result = false; + try { + result = admin.runCommand({isMaster:1}).ismaster; + } + catch(e) { + print(e); + return false; + } + return result; + }); print("1"); for (var i=0; i<100000; i++) { @@ -73,45 +82,113 @@ print("total in foo: "+foo.bar.count()); print("2"); admin.runCommand( {fsync:1,lock:1} ); -copyDbpath( basePath + "-p", basePath + "-s" ); +copyDbpath( basePath + "-p", basePath + "-s"+1 ); admin.$cmd.sys.unlock.findOne(); - print("3"); -var sargs = new MongodRunner( ports[ 1 ], basePath + "-s", false, false, +var startSlave = function(n) { + var sargs = new MongodRunner( ports[ n ], basePath + "-s"+n, false, false, ["--replSet", basename, "--fastsync", "--oplogSize", 2], {no_bind : true} ); -var reuseData = true; -sargs.start(reuseData); + var reuseData = true; + var conn = sargs.start(reuseData); + + config = local.system.replset.findOne(); + config.version++; + config.members.push({_id:n, host:hostname+":"+ports[n]}); + + result = admin.runCommand({replSetReconfig : config}); + printjson(result); + assert(result.ok, "reconfig worked"); + reconnect(p); + + print("4"); + var status = admin.runCommand({replSetGetStatus : 1}); + var count = 0; + while (status.members[n].state != 2 && count < 200) { + print("not a secondary yet"); + if (count % 10 == 0) { + printjson(status); + } + assert(!status.members[n].errmsg || !status.members[n].errmsg.match("^initial sync cloning db")); -config = local.system.replset.findOne(); -config.version++; -config.members.push({_id:1, host:hostname+":"+ports[1]}); + sleep(1000); -result = admin.runCommand({replSetReconfig : config}); -assert(result.ok, "reconfig worked"); -reconnect(p); + // disconnection could happen here + try { + status = admin.runCommand({replSetGetStatus : 1}); + } + catch (e) { + print(e); + } + count++; + } -print("4"); -var status = admin.runCommand({replSetGetStatus : 1}); -var count = 0; -while (status.members[1].state != 2 && count < 200) { - print("not a secondary yet"); - if (count % 10 == 0) { - printjson(status); - } - assert(!status.members[1].errmsg || !status.members[1].errmsg.match("^initial sync cloning db")); - - sleep(1000); - - // disconnection could happen here - try { - status = admin.runCommand({replSetGetStatus : 1}); - } - catch (e) { - print(e); - } - count++; + assert.eq(status.members[n].state, 2); + + assert.soon(function() { + return admin.runCommand({isMaster : 1}).ismaster; + }); + + 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; + }); + + return conn; +}; + +var s1 = startSlave(1); + +var me1 = s1.getDB("local").me.findOne(); + +print("me: " +me1._id); +assert(me1._id != null); + +print("5"); +s1.getDB("admin").runCommand( {fsync:1,lock:1} ); +copyDbpath( basePath + "-s1", basePath + "-s2" ); +s1.getDB("admin").$cmd.sys.unlock.findOne(); + +var s2 = startSlave(2); + +var me2 = s2.getDB("local").me.findOne(); + +print("me: " +me2._id); +assert(me1._id != me2._id); + +print("restart member with a different port and make it a new set"); +try { + p.getDB("admin").runCommand({shutdown:1}); +} +catch(e) { + print("good, shutting down: " +e); } +sleep(10000); + +pargs = new MongodRunner( ports[ 3 ], basePath + "-p", false, false, + ["--replSet", basename, "--oplogSize", 2], + {no_bind : true} ); +p = pargs.start(true); + +printjson(p.getDB("admin").runCommand({replSetGetStatus:1})); + +p.getDB("admin").runCommand({replSetReconfig : { + _id : basename, + members : [{_id:0, host : hostname+":"+ports[3]}] + }, force : true}); + +print("start waiting for primary..."); +assert.soon(function() { + try { + return p.getDB("admin").runCommand({isMaster : 1}).ismaster; + } + catch(e) { + print(e); + } + return false; + }, "waiting for master", 60000); -assert.eq(status.members[1].state, 2); diff --git a/jstests/replsets/initial_sync1.js b/jstests/replsets/initial_sync1.js index df978c4..4cfd606 100644 --- a/jstests/replsets/initial_sync1.js +++ b/jstests/replsets/initial_sync1.js @@ -95,12 +95,11 @@ replTest.stop(1); print("8. Eventually it should become a secondary"); print("if initial sync has started, this will cause it to fail and sleep for 5 minutes"); -sleep(5*60*1000); wait(function() { var status = admin_s2.runCommand({replSetGetStatus:1}); occasionally(function() { printjson(status); }); return status.members[2].state == 2; - }); + }, 350); print("9. Bring #2 back up"); @@ -122,5 +121,5 @@ for (var i=0; i<10000; i++) { print("11. Everyone happy eventually"); -replTest.awaitReplication(); +replTest.awaitReplication(300000); diff --git a/jstests/replsets/initial_sync3.js b/jstests/replsets/initial_sync3.js index 471aa16..7f2af94 100644 --- a/jstests/replsets/initial_sync3.js +++ b/jstests/replsets/initial_sync3.js @@ -43,14 +43,14 @@ wait(function() { if (!status.members) { return false; } - + for (i=0; i<7; i++) { if (status.members[i].state != 1 && status.members[i].state != 2) { return false; } } return true; - + }); replTest.awaitReplication(); @@ -66,6 +66,7 @@ rs2.initiate(); master = rs2.getMaster(); var config = master.getDB("local").system.replset.findOne(); config.version++; +config.members[0].priority = 2; config.members[0].initialSync = {state : 2}; config.members[1].initialSync = {state : 1}; try { @@ -75,12 +76,34 @@ catch(e) { print("trying to reconfigure: "+e); } -master = rs2.getMaster(); -config = master.getDB("local").system.replset.findOne(); +// wait for a heartbeat, too, just in case sync happens before hb +assert.soon(function() { + try { + for (var n in rs2.nodes) { + if (rs2.nodes[n].getDB("local").system.replset.findOne().version != 2) { + return false; + } + } + } + catch (e) { + return false; + } + return true; +}); + +rs2.awaitReplication(); + +// test partitioning +master = rs2.bridge(); +rs2.partition(0, 2); + +master.getDB("foo").bar.baz.insert({x:1}); +rs2.awaitReplication(); -assert(typeof(config.members[0].initialSync) == "object"); -assert.eq(config.members[0].initialSync.state, 2); -assert.eq(config.members[1].initialSync.state, 1); +master.getDB("foo").bar.baz.insert({x:2}); +var x = master.getDB("foo").runCommand({getLastError : 1, w : 3, wtimeout : 5000}); +printjson(x); +assert.eq(null, x.err); rs2.stopSet(); diff --git a/jstests/replsets/key1 b/jstests/replsets/key1 deleted file mode 100644 index b5c19e4..0000000 --- a/jstests/replsets/key1 +++ /dev/null @@ -1 +0,0 @@ -foop de doop diff --git a/jstests/replsets/key2 b/jstests/replsets/key2 deleted file mode 100644 index cbde821..0000000 --- a/jstests/replsets/key2 +++ /dev/null @@ -1 +0,0 @@ -other key diff --git a/jstests/replsets/maintenance.js b/jstests/replsets/maintenance.js new file mode 100644 index 0000000..5b068cd --- /dev/null +++ b/jstests/replsets/maintenance.js @@ -0,0 +1,32 @@ + + +var replTest = new ReplSetTest( {name: 'unicomplex', nodes: 3} ); +var conns = replTest.startSet(); +replTest.initiate(); + +// Make sure we have a master +var master = replTest.getMaster(); + +for (i=0;i<10000; i++) { master.getDB("bar").foo.insert({x:1,y:i,abc:123,str:"foo bar baz"}); } +for (i=0;i<1000; i++) { master.getDB("bar").foo.update({y:i},{$push :{foo : "barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"}}); } + +replTest.awaitReplication(); + +assert.soon(function() { return conns[2].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; }); + +print("joining"); +join(); + +print("check secondary becomes a secondary again"); +var x = 0; +assert.soon(function() { + var im = conns[2].getDB("admin").isMaster(); + if (x++ % 5 == 0) printjson(im); + return im.secondary; +}); + diff --git a/jstests/replsets/majority.js b/jstests/replsets/majority.js new file mode 100644 index 0000000..6df1a41 --- /dev/null +++ b/jstests/replsets/majority.js @@ -0,0 +1,60 @@ +var num = 5; +var host = getHostName(); +var name = "tags"; +var timeout = 10000; + +var replTest = new ReplSetTest( {name: name, nodes: num, startPort:31000} ); +var nodes = replTest.startSet(); +var port = replTest.ports; +replTest.initiate({_id : name, members : + [ + {_id:0, host : host+":"+port[0], priority : 2}, + {_id:1, host : host+":"+port[1]}, + {_id:2, host : host+":"+port[2]}, + {_id:3, host : host+":"+port[3], arbiterOnly : true}, + {_id:4, host : host+":"+port[4], arbiterOnly : true}, + ], + }); + +replTest.awaitReplication(); +replTest.bridge(); + +var testInsert = function() { + master.getDB("foo").bar.insert({x:1}); + var result = master.getDB("foo").runCommand({getLastError:1, w:"majority", wtimeout:timeout}); + printjson(result); + return result; +}; + +var master = replTest.getMaster(); + +print("get back in the groove"); +testInsert(); +replTest.awaitReplication(); + +print("makes sure majority works"); +assert.eq(testInsert().err, null); + +print("setup: 0,1 | 2,3,4"); +replTest.partition(0,2); +replTest.partition(0,3); +replTest.partition(0,4); +replTest.partition(1,2); +replTest.partition(1,3); +replTest.partition(1,4); + +print("make sure majority doesn't work"); +// primary should now be 2 +master = replTest.getMaster(); +assert.eq(testInsert().err, "timeout"); + +print("bring set back together"); +replTest.unPartition(0,2); +replTest.unPartition(0,3); +replTest.unPartition(1,4); + +master = replTest.getMaster(); + +print("make sure majority works"); +assert.eq(testInsert().err, null); + diff --git a/jstests/replsets/randomcommands1.js b/jstests/replsets/randomcommands1.js deleted file mode 100644 index c451e74..0000000 --- a/jstests/replsets/randomcommands1.js +++ /dev/null @@ -1,29 +0,0 @@ - -replTest = new ReplSetTest( {name: 'randomcommands1', nodes: 3} ); - -nodes = replTest.startSet(); -replTest.initiate(); - -master = replTest.getMaster(); -slaves = replTest.liveNodes.slaves; -printjson(replTest.liveNodes); - -db = master.getDB("foo") -t = db.foo - -ts = slaves.map( function(z){ z.setSlaveOk(); return z.getDB( "foo" ).foo; } ) - -t.save({a: 1000}); -t.ensureIndex( { a : 1 } ) - -db.getLastError( 3 , 30000 ) - -ts.forEach( function(z){ assert.eq( 2 , z.getIndexKeys().length , "A " + z.getMongo() ); } ) - -t.reIndex() - -db.getLastError( 3 , 30000 ) -ts.forEach( function(z){ assert.eq( 2 , z.getIndexKeys().length , "A " + z.getMongo() ); } ) - -replTest.stopSet( 15 ) - diff --git a/jstests/replsets/reconfig.js b/jstests/replsets/reconfig.js new file mode 100644 index 0000000..b7dca03 --- /dev/null +++ b/jstests/replsets/reconfig.js @@ -0,0 +1,69 @@ + +// try reconfiguring with servers down + +var replTest = new ReplSetTest({ name: 'testSet', nodes: 5 }); +var nodes = replTest.startSet(); +replTest.initiate(); + +var master = replTest.getMaster(); + +print("initial sync"); +master.getDB("foo").bar.insert({X:1}); +replTest.awaitReplication(); + +print("stopping 3 & 4"); +replTest.stop(3); +replTest.stop(4); + +print("reconfiguring"); +master = replTest.getMaster(); +var config = master.getDB("local").system.replset.findOne(); +var oldVersion = config.version++; +config.members[0].votes = 2; +config.members[3].votes = 2; +try { + master.getDB("admin").runCommand({replSetReconfig : config}); +} +catch(e) { + print(e); +} + +var config = master.getDB("local").system.replset.findOne(); +assert.eq(oldVersion+1, config.version); + + +print("0 & 3 up; 1, 2, 4 down"); +replTest.restart(3); + +// in case 0 isn't master +replTest.awaitReplication(); + +replTest.stop(1); +replTest.stop(2); + +print("try to reconfigure with a 'majority' down"); +oldVersion = config.version; +config.version++; +master = replTest.getMaster(); +try { + master.getDB("admin").runCommand({replSetReconfig : config}); +} +catch (e) { + print(e); +} + +var config = master.getDB("local").system.replset.findOne(); +assert.eq(oldVersion+1, config.version); + +replTest.stopSet(); + +replTest2 = new ReplSetTest({name : 'testSet2', nodes : 1}); +nodes = replTest2.startSet(); + +result = nodes[0].getDB("admin").runCommand({replSetInitiate : {_id : "testSet2", members : [ + {_id : 0, tags : ["member0"]} + ]}}); + +assert(result.errmsg.match(/bad or missing host field/)); + +replTest2.stopSet(); diff --git a/jstests/replsets/remove1.js b/jstests/replsets/remove1.js index ebd17d6..f93fe9e 100644 --- a/jstests/replsets/remove1.js +++ b/jstests/replsets/remove1.js @@ -16,7 +16,7 @@ var host = getHostName(); print("Start set with three nodes"); -var replTest = new ReplSetTest( {name: name, nodes: 3} ); +var replTest = new ReplSetTest( {name: name, nodes: 2} ); var nodes = replTest.startSet(); replTest.initiate(); var master = replTest.getMaster(); @@ -28,85 +28,44 @@ master.getDB("foo").bar.baz.insert({x:1}); replTest.awaitReplication(); -print("Remove slave2"); +print("Remove slaves"); var config = replTest.getReplSetConfig(); config.members.pop(); config.version = 2; -try { - master.getDB("admin").runCommand({replSetReconfig:config}); -} -catch(e) { - print(e); -} -reconnect(master); - - -print("Remove slave1"); -config.members.pop(); -config.version = 3; -try { - master.getDB("admin").runCommand({replSetReconfig:config}); -} -catch(e) { - print(e); -} -reconnect(master); - -print("sleeping 1"); -sleep(10000); -// these are already down, but this clears their ports from memory so that they -// can be restarted later -stopMongod(replTest.getPort(1)); -stopMongod(replTest.getPort(2)); - - -print("Bring slave1 back up"); -var paths = [ replTest.getPath(1), replTest.getPath(2) ]; -var ports = allocatePorts(2, replTest.getPort(2)+1); -var args = ["mongod", "--port", ports[0], "--dbpath", paths[0], "--noprealloc", "--smallfiles", "--rest"]; -var conn = startMongoProgram.apply( null, args ); -conn.getDB("local").system.replset.remove(); -printjson(conn.getDB("local").runCommand({getlasterror:1})); -print(conn); -print("sleeping 2"); -sleep(10000); -stopMongod(ports[0]); - -replTest.restart(1); - - -print("Bring slave2 back up"); -args[2] = ports[1]; -args[4] = paths[1]; -conn = startMongoProgram.apply( null, args ); -conn.getDB("local").system.replset.remove(); -print("path: "+paths[1]); -print("sleeping 3"); -sleep(10000); -stopMongod(ports[1]); - -replTest.restart(2); -sleep(10000); - - -print("Add them back as slaves"); +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"); config.members.push({_id:1, host : host+":"+replTest.getPort(1)}); -config.members.push({_id:2, host : host+":"+replTest.getPort(2)}); -config.version = 4; +config.version = 3; +printjson(config); wait(function() { try { - master.getDB("admin").runCommand({replSetReconfig:config}); + master.getDB("admin").runCommand({replSetReconfig:config}); } catch(e) { - print(e); + print(e); } reconnect(master); + printjson(master.getDB("admin").runCommand({replSetGetStatus:1})); master.setSlaveOk(); var newConfig = master.getDB("local").system.replset.findOne(); - return newConfig.version == 4; - }); + print( "newConfig: " + tojson(newConfig) ); + return newConfig.version == 3; +} , "wait1" ); print("Make sure everyone's secondary"); @@ -115,18 +74,49 @@ wait(function() { occasionally(function() { printjson(status); }); - - if (!status.members || status.members.length != 3) { + + if (!status.members || status.members.length != 2) { return false; } - for (var i = 0; i<3; i++) { + for (var i = 0; i<2; i++) { if (status.members[i].state != 1 && status.members[i].state != 2) { return false; } } return true; - }); +} , "wait2" ); + + +print("reconfig with minority"); +replTest.stop(1); + +assert.soon(function() { + try { + return master.getDB("admin").runCommand({isMaster : 1}).secondary; + } + catch(e) { + print("trying to get master: "+e); + } +}); + +config.version = 4; +config.members.pop(); +try { + master.getDB("admin").runCommand({replSetReconfig : config, force : true}); +} +catch(e) { + print(e); +} + +reconnect(master); +assert.soon(function() { + return master.getDB("admin").runCommand({isMaster : 1}).ismaster; +}); + +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 5ac94e7..6387c5d 100644 --- a/jstests/replsets/replset1.js +++ b/jstests/replsets/replset1.js @@ -108,6 +108,28 @@ doTest = function( signal ) { assert.eq( 1000 , count.n , "slave count wrong: " + slave ); }); + // last error + master = replTest.getMaster(); + slaves = replTest.liveNodes.slaves; + printjson(replTest.liveNodes); + + db = master.getDB("foo") + t = db.foo + + ts = slaves.map( function(z){ z.setSlaveOk(); return z.getDB( "foo" ).foo; } ) + + t.save({a: 1000}); + t.ensureIndex( { a : 1 } ) + + db.getLastError( 3 , 30000 ) + + ts.forEach( function(z){ assert.eq( 2 , z.getIndexKeys().length , "A " + z.getMongo() ); } ) + + t.reIndex() + + db.getLastError( 3 , 30000 ) + ts.forEach( function(z){ assert.eq( 2 , z.getIndexKeys().length , "A " + z.getMongo() ); } ) + // Shut down the set and finish the test. replTest.stopSet( signal ); } diff --git a/jstests/replsets/replset3.js b/jstests/replsets/replset3.js index faa0627..ba08eac 100644 --- a/jstests/replsets/replset3.js +++ b/jstests/replsets/replset3.js @@ -29,7 +29,7 @@ doTest = function (signal) { // Step down master. Note: this may close our connection! try { - master.getDB("admin").runCommand({ replSetStepDown: true }); + master.getDB("admin").runCommand({ replSetStepDown: true, force: 1 }); } catch (err) { print("caught: " + err + " on stepdown"); } diff --git a/jstests/replsets/replset5.js b/jstests/replsets/replset5.js index 6a7d8a5..67ce2d7 100644 --- a/jstests/replsets/replset5.js +++ b/jstests/replsets/replset5.js @@ -23,51 +23,63 @@ doTest = function (signal) { master.getDB("barDB").bar.save({ a: 1 }); replTest.awaitReplication(); - // These writes should be replicated immediately - var docNum = 5000; - for(var n=0; n