Skip to content
This repository was archived by the owner on Jul 21, 2023. It is now read-only.

Commit 46d78eb

Browse files
dirkmcjacobheun
authored andcommittedSep 27, 2019
refactor: callbacks -> async / await (#78)
BREAKING CHANGE: All places in the API that used callbacks are now replaced with async/await * chore: update CI file * test: add compliance tests
1 parent 64a16d7 commit 46d78eb

13 files changed

+384
-476
lines changed
 

‎.travis.yml

+2-4
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,20 @@ stages:
77

88
node_js:
99
- '10'
10+
- '12'
1011

1112
os:
1213
- linux
1314
- osx
15+
- windows
1416

1517
script: npx nyc -s npm run test:node -- --bail
1618
after_success: npx nyc report --reporter=text-lcov > coverage.lcov && npx codecov
1719

1820
jobs:
1921
include:
20-
- os: windows
21-
cache: false
22-
2322
- stage: check
2423
script:
25-
- npx aegir commitlint --travis
2624
- npx aegir dep-check
2725
- npm run lint
2826

‎README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ mdns.on('peer', (peerInfo) => {
2828
})
2929

3030
// Broadcast for 20 seconds
31-
mdns.start(() => setTimeout(() => mdns.stop(() => {}), 20 * 1000))
31+
mdns.start()
32+
setTimeout(() => mdns.stop(), 20 * 1000)
3233
```
3334

3435
- options

‎package.json

+8-6
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,20 @@
3434
},
3535
"homepage": "https://github.com/libp2p/js-libp2p-mdns",
3636
"devDependencies": {
37-
"aegir": "^18.2.2",
37+
"aegir": "^20.3.1",
3838
"chai": "^4.2.0",
39-
"dirty-chai": "^2.0.1"
39+
"delay": "^4.3.0",
40+
"dirty-chai": "^2.0.1",
41+
"interface-discovery": "^0.1.1",
42+
"p-defer": "^3.0.0"
4043
},
4144
"dependencies": {
4245
"async": "^2.6.2",
4346
"debug": "^4.1.1",
44-
"libp2p-tcp": "~0.13.0",
45-
"multiaddr": "^6.0.6",
47+
"multiaddr": "^7.1.0",
4648
"multicast-dns": "^7.2.0",
47-
"peer-id": "~0.12.2",
48-
"peer-info": "~0.15.1"
49+
"peer-id": "~0.13.3",
50+
"peer-info": "~0.17.0"
4951
},
5052
"contributors": [
5153
"Alan Shaw <alan.shaw@protocol.ai>",

‎src/compat/index.js

+12-15
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// Compatibility with Go libp2p MDNS
44

55
const EE = require('events')
6-
const parallel = require('async/parallel')
76
const Responder = require('./responder')
87
const Querier = require('./querier')
98

@@ -15,9 +14,9 @@ class GoMulticastDNS extends EE {
1514
this._onPeer = this._onPeer.bind(this)
1615
}
1716

18-
start (callback) {
17+
async start () {
1918
if (this._started) {
20-
return callback(new Error('MulticastDNS service is already started'))
19+
return
2120
}
2221

2322
this._started = true
@@ -26,20 +25,18 @@ class GoMulticastDNS extends EE {
2625

2726
this._querier.on('peer', this._onPeer)
2827

29-
parallel([
30-
cb => this._responder.start(cb),
31-
cb => this._querier.start(cb)
32-
], callback)
28+
await Promise.all([
29+
this._responder.start(),
30+
this._querier.start()
31+
])
3332
}
3433

3534
_onPeer (peerInfo) {
3635
this.emit('peer', peerInfo)
3736
}
3837

39-
stop (callback) {
40-
if (!this._started) {
41-
return callback(new Error('MulticastDNS service is not started'))
42-
}
38+
stop () {
39+
if (!this._started) return
4340

4441
const responder = this._responder
4542
const querier = this._querier
@@ -50,10 +47,10 @@ class GoMulticastDNS extends EE {
5047

5148
querier.removeListener('peer', this._onPeer)
5249

53-
parallel([
54-
cb => responder.stop(cb),
55-
cb => querier.stop(cb)
56-
], callback)
50+
return Promise.all([
51+
responder.stop(),
52+
querier.stop()
53+
])
5754
}
5855
}
5956

‎src/compat/querier.js

+41-43
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ const MDNS = require('multicast-dns')
66
const Multiaddr = require('multiaddr')
77
const PeerInfo = require('peer-info')
88
const PeerId = require('peer-id')
9-
const nextTick = require('async/nextTick')
10-
const log = require('debug')('libp2p:mdns:compat:querier')
9+
const debug = require('debug')
10+
const log = debug('libp2p:mdns:compat:querier')
11+
log.error = debug('libp2p:mdns:compat:querier:error')
1112
const { SERVICE_TAG_LOCAL, MULTICAST_IP, MULTICAST_PORT } = require('./constants')
1213

1314
class Querier extends EE {
@@ -28,7 +29,7 @@ class Querier extends EE {
2829
this._onResponse = this._onResponse.bind(this)
2930
}
3031

31-
start (callback) {
32+
start () {
3233
this._handle = periodically(() => {
3334
// Create a querier that queries multicast but gets responses unicast
3435
const mdns = MDNS({ multicast: false, interface: '0.0.0.0', port: 0 })
@@ -44,20 +45,18 @@ class Querier extends EE {
4445
})
4546

4647
return {
47-
stop: callback => {
48+
stop: () => {
4849
mdns.removeListener('response', this._onResponse)
49-
mdns.destroy(callback)
50+
return new Promise(resolve => mdns.destroy(resolve))
5051
}
5152
}
5253
}, {
5354
period: this._options.queryPeriod,
5455
interval: this._options.queryInterval
5556
})
56-
57-
nextTick(() => callback())
5857
}
5958

60-
_onResponse (event, info) {
59+
async _onResponse (event, info) {
6160
const answers = event.answers || []
6261
const ptrRecord = answers.find(a => a.type === 'PTR' && a.name === SERVICE_TAG_LOCAL)
6362

@@ -87,37 +86,40 @@ class Querier extends EE {
8786
return log('failed to create peer ID from TXT record data', peerIdStr, err)
8887
}
8988

90-
PeerInfo.create(peerId, (err, info) => {
91-
if (err) return log('failed to create peer info from peer ID', peerId, err)
89+
let peerInfo
90+
try {
91+
peerInfo = await PeerInfo.create(peerId)
92+
} catch (err) {
93+
return log.error('failed to create peer info from peer ID', peerId, err)
94+
}
9295

93-
const srvRecord = answers.find(a => a.type === 'SRV')
94-
if (!srvRecord) return log('missing SRV record in response')
96+
const srvRecord = answers.find(a => a.type === 'SRV')
97+
if (!srvRecord) return log('missing SRV record in response')
9598

96-
log('peer found', peerIdStr)
99+
log('peer found', peerIdStr)
97100

98-
const { port } = srvRecord.data || {}
99-
const protos = { A: 'ip4', AAAA: 'ip6' }
101+
const { port } = srvRecord.data || {}
102+
const protos = { A: 'ip4', AAAA: 'ip6' }
100103

101-
const multiaddrs = answers
102-
.filter(a => ['A', 'AAAA'].includes(a.type))
103-
.reduce((addrs, a) => {
104-
const maStr = `/${protos[a.type]}/${a.data}/tcp/${port}`
105-
try {
106-
addrs.push(new Multiaddr(maStr))
107-
log(maStr)
108-
} catch (err) {
109-
log(`failed to create multiaddr from ${a.type} record data`, maStr, port, err)
110-
}
111-
return addrs
112-
}, [])
104+
const multiaddrs = answers
105+
.filter(a => ['A', 'AAAA'].includes(a.type))
106+
.reduce((addrs, a) => {
107+
const maStr = `/${protos[a.type]}/${a.data}/tcp/${port}`
108+
try {
109+
addrs.push(new Multiaddr(maStr))
110+
log(maStr)
111+
} catch (err) {
112+
log(`failed to create multiaddr from ${a.type} record data`, maStr, port, err)
113+
}
114+
return addrs
115+
}, [])
113116

114-
multiaddrs.forEach(addr => info.multiaddrs.add(addr))
115-
this.emit('peer', info)
116-
})
117+
multiaddrs.forEach(addr => peerInfo.multiaddrs.add(addr))
118+
this.emit('peer', peerInfo)
117119
}
118120

119-
stop (callback) {
120-
this._handle.stop(callback)
121+
stop () {
122+
return this._handle.stop()
121123
}
122124
}
123125

@@ -140,27 +142,23 @@ function periodically (fn, options) {
140142

141143
const reRun = () => {
142144
handle = fn()
143-
timeoutId = setTimeout(() => {
144-
handle.stop(err => {
145-
if (err) log(err)
146-
if (!stopped) {
147-
timeoutId = setTimeout(reRun, options.interval)
148-
}
149-
})
145+
timeoutId = setTimeout(async () => {
146+
await handle.stop().catch(log)
147+
if (!stopped) {
148+
timeoutId = setTimeout(reRun, options.interval)
149+
}
150150
handle = null
151151
}, options.period)
152152
}
153153

154154
reRun()
155155

156156
return {
157-
stop (callback) {
157+
stop () {
158158
stopped = true
159159
clearTimeout(timeoutId)
160160
if (handle) {
161-
handle.stop(callback)
162-
} else {
163-
callback()
161+
return handle.stop()
164162
}
165163
}
166164
}

‎src/compat/responder.js

+10-16
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@ const OS = require('os')
44
const assert = require('assert')
55
const MDNS = require('multicast-dns')
66
const log = require('debug')('libp2p:mdns:compat:responder')
7-
const TCP = require('libp2p-tcp')
8-
const nextTick = require('async/nextTick')
97
const { SERVICE_TAG_LOCAL } = require('./constants')
108

11-
const tcp = new TCP()
12-
139
class Responder {
1410
constructor (peerInfo) {
1511
assert(peerInfo, 'missing peerInfo parameter')
@@ -18,16 +14,15 @@ class Responder {
1814
this._onQuery = this._onQuery.bind(this)
1915
}
2016

21-
start (callback) {
17+
start () {
2218
this._mdns = MDNS()
2319
this._mdns.on('query', this._onQuery)
24-
nextTick(() => callback())
2520
}
2621

2722
_onQuery (event, info) {
28-
const multiaddrs = tcp.filter(this._peerInfo.multiaddrs.toArray())
23+
const addresses = this._peerInfo.multiaddrs.toArray().map(ma => ma.toOptions())
2924
// Only announce TCP for now
30-
if (!multiaddrs.length) return
25+
if (!addresses.length) return
3126

3227
const questions = event.questions || []
3328

@@ -48,7 +43,7 @@ class Responder {
4843
})
4944

5045
// Only announce TCP multiaddrs for now
51-
const port = multiaddrs[0].toString().split('/')[4]
46+
const port = addresses[0].port
5247

5348
answers.push({
5449
name: peerServiceTagLocal,
@@ -71,15 +66,14 @@ class Responder {
7166
data: [Buffer.from(this._peerIdStr)]
7267
})
7368

74-
multiaddrs.forEach((ma) => {
75-
const proto = ma.protoNames()[0]
76-
if (proto === 'ip4' || proto === 'ip6') {
69+
addresses.forEach((ma) => {
70+
if (['ipv4', 'ipv6'].includes(ma.family)) {
7771
answers.push({
7872
name: OS.hostname(),
79-
type: proto === 'ip4' ? 'A' : 'AAAA',
73+
type: ma.family === 'ipv4' ? 'A' : 'AAAA',
8074
class: 'IN',
8175
ttl: 120,
82-
data: ma.toString().split('/')[2]
76+
data: ma.host
8377
})
8478
}
8579
})
@@ -88,9 +82,9 @@ class Responder {
8882
this._mdns.respond(answers, info)
8983
}
9084

91-
stop (callback) {
85+
stop () {
9286
this._mdns.removeListener('query', this._onQuery)
93-
this._mdns.destroy(callback)
87+
return new Promise(resolve => this._mdns.destroy(resolve))
9488
}
9589
}
9690

‎src/index.js

+41-34
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
const multicastDNS = require('multicast-dns')
44
const EventEmitter = require('events').EventEmitter
55
const assert = require('assert')
6-
const nextTick = require('async/nextTick')
7-
const parallel = require('async/parallel')
86
const debug = require('debug')
97
const log = debug('libp2p:mdns')
108
const query = require('./query')
119
const GoMulticastDNS = require('./compat')
1210

1311
class MulticastDNS extends EventEmitter {
14-
constructor (options) {
12+
constructor (options = {}) {
1513
super()
1614
assert(options.peerInfo, 'needs a PeerInfo to work')
1715

@@ -32,56 +30,65 @@ class MulticastDNS extends EventEmitter {
3230
}
3331
}
3432

35-
start (callback) {
36-
const mdns = multicastDNS({ port: this.port })
33+
/**
34+
* Start sending queries to the LAN.
35+
*
36+
* @returns {void}
37+
*/
38+
async start () {
39+
if (this.mdns) return
3740

38-
this.mdns = mdns
41+
this.mdns = multicastDNS({ port: this.port })
42+
this.mdns.on('query', (event) => this._onMdnsQuery(event))
43+
this.mdns.on('response', (event) => this._onMdnsResponse(event))
3944

4045
this._queryInterval = query.queryLAN(this.mdns, this.serviceTag, this.interval)
4146

42-
mdns.on('response', (event) => {
43-
query.gotResponse(event, this.peerInfo, this.serviceTag, (err, foundPeer) => {
44-
if (err) {
45-
return log('Error processing peer response', err)
46-
}
47-
48-
this._onPeer(foundPeer)
49-
})
50-
})
47+
if (this._goMdns) {
48+
await this._goMdns.start()
49+
}
50+
}
5151

52-
mdns.on('query', (event) => {
53-
query.gotQuery(event, this.mdns, this.peerInfo, this.serviceTag, this.broadcast)
54-
})
52+
_onMdnsQuery (event) {
53+
query.gotQuery(event, this.mdns, this.peerInfo, this.serviceTag, this.broadcast)
54+
}
5555

56-
if (this._goMdns) {
57-
this._goMdns.start(callback)
58-
} else {
59-
nextTick(() => callback())
56+
async _onMdnsResponse (event) {
57+
try {
58+
const foundPeer = await query.gotResponse(event, this.peerInfo, this.serviceTag)
59+
this.emit('peer', foundPeer)
60+
} catch (err) {
61+
log('Error processing peer response', err)
6062
}
6163
}
6264

6365
_onPeer (peerInfo) {
6466
this.emit('peer', peerInfo)
6567
}
6668

67-
stop (callback) {
69+
/**
70+
* Stop sending queries to the LAN.
71+
*
72+
* @returns {Promise}
73+
*/
74+
async stop () {
6875
if (!this.mdns) {
69-
return callback(new Error('MulticastDNS service had not started yet'))
76+
return
7077
}
7178

79+
this.mdns.removeListener('query', this._onMdnsQuery)
80+
this.mdns.removeListener('query', this._onMdnsResponse)
81+
this._goMdns && this._goMdns.removeListener('peer', this._onPeer)
82+
7283
clearInterval(this._queryInterval)
7384
this._queryInterval = null
7485

75-
if (this._goMdns) {
76-
this._goMdns.removeListener('peer', this._onPeer)
77-
parallel([
78-
cb => this._goMdns.stop(cb),
79-
cb => this.mdns.destroy(cb)
80-
], callback)
81-
} else {
82-
this.mdns.destroy(callback)
83-
this.mdns = undefined
84-
}
86+
await Promise.all([
87+
this._goMdns && this._goMdns.stop(),
88+
new Promise((resolve) => this.mdns.destroy(resolve))
89+
])
90+
91+
this.mdns = undefined
8592
}
8693
}
8794

‎src/query.js

+15-28
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ const Peer = require('peer-info')
44
const os = require('os')
55
const debug = require('debug')
66
const log = debug('libp2p:mdns')
7+
log.error = debug('libp2p:mdns:error')
78
const Multiaddr = require('multiaddr')
89
const Id = require('peer-id')
9-
const TCP = require('libp2p-tcp')
10-
const tcp = new TCP()
1110

1211
module.exports = {
1312

@@ -27,7 +26,7 @@ module.exports = {
2726
return setInterval(query, interval)
2827
},
2928

30-
gotResponse: function (rsp, peerInfo, serviceTag, callback) {
29+
gotResponse: async function (rsp, peerInfo, serviceTag) {
3130
if (!rsp.answers) { return }
3231

3332
const answers = {
@@ -72,23 +71,21 @@ module.exports = {
7271

7372
const peerId = Id.createFromB58String(b58Id)
7473

75-
Peer.create(peerId, (err, peerFound) => {
76-
if (err) {
77-
return log('Error creating PeerInfo from new found peer', err)
78-
}
79-
74+
try {
75+
const peerFound = await Peer.create(peerId)
8076
multiaddrs.forEach((addr) => peerFound.multiaddrs.add(addr))
81-
82-
callback(null, peerFound)
83-
})
77+
return peerFound
78+
} catch (err) {
79+
log.error('Error creating PeerInfo from new found peer', err)
80+
}
8481
},
8582

8683
gotQuery: function (qry, mdns, peerInfo, serviceTag, broadcast) {
8784
if (!broadcast) { return }
8885

89-
const multiaddrs = tcp.filter(peerInfo.multiaddrs.toArray())
86+
const addresses = peerInfo.multiaddrs.toArray().map(ma => ma.toOptions())
9087
// Only announce TCP for now
91-
if (multiaddrs.length === 0) { return }
88+
if (addresses.length === 0) { return }
9289

9390
if (qry.questions[0] && qry.questions[0].name === serviceTag) {
9491
const answers = []
@@ -102,7 +99,7 @@ module.exports = {
10299
})
103100

104101
// Only announce TCP multiaddrs for now
105-
const port = multiaddrs[0].toString().split('/')[4]
102+
const port = addresses[0].port
106103

107104
answers.push({
108105
name: peerInfo.id.toB58String() + '.' + serviceTag,
@@ -125,24 +122,14 @@ module.exports = {
125122
data: peerInfo.id.toB58String()
126123
})
127124

128-
multiaddrs.forEach((ma) => {
129-
if (ma.protoNames()[0] === 'ip4') {
130-
answers.push({
131-
name: os.hostname(),
132-
type: 'A',
133-
class: 'IN',
134-
ttl: 120,
135-
data: ma.toString().split('/')[2]
136-
})
137-
return
138-
}
139-
if (ma.protoNames()[0] === 'ip6') {
125+
addresses.forEach((addr) => {
126+
if (['ipv4', 'ipv6'].includes(addr.family)) {
140127
answers.push({
141128
name: os.hostname(),
142-
type: 'AAAA',
129+
type: addr.family === 'ipv4' ? 'A' : 'AAAA',
143130
class: 'IN',
144131
ttl: 120,
145-
data: ma.toString().split('/')[2]
132+
data: addr.host
146133
})
147134
}
148135
})

‎test/compat/go-multicast-dns.spec.js

+28-41
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ const dirtyChai = require('dirty-chai')
66
const expect = chai.expect
77
chai.use(dirtyChai)
88
const PeerInfo = require('peer-info')
9-
const map = require('async/map')
10-
const series = require('async/series')
9+
const pDefer = require('p-defer')
1110

1211
const GoMulticastDNS = require('../../src/compat')
1312

@@ -18,67 +17,55 @@ describe('GoMulticastDNS', () => {
1817
]
1918
let peerInfos
2019

21-
before(done => {
22-
map(peerAddrs, (addr, cb) => {
23-
PeerInfo.create((err, info) => {
24-
expect(err).to.not.exist()
25-
info.multiaddrs.add(addr)
26-
cb(null, info)
27-
})
28-
}, (err, infos) => {
29-
expect(err).to.not.exist()
30-
peerInfos = infos
31-
done()
20+
before(async () => {
21+
peerInfos = await Promise.all([
22+
PeerInfo.create(),
23+
PeerInfo.create()
24+
])
25+
26+
peerInfos.forEach((peer, index) => {
27+
peer.multiaddrs.add(peerAddrs[index])
3228
})
3329
})
3430

35-
it('should start and stop', done => {
31+
it('should start and stop', async () => {
3632
const mdns = new GoMulticastDNS(peerInfos[0])
3733

38-
mdns.start(err => {
39-
expect(err).to.not.exist()
40-
mdns.stop(err => {
41-
expect(err).to.not.exist()
42-
done()
43-
})
44-
})
34+
await mdns.start()
35+
return mdns.stop()
4536
})
4637

47-
it('should not start when started', done => {
38+
it('should ignore multiple start calls', async () => {
4839
const mdns = new GoMulticastDNS(peerInfos[0])
4940

50-
mdns.start(err => {
51-
expect(err).to.not.exist()
41+
await mdns.start()
42+
await mdns.start()
5243

53-
mdns.start(err => {
54-
expect(err.message).to.equal('MulticastDNS service is already started')
55-
mdns.stop(done)
56-
})
57-
})
44+
return mdns.stop()
5845
})
5946

60-
it('should not stop when not started', done => {
47+
it('should ignore unnecessary stop calls', async () => {
6148
const mdns = new GoMulticastDNS(peerInfos[0])
62-
63-
mdns.stop(err => {
64-
expect(err.message).to.equal('MulticastDNS service is not started')
65-
done()
66-
})
49+
await mdns.stop()
6750
})
6851

69-
it('should emit peer info when peer is discovered', done => {
52+
it('should emit peer info when peer is discovered', async () => {
7053
const mdnsA = new GoMulticastDNS(peerInfos[0])
7154
const mdnsB = new GoMulticastDNS(peerInfos[1])
55+
const defer = pDefer()
7256

7357
mdnsA.on('peer', info => {
7458
if (!info.id.isEqual(peerInfos[1].id)) return
7559
expect(info.multiaddrs.has(peerAddrs[1])).to.be.true()
76-
done()
60+
defer.resolve()
7761
})
7862

79-
series([
80-
cb => mdnsA.start(cb),
81-
cb => mdnsB.start(cb)
82-
], err => expect(err).to.not.exist())
63+
// Start in series
64+
Promise.all([
65+
mdnsA.start(),
66+
mdnsB.start()
67+
])
68+
69+
await defer.promise
8370
})
8471
})

‎test/compat/querier.spec.js

+56-78
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ const dirtyChai = require('dirty-chai')
66
const expect = chai.expect
77
chai.use(dirtyChai)
88
const PeerInfo = require('peer-info')
9-
const parallel = require('async/parallel')
10-
const map = require('async/map')
119
const MDNS = require('multicast-dns')
1210
const OS = require('os')
11+
const delay = require('delay')
1312

1413
const Querier = require('../../src/compat/querier')
1514
const { SERVICE_TAG_LOCAL } = require('../../src/compat/constants')
@@ -22,43 +21,32 @@ describe('Querier', () => {
2221
]
2322
let peerInfos
2423

25-
before(done => {
26-
map(peerAddrs, (addr, cb) => {
27-
PeerInfo.create((err, info) => {
28-
expect(err).to.not.exist()
29-
info.multiaddrs.add(addr)
30-
cb(null, info)
31-
})
32-
}, (err, infos) => {
33-
expect(err).to.not.exist()
34-
peerInfos = infos
35-
done()
24+
before(async () => {
25+
peerInfos = await Promise.all([
26+
PeerInfo.create(),
27+
PeerInfo.create()
28+
])
29+
30+
peerInfos.forEach((peer, index) => {
31+
peer.multiaddrs.add(peerAddrs[index])
3632
})
3733
})
3834

39-
afterEach(done => {
40-
parallel([
41-
cb => querier ? querier.stop(cb) : cb(),
42-
cb => mdns ? mdns.destroy(cb) : cb()
43-
], err => {
44-
querier = mdns = null
45-
done(err)
46-
})
35+
afterEach(() => {
36+
return Promise.all([
37+
querier && querier.stop(),
38+
mdns && mdns.destroy()
39+
])
4740
})
4841

49-
it('should start and stop', done => {
42+
it('should start and stop', async () => {
5043
const querier = new Querier(peerInfos[0].id)
5144

52-
querier.start(err => {
53-
expect(err).to.not.exist()
54-
querier.stop(err => {
55-
expect(err).to.not.exist()
56-
done()
57-
})
58-
})
45+
await querier.start()
46+
await querier.stop()
5947
})
6048

61-
it('should query on interval', done => {
49+
it('should query on interval', async () => {
6250
querier = new Querier(peerInfos[0].id, { queryPeriod: 0, queryInterval: 10 })
6351
mdns = MDNS()
6452

@@ -70,17 +58,14 @@ describe('Querier', () => {
7058
queryCount++
7159
})
7260

73-
querier.start(err => expect(err).to.not.exist())
74-
75-
setTimeout(() => {
76-
// Should have queried at least twice by now!
77-
expect(queryCount >= 2).to.be.true()
78-
done()
79-
}, 100)
61+
await querier.start()
62+
await delay(100)
63+
// Should have queried at least twice by now!
64+
expect(queryCount >= 2).to.be.true()
8065
})
8166

82-
it('should not emit peer for responses with non matching service tags', done => {
83-
ensureNoPeer(event => {
67+
it('should not emit peer for responses with non matching service tags', () => {
68+
return ensureNoPeer(event => {
8469
const peerServiceTagLocal = `${peerInfos[1].id.toB58String()}.${SERVICE_TAG_LOCAL}`
8570
const bogusServiceTagLocal = '_ifps-discovery._udp'
8671

@@ -91,11 +76,11 @@ describe('Querier', () => {
9176
ttl: 120,
9277
data: peerServiceTagLocal
9378
}]
94-
}, done)
79+
})
9580
})
9681

97-
it('should not emit peer for responses with missing TXT record', done => {
98-
ensureNoPeer(event => {
82+
it('should not emit peer for responses with missing TXT record', () => {
83+
return ensureNoPeer(event => {
9984
const peerServiceTagLocal = `${peerInfos[1].id.toB58String()}.${SERVICE_TAG_LOCAL}`
10085

10186
return [{
@@ -105,11 +90,11 @@ describe('Querier', () => {
10590
ttl: 120,
10691
data: peerServiceTagLocal
10792
}]
108-
}, done)
93+
})
10994
})
11095

111-
it('should not emit peer for responses with missing peer ID in TXT record', done => {
112-
ensureNoPeer(event => {
96+
it('should not emit peer for responses with missing peer ID in TXT record', () => {
97+
return ensureNoPeer(event => {
11398
const peerServiceTagLocal = `${peerInfos[1].id.toB58String()}.${SERVICE_TAG_LOCAL}`
11499

115100
return [{
@@ -125,11 +110,11 @@ describe('Querier', () => {
125110
ttl: 120,
126111
data: [] // undefined peer ID
127112
}]
128-
}, done)
113+
})
129114
})
130115

131-
it('should not emit peer for responses to self', done => {
132-
ensureNoPeer(event => {
116+
it('should not emit peer for responses to self', () => {
117+
return ensureNoPeer(event => {
133118
const peerServiceTagLocal = `${peerInfos[1].id.toB58String()}.${SERVICE_TAG_LOCAL}`
134119

135120
return [{
@@ -145,12 +130,12 @@ describe('Querier', () => {
145130
ttl: 120,
146131
data: peerInfos[0].id.toB58String()
147132
}]
148-
}, done)
133+
})
149134
})
150135

151136
// TODO: unskip when https://github.com/libp2p/js-peer-id/issues/83 is resolved
152-
it.skip('should not emit peer for responses with invalid peer ID in TXT record', done => {
153-
ensureNoPeer(event => {
137+
it.skip('should not emit peer for responses with invalid peer ID in TXT record', () => {
138+
return ensureNoPeer(event => {
154139
const peerServiceTagLocal = `${peerInfos[1].id.toB58String()}.${SERVICE_TAG_LOCAL}`
155140

156141
return [{
@@ -166,11 +151,11 @@ describe('Querier', () => {
166151
ttl: 120,
167152
data: '🤪'
168153
}]
169-
}, done)
154+
})
170155
})
171156

172-
it('should not emit peer for responses with missing SRV record', done => {
173-
ensureNoPeer(event => {
157+
it('should not emit peer for responses with missing SRV record', () => {
158+
return ensureNoPeer(event => {
174159
const peerServiceTagLocal = `${peerInfos[1].id.toB58String()}.${SERVICE_TAG_LOCAL}`
175160

176161
return [{
@@ -186,11 +171,11 @@ describe('Querier', () => {
186171
ttl: 120,
187172
data: peerInfos[1].id.toB58String()
188173
}]
189-
}, done)
174+
})
190175
})
191176

192-
it('should emit peer for responses even if no multiaddrs', done => {
193-
ensurePeer(event => {
177+
it('should emit peer for responses even if no multiaddrs', () => {
178+
return ensurePeer(event => {
194179
const peerServiceTagLocal = `${peerInfos[1].id.toB58String()}.${SERVICE_TAG_LOCAL}`
195180

196181
return [{
@@ -217,11 +202,11 @@ describe('Querier', () => {
217202
target: OS.hostname()
218203
}
219204
}]
220-
}, done)
205+
})
221206
})
222207

223-
it('should emit peer for responses with valid multiaddrs', done => {
224-
ensurePeer(event => {
208+
it('should emit peer for responses with valid multiaddrs', () => {
209+
return ensurePeer(event => {
225210
const peerServiceTagLocal = `${peerInfos[1].id.toB58String()}.${SERVICE_TAG_LOCAL}`
226211

227212
return [{
@@ -254,15 +239,14 @@ describe('Querier', () => {
254239
ttl: 120,
255240
data: peerAddrs[1].split('/')[2]
256241
}]
257-
}, done)
242+
})
258243
})
259244

260245
/**
261246
* Ensure peerInfos[1] are emitted from `querier`
262247
* @param {Function} getResponse Given a query, construct a response to test the querier
263-
* @param {Function} callback Callback called when test finishes
264248
*/
265-
function ensurePeer (getResponse, callback) {
249+
async function ensurePeer (getResponse) {
266250
querier = new Querier(peerInfos[0].id)
267251
mdns = MDNS()
268252

@@ -280,20 +264,16 @@ describe('Querier', () => {
280264
peerInfo = info
281265
})
282266

283-
querier.start(err => {
284-
if (err) return callback(err)
285-
setTimeout(() => {
286-
callback(peerInfo ? null : new Error('Missing peer'))
287-
}, 100)
288-
})
267+
await querier.start()
268+
await delay(100)
269+
if (!peerInfo) throw new Error('Missing peer')
289270
}
290271

291272
/**
292273
* Ensure none of peerInfos are emitted from `querier`
293274
* @param {Function} getResponse Given a query, construct a response to test the querier
294-
* @param {Function} callback Callback called when test finishes
295275
*/
296-
function ensureNoPeer (getResponse, callback) {
276+
async function ensureNoPeer (getResponse) {
297277
querier = new Querier(peerInfos[0].id)
298278
mdns = MDNS()
299279

@@ -311,12 +291,10 @@ describe('Querier', () => {
311291
peerInfo = info
312292
})
313293

314-
querier.start(err => {
315-
if (err) return callback(err)
316-
setTimeout(() => {
317-
if (!peerInfo) return callback()
318-
callback(Object.assign(new Error('Unexpected peer'), { peerInfo }))
319-
}, 100)
320-
})
294+
await querier.start()
295+
await delay(100)
296+
297+
if (!peerInfo) return
298+
throw Object.assign(new Error('Unexpected peer'), { peerInfo })
321299
}
322300
})

‎test/compat/responder.spec.js

+81-100
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ const dirtyChai = require('dirty-chai')
66
const expect = chai.expect
77
chai.use(dirtyChai)
88
const PeerInfo = require('peer-info')
9-
const parallel = require('async/parallel')
10-
const map = require('async/map')
119
const MDNS = require('multicast-dns')
10+
const delay = require('delay')
11+
const pDefer = require('p-defer')
1212

1313
const Responder = require('../../src/compat/responder')
1414
const { SERVICE_TAG_LOCAL, MULTICAST_IP, MULTICAST_PORT } = require('../../src/compat/constants')
@@ -21,141 +21,122 @@ describe('Responder', () => {
2121
]
2222
let peerInfos
2323

24-
before(done => {
25-
map(peerAddrs, (addr, cb) => {
26-
PeerInfo.create((err, info) => {
27-
expect(err).to.not.exist()
28-
info.multiaddrs.add(addr)
29-
cb(null, info)
30-
})
31-
}, (err, infos) => {
32-
expect(err).to.not.exist()
33-
peerInfos = infos
34-
done()
24+
before(async () => {
25+
peerInfos = await Promise.all([
26+
PeerInfo.create(),
27+
PeerInfo.create()
28+
])
29+
30+
peerInfos.forEach((peer, index) => {
31+
peer.multiaddrs.add(peerAddrs[index])
3532
})
3633
})
3734

38-
afterEach(done => {
39-
parallel([
40-
cb => responder ? responder.stop(cb) : cb(),
41-
cb => mdns ? mdns.destroy(cb) : cb()
42-
], err => {
43-
responder = mdns = null
44-
done(err)
45-
})
35+
afterEach(() => {
36+
return Promise.all([
37+
responder && responder.stop(),
38+
mdns && mdns.destroy()
39+
])
4640
})
4741

48-
it('should start and stop', done => {
42+
it('should start and stop', async () => {
4943
const responder = new Responder(peerInfos[0])
5044

51-
responder.start(err => {
52-
expect(err).to.not.exist()
53-
responder.stop(err => {
54-
expect(err).to.not.exist()
55-
done()
56-
})
57-
})
45+
await responder.start()
46+
await responder.stop()
5847
})
5948

60-
it('should not respond to a query if no TCP addresses', done => {
61-
PeerInfo.create((err, peerInfo) => {
62-
expect(err).to.not.exist()
63-
64-
responder = new Responder(peerInfo)
65-
mdns = MDNS({ multicast: false, interface: '0.0.0.0', port: 0 })
66-
67-
responder.start(err => {
68-
expect(err).to.not.exist()
49+
it('should not respond to a query if no TCP addresses', async () => {
50+
const peerInfo = await PeerInfo.create()
51+
responder = new Responder(peerInfo)
52+
mdns = MDNS({ multicast: false, interface: '0.0.0.0', port: 0 })
6953

70-
let response
54+
await responder.start()
7155

72-
mdns.on('response', event => {
73-
if (isResponseFrom(event, peerInfo)) {
74-
response = event
75-
}
76-
})
56+
let response
7757

78-
mdns.query({
79-
id: 1, // id > 0 for unicast response
80-
questions: [{ name: SERVICE_TAG_LOCAL, type: 'PTR', class: 'IN' }]
81-
}, null, {
82-
address: MULTICAST_IP,
83-
port: MULTICAST_PORT
84-
})
58+
mdns.on('response', event => {
59+
if (isResponseFrom(event, peerInfo)) {
60+
response = event
61+
}
62+
})
8563

86-
setTimeout(() => {
87-
done(response ? new Error('Unexpected repsonse') : null)
88-
}, 100)
89-
})
64+
mdns.query({
65+
id: 1, // id > 0 for unicast response
66+
questions: [{ name: SERVICE_TAG_LOCAL, type: 'PTR', class: 'IN' }]
67+
}, null, {
68+
address: MULTICAST_IP,
69+
port: MULTICAST_PORT
9070
})
71+
72+
await delay(100)
73+
expect(response).to.not.exist()
9174
})
9275

93-
it('should not respond to a query with non matching service tag', done => {
76+
it('should not respond to a query with non matching service tag', async () => {
9477
responder = new Responder(peerInfos[0])
9578
mdns = MDNS({ multicast: false, interface: '0.0.0.0', port: 0 })
9679

97-
responder.start(err => {
98-
expect(err).to.not.exist()
99-
100-
let response
80+
await responder.start()
10181

102-
mdns.on('response', event => {
103-
if (isResponseFrom(event, peerInfos[0])) {
104-
response = event
105-
}
106-
})
82+
let response
10783

108-
const bogusServiceTagLocal = '_ifps-discovery._udp'
84+
mdns.on('response', event => {
85+
if (isResponseFrom(event, peerInfos[0])) {
86+
response = event
87+
}
88+
})
10989

110-
mdns.query({
111-
id: 1, // id > 0 for unicast response
112-
questions: [{ name: bogusServiceTagLocal, type: 'PTR', class: 'IN' }]
113-
}, null, {
114-
address: MULTICAST_IP,
115-
port: MULTICAST_PORT
116-
})
90+
const bogusServiceTagLocal = '_ifps-discovery._udp'
11791

118-
setTimeout(() => {
119-
done(response ? new Error('Unexpected repsonse') : null)
120-
}, 100)
92+
mdns.query({
93+
id: 1, // id > 0 for unicast response
94+
questions: [{ name: bogusServiceTagLocal, type: 'PTR', class: 'IN' }]
95+
}, null, {
96+
address: MULTICAST_IP,
97+
port: MULTICAST_PORT
12198
})
99+
100+
await delay(100)
101+
expect(response).to.not.exist()
122102
})
123103

124-
it('should respond correctly', done => {
104+
it('should respond correctly', async () => {
125105
responder = new Responder(peerInfos[0])
126106
mdns = MDNS({ multicast: false, interface: '0.0.0.0', port: 0 })
127107

128-
responder.start(err => {
129-
expect(err).to.not.exist()
108+
await responder.start()
109+
const defer = pDefer()
130110

131-
mdns.on('response', event => {
132-
if (!isResponseFrom(event, peerInfos[0])) return
111+
mdns.on('response', event => {
112+
if (!isResponseFrom(event, peerInfos[0])) return
133113

134-
const srvRecord = event.answers.find(a => a.type === 'SRV')
135-
if (!srvRecord) return done(new Error('Missing SRV record'))
114+
const srvRecord = event.answers.find(a => a.type === 'SRV')
115+
if (!srvRecord) return defer.reject(new Error('Missing SRV record'))
136116

137-
const { port } = srvRecord.data || {}
138-
const protos = { A: 'ip4', AAAA: 'ip6' }
117+
const { port } = srvRecord.data || {}
118+
const protos = { A: 'ip4', AAAA: 'ip6' }
139119

140-
const addrs = event.answers
141-
.filter(a => ['A', 'AAAA'].includes(a.type))
142-
.map(a => `/${protos[a.type]}/${a.data}/tcp/${port}`)
120+
const addrs = event.answers
121+
.filter(a => ['A', 'AAAA'].includes(a.type))
122+
.map(a => `/${protos[a.type]}/${a.data}/tcp/${port}`)
143123

144-
if (!addrs.includes(peerAddrs[0])) {
145-
return done(new Error('Missing peer address in response: ' + peerAddrs[0]))
146-
}
124+
if (!addrs.includes(peerAddrs[0])) {
125+
return defer.reject(new Error('Missing peer address in response: ' + peerAddrs[0]))
126+
}
147127

148-
done()
149-
})
128+
defer.resolve()
129+
})
150130

151-
mdns.query({
152-
id: 1, // id > 0 for unicast response
153-
questions: [{ name: SERVICE_TAG_LOCAL, type: 'PTR', class: 'IN' }]
154-
}, null, {
155-
address: MULTICAST_IP,
156-
port: MULTICAST_PORT
157-
})
131+
mdns.query({
132+
id: 1, // id > 0 for unicast response
133+
questions: [{ name: SERVICE_TAG_LOCAL, type: 'PTR', class: 'IN' }]
134+
}, null, {
135+
address: MULTICAST_IP,
136+
port: MULTICAST_PORT
158137
})
138+
139+
await defer.promise
159140
})
160141
})
161142

‎test/compliance.spec.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict'
2+
3+
const test = require('interface-discovery')
4+
const PeerInfo = require('peer-info')
5+
const MulticastDNS = require('../src')
6+
let mdns
7+
8+
const common = {
9+
async setup () {
10+
const peerInfo = await PeerInfo.create()
11+
mdns = new MulticastDNS({
12+
peerInfo,
13+
broadcast: false,
14+
port: 50001,
15+
compat: true
16+
})
17+
18+
return mdns
19+
}
20+
}
21+
22+
// use all of the test suits
23+
test(common)

‎test/multicast-dns.spec.js

+65-110
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ const expect = chai.expect
77
chai.use(dirtyChai)
88
const multiaddr = require('multiaddr')
99
const PeerInfo = require('peer-info')
10-
const parallel = require('async/parallel')
11-
const series = require('async/series')
1210

1311
const MulticastDNS = require('./../src')
1412

@@ -18,50 +16,28 @@ describe('MulticastDNS', () => {
1816
let pC
1917
let pD
2018

21-
before(function (done) {
19+
before(async function () {
2220
this.timeout(80 * 1000)
2321

24-
parallel([
25-
(cb) => {
26-
PeerInfo.create((err, peer) => {
27-
expect(err).to.not.exist()
28-
29-
pA = peer
30-
pA.multiaddrs.add(multiaddr('/ip4/127.0.0.1/tcp/20001'))
31-
cb()
32-
})
33-
},
34-
(cb) => {
35-
PeerInfo.create((err, peer) => {
36-
expect(err).to.not.exist()
37-
38-
pB = peer
39-
pB.multiaddrs.add(multiaddr('/ip4/127.0.0.1/tcp/20002'))
40-
pB.multiaddrs.add(multiaddr('/ip6/::1/tcp/20002'))
41-
cb()
42-
})
43-
},
44-
(cb) => {
45-
PeerInfo.create((err, peer) => {
46-
expect(err).to.not.exist()
47-
pC = peer
48-
pC.multiaddrs.add(multiaddr('/ip4/127.0.0.1/tcp/20003'))
49-
pC.multiaddrs.add(multiaddr('/ip4/127.0.0.1/tcp/30003/ws'))
50-
cb()
51-
})
52-
},
53-
(cb) => {
54-
PeerInfo.create((err, peer) => {
55-
if (err) { cb(err) }
56-
pD = peer
57-
pD.multiaddrs.add(multiaddr('/ip4/127.0.0.1/tcp/30003/ws'))
58-
cb()
59-
})
60-
}
61-
], done)
22+
;[pA, pB, pC, pD] = await Promise.all([
23+
PeerInfo.create(),
24+
PeerInfo.create(),
25+
PeerInfo.create(),
26+
PeerInfo.create()
27+
])
28+
29+
pA.multiaddrs.add(multiaddr('/ip4/127.0.0.1/tcp/20001'))
30+
31+
pB.multiaddrs.add(multiaddr('/ip4/127.0.0.1/tcp/20002'))
32+
pB.multiaddrs.add(multiaddr('/ip6/::1/tcp/20002'))
33+
34+
pC.multiaddrs.add(multiaddr('/ip4/127.0.0.1/tcp/20003'))
35+
pC.multiaddrs.add(multiaddr('/ip4/127.0.0.1/tcp/30003/ws'))
36+
37+
pD.multiaddrs.add(multiaddr('/ip4/127.0.0.1/tcp/30003/ws'))
6238
})
6339

64-
it('find another peer', function (done) {
40+
it('find another peer', async function () {
6541
this.timeout(40 * 1000)
6642

6743
const mdnsA = new MulticastDNS({
@@ -77,23 +53,17 @@ describe('MulticastDNS', () => {
7753
compat: false
7854
})
7955

80-
parallel([
81-
(cb) => mdnsA.start(cb),
82-
(cb) => mdnsB.start(cb)
83-
], () => {
84-
mdnsA.once('peer', (peerInfo) => {
85-
expect(pB.id.toB58String()).to.eql(peerInfo.id.toB58String())
86-
parallel([
87-
(cb) => mdnsA.stop(cb),
88-
(cb) => mdnsB.stop(cb)
89-
], done)
90-
})
91-
92-
mdnsB.once('peer', (peerInfo) => {})
93-
})
56+
mdnsA.start()
57+
mdnsB.start()
58+
59+
const peerInfo = await new Promise((resolve) => mdnsA.once('peer', resolve))
60+
61+
expect(pB.id.toB58String()).to.eql(peerInfo.id.toB58String())
62+
63+
await Promise.all([mdnsA.stop(), mdnsB.stop()])
9464
})
9565

96-
it('only announce TCP multiaddrs', function (done) {
66+
it('only announce TCP multiaddrs', async function () {
9767
this.timeout(40 * 1000)
9868

9969
const mdnsA = new MulticastDNS({
@@ -113,27 +83,23 @@ describe('MulticastDNS', () => {
11383
compat: false
11484
})
11585

116-
parallel([
117-
(cb) => mdnsA.start(cb),
118-
(cb) => mdnsC.start(cb),
119-
(cb) => mdnsD.start(cb)
120-
121-
], () => {
122-
mdnsA.once('peer', (peerInfo) => {
123-
expect(pC.id.toB58String()).to.eql(peerInfo.id.toB58String())
124-
expect(peerInfo.multiaddrs.size).to.equal(1)
125-
parallel([
126-
(cb) => mdnsA.stop(cb),
127-
(cb) => mdnsC.stop(cb),
128-
(cb) => mdnsD.stop(cb)
129-
], done)
130-
})
131-
132-
mdnsC.once('peer', (peerInfo) => {})
133-
})
86+
mdnsA.start()
87+
mdnsC.start()
88+
mdnsD.start()
89+
90+
const peerInfo = await new Promise((resolve) => mdnsA.once('peer', resolve))
91+
92+
expect(pC.id.toB58String()).to.eql(peerInfo.id.toB58String())
93+
expect(peerInfo.multiaddrs.size).to.equal(1)
94+
95+
await Promise.all([
96+
mdnsA.stop(),
97+
mdnsC.stop(),
98+
mdnsD.stop()
99+
])
134100
})
135101

136-
it('announces IP6 addresses', function (done) {
102+
it('announces IP6 addresses', async function () {
137103
this.timeout(40 * 1000)
138104

139105
const mdnsA = new MulticastDNS({
@@ -149,24 +115,18 @@ describe('MulticastDNS', () => {
149115
compat: false
150116
})
151117

152-
series([
153-
(cb) => mdnsB.start(cb),
154-
(cb) => mdnsA.start(cb)
155-
], () => {
156-
mdnsA.once('peer', (peerInfo) => {
157-
expect(pB.id.toB58String()).to.eql(peerInfo.id.toB58String())
158-
expect(peerInfo.multiaddrs.size).to.equal(2)
159-
parallel([
160-
(cb) => mdnsA.stop(cb),
161-
(cb) => mdnsB.stop(cb)
162-
], done)
163-
})
164-
165-
mdnsB.once('peer', (peerInfo) => {})
166-
})
118+
mdnsA.start()
119+
mdnsB.start()
120+
121+
const peerInfo = await new Promise((resolve) => mdnsA.once('peer', resolve))
122+
123+
expect(pB.id.toB58String()).to.eql(peerInfo.id.toB58String())
124+
expect(peerInfo.multiaddrs.size).to.equal(2)
125+
126+
await Promise.all([mdnsA.stop(), mdnsB.stop()])
167127
})
168128

169-
it('doesn\'t emit peers after stop', function (done) {
129+
it('doesn\'t emit peers after stop', async function () {
170130
this.timeout(40 * 1000)
171131

172132
const mdnsA = new MulticastDNS({
@@ -181,28 +141,23 @@ describe('MulticastDNS', () => {
181141
compat: false
182142
})
183143

184-
series([
185-
(cb) => mdnsA.start(cb),
186-
(cb) => setTimeout(cb, 1000),
187-
(cb) => mdnsA.stop(cb),
188-
(cb) => mdnsC.start(cb)
189-
], () => {
190-
setTimeout(() => mdnsC.stop(done), 5000)
191-
mdnsC.once('peer', (peerInfo) => {
192-
done(new Error('Should not receive new peer.'))
193-
})
144+
mdnsA.start()
145+
await new Promise((resolve) => setTimeout(resolve, 1000))
146+
await mdnsA.stop()
147+
mdnsC.start()
148+
149+
mdnsC.once('peer', (peerInfo) => {
150+
throw new Error('Should not receive new peer.')
194151
})
152+
153+
await new Promise((resolve) => setTimeout(resolve, 5000))
154+
await mdnsC.stop()
195155
})
196156

197-
it('should start and stop with go-libp2p-mdns compat', done => {
157+
it('should start and stop with go-libp2p-mdns compat', async () => {
198158
const mdns = new MulticastDNS({ peerInfo: pA, port: 50004 })
199159

200-
mdns.start(err => {
201-
expect(err).to.not.exist()
202-
mdns.stop(err => {
203-
expect(err).to.not.exist()
204-
done()
205-
})
206-
})
160+
await mdns.start()
161+
await mdns.stop()
207162
})
208163
})

0 commit comments

Comments
 (0)
This repository has been archived.