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

Commit 7dcb3c4

Browse files
authored
Merge pull request #340 from ipfs/feat/ipfs-factory
feat(factory): use the factory mode
2 parents 6948370 + d5ec781 commit 7dcb3c4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+321
-74
lines changed

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
node_modules
22
*.log
3-
test/tmp-disposable-nodes-addrs.json
3+
test/setup/tmp-disposable-nodes-addrs.json
44
dist
55
lib
6-
coverage
6+
coverage

gulpfile.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,12 @@
22

33
const gulp = require('gulp')
44

5-
require('./tasks/test')
5+
require('./test/setup/spawn-daemons')
6+
require('./test/factory/factory-tasks')
7+
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'])
12+
613
require('aegir/gulp')(gulp)

package.json

+4-1
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-
"interface-ipfs-core": "^0.6.0",
36+
"hapi": "^14.1.0",
37+
"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"

tasks/test.js

-10
This file was deleted.

test/api/object.spec.js

-17
This file was deleted.

test/browser.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
'use strict'
22

3-
require('./setup')
3+
require('./setup/setup-ipfs-api-clients')
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

test/factory/daemon-spawner.js

+89
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

+54
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

+34
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

+28
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

+20
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+
})
File renamed without changes.
File renamed without changes.
File renamed without changes.

test/api/config.spec.js renamed to test/interface-ipfs-core/config.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ describe('.config', () => {
6565
return done()
6666
}
6767

68-
apiClients.c.config.replace(path.join(__dirname, '/../r-config.json'), (err, res) => {
68+
apiClients.c.config.replace(path.join(__dirname, '/../data/r-config.json'), (err, res) => {
6969
expect(err).to.not.exist
7070
expect(res).to.be.equal(null)
7171
done()
@@ -126,7 +126,7 @@ describe('.config', () => {
126126
return
127127
}
128128

129-
return apiClients.c.config.replace(path.join(__dirname, '/../r-config.json'))
129+
return apiClients.c.config.replace(path.join(__dirname, '/../data/r-config.json'))
130130
.then((res) => {
131131
expect(res).to.be.equal(null)
132132
})

test/api/dht.spec.js renamed to test/interface-ipfs-core/dht.spec.js

-1
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()
File renamed without changes.

test/api/files.spec.js renamed to test/interface-ipfs-core/files.spec.js

+25-9
Original file line numberDiff line numberDiff line change
@@ -7,25 +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')
11+
const fs = require('fs')
12+
const FactoryClient = require('../factory/factory-client')
13+
const testfile = fs.readFileSync(path.join(__dirname, '/../data/testfile.txt'))
1014

11-
let testfile
15+
// add, cat, get and ls tests from interface-ipfs-core
16+
let fc
1217

13-
testfile = require('fs').readFileSync(path.join(__dirname, '/../testfile.txt'))
14-
15-
// Load the add/cat/get/ls commands from interface-ipfs-core
1618
const common = {
17-
setup: function (cb) {
18-
cb(null, apiClients.a)
19+
setup: function (callback) {
20+
fc = new FactoryClient()
21+
callback(null, fc)
1922
},
20-
teardown: function (cb) {
21-
cb()
23+
teardown: function (callback) {
24+
fc.dismantle(callback)
2225
}
2326
}
2427

2528
test.files(common)
2629

27-
// Describe the (mfs) tests
30+
// mfs tests
2831
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+
2945
it('files.mkdir', (done) => {
3046
apiClients.a.files.mkdir('/test-folder', function (err) {
3147
expect(err).to.not.exist

0 commit comments

Comments
 (0)