mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-06-15 02:01:21 +00:00
refactor: async routing (#489)
* feat: async routing * chore: put dht extra api commands under content routing * chore: add default option to createPeerInfo Co-Authored-By: Jacob Heun <jacobheun@gmail.com> * chore: address review * chore: rm dlv
This commit is contained in:
219
test/peer-routing/peer-routing.node.js
Normal file
219
test/peer-routing/peer-routing.node.js
Normal file
@ -0,0 +1,219 @@
|
||||
'use strict'
|
||||
/* eslint-env mocha */
|
||||
|
||||
const chai = require('chai')
|
||||
chai.use(require('dirty-chai'))
|
||||
const { expect } = chai
|
||||
const nock = require('nock')
|
||||
const sinon = require('sinon')
|
||||
|
||||
const pDefer = require('p-defer')
|
||||
const mergeOptions = require('merge-options')
|
||||
|
||||
const DelegatedPeerRouter = require('libp2p-delegated-peer-routing')
|
||||
|
||||
const peerUtils = require('../utils/creators/peer')
|
||||
const { baseOptions, routingOptions } = require('./utils')
|
||||
|
||||
describe('peer-routing', () => {
|
||||
describe('no routers', () => {
|
||||
let node
|
||||
|
||||
before(async () => {
|
||||
[node] = await peerUtils.createPeer({
|
||||
config: baseOptions
|
||||
})
|
||||
})
|
||||
|
||||
it('.findPeer should return an error', async () => {
|
||||
await expect(node.peerRouting.findPeer('a cid'))
|
||||
.to.eventually.be.rejected()
|
||||
.and.to.have.property('code', 'NO_ROUTERS_AVAILABLE')
|
||||
})
|
||||
})
|
||||
|
||||
describe('via dht router', () => {
|
||||
const number = 5
|
||||
let nodes
|
||||
|
||||
before(async () => {
|
||||
nodes = await peerUtils.createPeer({
|
||||
number,
|
||||
config: routingOptions
|
||||
})
|
||||
|
||||
// Ring dial
|
||||
await Promise.all(
|
||||
nodes.map((peer, i) => peer.dial(nodes[(i + 1) % number].peerInfo))
|
||||
)
|
||||
})
|
||||
|
||||
after(() => {
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
after(() => Promise.all(nodes.map((n) => n.stop())))
|
||||
|
||||
it('should use the nodes dht', () => {
|
||||
const deferred = pDefer()
|
||||
|
||||
sinon.stub(nodes[0]._dht, 'findPeer').callsFake(() => {
|
||||
deferred.resolve()
|
||||
return nodes[1].peerInfo
|
||||
})
|
||||
|
||||
nodes[0].peerRouting.findPeer()
|
||||
return deferred.promise
|
||||
})
|
||||
})
|
||||
|
||||
describe('via delegate router', () => {
|
||||
let node
|
||||
let delegate
|
||||
|
||||
beforeEach(async () => {
|
||||
delegate = new DelegatedPeerRouter({
|
||||
host: '0.0.0.0',
|
||||
protocol: 'http',
|
||||
port: 60197
|
||||
})
|
||||
|
||||
;[node] = await peerUtils.createPeer({
|
||||
config: mergeOptions(baseOptions, {
|
||||
modules: {
|
||||
peerRouting: [delegate]
|
||||
},
|
||||
config: {
|
||||
dht: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
nock.cleanAll()
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
afterEach(() => node.stop())
|
||||
|
||||
it('should use the delegate router to find peers', async () => {
|
||||
const deferred = pDefer()
|
||||
|
||||
sinon.stub(delegate, 'findPeer').callsFake(() => {
|
||||
deferred.resolve()
|
||||
return 'fake peer-info'
|
||||
})
|
||||
|
||||
await node.peerRouting.findPeer()
|
||||
return deferred.promise
|
||||
})
|
||||
|
||||
it('should be able to find a peer', async () => {
|
||||
const peerKey = 'QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSySnL'
|
||||
const mockApi = nock('http://0.0.0.0:60197')
|
||||
.post('/api/v0/dht/findpeer')
|
||||
.query({
|
||||
arg: peerKey
|
||||
})
|
||||
.reply(200, `{"Extra":"","ID":"some other id","Responses":null,"Type":0}\n{"Extra":"","ID":"","Responses":[{"Addrs":["/ip4/127.0.0.1/tcp/4001"],"ID":"${peerKey}"}],"Type":2}\n`, [
|
||||
'Content-Type', 'application/json',
|
||||
'X-Chunked-Output', '1'
|
||||
])
|
||||
|
||||
const peerInfo = await node.peerRouting.findPeer(peerKey)
|
||||
|
||||
expect(peerInfo.id.toB58String()).to.equal(peerKey)
|
||||
expect(mockApi.isDone()).to.equal(true)
|
||||
})
|
||||
|
||||
it('should error when a peer cannot be found', async () => {
|
||||
const peerKey = 'key of a peer not on the network'
|
||||
const mockApi = nock('http://0.0.0.0:60197')
|
||||
.post('/api/v0/dht/findpeer')
|
||||
.query({
|
||||
arg: peerKey
|
||||
})
|
||||
.reply(200, '{"Extra":"","ID":"some other id","Responses":null,"Type":6}\n{"Extra":"","ID":"yet another id","Responses":null,"Type":0}\n{"Extra":"routing:not found","ID":"","Responses":null,"Type":3}\n', [
|
||||
'Content-Type', 'application/json',
|
||||
'X-Chunked-Output', '1'
|
||||
])
|
||||
|
||||
await expect(node.peerRouting.findPeer(peerKey))
|
||||
.to.eventually.be.rejected()
|
||||
|
||||
expect(mockApi.isDone()).to.equal(true)
|
||||
})
|
||||
|
||||
it('should handle errors from the api', async () => {
|
||||
const peerKey = 'key of a peer not on the network'
|
||||
const mockApi = nock('http://0.0.0.0:60197')
|
||||
.post('/api/v0/dht/findpeer')
|
||||
.query({
|
||||
arg: peerKey
|
||||
})
|
||||
.reply(502)
|
||||
|
||||
await expect(node.peerRouting.findPeer(peerKey))
|
||||
.to.eventually.be.rejected()
|
||||
|
||||
expect(mockApi.isDone()).to.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('via dht and delegate routers', () => {
|
||||
let node
|
||||
let delegate
|
||||
|
||||
beforeEach(async () => {
|
||||
delegate = new DelegatedPeerRouter({
|
||||
host: '0.0.0.0',
|
||||
protocol: 'http',
|
||||
port: 60197
|
||||
})
|
||||
|
||||
;[node] = await peerUtils.createPeer({
|
||||
config: mergeOptions(routingOptions, {
|
||||
modules: {
|
||||
peerRouting: [delegate]
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
afterEach(() => node.stop())
|
||||
|
||||
it('should only use the dht if it finds the peer', async () => {
|
||||
const dhtDeferred = pDefer()
|
||||
|
||||
sinon.stub(node._dht, 'findPeer').callsFake(() => {
|
||||
dhtDeferred.resolve()
|
||||
return node.peerInfo
|
||||
})
|
||||
sinon.stub(delegate, 'findPeer').callsFake(() => {
|
||||
throw new Error('the delegate should not have been called')
|
||||
})
|
||||
|
||||
await node.peerRouting.findPeer('a peer id')
|
||||
await dhtDeferred.promise
|
||||
})
|
||||
|
||||
it('should use the delegate if the dht fails to find the peer', async () => {
|
||||
const results = [true]
|
||||
|
||||
sinon.stub(node._dht, 'findPeer').callsFake(() => {})
|
||||
sinon.stub(delegate, 'findPeer').callsFake(() => {
|
||||
return results
|
||||
})
|
||||
|
||||
const peer = await node.peerRouting.findPeer('a peer id')
|
||||
expect(peer).to.eql(results)
|
||||
})
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user