diff --git a/.gitignore b/.gitignore index da170aa32..0234febe2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ node_modules *.log -test/tmp-disposable-nodes-addrs.json +test/setup/tmp-disposable-nodes-addrs.json dist lib -coverage \ No newline at end of file +coverage diff --git a/gulpfile.js b/gulpfile.js index 246ec395c..c3484e169 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,5 +2,12 @@ const gulp = require('gulp') -require('./tasks/test') +require('./test/setup/spawn-daemons') +require('./test/factory/factory-tasks') + +gulp.task('test:node:before', ['daemons:start', 'factory:start']) +gulp.task('test:node:after', ['daemons:stop', 'factory:stop']) +gulp.task('test:browser:before', ['daemons:start', 'factory:start']) +gulp.task('test:browser:after', ['daemons:stop', 'factory:stop']) + require('aegir/gulp')(gulp) diff --git a/package.json b/package.json index 6f8915b59..f4950b6f7 100644 --- a/package.json +++ b/package.json @@ -33,10 +33,13 @@ "aegir": "^6.0.0", "chai": "^3.5.0", "gulp": "^3.9.1", - "interface-ipfs-core": "^0.6.0", + "hapi": "^14.1.0", + "interface-ipfs-core": "^0.7.2", "ipfsd-ctl": "^0.14.0", "passthrough-counter": "^1.0.0", "pre-commit": "^1.1.3", + "socket.io": "^1.4.8", + "socket.io-client": "^1.4.8", "stream-equal": "^0.1.8", "stream-http": "^2.3.1", "streamifier": "^0.1.1" diff --git a/tasks/test.js b/tasks/test.js deleted file mode 100644 index 5b3062738..000000000 --- a/tasks/test.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict' - -const gulp = require('gulp') - -require('./daemons') - -gulp.task('test:node:before', ['daemons:start']) -gulp.task('test:node:after', ['daemons:stop']) -gulp.task('test:browser:before', ['daemons:start']) -gulp.task('test:browser:after', ['daemons:stop']) diff --git a/test/api/object.spec.js b/test/api/object.spec.js deleted file mode 100644 index ae50909dd..000000000 --- a/test/api/object.spec.js +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-env mocha */ -/* globals apiClients */ - -'use strict' - -const test = require('interface-ipfs-core') - -const common = { - setup: function (cb) { - cb(null, apiClients.a) - }, - teardown: function (cb) { - cb() - } -} - -test.object(common) diff --git a/test/browser.js b/test/browser.js index cc2566c73..ebfd1aada 100644 --- a/test/browser.js +++ b/test/browser.js @@ -1,3 +1,3 @@ 'use strict' -require('./setup') +require('./setup/setup-ipfs-api-clients') diff --git a/test/15mb.random b/test/data/15mb.random similarity index 100% rename from test/15mb.random rename to test/data/15mb.random diff --git a/test/r-config.json b/test/data/r-config.json similarity index 100% rename from test/r-config.json rename to test/data/r-config.json diff --git a/test/test-folder/add.js b/test/data/test-folder/add.js similarity index 100% rename from test/test-folder/add.js rename to test/data/test-folder/add.js diff --git a/test/test-folder/cat.js b/test/data/test-folder/cat.js similarity index 100% rename from test/test-folder/cat.js rename to test/data/test-folder/cat.js diff --git a/test/test-folder/files/hello.txt b/test/data/test-folder/files/hello.txt similarity index 100% rename from test/test-folder/files/hello.txt rename to test/data/test-folder/files/hello.txt diff --git a/test/test-folder/files/ipfs.txt b/test/data/test-folder/files/ipfs.txt similarity index 100% rename from test/test-folder/files/ipfs.txt rename to test/data/test-folder/files/ipfs.txt diff --git a/test/test-folder/hello-link b/test/data/test-folder/hello-link similarity index 100% rename from test/test-folder/hello-link rename to test/data/test-folder/hello-link diff --git a/test/test-folder/ipfs-add.js b/test/data/test-folder/ipfs-add.js similarity index 100% rename from test/test-folder/ipfs-add.js rename to test/data/test-folder/ipfs-add.js diff --git a/test/test-folder/ls.js b/test/data/test-folder/ls.js similarity index 100% rename from test/test-folder/ls.js rename to test/data/test-folder/ls.js diff --git a/test/test-folder/version.js b/test/data/test-folder/version.js similarity index 100% rename from test/test-folder/version.js rename to test/data/test-folder/version.js diff --git a/test/testconfig.json b/test/data/testconfig.json similarity index 100% rename from test/testconfig.json rename to test/data/testconfig.json diff --git a/test/testfile.txt b/test/data/testfile.txt similarity index 100% rename from test/testfile.txt rename to test/data/testfile.txt diff --git a/test/factory/daemon-spawner.js b/test/factory/daemon-spawner.js new file mode 100644 index 000000000..f4f9f9498 --- /dev/null +++ b/test/factory/daemon-spawner.js @@ -0,0 +1,89 @@ +'use strict' + +// const defaultConfig = require('./default-config.json') +const ipfsd = require('ipfsd-ctl') +const series = require('run-series') + +module.exports = Factory + +function Factory () { + if (!(this instanceof Factory)) { + return new Factory() + } + + const nodes = [] + + this.spawnNode = (repoPath, config, callback) => { + if (typeof repoPath === 'function') { + callback = repoPath + repoPath = undefined + } + if (typeof config === 'function') { + callback = config + config = undefined + } + + // if (!repoPath) { + // repoPath = '/tmp/.ipfs-' + Math.random() + // .toString() + // .substring(2, 8) + // } + + // TODO + // - [ ] Support custom repoPath + // - [ ] Support custom config + // This will come once the new ipfsd-ctl is + // complete: https://github.com/ipfs/js-ipfsd-ctl/pull/89 + + spawnEphemeralNode((err, node) => { + if (err) { + return callback(err) + } + nodes.push(node) + callback(null, node.apiAddr) + }) + } + + this.dismantle = function (callback) { + series( + nodes.map((node) => { + return node.stopDaemon + }), callback) + } +} + +function spawnEphemeralNode (callback) { + ipfsd.disposable((err, node) => { + if (err) { + return callback(err) + } + // Note: we have to set each config value + // independently since the config/replace endpoint + // doesn't work as expected + series([ + (cb) => { + node.setConfig('Bootstrap', null, cb) + }, + (cb) => { + node.setConfig('Discovery', '{}', cb) + }, + (cb) => { + const headers = { + HTTPHeaders: { + 'Access-Control-Allow-Origin': ['*'] + } + } + node.setConfig('API', JSON.stringify(headers), cb) + }, + (cb) => { + node.startDaemon(cb) + } + ], (err) => { + if (err) { + return callback(err) + } + + callback(null, node) + }) + }) +} diff --git a/test/factory/factory-client.js b/test/factory/factory-client.js new file mode 100644 index 000000000..07fa65c2c --- /dev/null +++ b/test/factory/factory-client.js @@ -0,0 +1,54 @@ +'use strict' + +const io = require('socket.io-client') +const ipfsAPI = require('../../src') + +module.exports = Factory + +function Factory () { + if (!(this instanceof Factory)) { + return new Factory() + } + const sioOptions = { + transports: ['websocket'], + 'force new connection': true + } + const sioUrl = 'http://localhost:55155' + let sioConnected = false + let ioC + + this.spawnNode = (repoPath, config, callback) => { + if (typeof repoPath === 'function') { + callback = repoPath + repoPath = undefined + } + if (typeof config === 'function') { + callback = config + config = undefined + } + + if (sioConnected) { + spawnNode() + } else { + ioC = io.connect(sioUrl, sioOptions) + ioC.on('connect_error', callback) + ioC.on('connect', () => { + sioConnected = true + spawnNode() + }) + } + + function spawnNode () { + ioC.once('fc-node', (apiAddr) => { + const ipfs = ipfsAPI(apiAddr) + callback(null, ipfs) + }) + ioC.emit('fs-spawn-node', repoPath, config) + } + } + + this.dismantle = function (callback) { + ioC.once('fc-nodes-shutdown', callback) + ioC.emit('fs-dismantle') + } +} diff --git a/test/factory/factory-server-routes.js b/test/factory/factory-server-routes.js new file mode 100644 index 000000000..4b0d655fe --- /dev/null +++ b/test/factory/factory-server-routes.js @@ -0,0 +1,34 @@ +'use strict' + +const SocketIO = require('socket.io') +const DaemonSpawner = require('./daemon-spawner') + +module.exports = (http) => { + const io = new SocketIO(http.listener) + io.on('connection', handle) + + const ds = new DaemonSpawner() + + function handle (socket) { + socket.on('fs-spawn-node', spawnNode.bind(socket)) + socket.on('fs-dismantle', dismantle.bind(socket)) + } + + function spawnNode (repoPath, config) { + ds.spawnNode(repoPath, config, (err, apiAddr) => { + if (err) { + throw err + } + this.emit('fc-node', apiAddr) + }) + } + + function dismantle () { + ds.dismantle((err) => { + if (err) { + throw err + } + this.emit('fc-nodes-shutdown') + }) + } +} diff --git a/test/factory/factory-server.js b/test/factory/factory-server.js new file mode 100644 index 000000000..6482714f2 --- /dev/null +++ b/test/factory/factory-server.js @@ -0,0 +1,28 @@ +'use strict' + +const Hapi = require('hapi') + +const port = Number(process.env.PORT) || 55155 +const options = { + connections: { + routes: { + cors: true + } + } +} + +module.exports = (callback) => { + const http = new Hapi.Server(options) + + http.connection({ port: port }) + + http.start((err) => { + if (err) { + return callback(err) + } + require('./factory-server-routes')(http) + + callback(null, http) + // note: http.stop(callback) to stop the server :) + }) +} diff --git a/test/factory/factory-tasks.js b/test/factory/factory-tasks.js new file mode 100644 index 000000000..d89d10e1f --- /dev/null +++ b/test/factory/factory-tasks.js @@ -0,0 +1,20 @@ +'use strict' + +const gulp = require('gulp') +const factoryServer = require('./factory-server') + +let factory + +gulp.task('factory:start', (done) => { + factoryServer((err, http) => { + if (err) { + throw err + } + factory = http + done() + }) +}) + +gulp.task('factory:stop', (done) => { + factory.stop(done) +}) diff --git a/test/api/bitswap.spec.js b/test/interface-ipfs-core/bitswap.spec.js similarity index 100% rename from test/api/bitswap.spec.js rename to test/interface-ipfs-core/bitswap.spec.js diff --git a/test/api/block.spec.js b/test/interface-ipfs-core/block.spec.js similarity index 100% rename from test/api/block.spec.js rename to test/interface-ipfs-core/block.spec.js diff --git a/test/api/bootstrap.spec.js b/test/interface-ipfs-core/bootstrap.spec.js similarity index 100% rename from test/api/bootstrap.spec.js rename to test/interface-ipfs-core/bootstrap.spec.js diff --git a/test/api/commands.spec.js b/test/interface-ipfs-core/commands.spec.js similarity index 100% rename from test/api/commands.spec.js rename to test/interface-ipfs-core/commands.spec.js diff --git a/test/api/config.spec.js b/test/interface-ipfs-core/config.spec.js similarity index 96% rename from test/api/config.spec.js rename to test/interface-ipfs-core/config.spec.js index 86914958e..ea0a9610c 100644 --- a/test/api/config.spec.js +++ b/test/interface-ipfs-core/config.spec.js @@ -65,7 +65,7 @@ describe('.config', () => { return done() } - apiClients.c.config.replace(path.join(__dirname, '/../r-config.json'), (err, res) => { + apiClients.c.config.replace(path.join(__dirname, '/../data/r-config.json'), (err, res) => { expect(err).to.not.exist expect(res).to.be.equal(null) done() @@ -126,7 +126,7 @@ describe('.config', () => { return } - return apiClients.c.config.replace(path.join(__dirname, '/../r-config.json')) + return apiClients.c.config.replace(path.join(__dirname, '/../data/r-config.json')) .then((res) => { expect(res).to.be.equal(null) }) diff --git a/test/api/dht.spec.js b/test/interface-ipfs-core/dht.spec.js similarity index 97% rename from test/api/dht.spec.js rename to test/interface-ipfs-core/dht.spec.js index 78bde491f..c24ab049e 100644 --- a/test/api/dht.spec.js +++ b/test/interface-ipfs-core/dht.spec.js @@ -24,7 +24,6 @@ describe('.dht', () => { // non ipns or pk hashes fail to fetch, known bug // bug: https://github.com/ipfs/go-ipfs/issues/1923#issuecomment-152932234 // apiClients.a.dht.get('scope', (err, value) => { - // console.log('->>', err, value) // expect(err).to.not.exist // expect(value).to.be.equal('interplanetary') // done() diff --git a/test/api/diag.spec.js b/test/interface-ipfs-core/diag.spec.js similarity index 100% rename from test/api/diag.spec.js rename to test/interface-ipfs-core/diag.spec.js diff --git a/test/api/files.spec.js b/test/interface-ipfs-core/files.spec.js similarity index 89% rename from test/api/files.spec.js rename to test/interface-ipfs-core/files.spec.js index 731a37395..d504fb596 100644 --- a/test/api/files.spec.js +++ b/test/interface-ipfs-core/files.spec.js @@ -7,25 +7,41 @@ const expect = require('chai').expect const isNode = require('detect-node') const path = require('path') const test = require('interface-ipfs-core') +const bs58 = require('bs58') +const fs = require('fs') +const FactoryClient = require('../factory/factory-client') +const testfile = fs.readFileSync(path.join(__dirname, '/../data/testfile.txt')) -let testfile +// add, cat, get and ls tests from interface-ipfs-core +let fc -testfile = require('fs').readFileSync(path.join(__dirname, '/../testfile.txt')) - -// Load the add/cat/get/ls commands from interface-ipfs-core const common = { - setup: function (cb) { - cb(null, apiClients.a) + setup: function (callback) { + fc = new FactoryClient() + callback(null, fc) }, - teardown: function (cb) { - cb() + teardown: function (callback) { + fc.dismantle(callback) } } test.files(common) -// Describe the (mfs) tests +// mfs tests describe('.files (pseudo mfs)', () => { + it('add file for testing', (done) => { + apiClients.a.files.add(testfile, (err, res) => { + expect(err).to.not.exist + + expect(res).to.have.length(1) + const mh = bs58.encode(res[0].node.multihash()).toString() + expect(mh).to.equal('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP') + expect(res[0].path).to.equal(mh) + expect(res[0].node.links).to.have.length(0) + done() + }) + }) + it('files.mkdir', (done) => { apiClients.a.files.mkdir('/test-folder', function (err) { expect(err).to.not.exist diff --git a/test/api/get.spec.js b/test/interface-ipfs-core/get.spec.js similarity index 83% rename from test/api/get.spec.js rename to test/interface-ipfs-core/get.spec.js index 77a9f7451..4a15577f7 100644 --- a/test/api/get.spec.js +++ b/test/interface-ipfs-core/get.spec.js @@ -7,21 +7,18 @@ const expect = require('chai').expect const isNode = require('detect-node') const fs = require('fs') -// const bl = require('bl') const concat = require('concat-stream') +const bs58 = require('bs58') const through = require('through2') const streamEqual = require('stream-equal') - const path = require('path') -// const extract = require('tar-stream').extract - -const testfile = fs.readFileSync(path.join(__dirname, '/../testfile.txt')) +const testfile = fs.readFileSync(path.join(__dirname, '/../data/testfile.txt')) let testfileBig - +let tfbPath if (isNode) { - const tfbPath = path.join(__dirname, '/../15mb.random') + tfbPath = path.join(__dirname, '/../data/15mb.random') testfileBig = fs.createReadStream(tfbPath, { bufferSize: 128 }) } @@ -89,6 +86,25 @@ describe('.get', () => { }) }) + it('add a BIG file (for testing get)', (done) => { + if (!isNode) { + return done() + } + + const bigFile = fs.readFileSync(tfbPath) + + apiClients.a.files.add(bigFile, (err, res) => { + expect(err).to.not.exist + + expect(res).to.have.length(1) + expect(res[0].node.links).to.have.length(58) + const mh = bs58.encode(res[0].node.multihash()).toString() + expect(res[0].path).to.equal(mh) + expect(mh).to.equal('Qme79tX2bViL26vNjPsF3DP1R9rMKMvnPYJiKTTKPrXJjq') + done() + }) + }) + it('get BIG file', (done) => { if (!isNode) { return done() diff --git a/test/api/id.spec.js b/test/interface-ipfs-core/id.spec.js similarity index 100% rename from test/api/id.spec.js rename to test/interface-ipfs-core/id.spec.js diff --git a/test/api/index.spec.js b/test/interface-ipfs-core/index.spec.js similarity index 100% rename from test/api/index.spec.js rename to test/interface-ipfs-core/index.spec.js diff --git a/test/api/log.spec.js b/test/interface-ipfs-core/log.spec.js similarity index 100% rename from test/api/log.spec.js rename to test/interface-ipfs-core/log.spec.js diff --git a/test/api/ls.spec.js b/test/interface-ipfs-core/ls.spec.js similarity index 100% rename from test/api/ls.spec.js rename to test/interface-ipfs-core/ls.spec.js diff --git a/test/api/mount.spec.js b/test/interface-ipfs-core/mount.spec.js similarity index 100% rename from test/api/mount.spec.js rename to test/interface-ipfs-core/mount.spec.js diff --git a/test/api/name.spec.js b/test/interface-ipfs-core/name.spec.js similarity index 100% rename from test/api/name.spec.js rename to test/interface-ipfs-core/name.spec.js diff --git a/test/interface-ipfs-core/object.spec.js b/test/interface-ipfs-core/object.spec.js new file mode 100644 index 000000000..9375bf087 --- /dev/null +++ b/test/interface-ipfs-core/object.spec.js @@ -0,0 +1,20 @@ +/* eslint-env mocha */ + +'use strict' + +const test = require('interface-ipfs-core') +const FactoryClient = require('../factory/factory-client') + +let fc + +const common = { + setup: function (callback) { + fc = new FactoryClient() + callback(null, fc) + }, + teardown: function (callback) { + fc.dismantle(callback) + } +} + +test.object(common) diff --git a/test/api/pin.spec.js b/test/interface-ipfs-core/pin.spec.js similarity index 100% rename from test/api/pin.spec.js rename to test/interface-ipfs-core/pin.spec.js diff --git a/test/api/ping.spec.js b/test/interface-ipfs-core/ping.spec.js similarity index 100% rename from test/api/ping.spec.js rename to test/interface-ipfs-core/ping.spec.js diff --git a/test/api/refs.spec.js b/test/interface-ipfs-core/refs.spec.js similarity index 100% rename from test/api/refs.spec.js rename to test/interface-ipfs-core/refs.spec.js diff --git a/test/api/repo.spec.js b/test/interface-ipfs-core/repo.spec.js similarity index 100% rename from test/api/repo.spec.js rename to test/interface-ipfs-core/repo.spec.js diff --git a/test/api/send.spec.js b/test/interface-ipfs-core/send.spec.js similarity index 100% rename from test/api/send.spec.js rename to test/interface-ipfs-core/send.spec.js diff --git a/test/api/swarm.spec.js b/test/interface-ipfs-core/swarm.spec.js similarity index 100% rename from test/api/swarm.spec.js rename to test/interface-ipfs-core/swarm.spec.js diff --git a/test/api/update.spec.js b/test/interface-ipfs-core/update.spec.js similarity index 100% rename from test/api/update.spec.js rename to test/interface-ipfs-core/update.spec.js diff --git a/test/api/version.spec.js b/test/interface-ipfs-core/version.spec.js similarity index 100% rename from test/api/version.spec.js rename to test/interface-ipfs-core/version.spec.js diff --git a/test/constructor.spec.js b/test/ipfs-api/constructor.spec.js similarity index 89% rename from test/constructor.spec.js rename to test/ipfs-api/constructor.spec.js index 952b12c25..ea6050f7f 100644 --- a/test/constructor.spec.js +++ b/test/ipfs-api/constructor.spec.js @@ -3,11 +3,11 @@ const expect = require('chai').expect -const ipfsAPI = require('../src/index.js') +const ipfsAPI = require('./../../src/index.js') describe('ipfsAPI constructor tests', () => { describe('parameter permuations', () => { - const apiAddrs = require('./tmp-disposable-nodes-addrs.json') + const apiAddrs = require('./../setup/tmp-disposable-nodes-addrs.json') const apiAddr = apiAddrs.a.split('/') function clientWorks (client, done) { diff --git a/test/request-api.spec.js b/test/ipfs-api/request-api.spec.js similarity index 90% rename from test/request-api.spec.js rename to test/ipfs-api/request-api.spec.js index 505edd892..79219b7d7 100644 --- a/test/request-api.spec.js +++ b/test/ipfs-api/request-api.spec.js @@ -3,12 +3,12 @@ const expect = require('chai').expect const isNode = require('detect-node') -const ipfsAPI = require('../src/index.js') +const ipfsAPI = require('./../../src/index.js') const noop = () => {} describe('ipfsAPI request tests', () => { describe('requestAPI', () => { - const apiAddrs = require('./tmp-disposable-nodes-addrs.json') + const apiAddrs = require('./../setup/tmp-disposable-nodes-addrs.json') const apiAddr = apiAddrs.a.split('/') it('excludes port from URL if config.port is falsy', (done) => { @@ -57,7 +57,7 @@ describe('ipfsAPI request tests', () => { res.end() }).listen(6001, () => { ipfsAPI('/ip4/127.0.0.1/tcp/6001') - .config.replace('test/r-config.json', (err) => { + .config.replace('test/data/r-config.json', (err) => { expect(err).to.not.exist server.close(done) }) diff --git a/test/node.js b/test/node.js index cc2566c73..ebfd1aada 100644 --- a/test/node.js +++ b/test/node.js @@ -1,3 +1,3 @@ 'use strict' -require('./setup') +require('./setup/setup-ipfs-api-clients') diff --git a/test/notes.org b/test/notes.org deleted file mode 100644 index 17cff15fb..000000000 --- a/test/notes.org +++ /dev/null @@ -1,12 +0,0 @@ -* broken -config replace -* left to test -** mount -needs unmount command? -** diag -** object put protobuf -** swarm -** dht -** ping -** name -resolve depends on publish diff --git a/test/setup.js b/test/setup/setup-ipfs-api-clients.js similarity index 96% rename from test/setup.js rename to test/setup/setup-ipfs-api-clients.js index ba768a0ef..33cc2ae17 100644 --- a/test/setup.js +++ b/test/setup/setup-ipfs-api-clients.js @@ -1,7 +1,7 @@ /* eslint-env mocha */ 'use strict' -const ipfsAPI = require('../src/index.js') +const ipfsAPI = require('./../../src/index.js') const apiAddrs = require('./tmp-disposable-nodes-addrs.json') // a, b, c diff --git a/tasks/daemons.js b/test/setup/spawn-daemons.js similarity index 91% rename from tasks/daemons.js rename to test/setup/spawn-daemons.js index ad1c1909d..986073732 100644 --- a/tasks/daemons.js +++ b/test/setup/spawn-daemons.js @@ -1,15 +1,15 @@ 'use strict' -/* eslint max-nested-callbacks: ["error", 8] */ // TODO reduce nesteness +// TODO reduce the callbacks nestness +/* eslint max-nested-callbacks: ["error", 8] */ const gulp = require('gulp') const fs = require('fs') const path = require('path') +const ipfsd = require('ipfsd-ctl') let daemons function startDisposableDaemons (callback) { - const ipfsd = require('ipfsd-ctl') - // a, b, c const ipfsNodes = {} @@ -21,7 +21,7 @@ function startDisposableDaemons (callback) { function finish () { counter++ if (counter === 3) { - const targetPath = path.join(__dirname, '/../test/tmp-disposable-nodes-addrs.json') + const targetPath = path.join(__dirname, '/tmp-disposable-nodes-addrs.json') fs.writeFileSync(targetPath, JSON.stringify(apiAddrs)) callback(ipfsNodes) }