Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

Commit d5ec781

Browse files
committed
feat(factory): create the factory (with socket.io) and attach it to the tests
1 parent e40f7d5 commit d5ec781

12 files changed

+288
-53
lines changed

gulpfile.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
const gulp = require('gulp')
44

55
require('./test/setup/spawn-daemons')
6+
require('./test/factory/factory-tasks')
67

7-
gulp.task('test:node:before', ['daemons:start'])
8-
gulp.task('test:node:after', ['daemons:stop'])
9-
gulp.task('test:browser:before', ['daemons:start'])
10-
gulp.task('test:browser:after', ['daemons:stop'])
8+
gulp.task('test:node:before', ['daemons:start', 'factory:start'])
9+
gulp.task('test:node:after', ['daemons:stop', 'factory:stop'])
10+
gulp.task('test:browser:before', ['daemons:start', 'factory:start'])
11+
gulp.task('test:browser:after', ['daemons:stop', 'factory:stop'])
1112

1213
require('aegir/gulp')(gulp)

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@
3333
"aegir": "^6.0.0",
3434
"chai": "^3.5.0",
3535
"gulp": "^3.9.1",
36+
"hapi": "^14.1.0",
3637
"interface-ipfs-core": "^0.7.2",
3738
"ipfsd-ctl": "^0.14.0",
3839
"passthrough-counter": "^1.0.0",
3940
"pre-commit": "^1.1.3",
41+
"socket.io": "^1.4.8",
42+
"socket.io-client": "^1.4.8",
4043
"stream-equal": "^0.1.8",
4144
"stream-http": "^2.3.1",
4245
"streamifier": "^0.1.1"

test/factory/daemon-spawner.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
'use strict'
2+
3+
// const defaultConfig = require('./default-config.json')
4+
const ipfsd = require('ipfsd-ctl')
5+
const series = require('run-series')
6+
7+
module.exports = Factory
8+
9+
function Factory () {
10+
if (!(this instanceof Factory)) {
11+
return new Factory()
12+
}
13+
14+
const nodes = []
15+
16+
this.spawnNode = (repoPath, config, callback) => {
17+
if (typeof repoPath === 'function') {
18+
callback = repoPath
19+
repoPath = undefined
20+
}
21+
if (typeof config === 'function') {
22+
callback = config
23+
config = undefined
24+
}
25+
26+
// if (!repoPath) {
27+
// repoPath = '/tmp/.ipfs-' + Math.random()
28+
// .toString()
29+
// .substring(2, 8)
30+
// }
31+
32+
// TODO
33+
// - [ ] Support custom repoPath
34+
// - [ ] Support custom config
35+
// This will come once the new ipfsd-ctl is
36+
// complete: https://github.com/ipfs/js-ipfsd-ctl/pull/89
37+
38+
spawnEphemeralNode((err, node) => {
39+
if (err) {
40+
return callback(err)
41+
}
42+
nodes.push(node)
43+
callback(null, node.apiAddr)
44+
})
45+
}
46+
47+
this.dismantle = function (callback) {
48+
series(
49+
nodes.map((node) => {
50+
return node.stopDaemon
51+
}), callback)
52+
}
53+
}
54+
55+
function spawnEphemeralNode (callback) {
56+
ipfsd.disposable((err, node) => {
57+
if (err) {
58+
return callback(err)
59+
}
60+
// Note: we have to set each config value
61+
// independently since the config/replace endpoint
62+
// doesn't work as expected
63+
series([
64+
(cb) => {
65+
node.setConfig('Bootstrap', null, cb)
66+
},
67+
(cb) => {
68+
node.setConfig('Discovery', '{}', cb)
69+
},
70+
(cb) => {
71+
const headers = {
72+
HTTPHeaders: {
73+
'Access-Control-Allow-Origin': ['*']
74+
}
75+
}
76+
node.setConfig('API', JSON.stringify(headers), cb)
77+
},
78+
(cb) => {
79+
node.startDaemon(cb)
80+
}
81+
], (err) => {
82+
if (err) {
83+
return callback(err)
84+
}
85+
86+
callback(null, node)
87+
})
88+
})
89+
}

