UNPKG

decentralized-internet

Version:

An NPM library of programs to create decentralized web and distributed computing projects

212 lines (183 loc) 7.41 kB
'use strict'; const path = require('path'); const assert = require('assertthat'), nock = require('nock'), request = require('supertest'), requireAll = require('require-all'); const Endpoint = require('../../lib/Endpoint'), stabilize = require('../../lib/routes/stabilize'); const mocks = requireAll(path.join(__dirname, 'mocks')); suite('stabilize', () => { test('is a function.', done => { assert.that(stabilize).is.ofType('function'); done(); }); test('throws an error if peer is missing.', done => { assert.that(function () { stabilize(); }).is.throwing('Peer is missing.'); done(); }); suite('route', function () { let peer; setup(function () { peer = new mocks.JoinedPeer({ host: 'localhost', port: 3000 }); }); test('is a function.', done => { assert.that(stabilize(peer)).is.ofType('function'); done(); }); test('fixes the successor if the successor is not reachable.', done => { let fixSuccessorCalled = false; peer.fixSuccessor = () => { fixSuccessorCalled = true; }; request(peer.app). post('/stabilize'). end((err, res) => { assert.that(err).is.null(); assert.that(res.statusCode).is.equalTo(500); assert.that(fixSuccessorCalled).is.true(); done(); }); }); suite('asks the successor about the successor\'s predecessor and', () => { suite('does not update its successor if the successor', () => { test('does not have a predecessor.', done => { const remotePeerPredecessor = nock('https://localhost:4000').post('/predecessor').reply(200); const remotePeerNotify = nock('https://localhost:4000').post('/notify').reply(200); request(peer.app). post('/stabilize'). end((err, res) => { assert.that(err).is.null(); assert.that(res.statusCode).is.equalTo(200); assert.that(peer.successor).is.equalTo({ host: 'localhost', port: 4000, id: 'dc4f424bb575238275aac70b0324ca3a77d5b3dd' }); assert.that(remotePeerPredecessor.isDone()).is.true(); assert.that(remotePeerNotify.isDone()).is.true(); done(); }); }); test('returns the peer itself.', done => { const remotePeerPredecessor = nock('https://localhost:4000').post('/predecessor').reply(200, peer.self); const remotePeerNotify = nock('https://localhost:4000').post('/notify').reply(200); request(peer.app). post('/stabilize'). end((err, res) => { assert.that(err).is.null(); assert.that(res.statusCode).is.equalTo(200); assert.that(peer.successor).is.equalTo({ host: 'localhost', port: 4000, id: 'dc4f424bb575238275aac70b0324ca3a77d5b3dd' }); assert.that(remotePeerPredecessor.isDone()).is.true(); assert.that(remotePeerNotify.isDone()).is.true(); done(); }); }); test('returns the successor itself.', done => { const remotePeerPredecessor = nock('https://localhost:4000').post('/predecessor').reply(200, peer.successor.self); const remotePeerNotify = nock('https://localhost:4000').post('/notify').reply(200); request(peer.app). post('/stabilize'). end((err, res) => { assert.that(err).is.null(); assert.that(res.statusCode).is.equalTo(200); assert.that(peer.successor).is.equalTo({ host: 'localhost', port: 4000, id: 'dc4f424bb575238275aac70b0324ca3a77d5b3dd' }); assert.that(remotePeerPredecessor.isDone()).is.true(); assert.that(remotePeerNotify.isDone()).is.true(); done(); }); }); test('returns a peer between the successor and the peer.', done => { const remotePeerPredecessor = nock('https://localhost:4000').post('/predecessor').reply(200, new Endpoint({ host: 'localhost', port: 2000 })); const remotePeerNotify = nock('https://localhost:4000').post('/notify').reply(200); request(peer.app). post('/stabilize'). end((err, res) => { assert.that(err).is.null(); assert.that(res.statusCode).is.equalTo(200); assert.that(peer.successor).is.equalTo({ host: 'localhost', port: 4000, id: 'dc4f424bb575238275aac70b0324ca3a77d5b3dd' }); assert.that(remotePeerPredecessor.isDone()).is.true(); assert.that(remotePeerNotify.isDone()).is.true(); done(); }); }); }); suite('updates its successor if the successor', () => { test('returns a peer between the peer itself and the successor.', done => { const remotePeerPredecessor = nock('https://localhost:2000').post('/predecessor').reply(200, new Endpoint({ host: 'localhost', port: 4000 })); const remotePeerNotify = nock('https://localhost:4000').post('/notify').reply(200); peer.successor = new Endpoint({ host: 'localhost', port: 2000 }); request(peer.app). post('/stabilize'). end((err, res) => { assert.that(err).is.null(); assert.that(res.statusCode).is.equalTo(200); assert.that(peer.successor).is.equalTo({ host: 'localhost', port: 4000, id: 'dc4f424bb575238275aac70b0324ca3a77d5b3dd' }); assert.that(remotePeerPredecessor.isDone()).is.true(); assert.that(remotePeerNotify.isDone()).is.true(); done(); }); }); }); }); test('notifies its successor about itself as potential predecessor.', done => { const remotePeerPredecessor = nock('https://localhost:4000').post('/predecessor').reply(200); const remotePeerNotify = nock('https://localhost:4000').post('/notify', peer.successor.self).reply(200); request(peer.app). post('/stabilize'). end((err, res) => { assert.that(err).is.null(); assert.that(res.statusCode).is.equalTo(200); assert.that(remotePeerPredecessor.isDone()).is.true(); assert.that(remotePeerNotify.isDone()).is.true(); done(); }); }); test('fixes successor if notifying the successor fails.', done => { const remotePeerPredecessor = nock('https://localhost:4000').post('/predecessor').reply(200); let fixSuccessorCalled = false; peer.fixSuccessor = () => { fixSuccessorCalled = true; }; request(peer.app). post('/stabilize'). end((err, res) => { assert.that(err).is.null(); assert.that(res.statusCode).is.equalTo(500); assert.that(fixSuccessorCalled).is.true(); assert.that(remotePeerPredecessor.isDone()).is.true(); done(); }); }); }); });