From 84e88901c28e39e406947d3711786383ad3f7e16 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Fri, 14 Apr 2017 08:48:58 -0700 Subject: [PATCH 1/3] test: adding circuit tests [wip] --- package.json | 5 +- test/circuit/circuit.spec.js | 443 ++++++++++++++++++++++++++++++ test/circuit/fixtures/nodes.js | 25 ++ test/circuit/helpers/test-node.js | 22 ++ test/circuit/helpers/utils.js | 110 ++++++++ 5 files changed, 603 insertions(+), 2 deletions(-) create mode 100644 test/circuit/circuit.spec.js create mode 100644 test/circuit/fixtures/nodes.js create mode 100644 test/circuit/helpers/test-node.js create mode 100644 test/circuit/helpers/utils.js diff --git a/package.json b/package.json index 2845307..8338643 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,8 @@ "dirty-chai": "^1.2.2", "lodash.times": "^4.3.2", "pre-commit": "^1.2.2", - "pull-stream": "^3.5.0" + "pull-stream": "^3.5.0", + "sinon": "^2.1.0" }, "dependencies": { "libp2p": "~0.9.0", @@ -76,4 +77,4 @@ "kumavis ", "varunagarwal315 " ] -} \ No newline at end of file +} diff --git a/test/circuit/circuit.spec.js b/test/circuit/circuit.spec.js new file mode 100644 index 0000000..6822ad2 --- /dev/null +++ b/test/circuit/circuit.spec.js @@ -0,0 +1,443 @@ +/* eslint-env mocha */ +'use strict' + +const TCP = require('libp2p-tcp') +const WS = require('libp2p-websockets') +const spdy = require('libp2p-spdy') +const multiplex = require('libp2p-multiplex') + +const waterfall = require('async/waterfall') +const utils = require('./helpers/utils') + +const sinon = require('sinon') + +const chai = require('chai') +chai.use(require('dirty-chai')) + +const expect = chai.expect + +const nodeKeys = require('./fixtures/nodes') + +describe('test relay', function () { + describe('test connecting over any relay', function () { + this.timeout(500000) + + let portBase = 9010 // TODO: randomize or mock sockets + let testNodes + + function setUpNodes (muxer, done) { + utils.createNodes( + { + relayNode: { + transports: [new TCP(), new WS()], + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}`, + `/ip4/0.0.0.0/tcp/${portBase++}/ws` + ], + isCrypto: true, + config: { + relay: { + Circuit: { + Enabled: true + } + } + } + }, + nodeA: { + transports: [new TCP()], + isCrypto: true, + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}` + ] + }, + nodeB: { + transports: [new WS()], + isCrypto: true, + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}/ws` + ] + } + }, + (err, nodes) => { + if (err) { + return done(err) + } + + testNodes = nodes + done() + }) + } + + beforeEach(function (done) { + setUpNodes(spdy, () => { + let nodeA = testNodes['nodeA'] + let nodeB = testNodes['nodeB'] + let relayNode = testNodes['relayNode'] + + // for now, explicitly add the relay nodes, + // because its really hard to time when they + // are added in the circuit. We have a test + // to verify that that functionality works on + // its own + waterfall([ + (cb) => nodeA.dial(relayNode.peerInfo, cb), + (conn, cb) => nodeB.dial(relayNode.peerInfo, cb) + ], () => setTimeout(done, 1000)) // WS needs some time to initialize + }) + }) + + afterEach(function circuitTests (done) { + // spdy throws a socket hangup... + // need to investigate how to properly shutdown, + // for now we'll ignore the error + utils.stopNodes(testNodes, () => done()) + }) + + it('dial to a node over a relay and write values', function (done) { + utils.dialAndReverse( + testNodes.nodeA, + testNodes.nodeB, + ['hello', 'hello1', 'hello2', 'hello3'], + (err, result) => { + expect(err).to.be.null() + expect(result[0]).to.equal('hello'.split('').reverse('').join('')) + expect(result[1]).to.equal('hello1'.split('').reverse('').join('')) + expect(result[2]).to.equal('hello2'.split('').reverse('').join('')) + expect(result[3]).to.equal('hello3'.split('').reverse('').join('')) + done() + }) + }) + }) + + describe('test listening on relay address', function () { + this.timeout(500000) + + describe(`listen on an explicit relay addr`, function () { + let portBase = 9020 // TODO: randomize or mock sockets + let testNodes + + let relaySpy1 + let relaySpy2 + let active = false + + function setUpNodes (muxer, done) { + utils.createNodes( + { + relayNode1: { + id: nodeKeys.node1, + transports: [new TCP(), new WS()], + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}`, + `/ip4/0.0.0.0/tcp/${portBase++}/ws` + ], + isCrypto: true, + config: { + relay: { + Circuit: { + Enabled: true, + Active: active + } + } + } + }, + relayNode2: { + id: nodeKeys.node2, + transports: [new TCP(), new WS()], + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}`, + `/ip4/0.0.0.0/tcp/${portBase++}/ws` + ], + isCrypto: true, + config: { + relay: { + Circuit: { + Enabled: true, + Active: active + } + } + } + }, + nodeA: { + id: nodeKeys.node3, + transports: [new TCP()], + isCrypto: true, + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}`, + `/ip4/0.0.0.0/tcp/9022/ipfs/${nodeKeys.node2.id}/p2p-circuit` + ] + }, + nodeB: { + id: nodeKeys.node4, + transports: [new WS()], + isCrypto: true, + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}/ws`, + `/ip4/0.0.0.0/tcp/9021/ws/ipfs/${nodeKeys.node1.id}/p2p-circuit` + ] + } + }, + (err, nodes) => { + if (err) { + return done(err) + } + + testNodes = nodes + relaySpy1 = sinon.spy(testNodes['relayNode1'].relayCircuit, 'circuit') + relaySpy2 = sinon.spy(testNodes['relayNode2'].relayCircuit, 'circuit') + + done() + }) + } + + describe(`passive`, function () { + beforeEach(function (done) { + waterfall([ + (cb) => setUpNodes(multiplex, cb), + (cb) => { + let nodeA = testNodes['nodeA'] + let nodeB = testNodes['nodeB'] + let relayNode1 = testNodes['relayNode1'] + let relayNode2 = testNodes['relayNode2'] + + waterfall([ + (cb) => nodeA.dial(relayNode1.peerInfo, cb), + (conn, cb) => nodeA.dial(relayNode2.peerInfo, cb), + (conn, cb) => nodeB.dial(relayNode1.peerInfo, cb), + (conn, cb) => nodeB.dial(relayNode2.peerInfo, cb) + ], () => setTimeout(cb, 1000)) // WS needs some time to initialize + } + ], done) + }) + + afterEach(function circuitTests (done) { + utils.stopNodes(testNodes, done) + }) + + it('dial over the correct relay', function (done) { + utils.dialAndReverse(testNodes['nodeA'], testNodes['nodeB'], ['hello'], (err, result) => { + expect(err).to.be.null() + expect(relaySpy2.called).to.be.not.ok() + expect(relaySpy1.called).to.be.ok() + + expect(relaySpy1.args[0][1].toString()) + .to + .equal((`/ipfs/${testNodes['nodeB'].peerInfo.id.toB58String()}`)) + + expect(result[0]).to.equal('hello'.split('').reverse('').join('')) + + done(err) + }) + }) + + it('dial over the correct relay and transport', function (done) { + utils.dialAndReverse(testNodes['nodeB'], testNodes['nodeA'], ['hello'], (err, result) => { + expect(err).to.be.null() + expect(relaySpy1.called).to.be.not.ok() + expect(relaySpy2.called).to.be.ok() + + expect(relaySpy2.args[0][1].toString()) + .to + .equal((`/ipfs/${testNodes['nodeA'].peerInfo.id.toB58String()}`)) + + expect(result[0]).to.equal('hello'.split('').reverse('').join('')) + + done(err) + }) + }) + }) + + // TODO: active dialing needs more work + describe.skip(`active`, function () { + beforeEach(function (done) { + active = true + setUpNodes(multiplex, () => { + setTimeout(done, 5000) // give the nodes time to startup + }) + }) + + afterEach(function circuitTests (done) { + utils.stopNodes(testNodes, done) + }) + + it('dial over the correct relay', function (done) { + utils.dialAndReverse(testNodes['nodeA'], testNodes['nodeB'], ['hello'], (err, result) => { + expect(err).to.be.null() + expect(relaySpy2.called).to.be.not.ok() + expect(relaySpy1.called).to.be.ok() + + expect(relaySpy1.args[0][1].toString()) + .to + .equal((`/ipfs/${testNodes['nodeB'].peerInfo.id.toB58String()}`)) + + expect(result[0]).to.equal('hello'.split('').reverse('').join('')) + + done(err) + }) + }) + + it('dial over the correct relay and transport', function (done) { + utils.dialAndReverse(testNodes['nodeB'], testNodes['nodeA'], ['hello'], (err, result) => { + expect(err).to.be.null() + expect(relaySpy1.called).to.be.not.ok() + expect(relaySpy2.called).to.be.ok() + + expect(relaySpy2.args[0][1].toString()) + .to + .equal((`/ipfs/${testNodes['nodeA'].peerInfo.id.toB58String()}`)) + + expect(result[0]).to.equal('hello'.split('').reverse('').join('')) + + done(err) + }) + }) + }) + }) + + describe(`listen on an explicit chained relay addr`, function () { + let portBase = 9030 // TODO: randomize or mock sockets + let testNodes + + let relaySpy1 + let relaySpy2 + + function setUpNodes (muxer, done) { + utils.createNodes( + { + relayNode1: { + id: nodeKeys.node1, + transports: [new TCP(), new WS()], + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}`, + `/ip4/0.0.0.0/tcp/${portBase++}/ws` + ], + isCrypto: true, + config: { + relay: { + Circuit: { + Enabled: true + } + } + } + }, + relayNode2: { + id: nodeKeys.node2, + transports: [new TCP(), new WS()], + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}`, + `/ip4/0.0.0.0/tcp/${portBase++}/ws` + ], + isCrypto: true, + config: { + relay: { + Circuit: { + Enabled: true + } + } + } + }, + nodeA: { + id: nodeKeys.node3, + transports: [new TCP()], + isCrypto: true, + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}`, + `/ip4/0.0.0.0/tcp/9033/ws/ipfs/${nodeKeys.node2.id}/p2p-circuit/` + + `ip4/0.0.0.0/tcp/9031/ipfs/${nodeKeys.node1.id}/p2p-circuit` + ] + }, + nodeB: { + id: nodeKeys.node4, + transports: [new WS()], + isCrypto: true, + muxer: muxer, + addrs: [ + `/ip4/0.0.0.0/tcp/${portBase++}/ws`, + `/ipfs/${nodeKeys.node1.id}/p2p-circuit/ipfs/${nodeKeys.node2.id}/p2p-circuit` + ] + } + }, + (err, nodes) => { + if (err) { + return done(err) + } + + testNodes = nodes + relaySpy1 = sinon.spy(testNodes['relayNode1'].relayCircuit, 'circuit') + relaySpy2 = sinon.spy(testNodes['relayNode2'].relayCircuit, 'circuit') + + done() + }) + } + + beforeEach(function (done) { + setUpNodes(multiplex, () => { + let nodeA = testNodes['nodeA'] + let nodeB = testNodes['nodeB'] + let relayNode1 = testNodes['relayNode1'] + let relayNode2 = testNodes['relayNode2'] + + waterfall([ + (cb) => nodeA.dial(relayNode1.peerInfo, cb), + (conn, cb) => nodeA.dial(relayNode2.peerInfo, cb), + (conn, cb) => nodeB.dial(relayNode1.peerInfo, cb), + (conn, cb) => nodeB.dial(relayNode2.peerInfo, cb), + (conn, cb) => relayNode1.dial(relayNode2.peerInfo, cb), + (conn, cb) => relayNode2.dial(relayNode1.peerInfo, cb) + ], () => setTimeout(done, 1000)) // WS needs some time to initialize + }) + }) + + afterEach(function circuitTests (done) { + utils.stopNodes(testNodes, done) + }) + + it('dial over the correct chained relay addr', function (done) { + utils.dialAndReverse(testNodes['nodeA'], testNodes['nodeB'], ['hello'], (err, result) => { + expect(err).to.be.null() + expect(relaySpy1.called).to.be.ok() + expect(relaySpy2.called).to.be.ok() + + expect(relaySpy1.args[0][1].toString()) + .to + .equal((`/ipfs/${testNodes['relayNode2'].peerInfo.id.toB58String()}`)) + + expect(relaySpy2.args[0][1].toString()) + .to + .equal((`/ipfs/${testNodes['nodeB'].peerInfo.id.toB58String()}`)) + + expect(result[0]).to.equal('hello'.split('').reverse('').join('')) + done(err) + }) + }) + + it('dial over the correct chained relay addr and transport', function (done) { + utils.dialAndReverse(testNodes['nodeB'], testNodes['nodeA'], ['hello'], (err, result) => { + expect(err).to.be.null() + expect(relaySpy1.called).to.be.ok() + expect(relaySpy2.called).to.be.ok() + + expect(relaySpy1.args[0][1].toString()) + .to + .equal((`/ipfs/${testNodes['nodeA'].peerInfo.id.toB58String()}`)) + + expect(relaySpy2.args[0][1].toString()) + .to + .equal((`/ip4/0.0.0.0/tcp/9031/ipfs/${testNodes['relayNode1'].peerInfo.id.toB58String()}`)) + + expect(result[0]).to.equal('hello'.split('').reverse('').join('')) + done(err) + }) + }) + }) + }) +}) diff --git a/test/circuit/fixtures/nodes.js b/test/circuit/fixtures/nodes.js new file mode 100644 index 0000000..71a274d --- /dev/null +++ b/test/circuit/fixtures/nodes.js @@ -0,0 +1,25 @@ +'use strict' + +exports.node1 = { + id: 'QmSswe1dCFRepmhjAMR5VfHeokGLcvVggkuDJm7RMfJSrE', + privKey: 'CAASpwkwggSjAgEAAoIBAQDJwzJPar4nylKY71Mm5q2BOED8uPf1ILvIi15VwVZWqter6flnlii/RKEcBypPbFqJHHa56MvybgQgrFmHKwDjnJvq4jyOZfR+o/D/99Ft1p2FAEBjImSXAgNpK4YsbyV5r0Q1+Avcj++aWWlLu6enUrL9WGzeUkf0U5L6XwXEPRUQdEojAIQi241P1hyqXX5gKAZVGqcPtKb6p1db3fcXodkS1G6JR90TopJHCqTCECp3SB9c6LlG7KXU92sIHJBlhOEEzGkEI1pM1SWnNnW5VLEypU7P56ifzzp4QxPNiJeC+cmE5SrgR3cXP44iKOuNVRJwBpCh5oNYqECzgqJ9AgMBAAECggEBAJpCdqXHrAmKJCqv2HiGqCODGhTfax1s4IYNIJwaTOPIjUrwgfKUGSVb2H4wcEX3RyVLsO6lMcFyIg/FFlJFK9HavE8SmFAbXZqxx6I9HE+JZjf5IEFrW1Mlg+wWDejNNe7adSF6O79wATaWo+32VNGWZilTQTGd4UvJ1jc9DZCh8zZeNhm4C6exXD45gMB0HI1t2ZNl47scsBEE4rV+s7F7y8Yk/tIsf0wSI/H8KSXS5I9aFxr3Z9c3HOfbVwhnIfNUDqcFTeU5BnhByYNLJ4v9xGj7puidcabVXkt2zLmm/LHbKVeGzec9LW5D+KkuB/pKaslsCXN6bVlu+SbVr9UCgYEA7MXfzZw36vDyfn4LPCN0wgzz11uh3cm31QzOPlWpA7hIsL/eInpvc8wa9yBRC1sRk41CedPHn913MR6EJi0Ne6/B1QOmRYBUjr60VPRNdTXCAiLykjXg6+TZ+AKnxlUGK1hjTo8krhpWq7iD/JchVlLoqDAXGFHvSxN0H3WEUm8CgYEA2iWC9w1v+YHfT2PXcLxYde9EuLVkIS4TM7Kb0N3wr/4+K4xWjVXuaJJLJoAbihNAZw0Y+2s1PswDUEpSG0jXeNXLs6XcQxYSEAu/pFdvHFeg2BfwVQoeEFlWyTJR29uti9/APaXMo8FSVAPPR5lKZLStJDM9hEfAPfUaHyic39MCgYAKQbwjNQw7Ejr+/cjQzxxkt5jskFyftfhPs2FP0/ghYB9OANHHnpQraQEWCYFZQ5WsVac2jdUM+NQL/a1t1e/Klt+HscPHKPsAwAQh1f9w/2YrH4ZwjQL0VRKYKs1HyzEcOZT7tzm4jQ2KHNEi5Q0dpzPK7WJivFHoZ6xVHIsh4wKBgAQq20mk9BKsLHvzyFXbA0WdgI6WyIbpvmwqaVegJcz26nEiiTTCA3/z64OcxunoXD6bvXJwJeBBPX73LIJg7dzdGLsh3AdcEJRF5S9ajEDaW7RFIM4/FzvwuPu2/mFY3QPjDmUfGb23H7+DIx6XCxjJatVaNT6lsEJ+wDUALZ8JAoGAO0YJSEziA7y0dXPK5azkJUMJ5yaN+zRDmoBnEggza34rQW0s16NnIR0EBzKGwbpNyePlProv4dQEaLF1kboKsSYvV2rW2ftLVdNqBHEUYFRC9ofPctCxwM1YU21TI2/k1squ+swApg2EHMev2+WKd+jpVPIbCIvJ3AjiAKZtiGQ=', + pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJwzJPar4nylKY71Mm5q2BOED8uPf1ILvIi15VwVZWqter6flnlii/RKEcBypPbFqJHHa56MvybgQgrFmHKwDjnJvq4jyOZfR+o/D/99Ft1p2FAEBjImSXAgNpK4YsbyV5r0Q1+Avcj++aWWlLu6enUrL9WGzeUkf0U5L6XwXEPRUQdEojAIQi241P1hyqXX5gKAZVGqcPtKb6p1db3fcXodkS1G6JR90TopJHCqTCECp3SB9c6LlG7KXU92sIHJBlhOEEzGkEI1pM1SWnNnW5VLEypU7P56ifzzp4QxPNiJeC+cmE5SrgR3cXP44iKOuNVRJwBpCh5oNYqECzgqJ9AgMBAAE=' +} + +exports.node2 = { + id: 'QmYJjAri5soV8RbeQcHaYYcTAYTET17QTvcoFMyKvRDTXe', + privKey: 'CAASpgkwggSiAgEAAoIBAQDt7YgUeBQsoN/lrgo690mB7yEh8G9iXhZiDecgZCLRRSl3v2cH9w4WjhoW9erfnVbdoTqkCK+se8uK01ySi/ubQQDPcrjacXTa6wAuRTbCG/0bUR9RxKtxZZBS1HaY7L923ulgGDTiVaRQ3JQqhzmQkaU0ikNcluSGaw0kmhXP6JmcL+wndKgW5VD9etcp2Qlk8uUFC/GAO90cOAuER3wnI3ocHGm9on9zyb97g4TDzIfjSaTW4Wanmx2yVbURQxmCba16X3LT9IMPqQaGOzq3+EewMLeCESbUm/uJaJLdqWrWRK4oNzxcMgmUkzav+s476HdA9CRo72am+g3Vdq+lAgMBAAECggEAcByKD6MZVoIjnlVo6qoVUA1+3kAuK/rLrz5/1wp4QYXGaW+eO+mVENm6v3D3UJESGnLbb+nL5Ymbunmn2EHvuBNkL1wOcJgfiPxM5ICmscaAeHu8N0plwpQp8m28yIheG8Qj0az2VmQmfhfCFVwMquuGHgC8hwdu/Uu6MLIObx1xjtaGbY9kk7nzAeXHeJ4RDeuNN0QrYuQVKwrIz1NtPNDR/cli298ZXJcm+HEhBCIHVIYpAq6BHSuiXVqPGEOYWYXo+yVhEtDJ8BmNqlN1Y1s6bnfu/tFkKUN6iQQ46vYnQEGTGR9lg7J/c6tqfRs9FcywWb9J1SX6HxPO8184zQKBgQD6vDYl20UT4ZtrzhFfMyV/1QUqFM/TdwNuiOsIewHBol9o7aOjrxrrbYVa1HOxETyBjmFsW+iIfOVl61SG2HcU4CG+O2s9WBo4JdRlOm4YQ8/83xO3YfbXzuTx8BMCyP/i1uPIZTKQFFAN0HiL96r4L60xHoWB7tQsbZiEbIO/2wKBgQDy7HnkgVeTld6o0+sT84FYRUotjDB00oUWiSeGtj0pFC4yIxhMhD8QjKiWoJyJItcoCsQ/EncuuwwRtuXi83793lJQR1DBYd+TSPg0M8J1pw97fUIPi/FU+jHtrsx7Vn/7Bk9voictsYVLAfbi68tYdsZpAaYOWYMY9NUfVuAmfwKBgCYZDwk1hgt9TkZVK2KRvPLthTldrC5veQAEoeHJ/vxTFbg105V9d9Op8odYnLOc8NqmrbrvRCfpAlo4JcHPhliPrdDf6m2Jw4IgjWNMO4pIU4QSyUYmBoHIGBWC6wCTVf47tKSwa7xkub0/nfF2km3foKtD/fk+NtMBXBlS+7ndAoGAJo6GIlCtN82X07AfJcGGjB4jUetoXYJ0gUkvruAKARUk5+xOFQcAg33v3EiNz+5pu/9JesFRjWc+2Sjwf/8p7t10ry1Ckg8Yz2XLj22PteDYQj91VsZdfaFgf1s5NXJbSdqMjSltkoEUqP0c1JOcaOQhRdVvJ+PpPPLPSPQfC70CgYBvJE1I06s7BEM1DOli3VyfNaJDI4k9W2dCJOU6Bh2MNmbdRjM3xnpOKH5SqRlCz/oI9pn4dxgbX6WPg331MD9CNYy2tt5KBQRrSuDj8p4jlzMIpX36hsyTTrzYU6WWSIPz6jXW8IexXKvXEmr8TVb78ZPiQfbG012cdUhAJniNgg==', + pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDt7YgUeBQsoN/lrgo690mB7yEh8G9iXhZiDecgZCLRRSl3v2cH9w4WjhoW9erfnVbdoTqkCK+se8uK01ySi/ubQQDPcrjacXTa6wAuRTbCG/0bUR9RxKtxZZBS1HaY7L923ulgGDTiVaRQ3JQqhzmQkaU0ikNcluSGaw0kmhXP6JmcL+wndKgW5VD9etcp2Qlk8uUFC/GAO90cOAuER3wnI3ocHGm9on9zyb97g4TDzIfjSaTW4Wanmx2yVbURQxmCba16X3LT9IMPqQaGOzq3+EewMLeCESbUm/uJaJLdqWrWRK4oNzxcMgmUkzav+s476HdA9CRo72am+g3Vdq+lAgMBAAE=' +} + +exports.node3 = { + id: 'QmQWqGdndSpAkxfk8iyiJyz3XXGkrDNujvc8vEst3baubA', + privKey: 'CAASpwkwggSjAgEAAoIBAQDdnGp0X7Pix5dIawfyuffVryRDRS5JXdyjayKUkgikJLYoiijB5TakrFKhx1SDKpmVLxxqAGz8m5iA2cHwetIQXTZvdYx7XXxv332En3ji8TiGRUiEFM8KQ5WCJ5G7yw8R2pv/pYdnMrPd04QbtSCn0cFVCiiA2Zkl5KnwBo/lf+sVI/TEeiwmVD9nxi13qWgBTmCysqH8Ppyu8fq+bQgqRZSlalVDswyIhgWlepPkD0uYakJJhhOxY+2RlbNhGY0qjRyMTYou2uR/hfd6j8uR++WdB0v3+DYWG2Kc3sWa4BLYb5r4trvQGO1Iagnwuk3AVoi7PldsaInekzWEVljDAgMBAAECggEAXx0jE49/xXWkmJBXePYYSL5C8hxfIV4HtJvm251R2CFpjTy/AXk/Wq4bSRQkUaeXA1CVAWntXP3rFmJfurb8McnP80agZNJa9ikV1jYbzEt71yUlWosT0XPwV0xkYBVnAmKxUafZ1ZENYcfGi53RxjVgpP8XIzZBZOIfjcVDPVw9NAOzQmq4i3DJEz5xZAkaeSM8mn5ZFl1JMBUOgyOHB7d4BWd3zuLyvnn0/08HlsaSUl0mZa3f2Lm2NlsjOiNfMCJTOIT+xDEP9THm5n2cqieSjvtpAZzV4kcoD0rB8OsyHQlFAEXzkgELDr5dVXji0rrIdVz8stYAKGfi996OAQKBgQDuviV1sc+ClJQA59vqbBiKxWqcuCKMzvmL4Yk1e/AkQeRt+JX9kALWzBx65fFmHTj4Lus8AIQoiruPxa0thtqh/m3SlucWnrdaW410xbz3KqQWS7bx+0sFWZIEi4N+PESrIYhtVbFuRiabYgliqdSU9shxtXXnvfhjl+9quZltiwKBgQDtoUCKqrZbm0bmzLvpnKdNodg1lUHaKGgEvWgza2N1t3b/GE07iha2KO3hBDta3bdfIEEOagY8o13217D0VIGsYNKpiEGLEeNIjfcXBEqAKiTfa/sXUfTprpWBZQ/7ZS+eZIYtQjq14EHa7ifAby1v3yDrMIuxphz5JfKdXFgYqQKBgHr47FikPwu2tkmFJCyqgzWvnEufOQSoc7eOc1tePIKggiX2/mM+M4gqWJ0hJeeAM+D6YeZlKa2sUBItMxeZN7JrWGw5mEx5cl4TfFhipgP2LdDiLRiVZL4bte+rYQ67wm8XdatDkYIIlkhBBi6Q5dPZDcQsQNAedPvvvb2OXi4jAoGBAKp06FpP+L2fle2LYSRDlhNvDCvrpDA8mdkEkRGJb/AKKdb09LnH5WDH3VNy+KzGrHoVJfWUAmNPAOFHeYzabaZcUeEAd5utui7afytIjbSABrEpwRTKWneiH2aROzSnMdBZ5ZHjlz/N3Q+RlHxKg/piwTdUPHCzasch/HX6vsr5AoGAGvhCNPKyCwpu8Gg5GQdx0yN6ZPar9wieD345cLanDZWKkLRQbo4SfkfoS+PDfOLzDbWFdPRnWQ0qhdPm3D/N1YD/nudHqbeDlx0dj/6lEHmmPKFFO2kiNFEhn8DycNGbvWyVBKksacuRXav21+LvW+TatUkRMhi8fgRoypnbJjg=', + pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdnGp0X7Pix5dIawfyuffVryRDRS5JXdyjayKUkgikJLYoiijB5TakrFKhx1SDKpmVLxxqAGz8m5iA2cHwetIQXTZvdYx7XXxv332En3ji8TiGRUiEFM8KQ5WCJ5G7yw8R2pv/pYdnMrPd04QbtSCn0cFVCiiA2Zkl5KnwBo/lf+sVI/TEeiwmVD9nxi13qWgBTmCysqH8Ppyu8fq+bQgqRZSlalVDswyIhgWlepPkD0uYakJJhhOxY+2RlbNhGY0qjRyMTYou2uR/hfd6j8uR++WdB0v3+DYWG2Kc3sWa4BLYb5r4trvQGO1Iagnwuk3AVoi7PldsaInekzWEVljDAgMBAAE=' +} + +exports.node4 = { + id: 'QmQvM2mpqkjyXWbTHSUidUAWN26GgdMphTh9iGDdjgVXCy', + privKey: 'CAASqAkwggSkAgEAAoIBAQC6pg6LYWbY+49SOYdYap6RPqKqZxg80IXeo3hiTUbiGtTruxVYZpnz3UbernL9J9mwlXJGRUQJUKmXmi1yePTQiyclpH0KyPefaWLbpxJQdCBI1TPZpDWo2hutWSPqhKBU1QyH2FLKQPWLdxuIX1cNFPtIlSl5gCxN6oiDIwh7++kxNM1G+d5XgJX6iHLlLoNv3Wn6XYX+VtYdyZRFk8gYyT2BrISbxmsrSjSOodwUUzF8TYTjsqW6ksL2x0mrRm2cMM9evULktqwU+I8l9ulASDbFWBXUToXaZSL9M+Oq5JvZO0WIjPeYVpAgWladtayhdxg5dBv8aTbDaM5DZvyRAgMBAAECggEAR65YbZz1k6Vg0HI5kXI4/YzxicHYJBrtHqjnJdGJxHILjZCmzPFydJ5phkG29ZRlXRS381bMn0s0Jn3WsFzVoHWgjitSvl6aAsXFapgKR42hjHcc15vh47wH3xYZ3gobTRkZG96vRO+XnX0bvM7orqR9MM3gRMI9wZqt3LcKnhpiqSlyEZ3Zehu7ZZ8B+XcUw42H6ZTXgmg5mCFEjS/1rVt+EsdZl7Ll7jHigahPA6qMjyRiZB6T20qQ0FFYfmaNuRuuC6cWUXf8DOgnEjMB/Mi/Feoip9bTqNBrVYn2XeDxdMv5pDznNKXpalsMkZwx5FpNOMKnIMdQFyAGtkeQ9QKBgQD3rjTiulitpbbQBzF8VXeymtMJAbR1TAqNv2yXoowhL3JZaWICM7nXHjjsJa3UzJygbi8bO0KWrw7tY0nUbPy5SmHtNYhmUsEjiTjqEnNRrYN68tEKr0HlgX+9rArsjOcwucl2svFSfk+rTYDHU5neZkDDhu1QmnZm/pQI92Lo4wKBgQDA6wpMd53fmX9DhWegs3xelRStcqBTw1ucWVRyPgY1hO1cJ0oReYIXKEw9CHNLW0RHvnVM26kRnqCl+dTcg7dhLuqrckuyQyY1KcRYG1ryJnz3euucaSF2UCsZCHvFNV7Vz8dszUMUVCogWmroVP6HE/BoazUCNh25s/dNwE+i+wKBgEfa1WL1luaBzgCaJaQhk4FQY2sYgIcLEYDACTwQn0C9aBpCdXmYEhEzpmX0JHM5DTOJ48atsYrPrK/3/yJOoB8NUk2kGzc8SOYLWGSoB6aphRx1N2o3IBH6ONoJAH5R/nxnWehCz7oUBP74lCS/v0MDPUS8bzrUJQeKUd4sDxjrAoGBAIRO7rJA+1qF+J1DWi4ByxNHJXZLfh/UhPj23w628SU1dGDWZVsUvZ7KOXdGW2RcRLj7q5E5uXtnEoCillViVJtnRPSun7Gzkfm2Gn3ezQH0WZKVkA+mnpd5JgW2JsS69L6pEPnS0OWZT4b+3AFZgXL8vs2ucR2CJeLdxYdilHuPAoGBAPLCzBkAboXZZtvEWqzqtVNqdMrjLHihFrpg4TXSsk8+ZQZCVN+sRyTGTvBX8+Jvx4at6ClaSgT3eJ/412fEH6CHvrFXjUE9W9y6X0axxaT63y1OXmFiB/hU3vjLWZKZWSDGNS7St02fYri4tWmGtJDjYG1maLRhMSzcoj4fP1xz', + pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6pg6LYWbY+49SOYdYap6RPqKqZxg80IXeo3hiTUbiGtTruxVYZpnz3UbernL9J9mwlXJGRUQJUKmXmi1yePTQiyclpH0KyPefaWLbpxJQdCBI1TPZpDWo2hutWSPqhKBU1QyH2FLKQPWLdxuIX1cNFPtIlSl5gCxN6oiDIwh7++kxNM1G+d5XgJX6iHLlLoNv3Wn6XYX+VtYdyZRFk8gYyT2BrISbxmsrSjSOodwUUzF8TYTjsqW6ksL2x0mrRm2cMM9evULktqwU+I8l9ulASDbFWBXUToXaZSL9M+Oq5JvZO0WIjPeYVpAgWladtayhdxg5dBv8aTbDaM5DZvyRAgMBAAE=' +} diff --git a/test/circuit/helpers/test-node.js b/test/circuit/helpers/test-node.js new file mode 100644 index 0000000..998bf07 --- /dev/null +++ b/test/circuit/helpers/test-node.js @@ -0,0 +1,22 @@ +'use strict' + +const Libp2p = require('libp2p') +const secio = require('libp2p-secio') + +class TestNode extends Libp2p { + constructor (peerInfo, transports, muxer, options) { + options = options || {} + + const modules = { + transport: transports, + connection: { + muxer: [muxer], + crypto: options.isCrypto ? [secio] : null + }, + discovery: [] + } + super(modules, peerInfo, null, options) + } +} + +module.exports = TestNode diff --git a/test/circuit/helpers/utils.js b/test/circuit/helpers/utils.js new file mode 100644 index 0000000..de198ca --- /dev/null +++ b/test/circuit/helpers/utils.js @@ -0,0 +1,110 @@ +'use strict' + +const TestNode = require('./test-node') +const PeerInfo = require('peer-info') +const PeerId = require('peer-id') +const eachAsync = require('async/each') +const pull = require('pull-stream') + +exports.createNodes = function createNodes (configNodes, callback) { + const nodes = {} + eachAsync(Object.keys(configNodes), (key, cb1) => { + let config = configNodes[key] + + const setup = (err, peer) => { + if (err) { + callback(err) + } + + eachAsync(config.addrs, (addr, cb2) => { + peer.multiaddrs.add(addr) + cb2() + }, (err) => { + if (err) { + return callback(err) + } + + nodes[key] = new TestNode(peer, config.transports, config.muxer, config.config) + cb1() + }) + } + + if (config.id) { + PeerId.createFromJSON(config.id, (err, peerId) => { + if (err) return callback(err) + PeerInfo.create(peerId, setup) + }) + } else { + PeerInfo.create(setup) + } + }, (err) => { + if (err) { + return callback(err) + } + + startNodes(nodes, (err) => { + if (err) { + callback(err) + } + + callback(null, nodes) + }) + }) +} + +function startNodes (nodes, callback) { + eachAsync(Object.keys(nodes), + (key, cb) => { + nodes[key].start(cb) + }, + (err) => { + if (err) { + return callback(err) + } + callback(null) + }) +} + +exports.stopNodes = function stopNodes (nodes, callback) { + eachAsync(Object.keys(nodes), + (key, cb) => { + nodes[key].stop(cb) + }, + (err) => { + if (err) { + return callback(err) + } + callback() + }) +} + +function reverse (protocol, conn) { + pull( + conn, + pull.map((data) => { + return data.toString().split('').reverse().join('') + }), + conn + ) +} + +exports.dialAndReverse = function dialAndRevers (srcNode, dstNode, vals, done) { + dstNode.handle('/ipfs/reverse/1.0.0', reverse) + + srcNode.dial(dstNode.peerInfo, '/ipfs/reverse/1.0.0', (err, conn) => { + if (err) return done(err) + + pull( + pull.values(vals), + conn, + pull.collect((err, data) => { + if (err) return done(err) + + let reversed = data.map((val, i) => { + return val.toString() + }) + + srcNode.hangUp(srcNode.peerInfo, () => done(null, reversed)) + })) + }) +} From 01ef9c12cae651dc70608a494ba05b57dbb5b702 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Sun, 16 Apr 2017 13:17:21 -0700 Subject: [PATCH 2/3] tests: fixing circuit tests --- test/circuit/circuit.spec.js | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/test/circuit/circuit.spec.js b/test/circuit/circuit.spec.js index 6822ad2..203d2c0 100644 --- a/test/circuit/circuit.spec.js +++ b/test/circuit/circuit.spec.js @@ -77,11 +77,6 @@ describe('test relay', function () { let nodeB = testNodes['nodeB'] let relayNode = testNodes['relayNode'] - // for now, explicitly add the relay nodes, - // because its really hard to time when they - // are added in the circuit. We have a test - // to verify that that functionality works on - // its own waterfall([ (cb) => nodeA.dial(relayNode.peerInfo, cb), (conn, cb) => nodeB.dial(relayNode.peerInfo, cb) @@ -169,7 +164,9 @@ describe('test relay', function () { muxer: muxer, addrs: [ `/ip4/0.0.0.0/tcp/${portBase++}`, - `/ip4/0.0.0.0/tcp/9022/ipfs/${nodeKeys.node2.id}/p2p-circuit` + `/ip4/0.0.0.0/tcp/9022/ipfs/${nodeKeys.node2.id}/p2p-circuit`, + `/ip4/0.0.0.0/tcp/9023/ws/ipfs/${nodeKeys.node2.id}/p2p-circuit`, + `/ipfs/${nodeKeys.node2.id}/p2p-circuit` ] }, nodeB: { @@ -179,7 +176,9 @@ describe('test relay', function () { muxer: muxer, addrs: [ `/ip4/0.0.0.0/tcp/${portBase++}/ws`, - `/ip4/0.0.0.0/tcp/9021/ws/ipfs/${nodeKeys.node1.id}/p2p-circuit` + `/ip4/0.0.0.0/tcp/9020/ipfs/${nodeKeys.node1.id}/p2p-circuit`, + `/ip4/0.0.0.0/tcp/9021/ws/ipfs/${nodeKeys.node1.id}/p2p-circuit`, + `/ipfs/${nodeKeys.node1.id}/p2p-circuit` ] } }, @@ -196,6 +195,7 @@ describe('test relay', function () { }) } + // no way to tell which relay is going to be used with multidialing describe(`passive`, function () { beforeEach(function (done) { waterfall([ @@ -253,16 +253,17 @@ describe('test relay', function () { }) }) - // TODO: active dialing needs more work describe.skip(`active`, function () { beforeEach(function (done) { active = true setUpNodes(multiplex, () => { - setTimeout(done, 5000) // give the nodes time to startup + setTimeout(done, 1000) // give the nodes time to startup }) }) afterEach(function circuitTests (done) { + relaySpy1.reset() + relaySpy2.reset() utils.stopNodes(testNodes, done) }) @@ -322,7 +323,8 @@ describe('test relay', function () { config: { relay: { Circuit: { - Enabled: true + Enabled: true, + Active: true } } } @@ -339,7 +341,8 @@ describe('test relay', function () { config: { relay: { Circuit: { - Enabled: true + Enabled: true, + Active: true } } } @@ -351,8 +354,8 @@ describe('test relay', function () { muxer: muxer, addrs: [ `/ip4/0.0.0.0/tcp/${portBase++}`, - `/ip4/0.0.0.0/tcp/9033/ws/ipfs/${nodeKeys.node2.id}/p2p-circuit/` + - `ip4/0.0.0.0/tcp/9031/ipfs/${nodeKeys.node1.id}/p2p-circuit` + `/ip4/0.0.0.0/tcp/9033/ws/ipfs/${nodeKeys.node2.id}/p2p-circuit` + + `/ip4/0.0.0.0/tcp/9031/ipfs/${nodeKeys.node1.id}/p2p-circuit` ] }, nodeB: { @@ -398,6 +401,8 @@ describe('test relay', function () { }) afterEach(function circuitTests (done) { + relaySpy1.reset() + relaySpy2.reset() utils.stopNodes(testNodes, done) }) From b9230682ff8a7c71abc33141e958915f5fcd786f Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Fri, 21 Apr 2017 16:04:50 -0700 Subject: [PATCH 3/3] tests: fixing tests to work with latests changes --- test/circuit/circuit.spec.js | 40 ++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/test/circuit/circuit.spec.js b/test/circuit/circuit.spec.js index 203d2c0..f94aea4 100644 --- a/test/circuit/circuit.spec.js +++ b/test/circuit/circuit.spec.js @@ -10,7 +10,6 @@ const waterfall = require('async/waterfall') const utils = require('./helpers/utils') const sinon = require('sinon') - const chai = require('chai') chai.use(require('dirty-chai')) @@ -38,8 +37,8 @@ describe('test relay', function () { isCrypto: true, config: { relay: { - Circuit: { - Enabled: true + circuit: { + enabled: true } } } @@ -85,9 +84,6 @@ describe('test relay', function () { }) afterEach(function circuitTests (done) { - // spdy throws a socket hangup... - // need to investigate how to properly shutdown, - // for now we'll ignore the error utils.stopNodes(testNodes, () => done()) }) @@ -132,9 +128,9 @@ describe('test relay', function () { isCrypto: true, config: { relay: { - Circuit: { - Enabled: true, - Active: active + circuit: { + enabled: true, + active: active } } } @@ -150,9 +146,9 @@ describe('test relay', function () { isCrypto: true, config: { relay: { - Circuit: { - Enabled: true, - Active: active + circuit: { + enabled: true, + active: active } } } @@ -188,8 +184,8 @@ describe('test relay', function () { } testNodes = nodes - relaySpy1 = sinon.spy(testNodes['relayNode1'].relayCircuit, 'circuit') - relaySpy2 = sinon.spy(testNodes['relayNode2'].relayCircuit, 'circuit') + relaySpy1 = sinon.spy(testNodes['relayNode1'].relayCircuit, '_circuit') + relaySpy2 = sinon.spy(testNodes['relayNode2'].relayCircuit, '_circuit') done() }) @@ -322,9 +318,9 @@ describe('test relay', function () { isCrypto: true, config: { relay: { - Circuit: { - Enabled: true, - Active: true + circuit: { + enabled: true, + active: true } } } @@ -340,9 +336,9 @@ describe('test relay', function () { isCrypto: true, config: { relay: { - Circuit: { - Enabled: true, - Active: true + circuit: { + enabled: true, + active: true } } } @@ -375,8 +371,8 @@ describe('test relay', function () { } testNodes = nodes - relaySpy1 = sinon.spy(testNodes['relayNode1'].relayCircuit, 'circuit') - relaySpy2 = sinon.spy(testNodes['relayNode2'].relayCircuit, 'circuit') + relaySpy1 = sinon.spy(testNodes['relayNode1'].relayCircuit, '_circuit') + relaySpy2 = sinon.spy(testNodes['relayNode2'].relayCircuit, '_circuit') done() })