mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-06-23 22:11:35 +00:00
refactor: connection manager (#511)
* refactor: initial refactor of the connection manager * fix: start/stop issues * fix: add tests and resolve pruning issues * chore: fix lint * test: move conn manager tests to node only for now * chore: apply suggestions from code review Co-Authored-By: Vasco Santos <vasco.santos@moxy.studio> * fix: assert min max connection options * test: fix assertion check for browser * docs: add api and config docs for conn manager
This commit is contained in:
133
test/connection-manager/index.spec.js
Normal file
133
test/connection-manager/index.spec.js
Normal file
@ -0,0 +1,133 @@
|
||||
'use strict'
|
||||
/* eslint-env mocha */
|
||||
|
||||
const chai = require('chai')
|
||||
chai.use(require('dirty-chai'))
|
||||
chai.use(require('chai-as-promised'))
|
||||
const { expect } = chai
|
||||
const sinon = require('sinon')
|
||||
|
||||
const { createPeer } = require('../utils/creators/peer')
|
||||
const mockConnection = require('../utils/mockConnection')
|
||||
const baseOptions = require('../utils/base-options.browser')
|
||||
|
||||
describe('Connection Manager', () => {
|
||||
let libp2p
|
||||
|
||||
afterEach(async () => {
|
||||
sinon.restore()
|
||||
libp2p && await libp2p.stop()
|
||||
})
|
||||
|
||||
it('should be able to create without metrics', async () => {
|
||||
[libp2p] = await createPeer({
|
||||
config: {
|
||||
modules: baseOptions.modules
|
||||
},
|
||||
started: false
|
||||
})
|
||||
|
||||
const spy = sinon.spy(libp2p.connectionManager, 'start')
|
||||
|
||||
await libp2p.start()
|
||||
expect(spy).to.have.property('callCount', 1)
|
||||
expect(libp2p.connectionManager._metrics).to.not.exist()
|
||||
})
|
||||
|
||||
it('should be able to create with metrics', async () => {
|
||||
[libp2p] = await createPeer({
|
||||
config: {
|
||||
modules: baseOptions.modules,
|
||||
metrics: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
started: false
|
||||
})
|
||||
|
||||
const spy = sinon.spy(libp2p.connectionManager, 'start')
|
||||
|
||||
await libp2p.start()
|
||||
expect(spy).to.have.property('callCount', 1)
|
||||
expect(libp2p.connectionManager._metrics).to.exist()
|
||||
})
|
||||
|
||||
it('should close lowest value peer connection when the maximum has been reached', async () => {
|
||||
const max = 5
|
||||
;[libp2p] = await createPeer({
|
||||
config: {
|
||||
modules: baseOptions.modules,
|
||||
connectionManager: {
|
||||
maxConnections: max
|
||||
}
|
||||
},
|
||||
started: false
|
||||
})
|
||||
|
||||
await libp2p.start()
|
||||
|
||||
sinon.spy(libp2p.connectionManager, '_maybeDisconnectOne')
|
||||
|
||||
// Add 1 too many connections
|
||||
const spies = new Map()
|
||||
await Promise.all([...new Array(max + 1)].map(async (_, index) => {
|
||||
const connection = await mockConnection()
|
||||
const spy = sinon.spy(connection, 'close')
|
||||
// The connections have the same remote id, give them random ones
|
||||
// so that we can verify the correct connection was closed
|
||||
sinon.stub(connection.remotePeer, 'toString').returns(index)
|
||||
const value = Math.random()
|
||||
spies.set(value, spy)
|
||||
libp2p.connectionManager.setPeerValue(connection.remotePeer, value)
|
||||
libp2p.connectionManager.onConnect(connection)
|
||||
}))
|
||||
|
||||
// get the lowest value
|
||||
const lowest = Array.from(spies.keys()).sort()[0]
|
||||
const lowestSpy = spies.get(lowest)
|
||||
|
||||
expect(libp2p.connectionManager._maybeDisconnectOne).to.have.property('callCount', 1)
|
||||
expect(lowestSpy).to.have.property('callCount', 1)
|
||||
})
|
||||
|
||||
it('should close connection when the maximum has been reached even without peer values', async () => {
|
||||
const max = 5
|
||||
;[libp2p] = await createPeer({
|
||||
config: {
|
||||
modules: baseOptions.modules,
|
||||
connectionManager: {
|
||||
maxConnections: max
|
||||
}
|
||||
},
|
||||
started: false
|
||||
})
|
||||
|
||||
await libp2p.start()
|
||||
|
||||
sinon.spy(libp2p.connectionManager, '_maybeDisconnectOne')
|
||||
|
||||
// Add 1 too many connections
|
||||
const spy = sinon.spy()
|
||||
await Promise.all([...new Array(max + 1)].map(async () => {
|
||||
const connection = await mockConnection()
|
||||
sinon.stub(connection, 'close').callsFake(() => spy())
|
||||
libp2p.connectionManager.onConnect(connection)
|
||||
}))
|
||||
|
||||
expect(libp2p.connectionManager._maybeDisconnectOne).to.have.property('callCount', 1)
|
||||
expect(spy).to.have.property('callCount', 1)
|
||||
})
|
||||
|
||||
it('should fail if the connection manager has mismatched connection limit options', async () => {
|
||||
await expect(createPeer({
|
||||
config: {
|
||||
modules: baseOptions.modules,
|
||||
connectionManager: {
|
||||
maxConnections: 5,
|
||||
minConnections: 6
|
||||
}
|
||||
},
|
||||
started: false
|
||||
})).to.eventually.rejected('maxConnections must be greater')
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user