mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-03-27 21:01:05 +00:00
* fix: add pubsub default config (#401) License: MIT Signed-off-by: Matthias Knopp <matthias-knopp@gmx.net> * docs: add default pubsub config to README (#401) License: MIT Signed-off-by: Matthias Knopp <matthias-knopp@gmx.net> * fix: pass config to provided PubSub (#401) License: MIT Signed-off-by: Matthias Knopp <matthias-knopp@gmx.net> * docs: adapt pubsub/example for new config (#401) License: MIT Signed-off-by: Matthias Knopp <matthias-knopp@gmx.net> * Update examples/pubsub/README.md Co-Authored-By: Jacob Heun <jacobheun@gmail.com> * test: add pubsub config tests (#401) License: MIT Signed-off-by: Matthias Knopp <matthias-knopp@gmx.net>
437 lines
12 KiB
JavaScript
437 lines
12 KiB
JavaScript
/* eslint-env mocha */
|
|
/* eslint max-nested-callbacks: ["error", 8] */
|
|
|
|
'use strict'
|
|
|
|
const chai = require('chai')
|
|
chai.use(require('dirty-chai'))
|
|
chai.use(require('chai-checkmark'))
|
|
const expect = chai.expect
|
|
const parallel = require('async/parallel')
|
|
const series = require('async/series')
|
|
const _times = require('lodash.times')
|
|
|
|
const Floodsub = require('libp2p-floodsub')
|
|
const mergeOptions = require('merge-options')
|
|
|
|
const { codes } = require('../src/errors')
|
|
const createNode = require('./utils/create-node')
|
|
|
|
function startTwo (options, callback) {
|
|
if (typeof options === 'function') {
|
|
callback = options
|
|
options = {}
|
|
}
|
|
|
|
const tasks = _times(2, () => (cb) => {
|
|
createNode('/ip4/0.0.0.0/tcp/0', mergeOptions({
|
|
config: {
|
|
peerDiscovery: {
|
|
mdns: {
|
|
enabled: false
|
|
}
|
|
},
|
|
pubsub: {
|
|
enabled: true
|
|
}
|
|
}
|
|
}, options), (err, node) => {
|
|
expect(err).to.not.exist()
|
|
node.start((err) => cb(err, node))
|
|
})
|
|
})
|
|
|
|
parallel(tasks, (err, nodes) => {
|
|
expect(err).to.not.exist()
|
|
|
|
nodes[0].dial(nodes[1].peerInfo, (err) => callback(err, nodes))
|
|
})
|
|
}
|
|
|
|
function stopTwo (nodes, callback) {
|
|
parallel([
|
|
(cb) => nodes[0].stop(cb),
|
|
(cb) => nodes[1].stop(cb)
|
|
], callback)
|
|
}
|
|
|
|
describe('.pubsub', () => {
|
|
describe('.pubsub on (default)', () => {
|
|
it('start two nodes and send one message, then unsubscribe', (done) => {
|
|
// Check the final series error, and the publish handler
|
|
expect(2).checks(done)
|
|
|
|
let nodes
|
|
const data = 'test'
|
|
const handler = (msg) => {
|
|
// verify the data is correct and mark the expect
|
|
expect(msg.data.toString()).to.eql(data).mark()
|
|
}
|
|
|
|
series([
|
|
// Start the nodes
|
|
(cb) => startTwo((err, _nodes) => {
|
|
nodes = _nodes
|
|
cb(err)
|
|
}),
|
|
// subscribe on the first
|
|
(cb) => nodes[0].pubsub.subscribe('pubsub', handler, null, cb),
|
|
// Wait a moment before publishing
|
|
(cb) => setTimeout(cb, 500),
|
|
// publish on the second
|
|
(cb) => nodes[1].pubsub.publish('pubsub', data, cb),
|
|
// Wait a moment before unsubscribing
|
|
(cb) => setTimeout(cb, 500),
|
|
// unsubscribe on the first
|
|
(cb) => nodes[0].pubsub.unsubscribe('pubsub', handler, cb),
|
|
// Stop both nodes
|
|
(cb) => stopTwo(nodes, cb)
|
|
], (err) => {
|
|
// Verify there was no error, and mark the expect
|
|
expect(err).to.not.exist().mark()
|
|
})
|
|
})
|
|
it('start two nodes and send one message, then unsubscribe without handler', (done) => {
|
|
// Check the final series error, and the publish handler
|
|
expect(3).checks(done)
|
|
|
|
let nodes
|
|
const data = Buffer.from('test')
|
|
const handler = (msg) => {
|
|
// verify the data is correct and mark the expect
|
|
expect(msg.data).to.eql(data).mark()
|
|
}
|
|
|
|
series([
|
|
// Start the nodes
|
|
(cb) => startTwo((err, _nodes) => {
|
|
nodes = _nodes
|
|
cb(err)
|
|
}),
|
|
// subscribe on the first
|
|
(cb) => nodes[0].pubsub.subscribe('pubsub', handler, {}, cb),
|
|
// Wait a moment before publishing
|
|
(cb) => setTimeout(cb, 500),
|
|
// publish on the second
|
|
(cb) => nodes[1].pubsub.publish('pubsub', data, cb),
|
|
// ls subscripts
|
|
(cb) => nodes[1].pubsub.ls(cb),
|
|
// get subscribed peers
|
|
(cb) => nodes[1].pubsub.peers('pubsub', cb),
|
|
// Wait a moment before unsubscribing
|
|
(cb) => setTimeout(cb, 500),
|
|
// unsubscribe from all
|
|
(cb) => nodes[0].pubsub.unsubscribe('pubsub', null, cb),
|
|
// Verify unsubscribed
|
|
(cb) => {
|
|
nodes[0].pubsub.ls((err, topics) => {
|
|
expect(topics.length).to.eql(0).mark()
|
|
cb(err)
|
|
})
|
|
},
|
|
// Stop both nodes
|
|
(cb) => stopTwo(nodes, cb)
|
|
], (err) => {
|
|
// Verify there was no error, and mark the expect
|
|
expect(err).to.not.exist().mark()
|
|
})
|
|
})
|
|
it('publish should fail if data is not a buffer nor a string', (done) => {
|
|
createNode('/ip4/0.0.0.0/tcp/0', {
|
|
config: {
|
|
peerDiscovery: {
|
|
mdns: {
|
|
enabled: false
|
|
}
|
|
},
|
|
pubsub: {
|
|
enabled: true
|
|
}
|
|
}
|
|
}, (err, node) => {
|
|
expect(err).to.not.exist()
|
|
|
|
node.start((err) => {
|
|
expect(err).to.not.exist()
|
|
|
|
node.pubsub.publish('pubsub', 10, (err) => {
|
|
expect(err).to.exist()
|
|
expect(err.code).to.equal('ERR_DATA_IS_NOT_VALID')
|
|
|
|
done()
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('.pubsub on using floodsub', () => {
|
|
it('start two nodes and send one message, then unsubscribe', (done) => {
|
|
// Check the final series error, and the publish handler
|
|
expect(2).checks(done)
|
|
|
|
let nodes
|
|
const data = Buffer.from('test')
|
|
const handler = (msg) => {
|
|
// verify the data is correct and mark the expect
|
|
expect(msg.data).to.eql(data).mark()
|
|
}
|
|
|
|
series([
|
|
// Start the nodes
|
|
(cb) => startTwo({
|
|
modules: {
|
|
pubsub: Floodsub
|
|
}
|
|
}, (err, _nodes) => {
|
|
nodes = _nodes
|
|
cb(err)
|
|
}),
|
|
// subscribe on the first
|
|
(cb) => nodes[0].pubsub.subscribe('pubsub', handler, cb),
|
|
// Wait a moment before publishing
|
|
(cb) => setTimeout(cb, 500),
|
|
// publish on the second
|
|
(cb) => nodes[1].pubsub.publish('pubsub', data, cb),
|
|
// Wait a moment before unsubscribing
|
|
(cb) => setTimeout(cb, 500),
|
|
// unsubscribe on the first
|
|
(cb) => nodes[0].pubsub.unsubscribe('pubsub', handler, cb),
|
|
// Stop both nodes
|
|
(cb) => stopTwo(nodes, cb)
|
|
], (err) => {
|
|
// Verify there was no error, and mark the expect
|
|
expect(err).to.not.exist().mark()
|
|
})
|
|
})
|
|
it('start two nodes and send one message, then unsubscribe without handler', (done) => {
|
|
// Check the final series error, and the publish handler
|
|
expect(3).checks(done)
|
|
|
|
let nodes
|
|
const data = Buffer.from('test')
|
|
const handler = (msg) => {
|
|
// verify the data is correct and mark the expect
|
|
expect(msg.data).to.eql(data).mark()
|
|
}
|
|
|
|
series([
|
|
// Start the nodes
|
|
(cb) => startTwo({
|
|
modules: {
|
|
pubsub: Floodsub
|
|
}
|
|
}, (err, _nodes) => {
|
|
nodes = _nodes
|
|
cb(err)
|
|
}),
|
|
// subscribe on the first
|
|
(cb) => nodes[0].pubsub.subscribe('pubsub', handler, cb),
|
|
// Wait a moment before publishing
|
|
(cb) => setTimeout(cb, 500),
|
|
// publish on the second
|
|
(cb) => nodes[1].pubsub.publish('pubsub', data, cb),
|
|
// Wait a moment before unsubscribing
|
|
(cb) => setTimeout(cb, 500),
|
|
// unsubscribe from all
|
|
(cb) => nodes[0].pubsub.unsubscribe('pubsub', null, cb),
|
|
// Verify unsubscribed
|
|
(cb) => {
|
|
nodes[0].pubsub.ls((err, topics) => {
|
|
expect(topics.length).to.eql(0).mark()
|
|
cb(err)
|
|
})
|
|
},
|
|
// Stop both nodes
|
|
(cb) => stopTwo(nodes, cb)
|
|
], (err) => {
|
|
// Verify there was no error, and mark the expect
|
|
expect(err).to.not.exist().mark()
|
|
})
|
|
})
|
|
it('publish should fail if data is not a buffer', (done) => {
|
|
createNode('/ip4/0.0.0.0/tcp/0', {
|
|
config: {
|
|
peerDiscovery: {
|
|
mdns: {
|
|
enabled: false
|
|
}
|
|
},
|
|
pubsub: {
|
|
enabled: true
|
|
}
|
|
},
|
|
modules: {
|
|
pubsub: Floodsub
|
|
}
|
|
}, (err, node) => {
|
|
expect(err).to.not.exist()
|
|
|
|
node.start((err) => {
|
|
expect(err).to.not.exist()
|
|
|
|
node.pubsub.publish('pubsub', 10, (err) => {
|
|
expect(err).to.exist()
|
|
expect(err.code).to.equal('ERR_DATA_IS_NOT_VALID')
|
|
|
|
done()
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('.pubsub off', () => {
|
|
it('fail to use pubsub if disabled', (done) => {
|
|
createNode('/ip4/0.0.0.0/tcp/0', {
|
|
config: {
|
|
peerDiscovery: {
|
|
mdns: {
|
|
enabled: false
|
|
}
|
|
}
|
|
}
|
|
}, (err, node) => {
|
|
expect(err).to.not.exist()
|
|
expect(node.pubsub).to.not.exist()
|
|
done()
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('.pubsub on and node not started', () => {
|
|
let libp2pNode
|
|
|
|
before(function (done) {
|
|
createNode('/ip4/0.0.0.0/tcp/0', {
|
|
config: {
|
|
peerDiscovery: {
|
|
mdns: {
|
|
enabled: false
|
|
}
|
|
},
|
|
pubsub: {
|
|
enabled: true
|
|
}
|
|
}
|
|
}, (err, node) => {
|
|
expect(err).to.not.exist()
|
|
|
|
libp2pNode = node
|
|
done()
|
|
})
|
|
})
|
|
|
|
it('fail to subscribe if node not started yet', (done) => {
|
|
libp2pNode.pubsub.subscribe('pubsub', () => { }, (err) => {
|
|
expect(err).to.exist()
|
|
expect(err.code).to.equal(codes.PUBSUB_NOT_STARTED)
|
|
|
|
done()
|
|
})
|
|
})
|
|
|
|
it('fail to unsubscribe if node not started yet', (done) => {
|
|
libp2pNode.pubsub.unsubscribe('pubsub', () => { }, (err) => {
|
|
expect(err).to.exist()
|
|
expect(err.code).to.equal(codes.PUBSUB_NOT_STARTED)
|
|
|
|
done()
|
|
})
|
|
})
|
|
|
|
it('fail to publish if node not started yet', (done) => {
|
|
libp2pNode.pubsub.publish('pubsub', Buffer.from('data'), (err) => {
|
|
expect(err).to.exist()
|
|
expect(err.code).to.equal(codes.PUBSUB_NOT_STARTED)
|
|
|
|
done()
|
|
})
|
|
})
|
|
|
|
it('fail to ls if node not started yet', (done) => {
|
|
libp2pNode.pubsub.ls((err) => {
|
|
expect(err).to.exist()
|
|
expect(err.code).to.equal(codes.PUBSUB_NOT_STARTED)
|
|
|
|
done()
|
|
})
|
|
})
|
|
|
|
it('fail to get subscribed peers to a topic if node not started yet', (done) => {
|
|
libp2pNode.pubsub.peers('pubsub', (err) => {
|
|
expect(err).to.exist()
|
|
expect(err.code).to.equal(codes.PUBSUB_NOT_STARTED)
|
|
|
|
done()
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('.pubsub config', () => {
|
|
it('toggle all pubsub options off (except enabled)', done => {
|
|
expect(3).checks(done)
|
|
|
|
class PubSubSpy {
|
|
constructor (node, config) {
|
|
expect(config).to.be.eql({
|
|
enabled: true,
|
|
selfEmit: false,
|
|
signMessages: false,
|
|
strictSigning: false
|
|
}).mark()
|
|
}
|
|
}
|
|
|
|
createNode('/ip4/0.0.0.0/tcp/0', {
|
|
modules: {
|
|
pubsub: PubSubSpy
|
|
},
|
|
config: {
|
|
pubsub: {
|
|
enabled: true,
|
|
selfEmit: false,
|
|
signMessages: false,
|
|
strictSigning: false
|
|
}
|
|
}
|
|
}, (err, node) => {
|
|
expect(err).to.not.exist().mark()
|
|
expect(node).to.exist().mark()
|
|
})
|
|
})
|
|
|
|
it('toggle all pubsub options on', done => {
|
|
expect(3).checks(done)
|
|
|
|
class PubSubSpy {
|
|
constructor (node, config) {
|
|
expect(config).to.be.eql({
|
|
enabled: true,
|
|
selfEmit: true,
|
|
signMessages: true,
|
|
strictSigning: true
|
|
}).mark()
|
|
}
|
|
}
|
|
|
|
createNode('/ip4/0.0.0.0/tcp/0', {
|
|
modules: {
|
|
pubsub: PubSubSpy
|
|
},
|
|
config: {
|
|
pubsub: {
|
|
enabled: true,
|
|
selfEmit: true,
|
|
signMessages: true,
|
|
strictSigning: true
|
|
}
|
|
}
|
|
}, (err, node) => {
|
|
expect(err).to.not.exist().mark()
|
|
expect(node).to.exist().mark()
|
|
})
|
|
})
|
|
})
|
|
})
|