UNPKG

webrtc-chord

Version:

Chord DHT Algorithm implementation for the browser using WebRTC and WebSockets

264 lines (223 loc) 6.85 kB
var spawn = require('child_process').spawn; var Lab = require('lab'); var Code = require('code'); var lab = exports.lab = Lab.script(); var experiment = lab.experiment; var test = lab.test; var before = lab.before; var after = lab.after; var expect = Code.expect; var pp = require('piri-piri'); var uuid = require('webrtc-chord-uuid'); var bigInt = require('big-integer'); var utils = require('../../webrtc-chord-signaling-server/src/lib/utils'); experiment('webrtc-chord:', function() { var ppIds = {}; var chordIds = {}; var signaling; var cA; var cB; var cC; var cD; before(function(done) { var options = { path: __dirname + '/serve_this.js', port: 9876, host: 'localhost' }; pp.start(options, function(err) { if (err) { console.log(err); process.exit(1); } startSignalingServer(done); }); }); function startSignalingServer(cb) { signaling = spawn('node', ['./../webrtc-chord-signaling-server/src/index.js']); signaling.stdout.on('data', function(data) { console.log('stdout: \n' + data); }); signaling.stderr.on('data', function(data) { console.log('stderr: \n' + data); }); setTimeout(function() { console.log('Signaling server has started'); cb(); }, 1000); } after(function(done) { setTimeout(function() { signaling.on('close', function(code) { // console.log('cp exited: ' + code); }); signaling.kill(); pp.farm.stop(function() {}); pp.close(function() {}); done(); }, 1000); }); test('spawn 4 browsers', {timeout: 60 * 1000}, function(done) { pp.farm.spawn(pp.uri(), 'canary'); pp.farm.spawn(pp.uri(), 'canary'); pp.farm.spawn(pp.uri(), 'canary'); pp.farm.spawn(pp.uri(), 'canary'); pp.waitForClients(4, function() { var clientIDs = pp.manager.getClientIDs(); ppIds.A = clientIDs[0]; ppIds.B = clientIDs[1]; ppIds.C = clientIDs[2]; ppIds.D = clientIDs[3]; cA = pp.manager.getClient(ppIds.A); cB = pp.manager.getClient(ppIds.B); cC = pp.manager.getClient(ppIds.C); cD = pp.manager.getClient(ppIds.D); done(); }); }); test('connect 2 nodes to the signaling server to start the hashring', {timeout: 60 * 60 * 1000} , function(done) { createNodeFromClient(cA, 500); createNodeFromClient(cB, 1000); var count = 0; waitForClient(cA, 'A'); waitForClient(cB, 'B'); function waitForClient(client, identifier) { client.waitToReceive(1, function() { var q = client.getQ(); expect(q[0].data.nodeId).to.be.string(); expect(q[0].data.message).to.be.string(); expect(q[0].data.message).to.equal('node is ready'); client.clearQ(); chordIds[identifier] = q[0].data.nodeId; count += 1; if (count === 2) { done(); } }); } }); test('send message from A to B', function(done) { cA.command('send', { toId: chordIds.B, message: 'hey, how is it going B' }); cB.waitToReceive(1, function() { var q = cB.getQ(); expect(q[0].data.nodeId).to.be.string(); expect(q[0].data.message).to.be.string(); cB.clearQ(); done(); }); }); test('connect a third node', {timeout: 60 * 60 * 1000} , function(done) { createNodeFromClient(cC, 100); waitForClient(cC, 'C'); function waitForClient(client, identifier) { client.waitToReceive(1, function() { var q = client.getQ(); expect(q[0].data.nodeId).to.be.string(); expect(q[0].data.message).to.be.string(); expect(q[0].data.message).to.equal('node is ready'); client.clearQ(); chordIds[identifier] = q[0].data.nodeId; setTimeout(done, 2000); }); } }); test('verify the fingerTable part 1', {timeout: 60 * 60 * 1000}, function(done) { cA.command('finger-table', {}); cB.command('finger-table', {}); cC.command('finger-table', {}); var count = 0; var fingers = {}; collect(cA, 'A'); collect(cB, 'B'); collect(cC, 'C'); function collect(client, identifier) { client.waitToReceive(1, function() { var q = client.getQ(); fingers[identifier] = q[0].data; client.clearQ(); count += 1; if (count === 3) { verify(); } }); } function verify() { expect(fingers.A.sucessor).to.not.equal(fingers.B.sucessor); expect(fingers.B.sucessor).to.not.equal(fingers.C.sucessor); expect(fingers.C.sucessor).to.not.equal(fingers.A.sucessor); done(); } }); test('kill node A'); test('connect a fourth node', {timeout: 60 * 60 * 1000} , function(done) { createNodeFromClient(cD, 100); waitForClient(cD, 'D'); function waitForClient(client, identifier) { client.waitToReceive(1, function() { var q = client.getQ(); expect(q[0].data.nodeId).to.be.string(); expect(q[0].data.message).to.be.string(); expect(q[0].data.message).to.equal('node is ready'); client.clearQ(); chordIds[identifier] = q[0].data.nodeId; setTimeout(done, 1000); }); } }); test('verify the fingerTable part II', {timeout: 60 * 60 * 1000}, function(done) { cA.command('finger-table', {}); cB.command('finger-table', {}); cC.command('finger-table', {}); cD.command('finger-table', {}); var count = 0; var fingers = {}; collect(cA, 'A'); collect(cB, 'B'); collect(cC, 'C'); collect(cD, 'D'); function collect(client, identifier) { client.waitToReceive(1, function() { var q = client.getQ(); fingers[identifier] = q[0].data; client.clearQ(); count += 1; if (count === 4) { verify(); } }); } function verify() { expect(fingers.A.sucessor).to.not.equal(fingers.B.sucessor); expect(fingers.B.sucessor).to.not.equal(fingers.C.sucessor); expect(fingers.C.sucessor).to.not.equal(fingers.D.sucessor); expect(fingers.D.sucessor).to.not.equal(fingers.A.sucessor); done(); } }); test('send message from B to D', {timeout: 60 * 60 * 1000}, function(done) { // console.log(chordIds); cB.command('send', { toId: chordIds.D, message: 'hey, how is it going D' }); cD.waitToReceive(1, function() { var q = cD.getQ(); expect(q[0].data.nodeId).to.be.string(); expect(q[0].data.message).to.be.string(); cD.clearQ(); setTimeout(done, 1000); }); }); /// helper functions function createNodeFromClient(client, time) { setTimeout(function() { client.command('create-node', {}); }, 500); } });