Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit ac95601

Browse files
authored
feat: complete PubSub implementation
* feat: PubSub Interop Tests and CLI+HTTP-API Implementation (#1081) * test: enable pubsub tests * fix: generate meaniful error when pubsub is called and not enabled * test: enable pubsub for factory daemon * test: enable pubsub tests * fix: generate meaniful error when pubsub is called and not enabled * test: enable pubsub for factory daemon * fiix(pubsub-subscribe): stop HAPI gzip from buffering our streamed response * test: fix spec/pubsub * fix: lint errors * test: tests js/go pubsub interop * test: pubsub interop tests * test: enable pubsub tests * fix: generate meaniful error when pubsub is called and not enabled * test: enable pubsub for factory daemon * fiix(pubsub-subscribe): stop HAPI gzip from buffering our streamed response * test: fix spec/pubsub * fix: lint errors * test: tests js/go pubsub interop * test: pubsub interop tests * test: more tests with different data types Note that binary data from JS to GO fails * HTTP API server: parsing query string as binary in pubsub publish * HTTP API: pubsub: publish should fail gracefully when no argument is given * chore: update deps * chore: update deps * last pass * chore: update deps * test: update interop tests * trying to fix cli pubsub tests * HTTP API server: pubsub pub buffer should have content * making linter happier * pubsub cli tests: higher timeout * making the linter even happier * tests: increasing some of the timeouts * fix: test was wrong * moar * mais um pouco * fix * meh * key size * moar timeouts * taaaaaaaaaaake ooooooonnn meeeeeeee * unomas * take it all * fix * moar * almost there * almost there part II * almost there part III * take out coverage from travis and pass it to circle * small adj in the travis config
1 parent 1c8ad75 commit ac95601

Some content is hidden

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

43 files changed

+712
-377
lines changed

.travis.yml

-6
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,16 @@ matrix:
77
env: CXX=g++-4.8
88
- node_js: 8
99
env: CXX=g++-4.8
10-
# - node_js: stable
11-
# env: CXX=g++-4.8
1210

1311
script:
1412
- npm run lint
1513
- npm run test
16-
- npm run coverage
1714
- make test
1815

1916
before_script:
2017
- export DISPLAY=:99.0
2118
- sh -e /etc/init.d/xvfb start
2219

23-
after_success:
24-
- npm run coverage-publish
25-
2620
addons:
2721
firefox: 'latest'
2822
apt:

circle.yml

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ machine:
22
node:
33
version: stable
44

5+
test:
6+
post:
7+
- npm run coverage -- --upload
8+
59
dependencies:
610
pre:
711
- google-chrome --version

package.json

+8-7
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"test:unit:node:gateway": "aegir test -t node -f test/gateway/index.js",
3434
"test:unit:node:cli": "aegir test -t node -f test/cli/index.js",
3535
"test:unit:browser": "aegir test -t browser --no-cors",
36-
"test:interop": "IPFS_TEST=interop aegir test -t node -t browser -f test/interop",
36+
"test:interop": "IPFS_TEST=interop aegir test -t node -f test/interop",
3737
"test:interop:node": "IPFS_TEST=interop aegir test -t node -f test/interop/node.js",
3838
"test:interop:browser": "IPFS_TEST=interop aegir test -t browser -f test/interop/browser.js",
3939
"test:bootstrapers": "IPFS_TEST=bootstrapers aegir test -t browser -f test/bootstrapers.js",
@@ -63,7 +63,7 @@
6363
},
6464
"homepage": "https://github.com/ipfs/js-ipfs#readme",
6565
"devDependencies": {
66-
"aegir": "^12.1.3",
66+
"aegir": "^12.2.0",
6767
"buffer-loader": "0.0.1",
6868
"chai": "^4.1.2",
6969
"delay": "^2.0.0",
@@ -75,8 +75,8 @@
7575
"expose-loader": "^0.7.4",
7676
"form-data": "^2.3.1",
7777
"hat": "0.0.3",
78-
"interface-ipfs-core": "~0.36.7",
79-
"ipfsd-ctl": "~0.24.1",
78+
"interface-ipfs-core": "~0.36.8",
79+
"ipfsd-ctl": "~0.25.1",
8080
"left-pad": "^1.2.0",
8181
"lodash": "^4.17.4",
8282
"mocha": "^4.0.1",
@@ -92,21 +92,22 @@
9292
},
9393
"dependencies": {
9494
"async": "^2.6.0",
95+
"binary-querystring": "~0.1.2",
9596
"bl": "^1.2.1",
9697
"boom": "^7.1.1",
9798
"bs58": "^4.0.1",
9899
"byteman": "^1.3.5",
99100
"cids": "^0.5.2",
100101
"debug": "^3.1.0",
101-
"file-type": "^7.2.0",
102+
"file-type": "^7.3.0",
102103
"filesize": "^3.5.11",
103104
"fsm-event": "^2.1.0",
104105
"get-folder-size": "^1.0.0",
105106
"glob": "^7.1.2",
106107
"hapi": "^16.6.2",
107108
"hapi-set-header": "^1.0.2",
108109
"hoek": "^5.0.2",
109-
"ipfs-api": "^17.1.0",
110+
"ipfs-api": "^17.1.2",
110111
"ipfs-bitswap": "~0.17.4",
111112
"ipfs-block": "~0.6.1",
112113
"ipfs-block-service": "~0.13.0",
@@ -120,7 +121,7 @@
120121
"joi": "^13.0.2",
121122
"libp2p": "~0.13.1",
122123
"libp2p-circuit": "~0.1.4",
123-
"libp2p-floodsub": "~0.12.1",
124+
"libp2p-floodsub": "~0.13.0",
124125
"libp2p-kad-dht": "~0.6.0",
125126
"libp2p-mdns": "~0.9.1",
126127
"libp2p-multiplex": "~0.5.0",

src/core/components/no-floodsub.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict'
2+
3+
const EventEmitter = require('events')
4+
5+
function fail () {
6+
throw new Error('The daemon must be run with \'--enable-pubsub-experiment\'')
7+
}
8+
9+
class NoFloodSub extends EventEmitter {
10+
constructor () {
11+
super()
12+
13+
this.peers = new Map()
14+
this.subscriptions = new Set()
15+
}
16+
17+
start (callback) { callback() }
18+
stop (callback) { callback() }
19+
publish () { fail() }
20+
subscribe () { fail() }
21+
unsubscribe () { fail() }
22+
}
23+
24+
module.exports = NoFloodSub

src/core/components/start.js

+5-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const series = require('async/series')
44
const Bitswap = require('ipfs-bitswap')
55
const FloodSub = require('libp2p-floodsub')
6+
const NoFloodSub = require('./no-floodsub')
67
const setImmediate = require('async/setImmediate')
78
const promisify = require('promisify-es6')
89

@@ -50,12 +51,10 @@ module.exports = (self) => {
5051
self._bitswap.start()
5152
self._blockService.setExchange(self._bitswap)
5253

53-
if (self._options.EXPERIMENTAL.pubsub) {
54-
self._pubsub = new FloodSub(self._libp2pNode)
55-
self._pubsub.start(done)
56-
} else {
57-
done()
58-
}
54+
self._pubsub = self._options.EXPERIMENTAL.pubsub
55+
? new FloodSub(self._libp2pNode)
56+
: new NoFloodSub()
57+
self._pubsub.start(done)
5958
})
6059
})
6160
}