test/factory/factory-client.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
'use strict'
2+
3+
const io = require('socket.io-client')
4+
const ipfsAPI = require('../../src')
5+
6+
module.exports = Factory
7+
8+
function Factory () {
9+
if (!(this instanceof Factory)) {
10+
return new Factory()
11+
}
12+
const sioOptions = {
13+
transports: ['websocket'],
14+
'force new connection': true
15+
}
16+
const sioUrl = 'http://localhost:55155'
17+
let sioConnected = false
18+
let ioC
19+
20+
this.spawnNode = (repoPath, config, callback) => {
21+
if (typeof repoPath === 'function') {
22+
callback = repoPath
23+
repoPath = undefined
24+
}
25+
if (typeof config === 'function') {
26+
callback = config
27+
config = undefined
28+
}
29+
30+
if (sioConnected) {
31+
spawnNode()
32+
} else {
33+
ioC = io.connect(sioUrl, sioOptions)
34+
ioC.on('connect_error', callback)
35+
ioC.on('connect', () => {
36+
sioConnected = true
37+
spawnNode()
38+
})
39+
}
40+
41+
function spawnNode () {
42+
ioC.once('fc-node', (apiAddr) => {
43+
const ipfs = ipfsAPI(apiAddr)
44+
callback(null, ipfs)
45+
})
46+
ioC.emit('fs-spawn-node', repoPath, config)
47+
}
48+
}
49+
50+
this.dismantle = function (callback) {
51+
ioC.once('fc-nodes-shutdown', callback)
52+
ioC.emit('fs-dismantle')
53+
}
54+
}

test/factory/factory-server-routes.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict'
2+
3+
const SocketIO = require('socket.io')
4+
const DaemonSpawner = require('./daemon-spawner')
5+
6+
module.exports = (http) => {
7+
const io = new SocketIO(http.listener)
8+
io.on('connection', handle)
9+
10+
const ds = new DaemonSpawner()
11+
12+
function handle (socket) {
13+
socket.on('fs-spawn-node', spawnNode.bind(socket))
14+
socket.on('fs-dismantle', dismantle.bind(socket))
15+
}
16+
17+
function spawnNode (repoPath, config) {
18+
ds.spawnNode(repoPath, config, (err, apiAddr) => {
19+
if (err) {
20+
throw err
21+
}
22+
this.emit('fc-node', apiAddr)
23+
})
24+
}
25+
26+
function dismantle () {
27+
ds.dismantle((err) => {
28+
if (err) {
29+
throw err
30+
}
31+
this.emit('fc-nodes-shutdown')
32+
})
33+
}
34+
}

test/factory/factory-server.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict'
2+
3+
const Hapi = require('hapi')
4+
5+
const port = Number(process.env.PORT) || 55155
6+
const options = {
7+
connections: {
8+
routes: {
9+
cors: true
10+
}
11+
}
12+
}
13+
14+
module.exports = (callback) => {
15+
const http = new Hapi.Server(options)
16+
17+
http.connection({ port: port })
18+
19+
http.start((err) => {
20+
if (err) {
21+
return callback(err)
22+
}
23+
require('./factory-server-routes')(http)
24+
25+
callback(null, http)
26+
// note: http.stop(callback) to stop the server :)
27+
})
28+
}

test/factory/factory-tasks.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict'
2+
3+
const gulp = require('gulp')
4+
const factoryServer = require('./factory-server')
5+
6+
let factory
7+
8+
gulp.task('factory:start', (done) => {
9+
factoryServer((err, http) => {
10+
if (err) {
11+
throw err
12+
}
13+
factory = http
14+
done()
15+
})
16+
})
17+
18+
gulp.task('factory:stop', (done) => {
19+
factory.stop(done)
20+
})

