mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-06-16 18:51:21 +00:00
fix: fix unintended aborts in dialer (#1185)
Fix a bug where `DialRequest` can abort wrong dial attempts. Co-authored-by: Robert Kiel <robert.kiel@hoprnet.io>
This commit is contained in:
@ -15,10 +15,11 @@ const error = new Error('dial failure')
|
||||
describe('Dial Request', () => {
|
||||
it('should end when a single multiaddr dials succeeds', async () => {
|
||||
const connection = mockConnection(mockMultiaddrConnection(mockDuplex(), await createEd25519PeerId()))
|
||||
const deferredConn = pDefer()
|
||||
const actions: Record<string, () => Promise<any>> = {
|
||||
'/ip4/127.0.0.1/tcp/1231': async () => await Promise.reject(error),
|
||||
'/ip4/127.0.0.1/tcp/1232': async () => await Promise.resolve(connection),
|
||||
'/ip4/127.0.0.1/tcp/1233': async () => await Promise.reject(error)
|
||||
'/ip4/127.0.0.1/tcp/1233': async () => await deferredConn.promise
|
||||
}
|
||||
const dialAction: DialAction = async (num) => await actions[num.toString()]()
|
||||
const controller = new AbortController()
|
||||
@ -32,15 +33,12 @@ describe('Dial Request', () => {
|
||||
dialAction
|
||||
})
|
||||
|
||||
sinon.spy(actions, '/ip4/127.0.0.1/tcp/1231')
|
||||
sinon.spy(actions, '/ip4/127.0.0.1/tcp/1232')
|
||||
sinon.spy(actions, '/ip4/127.0.0.1/tcp/1233')
|
||||
// Make sure that dial attempt comes back before terminating last dial action
|
||||
expect(await dialRequest.run({ signal: controller.signal })).to.equal(connection)
|
||||
|
||||
// End third dial attempt
|
||||
deferredConn.resolve()
|
||||
|
||||
const result = await dialRequest.run({ signal: controller.signal })
|
||||
expect(result).to.equal(connection)
|
||||
expect(actions['/ip4/127.0.0.1/tcp/1231']).to.have.property('callCount', 1)
|
||||
expect(actions['/ip4/127.0.0.1/tcp/1232']).to.have.property('callCount', 1)
|
||||
expect(actions['/ip4/127.0.0.1/tcp/1233']).to.have.property('callCount', 0)
|
||||
expect(dialerReleaseTokenSpy.callCount).to.equal(2)
|
||||
})
|
||||
|
||||
@ -73,14 +71,16 @@ describe('Dial Request', () => {
|
||||
// Let the first dials run
|
||||
await delay(0)
|
||||
|
||||
// Finish the first 2 dials
|
||||
firstDials.reject(error)
|
||||
await delay(0)
|
||||
|
||||
// Only 1 dial should remain, so 1 token should have been released
|
||||
expect(actions['/ip4/127.0.0.1/tcp/1231']).to.have.property('callCount', 1)
|
||||
expect(actions['/ip4/127.0.0.1/tcp/1232']).to.have.property('callCount', 1)
|
||||
expect(actions['/ip4/127.0.0.1/tcp/1233']).to.have.property('callCount', 1)
|
||||
expect(actions['/ip4/127.0.0.1/tcp/1233']).to.have.property('callCount', 0)
|
||||
|
||||
// Finish the first 2 dials
|
||||
firstDials.reject(error)
|
||||
|
||||
await delay(0)
|
||||
|
||||
expect(dialerReleaseTokenSpy.callCount).to.equal(1)
|
||||
|
||||
// Finish the dial and release the 2nd token
|
||||
@ -214,4 +214,45 @@ describe('Dial Request', () => {
|
||||
expect(dialerGetTokensSpy.calledWith(addrs.length)).to.equal(true)
|
||||
expect(dialerReleaseTokenSpy.callCount).to.equal(2)
|
||||
})
|
||||
|
||||
it('should abort other dials when one succeeds', async () => {
|
||||
const connection = mockConnection(mockMultiaddrConnection(mockDuplex(), await createEd25519PeerId()))
|
||||
const actions: Record<string, () => Promise<any>> = {
|
||||
'/ip4/127.0.0.1/tcp/1231': async () => {
|
||||
await delay(100)
|
||||
},
|
||||
'/ip4/127.0.0.1/tcp/1232': async () => {
|
||||
// Successful dial takes longer to establish
|
||||
await delay(1000)
|
||||
|
||||
return connection
|
||||
},
|
||||
|
||||
'/ip4/127.0.0.1/tcp/1233': async () => {
|
||||
await delay(100)
|
||||
}
|
||||
}
|
||||
|
||||
const signals: Record<string, AbortSignal | undefined> = {}
|
||||
|
||||
const dialRequest = new DialRequest({
|
||||
addrs: Object.keys(actions).map(str => new Multiaddr(str)),
|
||||
dialer: new Dialer({
|
||||
maxParallelDials: 3
|
||||
}),
|
||||
dialAction: async (ma, opts) => {
|
||||
signals[ma.toString()] = opts.signal
|
||||
return await actions[ma.toString()]()
|
||||
}
|
||||
})
|
||||
|
||||
await expect(dialRequest.run()).to.eventually.equal(connection)
|
||||
|
||||
// Dial attempt finished without connection
|
||||
expect(signals['/ip4/127.0.0.1/tcp/1231']).to.have.property('aborted', false)
|
||||
// Dial attempt led to connection
|
||||
expect(signals['/ip4/127.0.0.1/tcp/1232']).to.have.property('aborted', false)
|
||||
// Dial attempt finished without connection
|
||||
expect(signals['/ip4/127.0.0.1/tcp/1233']).to.have.property('aborted', false)
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user