From 9e613771eb2de33294141988859555e78fb8ee09 Mon Sep 17 00:00:00 2001 From: David Dias Date: Mon, 18 Dec 2017 12:56:55 +0000 Subject: [PATCH] test: port interop tests to interop repo (#1157) * port interop tests to interop repo * fix --- .aegir.js | 8 - README.md | 33 +-- package.json | 28 +- test/interop/browser.js | 10 - test/interop/circuit-relay.js | 167 ----------- test/interop/exchange-files.js | 216 -------------- test/interop/kad-dht.js | 109 ------- test/interop/node.js | 8 - test/interop/pubsub.js | 346 ---------------------- test/interop/repo.js | 85 ------ test/utils/another-daemon-spawner.js | 51 ---- test/utils/interop-daemon-spawner/go.js | 73 ----- test/utils/interop-daemon-spawner/js.js | 87 ------ test/utils/interop-daemon-spawner/util.js | 9 - 14 files changed, 23 insertions(+), 1207 deletions(-) delete mode 100644 test/interop/browser.js delete mode 100644 test/interop/circuit-relay.js delete mode 100644 test/interop/exchange-files.js delete mode 100644 test/interop/kad-dht.js delete mode 100644 test/interop/node.js delete mode 100644 test/interop/pubsub.js delete mode 100644 test/interop/repo.js delete mode 100644 test/utils/interop-daemon-spawner/go.js delete mode 100644 test/utils/interop-daemon-spawner/js.js delete mode 100644 test/utils/interop-daemon-spawner/util.js diff --git a/.aegir.js b/.aegir.js index bd4bdbb6f0..148ab3fbb8 100644 --- a/.aegir.js +++ b/.aegir.js @@ -3,7 +3,6 @@ const parallel = require('async/parallel') const ads = require('./test/utils/another-daemon-spawner') const js = ads.spawnJsNode -const go = ads.spawnGoNode const stop = ads.stopNodes /* @@ -20,13 +19,6 @@ function start (done) { (cb) => js([`${base}/10014`, `${base}/20014/ws`], true, 31014, 32014, cb), (cb) => js([`${base}/10015`, `${base}/20015/ws`], true, 31015, 32015, cb) ], done) - } else if (process.env.IPFS_TEST === 'interop') { - parallel([ - (cb) => go([`${base}/10027`, `${base}/20027/ws`], true, 33027, 44027, cb), - (cb) => go([`${base}/10028`, `${base}/20028/ws`], true, 33028, 44028, cb), - (cb) => go([`${base}/10031`, `${base}/20031/ws`], true, 33031, 44031, cb), - (cb) => go([`${base}/10032`, `${base}/20032/ws`], true, 33032, 44032, cb) - ], done) } else if (process.env.IPFS_TEST === 'bootstrapers') { done() } diff --git a/README.md b/README.md index a5d746902f..8765020b71 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,6 @@
-

### Project status @@ -494,51 +492,42 @@ A way to mitigate this in Chrome, is to run your IPFS node inside a Service Work > npm test # run just IPFS tests in Node.js -> npm run test:unit:node:core +> npm run test:node:core # run just IPFS core tests -> npm run test:unit:node:core +> npm run test:node:core # run just IPFS HTTP-API tests -> npm run test:unit:node:http +> npm run test:node:http # run just IPFS CLI tests -> npm run test:unit:node:cli +> npm run test:node:cli # run just IPFS core tests in the Browser (Chrome) -> npm run test:unit:browser +> npm run test:browser ``` ### Run interop tests -```sh -# run all the interop tsts -> npm run test:interop - -# run just IPFS interop tests in Node.js using one go-ipfs daemon and one js-ipfs daemon -> npm run test:interop:node - -# run just IPFS interop testsin the Browser (Chrome) using one instance in the browser and one go-ipfs daemon -> npm run test:interop:browser -``` +Run the interop tests with https://github.com/ipfs/interop ### Run benchmark tests ```sh # run all the benchmark tests -> npm run test:benchmark +> npm run benchmark # run just IPFS benchmarks in Node.js -> npm run test:benchmark:node +> npm run benchmark:node # run just IPFS benchmarks in Node.js for an IPFS instance -> npm run test:benchmark:node:core +> npm run benchmark:node:core # run just IPFS benchmarks in Node.js for an IPFS daemon -> npm run test:benchmark:node:http +> npm run benchmark:node:http # run just IPFS benchmarks in the browser (Chrome) -> npm run test:benchmark:browser +> npm run benchmark:browser ``` ### Lint diff --git a/package.json b/package.json index 8775134e76..cb6446bfb9 100644 --- a/package.json +++ b/package.json @@ -24,24 +24,21 @@ "test": "aegir test -t node -t browser --no-cors", "test:node": "aegir test -t node", "test:browser": "aegir test -t browser -t webworker --no-cors", + "test:node": "aegir test -t node", + "test:node:core": "aegir test -t node -f test/core/**.js", + "test:node:http": "aegir test -t node -f test/http-api/index.js", + "test:node:gateway": "aegir test -t node -f test/gateway/index.js", + "test:node:cli": "aegir test -t node -f test/cli/index.js", + "test:browser": "aegir test -t browser --no-cors", + "test:bootstrapers": "IPFS_TEST=bootstrapers aegir test -t browser -f test/bootstrapers.js", + "benchmark": "echo \"Error: no benchmarks yet\" && exit 1", + "benchmark:node": "echo \"Error: no benchmarks yet\" && exit 1", + "benchmark:node:core": "echo \"Error: no benchmarks yet\" && exit 1", + "benchmark:node:http": "echo \"Error: no benchmarks yet\" && exit 1", + "benchmark:browser": "echo \"Error: no benchmarks yet\" && exit 1", "release": "aegir release -t node -t browser", "release-minor": "aegir release --type minor -t node -t browser", "release-major": "aegir release --type major -t node -t browser", - "test:unit:node": "aegir test -t node", - "test:unit:node:core": "aegir test -t node -f test/core/**.js", - "test:unit:node:http": "aegir test -t node -f test/http-api/index.js", - "test:unit:node:gateway": "aegir test -t node -f test/gateway/index.js", - "test:unit:node:cli": "aegir test -t node -f test/cli/index.js", - "test:unit:browser": "aegir test -t browser --no-cors", - "test:interop": "IPFS_TEST=interop aegir test -t node -f test/interop", - "test:interop:node": "IPFS_TEST=interop aegir test -t node -f test/interop/node.js", - "test:interop:browser": "IPFS_TEST=interop aegir test -t browser -f test/interop/browser.js", - "test:bootstrapers": "IPFS_TEST=bootstrapers aegir test -t browser -f test/bootstrapers.js", - "test:benchmark": "echo \"Error: no benchmarks yet\" && exit 1", - "test:benchmark:node": "echo \"Error: no benchmarks yet\" && exit 1", - "test:benchmark:node:core": "echo \"Error: no benchmarks yet\" && exit 1", - "test:benchmark:node:http": "echo \"Error: no benchmarks yet\" && exit 1", - "test:benchmark:browser": "echo \"Error: no benchmarks yet\" && exit 1", "coverage": "aegir coverage", "coverage-publish": "aegir-coverage publish" }, @@ -76,7 +73,6 @@ "form-data": "^2.3.1", "hat": "0.0.3", "interface-ipfs-core": "~0.36.15", - "ipfsd-ctl": "~0.26.0", "left-pad": "^1.2.0", "lodash": "^4.17.4", "mocha": "^4.0.1", diff --git a/test/interop/browser.js b/test/interop/browser.js deleted file mode 100644 index 40a2a297b4..0000000000 --- a/test/interop/browser.js +++ /dev/null @@ -1,10 +0,0 @@ -/* eslint-env mocha */ -'use strict' - -describe('browser interop tests', () => { - it('need to get written', function (done) { - this.timeout(10 * 1000) - // for teardown time - setTimeout(done, 5 * 1000) - }) -}) diff --git a/test/interop/circuit-relay.js b/test/interop/circuit-relay.js deleted file mode 100644 index 2bf1c707dc..0000000000 --- a/test/interop/circuit-relay.js +++ /dev/null @@ -1,167 +0,0 @@ -/* eslint max-nested-callbacks: ["error", 8] */ -/* eslint-env mocha */ -'use strict' - -const chai = require('chai') -const dirtyChai = require('dirty-chai') -const expect = chai.expect -chai.use(dirtyChai) -const parallel = require('async/parallel') -const series = require('async/series') -const bl = require('bl') -const waterfall = require('async/waterfall') -const multiaddr = require('multiaddr') -const crypto = require('crypto') - -const ads = require('../utils/another-daemon-spawner') -const js = ads.spawnJsNode -const go = ads.spawnGoNode -const stop = ads.stopNodes - -describe.skip('circuit interop', () => { - let jsTCP - let jsTCPAddrs - let jsWS - let jsWSAddrs - let jsRelayAddrs - - let goRelayAddrs - - let goTCPAddrs - let goTCP - - let goWSAddrs - let goWS - - beforeEach((done) => { - const base = '/ip4/127.0.0.1/tcp' - - parallel([ - (cb) => js([`${base}/61454/ws`, `${base}/61453`], true, cb), - (cb) => js([`${base}/9002`], cb), - (cb) => js([`${base}/9003/ws`], cb), - (cb) => go([`${base}/0/ws`, `${base}/0`], true, cb), - (cb) => go([`${base}/0`], cb), - (cb) => go([`${base}/0/ws`], cb) - ], (err, nodes) => { - expect(err).to.not.exist() - - jsRelayAddrs = nodes[0][1].map((a) => a.toString()).filter((a) => !a.includes('/p2p-circuit')) - jsTCP = nodes[1][0] - jsTCPAddrs = nodes[1][1].map((a) => a.toString()).filter((a) => a.includes('/p2p-circuit')) - jsWS = nodes[2][0] - jsWSAddrs = nodes[2][1].map((a) => a.toString()).filter((a) => a.includes('/p2p-circuit')) - - goRelayAddrs = nodes[3][1] - goTCP = nodes[4][0].api - goTCPAddrs = nodes[4][1] - goWS = nodes[5][0].api - goWSAddrs = nodes[5][1] - done() - }) - }) - - afterEach(() => stop()) - - it('jsWS <-> jsRelay <-> jsTCP', (done) => { - const data = crypto.randomBytes(128) - series([ - (cb) => jsWS.swarm.connect(jsRelayAddrs[0], cb), - (cb) => jsTCP.swarm.connect(jsRelayAddrs[1], cb), - (cb) => setTimeout(cb, 1000), - (cb) => jsTCP.swarm.connect(jsWSAddrs[0], cb) - ], (err) => { - expect(err).to.not.exist() - waterfall([ - (cb) => jsTCP.files.add(data, cb), - (res, cb) => jsWS.files.cat(res[0].hash, cb), - (stream, cb) => stream.pipe(bl(cb)) - ], done) - }) - }) - - it('goWS <-> jsRelay <-> goTCP', (done) => { - const data = crypto.randomBytes(128) - series([ - (cb) => goWS.swarm.connect(jsRelayAddrs[0], cb), - (cb) => goTCP.swarm.connect(jsRelayAddrs[1], cb), - (cb) => setTimeout(cb, 1000), - (cb) => goTCP.swarm.connect(`/p2p-circuit/ipfs/${multiaddr(goWSAddrs[0]).getPeerId()}`, cb) - ], (err) => { - expect(err).to.not.exist() - waterfall([ - (cb) => goTCP.files.add(data, cb), - (res, cb) => goWS.files.cat(res[0].hash, cb), - (stream, cb) => stream.pipe(bl(cb)) - ], done) - }) - }) - - it('jsWS <-> jsRelay <-> goTCP', (done) => { - const data = crypto.randomBytes(128) - series([ - (cb) => jsWS.swarm.connect(jsRelayAddrs[0], cb), - (cb) => goTCP.swarm.connect(jsRelayAddrs[1], cb), - (cb) => setTimeout(cb, 1000), - (cb) => goTCP.swarm.connect(jsWSAddrs[0], cb) - ], (err) => { - expect(err).to.not.exist() - waterfall([ - (cb) => goTCP.files.add(data, cb), - (res, cb) => jsWS.files.cat(res[0].hash, cb), - (stream, cb) => stream.pipe(bl(cb)) - ], done) - }) - }) - - it('jsTCP <-> goRelay <-> jsWS', (done) => { - const data = crypto.randomBytes(128) - series([ - (cb) => jsTCP.swarm.connect(goRelayAddrs[2], cb), - (cb) => jsWS.swarm.connect(goRelayAddrs[0], cb), - (cb) => setTimeout(cb, 1000), - (cb) => jsWS.swarm.connect(jsTCPAddrs[0], cb) - ], (err) => { - expect(err).to.not.exist() - waterfall([ - (cb) => jsTCP.files.add(data, cb), - (res, cb) => jsWS.files.cat(res[0].hash, cb), - (stream, cb) => stream.pipe(bl(cb)) - ], done) - }) - }) - - it('goTCP <-> goRelay <-> goWS', (done) => { - const data = crypto.randomBytes(128) - series([ - (cb) => goWS.swarm.connect(goRelayAddrs[0], cb), - (cb) => goTCP.swarm.connect(goRelayAddrs[2], cb), - (cb) => setTimeout(cb, 1000), - (cb) => goWS.swarm.connect(`/p2p-circuit/ipfs/${multiaddr(goTCPAddrs[0]).getPeerId()}`, cb) - ], (err) => { - expect(err).to.not.exist() - waterfall([ - (cb) => goTCP.files.add(data, cb), - (res, cb) => goWS.files.cat(res[0].hash, cb), - (stream, cb) => stream.pipe(bl(cb)) - ], done) - }) - }) - - it('jsWS <-> goRelay <-> goTCP', (done) => { - const data = crypto.randomBytes(128) - series([ - (cb) => jsWS.swarm.connect(goRelayAddrs[0], cb), - (cb) => goTCP.swarm.connect(goRelayAddrs[2], cb), - (cb) => setTimeout(cb, 1000), - (cb) => goTCP.swarm.connect(`/p2p-circuit/ipfs/${multiaddr(jsWSAddrs[0]).getPeerId()}`, cb) - ], (err) => { - expect(err).to.not.exist() - waterfall([ - (cb) => goTCP.files.add(data, cb), - (res, cb) => jsWS.files.cat(res[0].hash, cb), - (stream, cb) => stream.pipe(bl(cb)) - ], done) - }) - }) -}) diff --git a/test/interop/exchange-files.js b/test/interop/exchange-files.js deleted file mode 100644 index 1c14ff57ef..0000000000 --- a/test/interop/exchange-files.js +++ /dev/null @@ -1,216 +0,0 @@ -/* eslint-env mocha */ -'use strict' - -const chai = require('chai') -const dirtyChai = require('dirty-chai') -const expect = chai.expect -chai.use(dirtyChai) -const series = require('async/series') -const parallel = require('async/parallel') -const waterfall = require('async/waterfall') -const crypto = require('crypto') -const pretty = require('pretty-bytes') -const randomFs = require('random-fs') -const promisify = require('promisify-es6') -const rimraf = require('rimraf') - -const rmDir = promisify(rimraf) - -const tmpDir = require('../utils/interop-daemon-spawner/util').tmpDir -const GoDaemon = require('../utils/interop-daemon-spawner/go') -const JsDaemon = require('../utils/interop-daemon-spawner/js') - -const sizes = [ - 1024, - 1024 * 62, - // starts failing with spdy - 1024 * 64, - 1024 * 512, - 1024 * 768, - 1024 * 1023, - 1024 * 1024, - 1024 * 1024 * 4, - 1024 * 1024 * 8 -] - -const dirs = [ - 5, - 10, - 50, - 100 -] - -describe('exchange files', () => { - let goDaemon - let jsDaemon - let js2Daemon - - before(function (done) { - this.timeout(15 * 1000) - goDaemon = new GoDaemon() - jsDaemon = new JsDaemon({port: 1}) - js2Daemon = new JsDaemon({port: 2}) - - parallel([ - (cb) => goDaemon.start(cb), - (cb) => jsDaemon.start(cb), - (cb) => js2Daemon.start(cb) - ], done) - }) - - after((done) => { - series([ - (cb) => goDaemon.stop(cb), - (cb) => jsDaemon.stop(cb), - (cb) => js2Daemon.stop(cb) - ], done) - }) - - it('connect go <-> js', (done) => { - let jsId - let goId - - series([ - (cb) => parallel([ - (cb) => jsDaemon.api.id(cb), - (cb) => goDaemon.api.id(cb) - ], (err, ids) => { - expect(err).to.not.exist() - jsId = ids[0] - goId = ids[1] - cb() - }), - (cb) => goDaemon.api.swarm.connect(jsId.addresses[0], cb), - (cb) => jsDaemon.api.swarm.connect(goId.addresses[0], cb), - (cb) => parallel([ - (cb) => goDaemon.api.swarm.peers(cb), - (cb) => jsDaemon.api.swarm.peers(cb) - ], (err, peers) => { - expect(err).to.not.exist() - expect(peers[0].map((p) => p.peer.toB58String())).to.include(jsId.id) - expect(peers[1].map((p) => p.peer.toB58String())).to.include(goId.id) - cb() - }) - ], done) - }) - - it('connect js <-> js', (done) => { - let jsId - let js2Id - - series([ - (cb) => parallel([ - (cb) => jsDaemon.api.id(cb), - (cb) => js2Daemon.api.id(cb) - ], (err, ids) => { - expect(err).to.not.exist() - jsId = ids[0] - js2Id = ids[1] - cb() - }), - (cb) => js2Daemon.api.swarm.connect(jsId.addresses[0], cb), - (cb) => jsDaemon.api.swarm.connect(js2Id.addresses[0], cb), - (cb) => parallel([ - (cb) => js2Daemon.api.swarm.peers(cb), - (cb) => jsDaemon.api.swarm.peers(cb) - ], (err, peers) => { - expect(err).to.not.exist() - expect(peers[0].map((p) => p.peer.toB58String())).to.include(jsId.id) - expect(peers[1].map((p) => p.peer.toB58String())).to.include(js2Id.id) - cb() - }) - ], done) - }) - - describe('cat file', () => sizes.forEach((size) => { - it(`go -> js: ${pretty(size)}`, (done) => { - const data = crypto.randomBytes(size) - waterfall([ - (cb) => goDaemon.api.add(data, cb), - (res, cb) => jsDaemon.api.cat(res[0].hash, cb) - ], (err, file) => { - expect(err).to.not.exist() - expect(file).to.be.eql(data) - done() - }) - }) - - it(`js -> go: ${pretty(size)}`, (done) => { - const data = crypto.randomBytes(size) - waterfall([ - (cb) => jsDaemon.api.add(data, cb), - (res, cb) => goDaemon.api.cat(res[0].hash, cb) - ], (err, file) => { - expect(err).to.not.exist() - expect(file).to.be.eql(data) - done() - }) - }) - - it(`js -> js: ${pretty(size)}`, (done) => { - const data = crypto.randomBytes(size) - waterfall([ - (cb) => js2Daemon.api.add(data, cb), - (res, cb) => jsDaemon.api.cat(res[0].hash, cb) - ], (err, file) => { - expect(err).to.not.exist() - expect(file).to.be.eql(data) - done() - }) - }) - })) - - // TODO these tests are not fetching the full dir?? - describe('get directory', () => dirs.forEach((num) => { - it(`go -> js: depth: 5, num: ${num}`, () => { - const dir = tmpDir() - return randomFs({ - path: dir, - depth: 5, - number: num - }).then(() => { - return goDaemon.api.util.addFromFs(dir, { recursive: true }) - }).then((res) => { - const hash = res[res.length - 1].hash - return jsDaemon.api.object.get(hash) - }).then((res) => { - expect(res).to.exist() - return rmDir(dir) - }) - }) - - it(`js -> go: depth: 5, num: ${num}`, () => { - const dir = tmpDir() - return randomFs({ - path: dir, - depth: 5, - number: num - }).then(() => { - return jsDaemon.api.util.addFromFs(dir, { recursive: true }) - }).then((res) => { - const hash = res[res.length - 1].hash - return goDaemon.api.object.get(hash) - }).then((res) => { - expect(res).to.exist() - return rmDir(dir) - }) - }) - - it(`js -> js: depth: 5, num: ${num}`, () => { - const dir = tmpDir() - return randomFs({ - path: dir, - depth: 5, - number: num - }).then(() => { - return js2Daemon.api.util.addFromFs(dir, { recursive: true }) - }).then((res) => { - const hash = res[res.length - 1].hash - return jsDaemon.api.object.get(hash) - }).then((res) => { - expect(res).to.exist() - return rmDir(dir) - }) - }) - })) -}) diff --git a/test/interop/kad-dht.js b/test/interop/kad-dht.js deleted file mode 100644 index 3c546986d5..0000000000 --- a/test/interop/kad-dht.js +++ /dev/null @@ -1,109 +0,0 @@ -/* eslint-env mocha */ -'use strict' - -const chai = require('chai') -const dirtyChai = require('dirty-chai') -const expect = chai.expect -chai.use(dirtyChai) -const series = require('async/series') -const crypto = require('crypto') -const parallel = require('async/parallel') -const waterfall = require('async/waterfall') -const bl = require('bl') - -const GODaemon = require('../utils/interop-daemon-spawner/go') -const JSDaemon = require('../utils/interop-daemon-spawner/js') - -describe.skip('kad-dht', () => { - describe('a JS node in the land of Go', () => { - let jsD - let goD1 - let goD2 - let goD3 - - before((done) => { - goD1 = new GODaemon() - goD2 = new GODaemon() - goD3 = new GODaemon() - - jsD = new JSDaemon({ port: 40 }) - - parallel([ - (cb) => goD1.start(cb), - (cb) => goD2.start(cb), - (cb) => goD3.start(cb), - (cb) => jsD.start(cb) - ], done) - }) - - after((done) => { - series([ - (cb) => goD1.stop(cb), - (cb) => goD2.stop(cb), - (cb) => goD3.stop(cb), - (cb) => jsD.stop(cb) - ], done) - }) - - it('make connections', (done) => { - parallel([ - (cb) => jsD.api.id(cb), - (cb) => goD1.api.id(cb), - (cb) => goD2.api.id(cb), - (cb) => goD3.api.id(cb) - ], (err, ids) => { - expect(err).to.not.exist() - parallel([ - (cb) => jsD.api.swarm.connect(ids[1].addresses[0], cb), - (cb) => goD1.api.swarm.connect(ids[2].addresses[0], cb), - (cb) => goD2.api.swarm.connect(ids[3].addresses[0], cb) - ], done) - }) - }) - - it('one hop', (done) => { - const data = crypto.randomBytes(9001) - - waterfall([ - (cb) => goD1.api.add(data, cb), - (res, cb) => jsD.api.cat(res[0].hash, cb), - (stream, cb) => stream.pipe(bl(cb)) - ], (err, file) => { - expect(err).to.not.exist() - expect(file).to.be.eql(data) - done() - }) - }) - - it('two hops', (done) => { - const data = crypto.randomBytes(9001) - - waterfall([ - (cb) => goD2.api.add(data, cb), - (res, cb) => jsD.api.cat(res[0].hash, cb), - (stream, cb) => stream.pipe(bl(cb)) - ], (err, file) => { - expect(err).to.not.exist() - expect(file).to.be.eql(data) - done() - }) - }) - - it('three hops', (done) => { - const data = crypto.randomBytes(9001) - - waterfall([ - (cb) => goD3.api.add(data, cb), - (res, cb) => jsD.api.cat(res[0].hash, cb), - (stream, cb) => stream.pipe(bl(cb)) - ], (err, file) => { - expect(err).to.not.exist() - expect(file).to.be.eql(data) - done() - }) - }) - }) - - describe('a Go node in the land of JS', () => {}) - describe('hybrid', () => {}) -}) diff --git a/test/interop/node.js b/test/interop/node.js deleted file mode 100644 index 7e4a513445..0000000000 --- a/test/interop/node.js +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-env mocha */ -'use strict' - -require('./repo') -require('./exchange-files') -require('./circuit-relay') -require('./kad-dht') -require('./pubsub') diff --git a/test/interop/pubsub.js b/test/interop/pubsub.js deleted file mode 100644 index 0bfa11f143..0000000000 --- a/test/interop/pubsub.js +++ /dev/null @@ -1,346 +0,0 @@ -/* eslint-env mocha */ -'use strict' - -const chai = require('chai') -const dirtyChai = require('dirty-chai') -const expect = chai.expect -chai.use(dirtyChai) -const series = require('async/series') -const parallel = require('async/parallel') - -const GoDaemon = require('../utils/interop-daemon-spawner/go') -const JSDaemon = require('../utils/interop-daemon-spawner/js') - -/* - * Wait for a condition to become true. When its true, callback is called. - */ -function waitFor (predicate, callback) { - const ttl = Date.now() + (2 * 1000) - const self = setInterval(() => { - if (predicate()) { - clearInterval(self) - return callback() - } - if (Date.now() > ttl) { - clearInterval(self) - return callback(new Error('waitFor time expired')) - } - }, 500) -} - -describe('pubsub', function () { - this.timeout(5 * 1000) - - let jsD - let goD - let jsId - let goId - - before(function (done) { - this.timeout(50 * 1000) - - goD = new GoDaemon({ - disposable: true, - init: true, - flags: ['--enable-pubsub-experiment'] - }) - jsD = new JSDaemon() - - parallel([ - (cb) => goD.start(cb), - (cb) => jsD.start(cb) - ], (done)) - }) - - after(function (done) { - this.timeout(50 * 1000) - - parallel([ - (cb) => goD.stop(cb), - (cb) => jsD.stop(cb) - ], done) - }) - - it('make connections', (done) => { - series([ - (cb) => jsD.api.id(cb), - (cb) => goD.api.id(cb) - ], (err, ids) => { - expect(err).to.not.exist() - - jsId = ids[0].id - goId = ids[1].id - - const jsLocalAddr = ids[0].addresses.find(a => a.includes('127.0.0.1')) - const goLocalAddr = ids[1].addresses.find(a => a.includes('127.0.0.1')) - - parallel([ - (cb) => jsD.api.swarm.connect(goLocalAddr, cb), - (cb) => goD.api.swarm.connect(jsLocalAddr, cb), - (cb) => setTimeout(() => { - cb() - }, 1000) - ], done) - }) - }) - - describe('ascii data', () => { - const data = Buffer.from('hello world') - - it('publish from Go, subscribe on Go', (done) => { - const topic = 'pubsub-go-go' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString()).to.equal(data.toString()) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', goId) - } - - series([ - (cb) => goD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => goD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - - it('publish from JS, subscribe on JS', (done) => { - const topic = 'pubsub-js-js' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString()).to.equal(data.toString()) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', jsId) - } - - series([ - (cb) => jsD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => jsD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - - it('publish from JS, subscribe on Go', (done) => { - const topic = 'pubsub-js-go' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString()).to.equal(data.toString()) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', jsId) - } - - series([ - (cb) => goD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => setTimeout(() => { cb() }, 500), - (cb) => jsD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - - it('publish from Go, subscribe on JS', (done) => { - const topic = 'pubsub-go-js' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString()).to.equal(data.toString()) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', goId) - } - - series([ - (cb) => jsD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => setTimeout(() => { cb() }, 500), - (cb) => goD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - }) - - describe('non-ascii data', () => { - const data = Buffer.from('你好世界') - - it('publish from Go, subscribe on Go', (done) => { - const topic = 'pubsub-non-ascii-go-go' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString()).to.equal(data.toString()) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', goId) - } - - series([ - (cb) => goD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => goD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - - it('publish from JS, subscribe on JS', (done) => { - const topic = 'pubsub-non-ascii-js-js' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString()).to.equal(data.toString()) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', jsId) - } - - series([ - (cb) => jsD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => jsD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - - it('publish from JS, subscribe on Go', (done) => { - const topic = 'pubsub-non-ascii-js-go' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString()).to.equal(data.toString()) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', jsId) - } - - series([ - (cb) => goD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => setTimeout(() => { cb() }, 500), - (cb) => jsD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - - it('publish from Go, subscribe on JS', (done) => { - const topic = 'pubsub-non-ascii-go-js' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString()).to.equal(data.toString()) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', goId) - } - - series([ - (cb) => jsD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => setTimeout(() => { cb() }, 500), - (cb) => goD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - }) - - describe('binary data', () => { - const data = Buffer.from('a36161636179656162830103056164a16466666666f400010203040506070809', 'hex') - - it('publish from Go, subscribe on Go', (done) => { - const topic = 'pubsub-binary-go-go' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString('hex')).to.equal(data.toString('hex')) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', goId) - } - - series([ - (cb) => goD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => setTimeout(() => { cb() }, 500), - (cb) => goD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - - it('publish from Go, subscribe on JS', (done) => { - const topic = 'pubsub-binary-go-js' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString('hex')).to.equal(data.toString('hex')) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', goId) - } - - series([ - (cb) => jsD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => setTimeout(() => { cb() }, 500), - (cb) => goD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - - it('publish from JS, subscribe on Go', (done) => { - const topic = 'pubsub-binary-js-go' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString('hex')).to.equal(data.toString('hex')) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', jsId) - } - - series([ - (cb) => goD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => setTimeout(() => { cb() }, 500), - (cb) => jsD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - - it('publish from JS, subscribe on JS', (done) => { - const topic = 'pubsub-binary-js-js' - let n = 0 - - function checkMessage (msg) { - ++n - expect(msg.data.toString('hex')).to.equal(data.toString('hex')) - expect(msg).to.have.property('seqno') - expect(Buffer.isBuffer(msg.seqno)).to.be.eql(true) - expect(msg).to.have.property('topicIDs').eql([topic]) - expect(msg).to.have.property('from', jsId) - } - - series([ - (cb) => jsD.api.pubsub.subscribe(topic, checkMessage, cb), - (cb) => setTimeout(() => { cb() }, 500), - (cb) => jsD.api.pubsub.publish(topic, data, cb), - (cb) => waitFor(() => n === 1, cb) - ], done) - }) - }) -}) diff --git a/test/interop/repo.js b/test/interop/repo.js deleted file mode 100644 index 83ebac02dc..0000000000 --- a/test/interop/repo.js +++ /dev/null @@ -1,85 +0,0 @@ -/* eslint-env mocha */ -'use strict' - -const chai = require('chai') -const dirtyChai = require('dirty-chai') -const expect = chai.expect -chai.use(dirtyChai) -const waterfall = require('async/waterfall') -const crypto = require('crypto') -const os = require('os') -const path = require('path') -const hat = require('hat') - -const GoDaemon = require('../utils/interop-daemon-spawner/go') -const JsDaemon = require('../utils/interop-daemon-spawner/js') - -function catAndCheck (daemon, hash, data, callback) { - daemon.api.cat(hash, (err, fileData) => { - expect(err).to.not.exist() - expect(fileData).to.eql(data) - callback() - }) -} - -describe('repo', () => { - it('read repo: go -> js', (done) => { - const dir = path.join(os.tmpdir(), hat()) - const data = crypto.randomBytes(1024 * 5) - - const goDaemon = new GoDaemon({ - init: true, - disposable: false, - path: dir - }) - let jsDaemon - - let hash - waterfall([ - (cb) => goDaemon.start(cb), - (cb) => goDaemon.api.add(data, cb), - (res, cb) => { - hash = res[0].hash - catAndCheck(goDaemon, hash, data, cb) - }, - (cb) => goDaemon.stop(cb), - (cb) => { - jsDaemon = new JsDaemon({ - init: false, - disposable: false, - path: dir - }) - jsDaemon.start(cb) - }, - (cb) => catAndCheck(goDaemon, hash, data, cb), - (cb) => jsDaemon.stop(cb) - ], done) - }) - - // This was last due to an update on go-ipfs that changed how datastore is - // configured - it.skip('read repo: js -> go', (done) => { - const dir = path.join(os.tmpdir(), hat()) - const data = crypto.randomBytes(1024 * 5) - - const jsDaemon = new JsDaemon({init: true, disposable: false, path: dir}) - let goDaemon - - let hash - waterfall([ - (cb) => jsDaemon.start(cb), - (cb) => jsDaemon.api.add(data, cb), - (res, cb) => { - hash = res[0].hash - catAndCheck(jsDaemon, hash, data, cb) - }, - (cb) => jsDaemon.stop(cb), - (cb) => { - goDaemon = new GoDaemon({init: false, disposable: false, path: dir}) - goDaemon.start(cb) - }, - (cb) => catAndCheck(goDaemon, hash, data, cb), - (cb) => goDaemon.stop(cb) - ], done) - }) -}) diff --git a/test/utils/another-daemon-spawner.js b/test/utils/another-daemon-spawner.js index c8d2295c5a..5d55be3295 100644 --- a/test/utils/another-daemon-spawner.js +++ b/test/utils/another-daemon-spawner.js @@ -7,62 +7,11 @@ const series = require('async/series') const relayConfig = require('./ipfs-factory-daemon/default-config.json') const Factory = require('./ipfs-factory-daemon') -const GoDaemon = require('./interop-daemon-spawner/go') const nodes = [] const factory = new Factory() exports = module.exports -exports.spawnGoNode = (addrs, hop, api, gateway, callback) => { - if (typeof hop === 'function') { - callback = hop - hop = false - } - if (typeof api === 'function') { - callback = api - api = 0 - } - if (typeof gateway === 'function') { - callback = gateway - gateway = 0 - } - - api = api || 0 - gateway = gateway || 0 - - const daemon = new GoDaemon({ - disposable: true, - init: true, - config: { - Addresses: { - Swarm: addrs, - API: `/ip4/0.0.0.0/tcp/${api}`, - Gateway: `/ip4/0.0.0.0/tcp/${gateway}` - }, - Swarm: { - AddrFilters: null, - DisableBandwidthMetrics: false, - DisableNatPortMap: false, - DisableRelay: false, - EnableRelayHop: hop - } - } - }) - - daemon.start((err) => { - if (err) { - return callback(err) - } - daemon.api.id((err, id) => { - if (err) { - return callback(err) - } - nodes.push(daemon) - callback(null, daemon, id.addresses) - }) - }) -} - exports.spawnJsNode = (addrs, hop, api, gateway, callback) => { let relayPeer let relayAddrs diff --git a/test/utils/interop-daemon-spawner/go.js b/test/utils/interop-daemon-spawner/go.js deleted file mode 100644 index 8010724d81..0000000000 --- a/test/utils/interop-daemon-spawner/go.js +++ /dev/null @@ -1,73 +0,0 @@ -'use strict' - -const ctl = require('ipfsd-ctl') -const waterfall = require('async/waterfall') - -class GoDaemon { - constructor (opts) { - opts = opts || { - disposable: true, - init: true - } - - this.init = opts.init - this.path = opts.path - this.disposable = opts.disposable - this.node = null - this.api = null - this.config = opts.config || {} - this.flags = opts.flags || {} - } - - start (callback) { - waterfall([ - (cb) => { - if (this.disposable) { - const config = Object.assign({ init: this.init }, this.config) - ctl.disposable(config, cb) - } else if (this.init) { - ctl.local(this.path, (err, node) => { - if (err) { - return cb(err) - } - node.init((err) => cb(err, node)) - }) - } else { - ctl.local(this.path, cb) - } - }, - (node, cb) => { - this.node = node - this.node.setConfig('Bootstrap', '[]', cb) - }, - (res, cb) => this.node.startDaemon(this.flags, cb), - (api, cb) => { - this.api = api - - if (process.env.DEBUG) { - this.api.log.tail((err, stream) => { - if (err) { - return console.error(err) - } - stream.on('data', (chunk) => { - console.log('go-log: %s.%s %s (%s)', chunk.system, chunk.subsystem || '', chunk.event, chunk.error) - }) - }) - this.node._run( - ['log', 'level', 'all', 'debug'], - {env: this.node.env}, - cb - ) - } else { - cb() - } - } - ], (err) => callback(err)) - } - - stop (callback) { - this.node.stopDaemon(callback) - } -} - -module.exports = GoDaemon diff --git a/test/utils/interop-daemon-spawner/js.js b/test/utils/interop-daemon-spawner/js.js deleted file mode 100644 index bd376ff892..0000000000 --- a/test/utils/interop-daemon-spawner/js.js +++ /dev/null @@ -1,87 +0,0 @@ -'use strict' - -const EventEmitter = require('events').EventEmitter -const IPFSAPI = require('ipfs-api') -const series = require('async/series') -const rimraf = require('rimraf') -const tmpDir = require('./util').tmpDir - -const HttpApi = require('../../../src/http') - -function portConfig (port) { - port = port + 5 - - return { - Gateway: '/ip4/127.0.0.1/tcp/' + (9090 + port), - API: '/ip4/127.0.0.1/tcp/' + (5002 + port), - Swarm: [ - '/ip4/127.0.0.1/tcp/' + (4003 + port), - '/ip4/127.0.0.1/tcp/' + (4104 + port) + '/ws' - ] - } -} - -class JsDaemon extends EventEmitter { - constructor (opts) { - super() - opts = Object.assign({}, { - disposable: true, - init: true - }, opts || {}) - - this.path = opts.path - this.disposable = opts.disposable - this.init = opts.init - this.port = opts.port || 1 - - this.path = opts.path || tmpDir() - this._started = false - - const extras = { - enablePubsubExperiment: true - } - if (this.init) { - const p = portConfig(this.port) - this.node = new HttpApi(this.path, { - Bootstrap: [], - Addresses: p - }, extras) - } else { - this.node = new HttpApi(this.path, null, extras) - } - - this.node.start(this.init, (err) => { - if (err) { - throw err - } - this._started = true - this.api = new IPFSAPI(this.node.apiMultiaddr) - - this.emit('start') - }) - } - - start (callback) { - if (!this._started) { - return this.once('start', callback) - } - - callback() - } - - stop (callback) { - this._started = false - series([ - (cb) => this.node.stop(cb), - (cb) => { - if (this.disposable) { - rimraf(this.path, cb) - } else { - cb() - } - } - ], (err) => callback(err)) - } -} - -module.exports = JsDaemon diff --git a/test/utils/interop-daemon-spawner/util.js b/test/utils/interop-daemon-spawner/util.js deleted file mode 100644 index 11b47f5780..0000000000 --- a/test/utils/interop-daemon-spawner/util.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict' - -const os = require('os') -const path = require('path') -const hat = require('hat') - -exports.tmpDir = (prefix) => { - return path.join(os.tmpdir(), prefix || 'js-ipfs-interop', hat()) -}