test/interface-ipfs-core/dht.spec.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ describe('.dht', () => {
2424
// non ipns or pk hashes fail to fetch, known bug
2525
// bug: https://github.com/ipfs/go-ipfs/issues/1923#issuecomment-152932234
2626
// apiClients.a.dht.get('scope', (err, value) => {
27-
// console.log('->>', err, value)
2827
// expect(err).to.not.exist
2928
// expect(value).to.be.equal('interplanetary')
3029
// done()

test/interface-ipfs-core/files.spec.js

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,41 @@ const expect = require('chai').expect
77
const isNode = require('detect-node')
88
const path = require('path')
99
const test = require('interface-ipfs-core')
10+
const bs58 = require('bs58')
1011
const fs = require('fs')
11-
12+
const FactoryClient = require('../factory/factory-client')
1213
const testfile = fs.readFileSync(path.join(__dirname, '/../data/testfile.txt'))
1314

14-
// Load the add/cat/get/ls commands from interface-ipfs-core
15+
// add, cat, get and ls tests from interface-ipfs-core
16+
let fc
17+
1518
const common = {
16-
setup: function (cb) {
17-
let c = 0
18-
cb(null, {
19-
spawnNode: (path, config, callback) => {
20-
if (typeof path === 'function') {
21-
callback = path
22-
path = undefined
23-
}
24-
switch (c) {
25-
case 0: callback(null, apiClients.a); c++; break
26-
case 1: callback(null, apiClients.b); c++; break
27-
case 2: callback(null, apiClients.c); c++; break
28-
default: callback(new Error('no more nodes available'))
29-
}
30-
}
31-
})
19+
setup: function (callback) {
20+
fc = new FactoryClient()
21+
callback(null, fc)
3222
},
33-
teardown: function (cb) {
34-
cb()
23+
teardown: function (callback) {
24+
fc.dismantle(callback)
3525
}
3626
}
3727

3828
test.files(common)
3929

40-
// Describe the (mfs) tests
30+
// mfs tests
4131
describe('.files (pseudo mfs)', () => {
32+
it('add file for testing', (done) => {
33+
apiClients.a.files.add(testfile, (err, res) => {
34+
expect(err).to.not.exist
35+
36+
expect(res).to.have.length(1)
37+
const mh = bs58.encode(res[0].node.multihash()).toString()
38+
expect(mh).to.equal('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
39+
expect(res[0].path).to.equal(mh)
40+
expect(res[0].node.links).to.have.length(0)
41+
done()
42+
})
43+
})
44+
4245
it('files.mkdir', (done) => {
4346
apiClients.a.files.mkdir('/test-folder', function (err) {
4447
expect(err).to.not.exist

test/interface-ipfs-core/get.spec.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@ const expect = require('chai').expect
88
const isNode = require('detect-node')
99
const fs = require('fs')
1010
const concat = require('concat-stream')
11+
const bs58 = require('bs58')
1112
const through = require('through2')
1213
const streamEqual = require('stream-equal')
1314
const path = require('path')
1415

1516
const testfile = fs.readFileSync(path.join(__dirname, '/../data/testfile.txt'))
1617

1718
let testfileBig
18-
19+
let tfbPath
1920
if (isNode) {
20-
const tfbPath = path.join(__dirname, '/../data/15mb.random')
21+
tfbPath = path.join(__dirname, '/../data/15mb.random')
2122
testfileBig = fs.createReadStream(tfbPath, { bufferSize: 128 })
2223
}
2324

@@ -85,6 +86,25 @@ describe('.get', () => {
8586
})
8687
})
8788

89+
it('add a BIG file (for testing get)', (done) => {
90+
if (!isNode) {
91+
return done()
92+
}
93+
94+
const bigFile = fs.readFileSync(tfbPath)
95+
96+
apiClients.a.files.add(bigFile, (err, res) => {
97+
expect(err).to.not.exist
98+
99+
expect(res).to.have.length(1)
100+
expect(res[0].node.links).to.have.length(58)
101+
const mh = bs58.encode(res[0].node.multihash()).toString()
102+
expect(res[0].path).to.equal(mh)
103+
expect(mh).to.equal('Qme79tX2bViL26vNjPsF3DP1R9rMKMvnPYJiKTTKPrXJjq')
104+
done()
105+
})
106+
})
107+
88108
it('get BIG file', (done) => {
89109
if (!isNode) {
90110
return done()

0 commit comments

Comments
 (0)