Files
mongo/jstests/repl/pair3.js
2010-02-02 15:12:08 -08:00

238 lines
7.1 KiB
JavaScript

// test arbitration
var baseName = "jstests_pair3test";
ismaster = function( n ) {
var im = n.getDB( "admin" ).runCommand( { "ismaster" : 1 } );
print( "ismaster: " + tojson( im ) );
assert( im, "command ismaster failed" );
return im.ismaster;
}
// bring up node connections before arbiter connections so that arb can forward to node when expected
connect = function() {
if ( lp == null ) {
lp = startMongoProgram( "mongobridge", "--port", lpPort, "--dest", "localhost:" + lPort );
}
if ( rp == null ) {
rp = startMongoProgram( "mongobridge", "--port", rpPort, "--dest", "localhost:" + rPort );
}
if ( al == null ) {
al = startMongoProgram( "mongobridge", "--port", alPort, "--dest", "localhost:" + aPort );
}
if ( ar == null ) {
ar = startMongoProgram( "mongobridge", "--port", arPort, "--dest", "localhost:" + aPort );
}
}
disconnectNode = function( mongo ) {
if ( lp ) {
stopMongoProgram( lpPort );
lp = null;
}
if ( rp ) {
stopMongoProgram( rpPort );
rp = null;
}
if ( mongo.host.match( new RegExp( "^127.0.0.1:" + lPort + "$" ) ) ) {
stopMongoProgram( alPort );
al = null;
} else if ( mongo.host.match( new RegExp( "^127.0.0.1:" + rPort + "$" ) ) ) {
stopMongoProgram( arPort );
ar = null;
} else {
assert( false, "don't know how to disconnect node: " + mongo );
}
}
doTest1 = function() {
al = ar = lp = rp = null;
ports = allocatePorts( 7 );
aPort = ports[ 0 ];
alPort = ports[ 1 ];
arPort = ports[ 2 ];
lPort = ports[ 3 ];
lpPort = ports[ 4 ];
rPort = ports[ 5 ];
rpPort = ports[ 6 ];
connect();
a = new MongodRunner( aPort, "/data/db/" + baseName + "-arbiter" );
l = new MongodRunner( lPort, "/data/db/" + baseName + "-left", "127.0.0.1:" + rpPort, "127.0.0.1:" + alPort );
r = new MongodRunner( rPort, "/data/db/" + baseName + "-right", "127.0.0.1:" + lpPort, "127.0.0.1:" + arPort );
pair = new ReplPair( l, r, a );
// normal startup
pair.start();
pair.waitForSteadyState();
// disconnect slave
disconnectNode( pair.slave() );
pair.waitForSteadyState( [ 1, -3 ], pair.master().host );
// disconnect master
disconnectNode( pair.master() );
pair.waitForSteadyState( [ -3, -3 ] );
// reconnect
connect();
pair.waitForSteadyState();
// disconnect master
disconnectNode( pair.master() );
pair.waitForSteadyState( [ 1, -3 ], pair.slave().host, true );
// disconnect new master
disconnectNode( pair.master() );
pair.waitForSteadyState( [ -3, -3 ] );
// reconnect
connect();
pair.waitForSteadyState();
// disconnect slave
disconnectNode( pair.slave() );
pair.waitForSteadyState( [ 1, -3 ], pair.master().host );
// reconnect slave
connect();
pair.waitForSteadyState( [ 1, 0 ], pair.master().host );
// disconnect master
disconnectNode( pair.master() );
pair.waitForSteadyState( [ 1, -3 ], pair.slave().host, true );
// reconnect old master
connect();
pair.waitForSteadyState( [ 1, 0 ], pair.master().host );
ports.forEach( function( x ) { stopMongoProgram( x ); } );
}
// this time don't start connected
doTest2 = function() {
al = ar = lp = rp = null;
ports = allocatePorts( 7 );
aPort = ports[ 0 ];
alPort = ports[ 1 ];
arPort = ports[ 2 ];
lPort = ports[ 3 ];
lpPort = ports[ 4 ];
rPort = ports[ 5 ];
rpPort = ports[ 6 ];
a = new MongodRunner( aPort, "/data/db/" + baseName + "-arbiter" );
l = new MongodRunner( lPort, "/data/db/" + baseName + "-left", "127.0.0.1:" + rpPort, "127.0.0.1:" + alPort );
r = new MongodRunner( rPort, "/data/db/" + baseName + "-right", "127.0.0.1:" + lpPort, "127.0.0.1:" + arPort );
pair = new ReplPair( l, r, a );
pair.start();
pair.waitForSteadyState( [ -3, -3 ] );
startMongoProgram( "mongobridge", "--port", arPort, "--dest", "localhost:" + aPort );
// there hasn't been an initial sync, no no node will become master
for( i = 0; i < 10; ++i ) {
assert( pair.isMaster( pair.right() ) == -3 && pair.isMaster( pair.left() ) == -3 );
sleep( 500 );
}
stopMongoProgram( arPort );
startMongoProgram( "mongobridge", "--port", alPort, "--dest", "localhost:" + aPort );
for( i = 0; i < 10; ++i ) {
assert( pair.isMaster( pair.right() ) == -3 && pair.isMaster( pair.left() ) == -3 );
sleep( 500 );
}
stopMongoProgram( alPort );
// connect l and r without a
startMongoProgram( "mongobridge", "--port", lpPort, "--dest", "localhost:" + lPort );
startMongoProgram( "mongobridge", "--port", rpPort, "--dest", "localhost:" + rPort );
pair.waitForSteadyState( [ 1, 0 ] );
ports.forEach( function( x ) { stopMongoProgram( x ); } );
}
// recover from master - master setup
doTest3 = function() {
al = ar = lp = rp = null;
ports = allocatePorts( 7 );
aPort = ports[ 0 ];
alPort = ports[ 1 ];
arPort = ports[ 2 ];
lPort = ports[ 3 ];
lpPort = ports[ 4 ];
rPort = ports[ 5 ];
rpPort = ports[ 6 ];
connect();
a = new MongodRunner( aPort, "/data/db/" + baseName + "-arbiter" );
l = new MongodRunner( lPort, "/data/db/" + baseName + "-left", "127.0.0.1:" + rpPort, "127.0.0.1:" + alPort );
r = new MongodRunner( rPort, "/data/db/" + baseName + "-right", "127.0.0.1:" + lpPort, "127.0.0.1:" + arPort );
pair = new ReplPair( l, r, a );
pair.start();
pair.waitForSteadyState();
// now can only talk to arbiter
stopMongoProgram( lpPort );
stopMongoProgram( rpPort );
pair.waitForSteadyState( [ 1, 1 ], null, true );
// recover
startMongoProgram( "mongobridge", "--port", lpPort, "--dest", "localhost:" + lPort );
startMongoProgram( "mongobridge", "--port", rpPort, "--dest", "localhost:" + rPort );
pair.waitForSteadyState( [ 1, 0 ], null, true );
ports.forEach( function( x ) { stopMongoProgram( x ); } );
}
// check that initial sync is persistent
doTest4 = function( signal ) {
al = ar = lp = rp = null;
ports = allocatePorts( 7 );
aPort = ports[ 0 ];
alPort = ports[ 1 ];
arPort = ports[ 2 ];
lPort = ports[ 3 ];
lpPort = ports[ 4 ];
rPort = ports[ 5 ];
rpPort = ports[ 6 ];
connect();
a = new MongodRunner( aPort, "/data/db/" + baseName + "-arbiter" );
l = new MongodRunner( lPort, "/data/db/" + baseName + "-left", "127.0.0.1:" + rpPort, "127.0.0.1:" + alPort );
r = new MongodRunner( rPort, "/data/db/" + baseName + "-right", "127.0.0.1:" + lpPort, "127.0.0.1:" + arPort );
pair = new ReplPair( l, r, a );
pair.start();
pair.waitForSteadyState();
pair.killNode( pair.left(), signal );
pair.killNode( pair.right(), signal );
stopMongoProgram( rpPort );
stopMongoProgram( lpPort );
// now can only talk to arbiter
pair.start( true );
pair.waitForSteadyState( [ 1, 1 ], null, true );
ports.forEach( function( x ) { stopMongoProgram( x ); } );
}
doTest1();
doTest2();
doTest3();
doTest4( 15 );
doTest4( 9 );