From 6058954780f1dc9886e2972b75aba83fe3716a3e Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Wed, 13 Feb 2019 09:53:36 +0000 Subject: [PATCH] test: JS IPFS 0.34 (#51) * test: add tests for CID version agnostic add and cat License: MIT Signed-off-by: Alan Shaw * chore: remove .only License: MIT Signed-off-by: Alan Shaw * fix: tests using files * fix: tests using files * fix: check for similar messages instead of identical * chore: update ipfs to RC License: MIT Signed-off-by: Alan Shaw * chore: update dependencies License: MIT Signed-off-by: Alan Shaw * fix: reinstate exchange directory tests License: MIT Signed-off-by: Alan Shaw * refactor: remove bootstrap nodes in tests License: MIT Signed-off-by: Alan Shaw * chore: update js-ipfs dep * chore: update js-ipfs version License: MIT Signed-off-by: Alan Shaw * refactor: remove bootstrap nodes in tests License: MIT Signed-off-by: Alan Shaw * chore: update deps * chore: add missing deps * chore: update timeout on cid tests --- package.json | 30 ++++---- test/cid-version-agnostic.js | 145 +++++++++++++++++++++++++++++++++++ test/exchange-files.js | 26 +++---- test/files.js | 22 ++++-- test/node.js | 1 + test/utils/circuit.js | 4 +- test/utils/daemon.js | 3 +- 7 files changed, 196 insertions(+), 35 deletions(-) create mode 100644 test/cid-version-agnostic.js diff --git a/package.json b/package.json index e6d73b29..32c946fa 100644 --- a/package.json +++ b/package.json @@ -35,39 +35,41 @@ }, "homepage": "https://github.com/ipfs/interop#readme", "devDependencies": { - "aegir": "^17.0.1", - "async": "^2.6.1", - "bl": "^2.1.2", + "aegir": "^18.1.0", + "async": "^2.6.2", + "bl": "^2.2.0", "bs58": "^4.0.1", "chai": "^4.2.0", - "cids": "~0.5.5", + "cids": "~0.5.7", "cross-env": "^5.2.0", "detect-node": "^2.0.4", - "dir-compare": "^1.4.0", + "dir-compare": "^1.7.1", "dirty-chai": "^2.0.1", - "eslint-plugin-react": "^7.11.1", + "eslint-plugin-react": "^7.12.4", "expose-loader": "~0.7.5", "form-data": "^2.3.3", "go-ipfs-dep": "~0.4.18", "hat": "0.0.3", - "ipfs": "~0.33.0", - "ipfs-api": "^26.1.2", + "ipfs": "~0.34.4", + "ipfs-http-client": "^29.1.0", "ipfs-unixfs": "~0.1.16", - "ipfsd-ctl": "~0.40.0", + "ipfs-repo": "~0.26.1", + "ipfsd-ctl": "~0.42.0", + "is-ci": "^2.0.0", "left-pad": "^1.3.0", - "libp2p-websocket-star-rendezvous": "~0.2.4", + "libp2p-websocket-star-rendezvous": "~0.3.0", "lodash": "^4.17.11", "mocha": "^5.2.0", "ncp": "^2.0.0", "pretty-bytes": "^5.1.0", "random-fs": "^1.0.3", - "rimraf": "^2.6.2", + "rimraf": "^2.6.3", "stream-to-promise": "^2.2.0", - "transform-loader": "~0.2.4", - "is-ci": "^1.2.1" + "transform-loader": "~0.2.4" }, "contributors": [], "dependencies": { - "is-os": "^1.0.1" + "is-os": "^1.0.1", + "promisify-es6": "^1.0.3" } } diff --git a/test/cid-version-agnostic.js b/test/cid-version-agnostic.js new file mode 100644 index 00000000..5466ed54 --- /dev/null +++ b/test/cid-version-agnostic.js @@ -0,0 +1,145 @@ +/* eslint-env mocha */ +'use strict' + +const chai = require('chai') +const dirtyChai = require('dirty-chai') +const expect = chai.expect +chai.use(dirtyChai) +const hat = require('hat') +const CID = require('cids') +const { + spawnInitAndStartGoDaemon, + spawnInitAndStartJsDaemon, + stopDaemon +} = require('./utils/daemon') + +describe('CID version agnostic', () => { + const daemons = {} + + before(async function () { + this.timeout(30 * 1000) + + const [ js0, js1, go0, go1 ] = await Promise.all([ + spawnInitAndStartJsDaemon(), + spawnInitAndStartJsDaemon(), + spawnInitAndStartGoDaemon(), + spawnInitAndStartGoDaemon() + ]) + Object.assign(daemons, { js0, js1, go0, go1 }) + + // Get peer IDs + await Promise.all(Object.keys(daemons).map(async k => { + daemons[k].peerId = await daemons[k].api.id() + })) + + await Promise.all([ + js0.api.swarm.connect(js1.peerId.addresses[0]), + js1.api.swarm.connect(js0.peerId.addresses[0]), + go0.api.swarm.connect(go1.peerId.addresses[0]), + go1.api.swarm.connect(go0.peerId.addresses[0]), + js0.api.swarm.connect(go0.peerId.addresses[0]), + go0.api.swarm.connect(js0.peerId.addresses[0]) + ]) + }) + + after(function () { + this.timeout(30 * 1000) + return Promise.all(Object.values(daemons).map(stopDaemon)) + }) + + it('should add v0 and cat v1 (go0 -> go0)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.go0.api.add(input, { cidVersion: 0 }) + const cidv1 = new CID(res[0].hash).toV1() + const output = await daemons.go0.api.cat(cidv1) + expect(output).to.deep.equal(input) + }) + + it('should add v0 and cat v1 (js0 -> js0)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.js0.api.add(input, { cidVersion: 0 }) + const cidv1 = new CID(res[0].hash).toV1() + const output = await daemons.js0.api.cat(cidv1) + expect(output).to.deep.equal(input) + }) + + it('should add v0 and cat v1 (go0 -> go1)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.go0.api.add(input, { cidVersion: 0 }) + const cidv1 = new CID(res[0].hash).toV1() + const output = await daemons.go1.api.cat(cidv1) + expect(output).to.deep.equal(input) + }) + + it('should add v0 and cat v1 (js0 -> js1)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.js0.api.add(input, { cidVersion: 0 }) + const cidv1 = new CID(res[0].hash).toV1() + const output = await daemons.js1.api.cat(cidv1) + expect(output).to.deep.equal(input) + }) + + it('should add v0 and cat v1 (js0 -> go0)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.js0.api.add(input, { cidVersion: 0 }) + const cidv1 = new CID(res[0].hash).toV1() + const output = await daemons.go0.api.cat(cidv1) + expect(output).to.deep.equal(input) + }) + + it('should add v0 and cat v1 (go0 -> js0)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.go0.api.add(input, { cidVersion: 0 }) + const cidv1 = new CID(res[0].hash).toV1() + const output = await daemons.js0.api.cat(cidv1) + expect(output).to.deep.equal(input) + }) + + it('should add v1 and cat v0 (go0 -> go0)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.go0.api.add(input, { cidVersion: 1, rawLeaves: false }) + const cidv0 = new CID(res[0].hash).toV0() + const output = await daemons.go0.api.cat(cidv0) + expect(output).to.deep.equal(input) + }) + + it('should add v1 and cat v0 (js0 -> js0)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.js0.api.add(input, { cidVersion: 1, rawLeaves: false }) + const cidv0 = new CID(res[0].hash).toV0() + const output = await daemons.js0.api.cat(cidv0) + expect(output).to.deep.equal(input) + }) + + it('should add v1 and cat v0 (go0 -> go1)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.go0.api.add(input, { cidVersion: 1, rawLeaves: false }) + const cidv0 = new CID(res[0].hash).toV0() + const output = await daemons.go1.api.cat(cidv0) + expect(output).to.deep.equal(input) + }) + + it('should add v1 and cat v0 (js0 -> js1)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.js0.api.add(input, { cidVersion: 1, rawLeaves: false }) + const cidv0 = new CID(res[0].hash).toV0() + const output = await daemons.js1.api.cat(cidv0) + expect(output).to.deep.equal(input) + }) + + it('should add v1 and cat v0 (js0 -> go0)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.js0.api.add(input, { cidVersion: 1, rawLeaves: false }) + const cidv0 = new CID(res[0].hash).toV0() + const output = await daemons.go0.api.cat(cidv0) + expect(output).to.deep.equal(input) + }) + + it('should add v1 and cat v0 (go0 -> js0)', async () => { + const input = Buffer.from(hat()) + const res = await daemons.go0.api.add(input, { cidVersion: 1, rawLeaves: false }) + const cidv0 = new CID(res[0].hash).toV0() + const output = await daemons.js0.api.cat(cidv0) + expect(output).to.deep.equal(input) + }) +}) diff --git a/test/exchange-files.js b/test/exchange-files.js index aaaab484..e8014e6e 100644 --- a/test/exchange-files.js +++ b/test/exchange-files.js @@ -111,10 +111,10 @@ describe('exchange files', () => { this.timeout(timeout) parallel([ - (cb) => goDf.spawn({ initOptions: { bits: 1024 } }, cb), - (cb) => goDf.spawn({ initOptions: { bits: 1024 } }, cb), - (cb) => jsDf.spawn({ type: 'js', initOptions: { bits: 512 } }, cb), - (cb) => jsDf.spawn({ type: 'js', initOptions: { bits: 512 } }, cb) + (cb) => goDf.spawn({ initOptions: { bits: 1024 }, config: { Bootstrap: [] } }, cb), + (cb) => goDf.spawn({ initOptions: { bits: 1024 }, config: { Bootstrap: [] } }, cb), + (cb) => jsDf.spawn({ type: 'js', initOptions: { bits: 512 }, config: { Bootstrap: [] } }, cb), + (cb) => jsDf.spawn({ type: 'js', initOptions: { bits: 512 }, config: { Bootstrap: [] } }, cb) ], (err, n) => { expect(err).to.not.exist() nodes = n @@ -284,7 +284,7 @@ describe('exchange files', () => { }) })) - if (isWindows) { return } + if (isWindows()) { return } // TODO fix dir tests on Windows describe('get directory', () => depth.forEach((d) => dirs.forEach((num) => { @@ -297,10 +297,10 @@ describe('exchange files', () => { depth: d, number: num }).then(() => { - return goDaemon.api.util.addFromFs(dir, { recursive: true }) + return goDaemon.api.addFromFs(dir, { recursive: true }) }).then((res) => { const hash = res[res.length - 1].hash - return jsDaemon.api.files.get(hash) + return jsDaemon.api.get(hash) }).then((res) => { expect(res).to.exist() return rmDir(dir) @@ -316,10 +316,10 @@ describe('exchange files', () => { depth: d, number: num }).then(() => { - return jsDaemon.api.util.addFromFs(dir, { recursive: true }) + return jsDaemon.api.addFromFs(dir, { recursive: true }) }).then((res) => { const hash = res[res.length - 1].hash - return goDaemon.api.files.get(hash) + return goDaemon.api.get(hash) }).then((res) => { expect(res).to.exist() return rmDir(dir) @@ -335,10 +335,10 @@ describe('exchange files', () => { depth: d, number: num }).then(() => { - return jsDaemon2.api.util.addFromFs(dir, { recursive: true }) + return jsDaemon2.api.addFromFs(dir, { recursive: true }) }).then((res) => { const hash = res[res.length - 1].hash - return jsDaemon.api.files.get(hash) + return jsDaemon.api.get(hash) }).then((res) => { expect(res).to.exist() return rmDir(dir) @@ -354,10 +354,10 @@ describe('exchange files', () => { depth: d, number: num }).then(() => { - return goDaemon2.api.util.addFromFs(dir, { recursive: true }) + return goDaemon2.api.addFromFs(dir, { recursive: true }) }).then((res) => { const hash = res[res.length - 1].hash - return goDaemon.api.files.get(hash) + return goDaemon.api.get(hash) }).then((res) => { expect(res).to.exist() return rmDir(dir) diff --git a/test/files.js b/test/files.js index efee4c6b..0b0a12c1 100644 --- a/test/files.js +++ b/test/files.js @@ -26,7 +26,7 @@ function checkNodeTypes (daemon, file) { expect(node.links.length).to.equal(2) return Promise.all( - node.links.map(link => daemon.api.object.get(link.toJSON().multihash).then(child => { + node.links.map(link => daemon.api.object.get(link.toJSON().cid).then(child => { const childMeta = UnixFs.unmarshal(child.data) expect(childMeta.type).to.equal('raw') @@ -67,11 +67,11 @@ const compare = (...ops) => { }) } -const compareErrors = (...ops) => { +const compareErrors = (expectedMessage, ...ops) => { expect(ops.length).to.be.above(1) return Promise.all( - // even if operations fail, their errors should be the same + // even if operations fail, their errors should be similar ops.map(op => op.then(() => { throw new ExpectedError('Expected operation to fail') }).catch(error => { @@ -88,9 +88,17 @@ const compareErrors = (...ops) => { .then(results => { expect(results.length).to.equal(ops.length) + // all implementations should have similar error messages + results.forEach(res => { + expect(res.message.toLowerCase()).to.contain(expectedMessage.toLowerCase()) + }) + const result = results.pop() - results.forEach(res => expect(res).to.deep.equal(result)) + // all implementations should have the same error code + results.forEach(res => { + expect(res.code).to.equal(result.code) + }) }) } @@ -138,6 +146,7 @@ describe('files', function () { } return compareErrors( + 'does not exist', readNonExistentFile(go), readNonExistentFile(js) ) @@ -149,6 +158,7 @@ describe('files', function () { } return compareErrors( + 'does not exist', readNonExistentFile(go), readNonExistentFile(js) ) @@ -171,6 +181,7 @@ describe('files', function () { const path = `/test-dir-${Math.random()}` return compareErrors( + 'already exists', go.api.files.mkdir(path).then(() => go.api.files.mkdir(path)), js.api.files.mkdir(path).then(() => js.api.files.mkdir(path)) ) @@ -189,6 +200,7 @@ describe('files', function () { const path = '/' return compareErrors( + 'already exists', go.api.files.mkdir(path).then(() => go.api.files.mkdir(path)), js.api.files.mkdir(path).then(() => js.api.files.mkdir(path)) ) @@ -196,7 +208,7 @@ describe('files', function () { describe('has the same hashes for', () => { const testHashesAreEqual = (daemon, data, options) => { - return daemon.api.files.add(data, options) + return daemon.api.add(data, options) .then(files => files[0].hash) } diff --git a/test/node.js b/test/node.js index 2d4fbbe0..4edb14ea 100644 --- a/test/node.js +++ b/test/node.js @@ -1,6 +1,7 @@ /* eslint-env mocha */ 'use strict' +require('./cid-version-agnostic') require('./pubsub') require('./circuit') require('./repo') diff --git a/test/utils/circuit.js b/test/utils/circuit.js index 36e1352c..6ec50832 100644 --- a/test/utils/circuit.js +++ b/test/utils/circuit.js @@ -98,8 +98,8 @@ exports.createGoNode = (addrs, callback) => { const data = crypto.randomBytes(128) exports.send = (nodeA, nodeB, callback) => { waterfall([ - (cb) => nodeA.files.add(data, cb), - (res, cb) => nodeB.files.cat(res[0].hash, cb), + (cb) => nodeA.add(data, cb), + (res, cb) => nodeB.cat(res[0].hash, cb), (buffer, cb) => { expect(buffer).to.deep.equal(data) cb() diff --git a/test/utils/daemon.js b/test/utils/daemon.js index f6d18e51..10982480 100644 --- a/test/utils/daemon.js +++ b/test/utils/daemon.js @@ -9,7 +9,8 @@ const spawnInitAndStartDaemon = (factory) => { factory.spawn({ initOptions: { bits: 1024 - } + }, + config: { Bootstrap: [] } }, (error, instance) => { if (error) { return reject(error)