diff options
Diffstat (limited to 'jstests/multiClient')
-rw-r--r-- | jstests/multiClient/rsDurKillRestart1.js | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/jstests/multiClient/rsDurKillRestart1.js b/jstests/multiClient/rsDurKillRestart1.js new file mode 100644 index 0000000..03e658b --- /dev/null +++ b/jstests/multiClient/rsDurKillRestart1.js @@ -0,0 +1,139 @@ +/* NOTE: This test requires mongo shell to be built with V8 javascript engines so +fork() is available */ + +/* +1. Starts up a replica set with 2 servers and 1 arbiter, all with --dur option. +2. Loads 10000 1K docs into a collection +3. Forks 5 client threads, each $pushes then $pulls its own id to/from the same array in all document (multi-update) +5. A 6th thread kills a random server in the replica set every 0-60 secs then restarts it 0-30 secs later. +-Tony */ + +load('jstests/libs/fun.js') +load('jstests/libs/concurrent.js') + +function random(n) { + return Math.floor(Math.random() * n) +} + +function makeText(size) { + var text = '' + for (var i = 0; i < size; i++) text += 'a' + return text +} + +function checkEqual (value, expected) { + if (value != expected) throw ('expected ' + expected + ' got ' + value) +} + +function deploy() { + var rs = new ReplSetTest({nodes: 3, oplogSize: 1000}) + rs.startSet({dur: null}) + var cfg = rs.getReplSetConfig() + cfg.members[2]['arbiterOnly'] = true + rs.initiate(cfg) + rs.awaitReplication() + return rs +} + +function confirmWrite(db) { + var cmd = {getlasterror: 1, fsync: true, w: 2} + var res = db.runCommand(cmd) + if (! res.ok) throw (tojson(cmd) + 'failed: ' + tojson(res)) +} + +N = 10000 +Text = makeText(1000) + +function loadInitialData(rs) { + var db = rs.getMaster().getDB('test') + for (var i = 0; i < N; i++) db['col'].insert({x: i, text: Text}) + confirmWrite(db) +} + +function newMasterConnection(ports) { + for (var i = 0; i < ports.length; i++) { + try { + print ('Try connect to '+ i) + var conn = new Mongo("127.0.0.1:" + ports[i]) + var rec = conn.getDB('admin').runCommand({ismaster: 1}) + if (rec && rec.ok && rec['ismaster']) { + print ('Connected ' + i) + return conn } + // else close conn + } catch(e) {} + } + throw 'no master: ' + ports +} + +function rsMaster(ports, oldConn) { + try { + var rec = oldConn.getDB('admin').runCommand({ismaster: 1}) + if (rec['ismaster']) return oldConn + } catch (e) {} + return newMasterConnection(ports) +} + +function queryAndUpdateData(ports) {return function(z) { + var conn = null + return function(i) { + function printFailure(e) {print ('Q&U' + z + '-' + i + ': ' + e)} + try { + sleep(1000 + (z * 500)) + print('update ' + z + ' round ' + i) + var db + try { + conn = rsMaster(ports, conn) + db = conn.getDB('test') + } catch (e) { + printFailure(e) + return + } + var n + try { + db['col'].update({}, {$push: {'z': z}}, false, true) + n = db['col'].count({'z': z}) + } catch (e) { + printFailure(e) + return + } + checkEqual (n, N) + sleep(1000) + try { + db['col'].update({}, {$pull: {'z': z}}, false, true) + n = db['col'].count({'z': z}) + } catch (e) { + printFailure(e) + return + } + checkEqual (n, 0) + } catch (e) {throw ('(Q&U' + z + '-' + i + ') ' + e)} + } +}} + +function killer(rs) {return function(i) { + try { + sleep(random(30) * 1000) + var r = random(rs.ports.length - 1) + print('Killing ' + r) + stopMongod(rs.getPort(r), 9) // hard kill + sleep(random(30) * 1000) + print('Restarting ' + r) + rs.restart(r, {dur: null}) + } catch (e) {throw ('(Killer-' + i + ') ' + e)} +}} + +function rsPorts(rs) { + ports = new Array() + for (var i = 0; i < rs.ports.length; i++) ports[i] = rs.getPort(i) + return ports +} + +function go(numRounds) { + var rs = deploy() + loadInitialData(rs) + var jobs = map(queryAndUpdateData(rsPorts(rs)), [1,2,3,4,5]) + parallel (numRounds, jobs, [killer(rs)]) + sleep (2000) + rs.stopSet() + print("rsDurKillRestart1.js SUCCESS") +} |