src/core/components/stop.js

+1-7
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,7 @@ module.exports = (self) => {
3131
self._bitswap.stop()
3232

3333
series([
34-
(cb) => {
35-
if (self._options.EXPERIMENTAL.pubsub) {
36-
self._pubsub.stop(cb)
37-
} else {
38-
cb()
39-
}
40-
},
34+
(cb) => self._pubsub.stop(cb),
4135
(cb) => self.libp2p.stop(cb),
4236
(cb) => self._repo.close(cb)
4337
], done)

src/http/api/resources/pubsub.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const PassThrough = require('stream').PassThrough
44
const bs58 = require('bs58')
5+
const binaryQueryString = require('binary-querystring')
56

67
exports = module.exports
78

@@ -48,6 +49,7 @@ exports.subscribe = {
4849

4950
reply(res)
5051
.header('X-Chunked-Output', '1')
52+
.header('content-encoding', 'identity') // stop gzip from buffering, see https://github.com/hapijs/hapi/issues/2975
5153
.header('content-type', 'application/json')
5254
})
5355
}
@@ -57,19 +59,21 @@ exports.publish = {
5759
handler: (request, reply) => {
5860
const arg = request.query.arg
5961
const topic = arg[0]
60-
const buf = arg[1]
62+
63+
const rawArgs = binaryQueryString(request.url.search)
64+
const buf = rawArgs.arg && rawArgs.arg[1]
6165

6266
const ipfs = request.server.app.ipfs
6367

6468
if (!topic) {
6569
return reply(new Error('Missing topic'))
6670
}
6771

68-
if (!buf) {
72+
if (!buf || buf.length === 0) {
6973
return reply(new Error('Missing buf'))
7074
}
7175

72-
ipfs.pubsub.publish(topic, Buffer.from(String(buf)), (err) => {
76+
ipfs.pubsub.publish(topic, buf, (err) => {
7377
if (err) {
7478
return reply(new Error(`Failed to publish to topic ${topic}: ${err}`))
7579
}

test/cli/bitswap.js

+30-27
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,39 @@
44
const expect = require('chai').expect
55
const runOn = require('../utils/on-and-off').on
66

7-
describe('bitswap', () => runOn((thing) => {
8-
let ipfs
9-
const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR'
7+
describe('bitswap', function () {
8+
runOn((thing) => {
9+
this.timeout(30000)
10+
let ipfs
11+
const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR'
1012

11-
before((done) => {
12-
ipfs = thing.ipfs
13-
ipfs('block get ' + key)
14-
.then(() => {})
15-
.catch(() => {})
16-
setTimeout(done, 800)
17-
})
13+
before((done) => {
14+
ipfs = thing.ipfs
15+
ipfs('block get ' + key)
16+
.then(() => {})
17+
.catch(() => {})
18+
setTimeout(done, 800)
19+
})
1820

19-
it('wantlist', () => {
20-
return ipfs('bitswap wantlist').then((out) => {
21-
expect(out).to.eql(key + '\n')
21+
it('wantlist', () => {
22+
return ipfs('bitswap wantlist').then((out) => {
23+
expect(out).to.eql(key + '\n')
24+
})
2225
})
23-
})
2426

25-
it('stat', () => {
26-
return ipfs('bitswap stat').then((out) => {
27-
expect(out).to.be.eql([
28-
'bitswap status',
29-
' blocks received: 0',
30-
' dup blocks received: 0',
31-
' dup data received: 0B',
32-
' wantlist [1 keys]',
33-
` ${key}`,
34-
' partners [0]',
35-
' '
36-
].join('\n') + '\n')
27+
it('stat', () => {
28+
return ipfs('bitswap stat').then((out) => {
29+
expect(out).to.be.eql([
30+
'bitswap status',
31+
' blocks received: 0',
32+
' dup blocks received: 0',
33+
' dup data received: 0B',
34+
' wantlist [1 keys]',
35+
` ${key}`,
36+
' partners [0]',
37+
' '
38+
].join('\n') + '\n')
39+
})
3740
})
3841
})
39-
}))
42+
})

test/cli/block.js

+17-6
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,41 @@ describe('block', () => runOnAndOff((thing) => {
1111
ipfs = thing.ipfs
1212
})
1313

14-
it('put', () => {
14+
it('put', function () {
15+
this.timeout(40 * 1000)
1516
return ipfs('block put test/fixtures/test-data/hello').then((out) => {
1617
expect(out).to.eql('QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp\n')
1718
})
1819
})
1920

20-
it('put with flags, format and mhtype', () => {
21+
it('put with flags, format and mhtype', function () {
22+
this.timeout(40 * 1000)
23+
2124
return ipfs('block put --format eth-block --mhtype keccak-256 test/fixtures/test-data/eth-block')
2225
.then((out) =>
2326
expect(out).to.eql('z43AaGF23fmvRnDP56Ub9WcJCfzSfqtmzNCCvmz5eudT8dtdCDS\n'))
2427
})
2528

26-
it('get', () => {
29+
it('get', function () {
30+
this.timeout(40 * 1000)
31+
2732
return ipfs('block get QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp')
2833
.then((out) => expect(out).to.eql('hello world\n'))
2934
})
3035

31-
it('get block from file without a final newline', () => {
36+
it('get block from file without a final newline', function () {
37+
this.timeout(40 * 1000)
38+
3239
return ipfs('block put test/fixtures/test-data/no-newline').then((out) => {
3340
expect(out).to.eql('QmTwbQs4sGcCiPxV97SpbHS7QgmVg9SiKxcG1AcF1Ly2SL\n')
3441
return ipfs('block get QmTwbQs4sGcCiPxV97SpbHS7QgmVg9SiKxcG1AcF1Ly2SL')
3542
})
3643
.then((out) => expect(out).to.eql('there is no newline at end of this file'))
3744
})
3845

39-
it('stat', () => {
46+
it('stat', function () {
47+
this.timeout(40 * 1000)
48+
4049
return ipfs('block stat QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp')
4150
.then((out) => {
4251
expect(out).to.eql([
@@ -46,7 +55,9 @@ describe('block', () => runOnAndOff((thing) => {
4655
})
4756
})
4857

49-
it.skip('rm', () => {
58+
it.skip('rm', function () {
59+
this.timeout(40 * 1000)
60+
5061
return ipfs('block rm QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp')
5162
.then((out) => {
5263
expect(out).to.eql(

0 commit comments

Comments
 (0)