238 lines
7.1 KiB
JavaScript
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 );
|