aedes 0.51.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/.github/actions/sticky-pr-comment/action.yml +55 -0
  2. package/.github/workflows/benchmark-compare-serial.yml +60 -0
  3. package/.github/workflows/ci.yml +12 -17
  4. package/.release-it.json +18 -0
  5. package/.taprc +15 -6
  6. package/README.md +6 -4
  7. package/aedes.d.ts +0 -6
  8. package/aedes.js +270 -242
  9. package/benchmarks/README.md +33 -0
  10. package/benchmarks/pingpong.js +94 -25
  11. package/benchmarks/receiver.js +77 -0
  12. package/benchmarks/report.js +150 -0
  13. package/benchmarks/runBenchmarks.js +118 -0
  14. package/benchmarks/sender.js +86 -0
  15. package/benchmarks/server.js +19 -18
  16. package/checkVersion.js +20 -0
  17. package/docs/Aedes.md +66 -8
  18. package/docs/Client.md +3 -4
  19. package/docs/Examples.md +39 -22
  20. package/docs/MIGRATION.md +50 -0
  21. package/eslint.config.js +8 -0
  22. package/example.js +51 -40
  23. package/examples/clusters/index.js +28 -23
  24. package/examples/clusters/package.json +10 -6
  25. package/lib/client.js +405 -306
  26. package/lib/handlers/connect.js +42 -38
  27. package/lib/handlers/index.js +9 -11
  28. package/lib/handlers/ping.js +2 -3
  29. package/lib/handlers/puback.js +5 -5
  30. package/lib/handlers/publish.js +29 -14
  31. package/lib/handlers/pubrec.js +9 -17
  32. package/lib/handlers/pubrel.js +34 -25
  33. package/lib/handlers/subscribe.js +47 -43
  34. package/lib/handlers/unsubscribe.js +16 -19
  35. package/lib/qos-packet.js +14 -17
  36. package/lib/utils.js +5 -12
  37. package/lib/write.js +4 -5
  38. package/package.json +134 -136
  39. package/test/auth.js +468 -804
  40. package/test/basic.js +613 -575
  41. package/test/bridge.js +44 -40
  42. package/test/client-pub-sub.js +531 -504
  43. package/test/close_socket_by_other_party.js +137 -102
  44. package/test/connect.js +487 -484
  45. package/test/drain-timeout.js +593 -0
  46. package/test/drain-toxiproxy.js +620 -0
  47. package/test/events.js +173 -145
  48. package/test/helper.js +351 -73
  49. package/test/keep-alive.js +40 -67
  50. package/test/meta.js +257 -210
  51. package/test/not-blocking.js +93 -197
  52. package/test/qos1.js +464 -554
  53. package/test/qos2.js +308 -393
  54. package/test/regr-21.js +39 -21
  55. package/test/require.cjs +22 -0
  56. package/test/retain.js +349 -398
  57. package/test/topics.js +176 -183
  58. package/test/types/aedes.test-d.ts +4 -8
  59. package/test/will.js +310 -428
  60. package/types/instance.d.ts +40 -35
  61. package/types/packet.d.ts +10 -10
  62. package/.coveralls.yml +0 -1
  63. package/benchmarks/bombing.js +0 -34
  64. package/benchmarks/bombingQoS1.js +0 -36
  65. package/benchmarks/throughputCounter.js +0 -23
  66. package/benchmarks/throughputCounterQoS1.js +0 -33
  67. package/types/.eslintrc.json +0 -47
@@ -1,14 +1,18 @@
1
- 'use strict'
2
-
3
- const { test } = require('tap')
4
- const { setup, connect, subscribe, noError } = require('./helper')
5
- const aedes = require('../')
6
-
7
- test('publish direct to a single client QoS 0', function (t) {
1
+ import { test } from 'node:test'
2
+ import { once } from 'node:events'
3
+ import {
4
+ connect,
5
+ createAndConnect,
6
+ nextPacket,
7
+ nextPacketWithTimeOut,
8
+ setup,
9
+ subscribe,
10
+ } from './helper.js'
11
+
12
+ test('publish direct to a single client QoS 0', async (t) => {
8
13
  t.plan(2)
9
14
 
10
- const broker = aedes()
11
- t.teardown(broker.close.bind(broker))
15
+ const s = await createAndConnect(t)
12
16
 
13
17
  const expected = {
14
18
  cmd: 'publish',
@@ -20,78 +24,67 @@ test('publish direct to a single client QoS 0', function (t) {
20
24
  retain: false
21
25
  }
22
26
 
23
- broker.on('client', function (client) {
24
- client.publish({
27
+ await new Promise(resolve => {
28
+ s.client.publish({
25
29
  topic: 'hello',
26
30
  payload: Buffer.from('world'),
27
31
  qos: 0
28
- }, function (err) {
29
- t.error(err, 'no error')
32
+ }, (err) => {
33
+ t.assert.ok(!err, 'no error')
34
+ resolve()
30
35
  })
31
36
  })
32
37
 
33
- const s = connect(setup(broker))
34
-
35
- s.outStream.once('data', function (packet) {
36
- t.same(packet, expected, 'packet matches')
37
- })
38
+ const packet = await nextPacket(s)
39
+ t.assert.deepEqual(structuredClone(packet), expected, 'packet matches')
38
40
  })
39
41
 
40
- test('publish direct to a single client throws error', function (t) {
42
+ test('publish direct to a single client throws error', async (t) => {
41
43
  t.plan(1)
42
44
 
43
- const broker = aedes()
44
- t.teardown(broker.close.bind(broker))
45
+ const s = await createAndConnect(t, { connect: { clean: false } })
45
46
 
46
- broker.persistence.outgoingEnqueue = function (sub, packet, done) {
47
- done(new Error('Throws error'))
47
+ s.broker.persistence.outgoingEnqueue = async () => {
48
+ throw new Error('Throws error')
48
49
  }
49
50
 
50
- broker.on('client', function (client) {
51
- client.publish({
51
+ await new Promise(resolve => {
52
+ s.client.publish({
52
53
  topic: 'hello',
53
54
  payload: Buffer.from('world'),
54
55
  qos: 1,
55
56
  retain: false
56
- }, function (err) {
57
- t.pass('Throws error', err.message, 'throws error')
57
+ }, (err) => {
58
+ t.assert.equal('Throws error', err.message, 'throws error')
59
+ resolve()
58
60
  })
59
61
  })
60
-
61
- connect(setup(broker), { clean: false })
62
62
  })
63
63
 
64
- test('publish direct to a single client throws error 2', function (t) {
64
+ test('publish direct to a single client throws error 2', async (t) => {
65
65
  t.plan(1)
66
66
 
67
- const broker = aedes()
68
- t.teardown(broker.close.bind(broker))
67
+ const s = await createAndConnect(t, { connect: { clean: false } })
69
68
 
70
- broker.persistence.outgoingUpdate = function (client, packet, done) {
71
- done(new Error('Throws error'), client, packet)
69
+ s.broker.persistence.outgoingUpdate = async () => {
70
+ throw new Error('Throws error')
72
71
  }
73
72
 
74
- broker.on('client', function (client) {
75
- client.publish({
76
- topic: 'hello',
77
- payload: Buffer.from('world'),
78
- qos: 1,
79
- retain: false
80
- }, () => {})
81
-
82
- client.once('error', function (err) {
83
- t.pass('Throws error', err.message, 'throws error')
84
- })
85
- })
73
+ s.client.publish({
74
+ topic: 'hello',
75
+ payload: Buffer.from('world'),
76
+ qos: 1,
77
+ retain: false
78
+ }, () => { })
86
79
 
87
- connect(setup(broker), { clean: false })
80
+ const [err] = await once(s.client, 'error')
81
+ t.assert.equal('Throws error', err.message, 'throws error')
88
82
  })
89
83
 
90
- test('publish direct to a single client QoS 1', function (t) {
84
+ test('publish direct to a single client QoS 1', async (t) => {
91
85
  t.plan(2)
92
86
 
93
- const broker = aedes()
94
- t.teardown(broker.close.bind(broker))
87
+ const s = await createAndConnect(t)
95
88
 
96
89
  const expected = {
97
90
  cmd: 'publish',
@@ -103,116 +96,131 @@ test('publish direct to a single client QoS 1', function (t) {
103
96
  retain: false
104
97
  }
105
98
 
106
- broker.on('client', function (client) {
107
- client.publish({
99
+ const publishPacket = new Promise(resolve => {
100
+ s.client.publish({
108
101
  topic: 'hello',
109
102
  payload: Buffer.from('world'),
110
103
  qos: 1
111
- }, function (err) {
112
- t.error(err, 'no error')
104
+ }, (err) => {
105
+ t.assert.ok(!err, 'no error')
106
+ resolve()
113
107
  })
114
108
  })
115
109
 
116
- const s = connect(setup(broker))
117
-
118
- s.outStream.once('data', function (packet) {
110
+ const processPacket = async () => {
111
+ const packet = await nextPacket(s)
119
112
  expected.messageId = packet.messageId
120
- t.same(packet, expected, 'packet matches')
113
+ t.assert.deepEqual(structuredClone(packet), expected, 'packet matches')
121
114
  s.inStream.write({
122
115
  cmd: 'puback',
123
116
  messageId: packet.messageId
124
117
  })
125
- })
126
- })
118
+ }
127
119
 
128
- test('publish QoS 2 throws error in pubrel', function (t) {
129
- t.plan(2)
120
+ // run parallel
121
+ await Promise.all([
122
+ publishPacket,
123
+ processPacket()
124
+ ])
125
+ })
130
126
 
131
- const broker = aedes()
132
- t.teardown(broker.close.bind(broker))
127
+ test('publish QoS 2 throws error in pubrel', async (t) => {
128
+ t.plan(3)
133
129
 
134
- const s = connect(setup(broker))
130
+ const s = await createAndConnect(t)
135
131
 
136
- broker.on('clientError', function (c, err) {
137
- t.pass('throws error')
138
- })
132
+ const clientError = async () => {
133
+ once(s.broker, 'clientError')
134
+ t.assert.ok(true, 'throws error')
135
+ }
139
136
 
140
- s.outStream.on('data', function (packet) {
141
- if (packet.cmd === 'publish') {
142
- s.inStream.write({
143
- cmd: 'pubrec',
144
- messageId: packet.messageId
145
- })
146
- s.broker.persistence.outgoingUpdate = function (client, pubrel, cb) {
147
- cb(new Error('error'))
148
- }
137
+ const processPacket = async () => {
138
+ const packet = await nextPacket(s)
139
+ t.assert.equal(packet.cmd, 'publish', 'publish packet')
140
+ s.inStream.write({
141
+ cmd: 'pubrec',
142
+ messageId: packet.messageId
143
+ })
144
+ s.broker.persistence.outgoingUpdate = async () => {
145
+ throw new Error('error')
149
146
  }
150
- })
147
+ }
151
148
 
152
- broker.on('clientReady', function (client) {
153
- client.publish({
149
+ const publishPacket = new Promise(resolve => {
150
+ s.client.publish({
154
151
  topic: 'hello',
155
152
  payload: Buffer.from('world'),
156
153
  qos: 2
157
- }, function (err) {
158
- t.error(err, 'no error')
154
+ }, (err) => {
155
+ t.assert.ok(!err, 'no error')
156
+ resolve()
159
157
  })
160
158
  })
159
+ // run parallel
160
+ await Promise.all([
161
+ clientError(),
162
+ processPacket(),
163
+ publishPacket,
164
+ ])
161
165
  })
162
166
 
163
- test('publish direct to a single client QoS 2', function (t) {
164
- t.plan(3)
167
+ test('publish direct to a single client QoS 2', async (t) => {
168
+ t.plan(5)
165
169
 
166
- const broker = aedes()
167
- t.teardown(broker.close.bind(broker))
170
+ const s = await createAndConnect(t)
168
171
 
169
172
  let publishCount = 0
170
173
  let nonPublishCount = 0
171
174
 
172
- broker.on('clientReady', function (client) {
173
- client.publish({
175
+ const publishPacket = new Promise(resolve => {
176
+ s.client.publish({
174
177
  topic: 'hello',
175
178
  payload: Buffer.from('world'),
176
179
  qos: 2
177
- }, function (err) {
178
- t.error(err, 'no error')
180
+ }, (err) => {
181
+ t.assert.ok(!err, 'no error')
182
+ resolve()
179
183
  })
180
- client.on('error', function (err) {
181
- t.error(err)
184
+ s.client.on('error', (err) => {
185
+ t.assert.fail(err)
182
186
  })
183
187
  })
184
188
 
185
- const s = connect(setup(broker))
186
-
187
- s.inStream.on('close', () => {
188
- t.equal(publishCount, 1)
189
- t.equal(nonPublishCount, 1)
190
- })
189
+ const checkOnClose = async () => {
190
+ await once(s.inStream, 'close')
191
+ t.assert.equal(publishCount, 1)
192
+ t.assert.equal(nonPublishCount, 1)
193
+ }
191
194
 
192
- s.outStream.on('data', function (packet) {
193
- if (packet.cmd === 'publish') {
194
- publishCount++
195
- s.inStream.write({
196
- cmd: 'pubrec',
197
- messageId: packet.messageId
198
- })
199
- } else {
200
- nonPublishCount++
201
- s.inStream.write({
202
- cmd: 'pubcomp',
203
- messageId: packet.messageId
204
- })
205
- s.inStream.destroy()
206
- }
207
- })
195
+ const processPacket = async () => {
196
+ const packet1 = await nextPacket(s)
197
+ t.assert.equal(packet1.cmd, 'publish', 'publish packet')
198
+ publishCount++
199
+ s.inStream.write({
200
+ cmd: 'pubrec',
201
+ messageId: packet1.messageId
202
+ })
203
+ const packet2 = await nextPacket(s)
204
+ t.assert.equal(packet2.cmd, 'pubrel', 'pubrel packet')
205
+ nonPublishCount++
206
+ s.inStream.write({
207
+ cmd: 'pubcomp',
208
+ messageId: packet2.messageId
209
+ })
210
+ s.inStream.destroy()
211
+ }
212
+ // run parallel
213
+ await Promise.all([
214
+ checkOnClose(),
215
+ processPacket(),
216
+ publishPacket,
217
+ ])
208
218
  })
209
219
 
210
- test('emit a `ack` event on PUBACK for QoS 1 [clean=false]', function (t) {
211
- t.plan(3)
212
-
213
- const broker = aedes()
214
- t.teardown(broker.close.bind(broker))
220
+ test('emit a `ack` event on PUBACK for QoS 1 [clean=false]', async (t) => {
221
+ t.plan(4)
215
222
 
223
+ const s = await createAndConnect(t, { connect: { clean: false } })
216
224
  const expected = {
217
225
  cmd: 'publish',
218
226
  topic: 'hello',
@@ -222,153 +230,187 @@ test('emit a `ack` event on PUBACK for QoS 1 [clean=false]', function (t) {
222
230
  dup: false
223
231
  }
224
232
 
225
- broker.on('clientReady', function (client) {
226
- client.publish({
233
+ const publishPacket = new Promise(resolve => {
234
+ s.client.publish({
227
235
  topic: 'hello',
228
236
  payload: Buffer.from('world'),
229
237
  qos: 1
230
- }, function (err) {
231
- t.error(err, 'no error')
238
+ }, (err) => {
239
+ t.assert.ok(!err, 'no error')
240
+ resolve()
232
241
  })
233
242
  })
234
243
 
235
- broker.once('ack', function (packet, client) {
244
+ const brokerAck = async () => {
245
+ const [packet] = await once(s.broker, 'ack')
236
246
  expected.brokerId = packet.brokerId
237
247
  expected.brokerCounter = packet.brokerCounter
238
248
  expected.messageId = packet.messageId
239
- t.same(packet, expected, 'ack packet is origianl packet')
240
- t.pass('got the ack event')
241
- })
242
-
243
- const s = connect(setup(broker), { clean: false })
249
+ t.assert.deepEqual(structuredClone(packet), expected, 'ack packet is original packet')
250
+ t.assert.ok(true, 'got the ack event')
251
+ }
244
252
 
245
- s.outStream.once('data', function (packet) {
253
+ const processPacket = async () => {
254
+ const packet = await nextPacket(s)
255
+ t.assert.equal(packet.cmd, 'publish', 'publish packet')
246
256
  s.inStream.write({
247
257
  cmd: 'puback',
248
258
  messageId: packet.messageId
249
259
  })
250
- })
260
+ }
261
+
262
+ // run parallel
263
+ await Promise.all([
264
+ brokerAck(),
265
+ processPacket(),
266
+ publishPacket,
267
+ ])
251
268
  })
252
269
 
253
- test('emit a `ack` event on PUBACK for QoS 1 [clean=true]', function (t) {
254
- t.plan(3)
270
+ test('emit a `ack` event on PUBACK for QoS 1 [clean=true]', async (t) => {
271
+ t.plan(4)
255
272
 
256
- const broker = aedes()
257
- t.teardown(broker.close.bind(broker))
273
+ const s = await createAndConnect(t, { connect: { clean: true } })
258
274
 
259
- broker.on('clientReady', function (client) {
260
- client.publish({
275
+ const publishPacket = new Promise(resolve => {
276
+ s.client.publish({
261
277
  topic: 'hello',
262
278
  payload: Buffer.from('world'),
263
279
  qos: 1
264
- }, function (err) {
265
- t.error(err, 'no error')
280
+ }, (err) => {
281
+ t.assert.ok(!err, 'no error')
282
+ resolve()
266
283
  })
267
284
  })
268
285
 
269
- broker.once('ack', function (packet, client) {
270
- t.equal(packet, undefined, 'ack packet is undefined')
271
- t.pass('got the ack event')
272
- })
273
-
274
- const s = connect(setup(broker), { clean: true })
286
+ const brokerAck = async () => {
287
+ const [packet] = await once(s.broker, 'ack')
288
+ t.assert.equal(packet, undefined, 'ack packet is undefined')
289
+ t.assert.ok(true, 'got the ack event')
290
+ }
275
291
 
276
- s.outStream.once('data', function (packet) {
292
+ const processPacket = async () => {
293
+ const packet = await nextPacket(s)
294
+ t.assert.equal(packet.cmd, 'publish', 'publish packet')
277
295
  s.inStream.write({
278
296
  cmd: 'puback',
279
297
  messageId: packet.messageId
280
298
  })
281
- })
299
+ }
300
+ // run parallel
301
+ await Promise.all([
302
+ brokerAck(),
303
+ processPacket(),
304
+ publishPacket,
305
+ ])
282
306
  })
283
307
 
284
- test('emit a `ack` event on PUBCOMP for QoS 2 [clean=false]', function (t) {
285
- t.plan(5)
308
+ test('emit a `ack` event on PUBCOMP for QoS 2 [clean=false]', async (t) => {
309
+ t.plan(7)
286
310
 
287
- const broker = aedes()
288
- t.teardown(broker.close.bind(broker))
311
+ const s = await createAndConnect(t, { connect: { clean: false } })
289
312
 
290
313
  let messageId
291
314
  let clientId
292
315
 
293
- broker.on('clientReady', function (client) {
294
- clientId = client.id
295
- client.publish({
316
+ const publishPacket = new Promise(resolve => {
317
+ clientId = s.client.id
318
+ s.client.publish({
296
319
  topic: 'hello',
297
320
  payload: Buffer.from('world'),
298
321
  qos: 2
299
- }, function (err) {
300
- t.error(err, 'no error')
322
+ }, (err) => {
323
+ t.assert.ok(!err, 'no error')
324
+ resolve()
301
325
  })
302
326
  })
303
327
 
304
- broker.once('ack', function (packet, client) {
305
- t.equal(client.id, clientId)
306
- t.equal(packet.messageId, messageId)
307
- t.equal(packet.cmd, 'pubrel', 'ack packet is purel')
308
- t.pass('got the ack event')
309
- })
310
-
311
- const s = connect(setup(broker), { clean: false })
328
+ const brokerAck = async () => {
329
+ const [packet, client] = await once(s.broker, 'ack')
330
+ t.assert.equal(client.id, clientId)
331
+ t.assert.equal(packet.messageId, messageId)
332
+ t.assert.equal(packet.cmd, 'pubrel', 'ack packet is pubrel')
333
+ t.assert.ok(true, 'got the ack event')
334
+ }
312
335
 
313
- s.outStream.on('data', function (packet) {
314
- if (packet.cmd === 'publish') {
315
- s.inStream.write({
316
- cmd: 'pubrec',
317
- messageId: packet.messageId
318
- })
319
- } else {
320
- messageId = packet.messageId
321
- s.inStream.write({
322
- cmd: 'pubcomp',
323
- messageId: packet.messageId
324
- })
325
- }
326
- })
336
+ const processPacket = async () => {
337
+ const packet1 = await nextPacket(s)
338
+ t.assert.equal(packet1.cmd, 'publish', 'publish packet')
339
+ s.inStream.write({
340
+ cmd: 'pubrec',
341
+ messageId: packet1.messageId
342
+ })
343
+ const packet2 = await nextPacket(s)
344
+ t.assert.equal(packet2.cmd, 'pubrel', 'pubrel packet')
345
+ messageId = packet2.messageId
346
+ s.inStream.write({
347
+ cmd: 'pubcomp',
348
+ messageId: packet2.messageId
349
+ })
350
+ }
351
+ // run parallel
352
+ await Promise.all([
353
+ brokerAck(),
354
+ processPacket(),
355
+ publishPacket,
356
+ ])
327
357
  })
328
358
 
329
- test('emit a `ack` event on PUBCOMP for QoS 2 [clean=true]', function (t) {
330
- t.plan(3)
359
+ test('emit a `ack` event on PUBCOMP for QoS 2 [clean=true]', async (t) => {
360
+ t.plan(6)
331
361
 
332
- const broker = aedes()
333
- t.teardown(broker.close.bind(broker))
362
+ const s = await createAndConnect(t, { connect: { clean: true } })
334
363
 
335
- broker.on('clientReady', function (client) {
336
- client.publish({
364
+ const publishPacket = new Promise(resolve => {
365
+ s.client.publish({
337
366
  topic: 'hello',
338
367
  payload: Buffer.from('world'),
339
368
  qos: 2
340
- }, function (err) {
341
- t.error(err, 'no error')
369
+ }, (err) => {
370
+ t.assert.ok(!err, 'no error')
371
+ resolve()
342
372
  })
343
373
  })
344
374
 
345
- broker.once('ack', function (packet, client) {
346
- t.equal(packet, undefined, 'ack packet is undefined')
347
- t.pass('got the ack event')
348
- })
349
-
350
- const s = connect(setup(broker), { clean: true })
375
+ const brokerAck = async () => {
376
+ const [packet, client] = await once(s.broker, 'ack')
377
+ t.assert.ok(client, 'client is defined')
378
+ t.assert.equal(packet, undefined, 'ack packet is undefined')
379
+ t.assert.ok(true, 'got the ack event')
380
+ }
351
381
 
352
- s.outStream.on('data', function (packet) {
353
- if (packet.cmd === 'publish') {
354
- s.inStream.write({
355
- cmd: 'pubrec',
356
- messageId: packet.messageId
357
- })
358
- } else {
359
- s.inStream.write({
360
- cmd: 'pubcomp',
361
- messageId: packet.messageId
362
- })
363
- }
364
- })
382
+ const processPacket = async () => {
383
+ const packet1 = await nextPacket(s)
384
+ t.assert.equal(packet1.cmd, 'publish', 'publish packet')
385
+ s.inStream.write({
386
+ cmd: 'pubrec',
387
+ messageId: packet1.messageId
388
+ })
389
+ const packet2 = await nextPacket(s)
390
+ t.assert.equal(packet2.cmd, 'pubrel', 'pubrel packet')
391
+ s.inStream.write({
392
+ cmd: 'pubcomp',
393
+ messageId: packet2.messageId
394
+ })
395
+ }
396
+ // run parallel
397
+ await Promise.all([
398
+ brokerAck(),
399
+ processPacket(),
400
+ publishPacket,
401
+ ])
365
402
  })
366
403
 
367
- test('offline message support for direct publish', function (t) {
404
+ test('offline message support for direct publish', async (t) => {
368
405
  t.plan(2)
369
406
 
370
- const broker = aedes()
371
- t.teardown(broker.close.bind(broker))
407
+ const opts = {
408
+ connect: {
409
+ clean: false,
410
+ clientId: 'abcde'
411
+ }
412
+ }
413
+ const s1 = await createAndConnect(t, opts)
372
414
 
373
415
  const expected = {
374
416
  cmd: 'publish',
@@ -379,43 +421,42 @@ test('offline message support for direct publish', function (t) {
379
421
  qos: 1,
380
422
  retain: false
381
423
  }
382
- const opts = {
383
- clean: false,
384
- clientId: 'abcde'
385
- }
386
424
 
387
- broker.once('client', function (client) {
388
- client.publish({
425
+ const publishPacket = new Promise(resolve => {
426
+ s1.client.publish({
389
427
  topic: 'hello',
390
428
  payload: Buffer.from('world'),
391
429
  qos: 1
392
- }, function (err) {
393
- t.error(err, 'no error')
430
+ }, (err) => {
431
+ t.assert.ok(!err, 'no error')
432
+ resolve()
394
433
  })
395
434
  })
396
435
 
397
- let s = connect(setup(broker), opts)
398
-
399
- s.outStream.once('data', function (packet) {
400
- s = connect(setup(broker), opts)
401
-
402
- s.outStream.once('data', function (packet) {
403
- s = connect(setup(broker), opts)
404
- s.inStream.write({
405
- cmd: 'puback',
406
- messageId: packet.messageId
407
- })
408
- delete packet.messageId
409
- t.same(packet, expected, 'packet must match')
436
+ const processPacket = async () => {
437
+ const packet1 = await nextPacket(s1)
438
+ // create a new subscriber, this will disconnect s1
439
+ const s2 = setup(s1.broker)
440
+ await connect(s2, opts)
441
+ s2.inStream.write({
442
+ cmd: 'puback',
443
+ messageId: packet1.messageId
410
444
  })
411
- })
445
+ const packet2 = await nextPacket(s2)
446
+ delete packet2.messageId
447
+ t.assert.deepEqual(structuredClone(packet2), expected, 'packet must match')
448
+ }
449
+ // run parallel
450
+ await Promise.all([
451
+ processPacket(),
452
+ publishPacket,
453
+ ])
412
454
  })
413
455
 
414
- test('subscribe a client programmatically', function (t) {
456
+ test('subscribe a client programmatically', async (t) => {
415
457
  t.plan(3)
416
458
 
417
- const broker = aedes()
418
- t.teardown(broker.close.bind(broker))
459
+ const s = await createAndConnect(t)
419
460
 
420
461
  const expected = {
421
462
  cmd: 'publish',
@@ -427,35 +468,31 @@ test('subscribe a client programmatically', function (t) {
427
468
  retain: false
428
469
  }
429
470
 
430
- broker.on('client', function (client) {
431
- client.subscribe({
471
+ await new Promise(resolve => {
472
+ s.client.subscribe({
432
473
  topic: 'hello',
433
474
  qos: 0
434
- }, function (err) {
435
- t.error(err, 'no error')
436
-
437
- broker.publish({
475
+ }, (err) => {
476
+ t.assert.ok(!err, 'no error')
477
+ s.broker.publish({
438
478
  topic: 'hello',
439
479
  payload: Buffer.from('world'),
440
480
  qos: 0
441
- }, function (err) {
442
- t.error(err, 'no error')
481
+ }, (err) => {
482
+ t.assert.ok(!err, 'no error')
483
+ resolve()
443
484
  })
444
485
  })
445
486
  })
446
487
 
447
- const s = connect(setup(broker))
448
-
449
- s.outStream.once('data', function (packet) {
450
- t.same(packet, expected, 'packet matches')
451
- })
488
+ const packet = await nextPacket(s)
489
+ t.assert.deepEqual(structuredClone(packet), expected, 'packet matches')
452
490
  })
453
491
 
454
- test('subscribe a client programmatically clears retain', function (t) {
492
+ test('subscribe a client programmatically clears retain', async (t) => {
455
493
  t.plan(3)
456
494
 
457
- const broker = aedes()
458
- t.teardown(broker.close.bind(broker))
495
+ const s = await createAndConnect(t)
459
496
 
460
497
  const expected = {
461
498
  cmd: 'publish',
@@ -467,36 +504,46 @@ test('subscribe a client programmatically clears retain', function (t) {
467
504
  retain: false
468
505
  }
469
506
 
470
- broker.on('client', function (client) {
471
- client.subscribe({
507
+ await new Promise(resolve => {
508
+ s.client.subscribe({
472
509
  topic: 'hello',
473
510
  qos: 0
474
- }, function (err) {
475
- t.error(err, 'no error')
511
+ }, (err) => {
512
+ t.assert.ok(!err, 'no error')
476
513
 
477
- broker.publish({
514
+ s.broker.publish({
478
515
  topic: 'hello',
479
516
  payload: Buffer.from('world'),
480
517
  qos: 0,
481
518
  retain: true
482
- }, function (err) {
483
- t.error(err, 'no error')
519
+ }, (err) => {
520
+ t.assert.ok(!err, 'no error')
521
+ resolve()
484
522
  })
485
523
  })
486
524
  })
487
525
 
488
- const s = connect(setup(broker))
489
-
490
- s.outStream.once('data', function (packet) {
491
- t.same(packet, expected, 'packet matches')
492
- })
526
+ // two packets are streamed
527
+ // - one with retain === true
528
+ // - one with retain === false
529
+ // the order varies depending on timing so we
530
+ // need to be able to handle both scenarios
531
+
532
+ for await (const packet of s.outStream) {
533
+ if (packet.retain === false) {
534
+ t.assert.deepEqual(structuredClone(packet), expected, 'packet matches')
535
+ s.inStream.end({
536
+ cmd: 'disconnect'
537
+ })
538
+ break
539
+ }
540
+ }
493
541
  })
494
542
 
495
- test('subscribe a bridge programmatically keeps retain', function (t) {
543
+ test('subscribe a bridge programmatically keeps retain', async (t) => {
496
544
  t.plan(3)
497
545
 
498
- const broker = aedes()
499
- t.teardown(broker.close.bind(broker))
546
+ const s = await createAndConnect(t)
500
547
 
501
548
  const expected = {
502
549
  cmd: 'publish',
@@ -508,71 +555,68 @@ test('subscribe a bridge programmatically keeps retain', function (t) {
508
555
  retain: true
509
556
  }
510
557
 
511
- broker.on('client', function (client) {
512
- client.subscribe({
558
+ await new Promise(resolve => {
559
+ s.client.subscribe({
513
560
  topic: 'hello',
514
561
  qos: 0,
515
562
  rap: true
516
- }, function (err) {
517
- t.error(err, 'no error')
563
+ }, (err) => {
564
+ t.assert.ok(!err, 'no error')
518
565
 
519
- broker.publish({
566
+ s.broker.publish({
520
567
  topic: 'hello',
521
568
  payload: Buffer.from('world'),
522
569
  qos: 0,
523
570
  retain: true
524
- }, function (err) {
525
- t.error(err, 'no error')
571
+ }, (err) => {
572
+ t.assert.ok(!err, 'no error')
573
+ resolve()
526
574
  })
527
575
  })
528
576
  })
529
577
 
530
- const s = connect(setup(broker))
531
-
532
- s.outStream.once('data', function (packet) {
533
- t.same(packet, expected, 'packet matches')
534
- })
578
+ const packet = await nextPacket(s)
579
+ if (packet.retain === true) {
580
+ t.assert.deepEqual(structuredClone(packet), expected, 'packet matches')
581
+ }
535
582
  })
536
583
 
537
- test('subscribe throws error when QoS > 0', function (t) {
584
+ test('subscribe throws error when QoS > 0', async (t) => {
538
585
  t.plan(3)
539
586
 
540
- const broker = aedes()
541
- t.teardown(broker.close.bind(broker))
587
+ const s = await createAndConnect(t)
542
588
 
543
- broker.on('clientReady', function (client) {
544
- client.subscribe({
589
+ await new Promise(resolve => {
590
+ s.client.subscribe({
545
591
  topic: 'hello',
546
592
  qos: 1
547
- }, function (err) {
548
- t.error(err, 'no error')
593
+ }, (err) => {
594
+ t.assert.ok(!err, 'no error')
549
595
 
550
596
  // makes writeQos throw error
551
- client.connected = false
552
- client.connecting = false
597
+ s.client.connected = false
598
+ s.client.connecting = false
553
599
 
554
- broker.publish({
600
+ s.broker.publish({
555
601
  topic: 'hello',
556
602
  payload: Buffer.from('world'),
557
603
  qos: 1
558
- }, function (err) {
559
- t.error(err, 'no error')
604
+ }, (err) => {
605
+ t.assert.ok(!err, 'no error')
560
606
  })
561
607
  })
562
- })
563
608
 
564
- broker.on('clientError', function (client, error) {
565
- t.equal(error.message, 'connection closed', 'should throw clientError')
609
+ s.broker.on('clientError', (client, error) => {
610
+ t.assert.equal(error.message, 'connection closed', 'should throw clientError')
611
+ resolve()
612
+ })
566
613
  })
567
-
568
- connect(setup(broker))
569
614
  })
570
615
 
571
- test('subscribe a client programmatically - wildcard', function (t) {
616
+ test('subscribe a client programmatically - wildcard', async (t) => {
572
617
  t.plan(3)
573
618
 
574
- const broker = aedes()
575
- t.teardown(broker.close.bind(broker))
619
+ const s = await createAndConnect(t)
576
620
 
577
621
  const expected = {
578
622
  cmd: 'publish',
@@ -584,143 +628,136 @@ test('subscribe a client programmatically - wildcard', function (t) {
584
628
  retain: false
585
629
  }
586
630
 
587
- broker.on('clientReady', function (client) {
588
- client.subscribe({
631
+ await new Promise(resolve => {
632
+ s.client.subscribe({
589
633
  topic: '+/world/1',
590
634
  qos: 0
591
- }, function (err) {
592
- t.error(err, 'no error')
635
+ }, (err) => {
636
+ t.assert.ok(!err, 'no error')
593
637
 
594
- broker.publish({
638
+ s.broker.publish({
595
639
  topic: 'hello/world/1',
596
640
  payload: Buffer.from('world'),
597
641
  qos: 0
598
- }, function (err) {
599
- t.error(err, 'no error')
642
+ }, (err) => {
643
+ t.assert.ok(!err, 'no error')
644
+ resolve()
600
645
  })
601
646
  })
602
647
  })
603
648
 
604
- const s = connect(setup(broker))
605
-
606
- s.outStream.once('data', function (packet) {
607
- t.same(packet, expected, 'packet matches')
608
- })
649
+ const packet = await nextPacket(s)
650
+ t.assert.deepEqual(structuredClone(packet), expected, 'packet matches')
609
651
  })
610
652
 
611
- test('unsubscribe a client', function (t) {
653
+ test('unsubscribe a client', async (t) => {
612
654
  t.plan(2)
613
655
 
614
- const broker = aedes()
615
- t.teardown(broker.close.bind(broker))
656
+ const s = await createAndConnect(t)
616
657
 
617
- broker.on('client', function (client) {
618
- client.subscribe({
658
+ await new Promise(resolve => {
659
+ s.client.subscribe({
619
660
  topic: 'hello',
620
661
  qos: 0
621
- }, function (err) {
622
- t.error(err, 'no error')
623
- client.unsubscribe([{
662
+ }, (err) => {
663
+ t.assert.ok(!err, 'no error')
664
+ s.client.unsubscribe([{
624
665
  topic: 'hello',
625
666
  qos: 0
626
- }], function (err) {
627
- t.error(err, 'no error')
667
+ }], (err) => {
668
+ t.assert.ok(!err, 'no error')
669
+ resolve()
628
670
  })
629
671
  })
630
672
  })
631
- connect(setup(broker))
632
673
  })
633
674
 
634
- test('unsubscribe should not call removeSubscriptions when [clean=true]', function (t) {
675
+ test('unsubscribe should not call removeSubscriptions when [clean=true]', async (t) => {
635
676
  t.plan(2)
636
677
 
637
- const broker = aedes()
638
- t.teardown(broker.close.bind(broker))
678
+ const s = await createAndConnect(t, { connect: { clean: true } })
639
679
 
640
- broker.persistence.removeSubscriptions = function (client, subs, cb) {
641
- cb(Error('remove subscription is called'))
680
+ s.broker.persistence.removeSubscriptions = async () => {
681
+ throw new Error('remove subscription is called')
642
682
  }
643
683
 
644
- broker.on('client', function (client) {
645
- client.subscribe({
684
+ await new Promise(resolve => {
685
+ s.client.subscribe({
646
686
  topic: 'hello',
647
687
  qos: 1
648
- }, function (err) {
649
- t.error(err, 'no error')
650
- client.unsubscribe({
688
+ }, (err) => {
689
+ t.assert.ok(!err, 'no error')
690
+ s.client.unsubscribe({
651
691
  unsubscriptions: [{
652
692
  topic: 'hello',
653
693
  qos: 1
654
694
  }],
655
695
  messageId: 42
656
- }, function (err) {
657
- t.error(err, 'no error')
696
+ }, (err) => {
697
+ t.assert.ok(!err, 'no error')
698
+ resolve()
658
699
  })
659
700
  })
660
701
  })
661
- connect(setup(broker), { clean: true })
662
702
  })
663
703
 
664
- test('unsubscribe throws error', function (t) {
704
+ test('unsubscribe throws error', async (t) => {
665
705
  t.plan(2)
666
706
 
667
- const broker = aedes()
668
- t.teardown(broker.close.bind(broker))
707
+ const s = await createAndConnect(t)
669
708
 
670
- broker.on('client', function (client) {
671
- client.subscribe({
709
+ await new Promise(resolve => {
710
+ s.client.subscribe({
672
711
  topic: 'hello',
673
712
  qos: 0
674
- }, function (err) {
675
- t.error(err, 'no error')
676
- broker.unsubscribe = function (topic, func, done) {
713
+ }, (err) => {
714
+ t.assert.ok(!err, 'no error')
715
+ s.broker.unsubscribe = (topic, func, done) => {
677
716
  done(new Error('error'))
678
717
  }
679
- client.unsubscribe({
718
+ s.client.unsubscribe({
680
719
  topic: 'hello',
681
720
  qos: 0
682
- }, function () {
683
- t.pass('throws error')
721
+ }, () => {
722
+ t.assert.ok(true, 'throws error')
723
+ resolve()
684
724
  })
685
725
  })
686
726
  })
687
- connect(setup(broker))
688
727
  })
689
728
 
690
- test('unsubscribe throws error 2', function (t) {
729
+ test('unsubscribe throws error 2', async (t) => {
691
730
  t.plan(2)
692
731
 
693
- const broker = aedes()
694
- t.teardown(broker.close.bind(broker))
732
+ const s = await createAndConnect(t)
695
733
 
696
- broker.on('client', function (client) {
697
- client.subscribe({
734
+ await new Promise(resolve => {
735
+ s.client.subscribe({
698
736
  topic: 'hello',
699
737
  qos: 2
700
- }, function (err) {
701
- t.error(err, 'no error')
702
- broker.persistence.removeSubscriptions = function (client, unsubscriptions, done) {
703
- done(new Error('error'))
738
+ }, (err) => {
739
+ t.assert.ok(!err, 'no error')
740
+ s.broker.persistence.removeSubscriptions = async () => {
741
+ throw new Error('error')
704
742
  }
705
- client.unsubscribe({
743
+ s.client.unsubscribe({
706
744
  unsubscriptions: [{
707
745
  topic: 'hello',
708
746
  qos: 2
709
747
  }],
710
748
  messageId: 42
711
- }, function () {
712
- t.pass('throws error')
749
+ }, () => {
750
+ t.assert.ok(true, 'throws error')
751
+ resolve()
713
752
  })
714
753
  })
715
754
  })
716
- connect(setup(broker))
717
755
  })
718
756
 
719
- test('subscribe a client programmatically multiple topics', function (t) {
757
+ test('subscribe a client programmatically multiple topics', async (t) => {
720
758
  t.plan(3)
721
759
 
722
- const broker = aedes()
723
- t.teardown(broker.close.bind(broker))
760
+ const s = await createAndConnect(t)
724
761
 
725
762
  const expected = {
726
763
  cmd: 'publish',
@@ -732,38 +769,34 @@ test('subscribe a client programmatically multiple topics', function (t) {
732
769
  retain: false
733
770
  }
734
771
 
735
- broker.on('client', function (client) {
736
- client.subscribe([{
772
+ await new Promise(resolve => {
773
+ s.client.subscribe([{
737
774
  topic: 'hello',
738
775
  qos: 0
739
776
  }, {
740
777
  topic: 'aaa',
741
778
  qos: 0
742
- }], function (err) {
743
- t.error(err, 'no error')
744
-
745
- broker.publish({
779
+ }], (err) => {
780
+ t.assert.ok(!err, 'no error')
781
+ s.broker.publish({
746
782
  topic: 'hello',
747
783
  payload: Buffer.from('world'),
748
784
  qos: 0
749
- }, function (err) {
750
- t.error(err, 'no error')
785
+ }, (err) => {
786
+ t.assert.ok(!err, 'no error')
787
+ resolve()
751
788
  })
752
789
  })
753
790
  })
754
791
 
755
- const s = connect(setup(broker))
756
-
757
- s.outStream.once('data', function (packet) {
758
- t.same(packet, expected, 'packet matches')
759
- })
792
+ const packet = await nextPacket(s)
793
+ t.assert.deepEqual(structuredClone(packet), expected, 'packet matches')
760
794
  })
761
795
 
762
- test('subscribe a client programmatically with full packet', function (t) {
796
+ test('subscribe a client programmatically with full packet', async (t) => {
763
797
  t.plan(3)
764
798
 
765
- const broker = aedes()
766
- t.teardown(broker.close.bind(broker))
799
+ const s = await createAndConnect(t)
767
800
 
768
801
  const expected = {
769
802
  cmd: 'publish',
@@ -775,8 +808,8 @@ test('subscribe a client programmatically with full packet', function (t) {
775
808
  retain: false
776
809
  }
777
810
 
778
- broker.on('client', function (client) {
779
- client.subscribe({
811
+ await new Promise(resolve => {
812
+ s.client.subscribe({
780
813
  subscriptions: [{
781
814
  topic: 'hello',
782
815
  qos: 0
@@ -784,131 +817,122 @@ test('subscribe a client programmatically with full packet', function (t) {
784
817
  topic: 'aaa',
785
818
  qos: 0
786
819
  }]
787
- }, function (err) {
788
- t.error(err, 'no error')
820
+ }, (err) => {
821
+ t.assert.ok(!err, 'no error')
789
822
 
790
- broker.publish({
823
+ s.broker.publish({
791
824
  topic: 'hello',
792
825
  payload: Buffer.from('world'),
793
826
  qos: 0
794
- }, function (err) {
795
- t.error(err, 'no error')
827
+ }, (err) => {
828
+ t.assert.ok(!err, 'no error')
829
+ resolve()
796
830
  })
797
831
  })
798
832
  })
799
833
 
800
- const s = connect(setup(broker))
801
-
802
- s.outStream.once('data', function (packet) {
803
- t.same(packet, expected, 'packet matches')
804
- })
834
+ const packet = await nextPacket(s)
835
+ t.assert.deepEqual(structuredClone(packet), expected, 'packet matches')
805
836
  })
806
837
 
807
- test('get message when client connects', function (t) {
838
+ test('get message when client connects', async (t) => {
808
839
  t.plan(2)
809
840
 
810
841
  const client1 = 'gav'
811
- const broker = aedes()
812
- t.teardown(broker.close.bind(broker))
842
+ const client2 = 'friend'
843
+ const s = await createAndConnect(t, { connect: { clientId: client1 } })
813
844
 
814
- broker.on('client', function (client) {
815
- client.subscribe({
845
+ await new Promise(resolve => {
846
+ s.client.subscribe({
816
847
  subscriptions: [{
817
848
  topic: '$SYS/+/new/clients',
818
849
  qos: 0
819
850
  }]
820
- }, function (err) {
821
- t.error(err, 'no error')
851
+ }, (err) => {
852
+ t.assert.ok(!err, 'no error')
853
+ resolve()
822
854
  })
823
855
  })
824
856
 
825
- const s1 = connect(setup(broker), { clientId: client1 })
857
+ const s2 = setup(s.broker)
858
+ await connect(s2, { connect: { clientId: client2 } })
826
859
 
827
- s1.outStream.on('data', function (packet) {
828
- t.equal(client1, packet.payload.toString())
829
- })
860
+ const packet = await nextPacket(s)
861
+ t.assert.equal(client2, packet.payload.toString())
830
862
  })
831
863
 
832
- test('get message when client disconnects', function (t) {
864
+ test('get message when client disconnects', async (t) => {
833
865
  t.plan(2)
834
866
 
835
867
  const client1 = 'gav'
836
868
  const client2 = 'friend'
837
- const broker = aedes()
838
- t.teardown(broker.close.bind(broker))
839
-
840
- broker.on('client', function (client) {
841
- if (client.id === client1) {
842
- client.subscribe({
843
- subscriptions: [{
844
- topic: '$SYS/+/disconnect/clients',
845
- qos: 0
846
- }]
847
- }, function (err) {
848
- t.error(err, 'no error')
849
- })
850
- } else {
851
- client.close()
852
- }
869
+ const s = await createAndConnect(t, { connect: { clientId: client1 } })
870
+
871
+ await new Promise(resolve => {
872
+ s.client.subscribe({
873
+ subscriptions: [{
874
+ topic: '$SYS/+/disconnect/clients',
875
+ qos: 0
876
+ }]
877
+ }, (err) => {
878
+ t.assert.ok(!err, 'no error')
879
+ resolve()
880
+ })
853
881
  })
854
882
 
855
- const s1 = connect(setup(broker), { clientId: client1 })
856
- connect(setup(broker), { clientId: client2 })
883
+ const s2 = setup(s.broker)
884
+ await connect(s2, { connect: { clientId: client2 } })
885
+ s2.client.close()
857
886
 
858
- s1.outStream.on('data', function (packet) {
859
- t.equal(client2, packet.payload.toString())
860
- })
887
+ const packet = await nextPacket(s)
888
+ t.assert.equal(client2, packet.payload.toString())
861
889
  })
862
890
 
863
- test('should not receive a message on negated subscription', function (t) {
864
- t.plan(4)
891
+ test('should not receive a message on negated subscription', async (t) => {
892
+ t.plan(5)
865
893
 
866
- const broker = aedes()
867
- t.teardown(broker.close.bind(broker))
894
+ const s = await createAndConnect(t)
868
895
 
869
- broker.authorizeSubscribe = function (client, sub, callback) {
896
+ s.broker.authorizeSubscribe = (client, sub, callback) => {
870
897
  callback(null, null)
871
898
  }
872
899
 
873
- broker.on('client', function (client) {
874
- broker.publish({
900
+ await new Promise(resolve => {
901
+ s.broker.publish({
875
902
  topic: 'hello',
876
903
  payload: Buffer.from('world'),
877
904
  qos: 0,
878
905
  retain: true
879
- }, function (err) {
880
- t.error(err, 'no error')
881
- client.subscribe([{
906
+ }, (err) => {
907
+ t.assert.ok(!err, 'no error')
908
+ s.client.subscribe([{
882
909
  topic: 'hello',
883
910
  qos: 0
884
911
  },
885
912
  {
886
913
  topic: 'hello',
887
914
  qos: 0
888
- }], function (err) {
889
- t.error(err, 'no error')
915
+ }], (err) => {
916
+ t.assert.ok(!err, 'no error')
917
+ resolve()
890
918
  })
891
919
  })
892
- })
893
920
 
894
- broker.on('subscribe', function (subs) {
895
- t.pass(subs.length, 1, 'Should dedupe subs')
896
- t.pass(subs[0].qos, 128, 'Qos should be 128 (Fail)')
921
+ s.broker.on('subscribe', subs => {
922
+ t.assert.equal(subs.length, 1, 'Should dedupe subs')
923
+ t.assert.equal(subs[0].qos, 128, 'Qos should be 128 (Fail)')
924
+ })
897
925
  })
898
926
 
899
- const s = connect(setup(broker))
900
- s.outStream.once('data', function (packet) {
901
- t.fail('Packet should not be received')
902
- })
927
+ const packet = await nextPacketWithTimeOut(s, 10)
928
+ t.assert.equal(packet, null, 'Packet should not be received')
903
929
  })
904
930
 
905
- test('programmatically add custom subscribe', function (t) {
931
+ test('programmatically add custom subscribe', async (t) => {
906
932
  t.plan(6)
907
933
 
908
- const broker = aedes({ clientId: 'my-client-xyz-7' })
909
- t.teardown(broker.close.bind(broker))
934
+ const s = await createAndConnect(t, { connect: { clientId: 'my-client-xyz-7' } })
910
935
 
911
- const s = connect(setup(broker), { clientId: 'my-client-xyz-7' })
912
936
  const expected = {
913
937
  cmd: 'publish',
914
938
  topic: 'hello',
@@ -927,36 +951,39 @@ test('programmatically add custom subscribe', function (t) {
927
951
  dup: false,
928
952
  clientId: 'my-client-xyz-7'
929
953
  }
930
- subscribe(t, s, 'hello', 0, function () {
931
- broker.subscribe('hello', deliver, function () {
932
- t.pass('subscribed')
933
- })
934
- s.outStream.on('data', function (packet) {
935
- t.same(packet, expected, 'packet matches')
936
- })
937
- s.inStream.write({
938
- cmd: 'publish',
939
- topic: 'hello',
940
- payload: 'world',
941
- qos: 0,
942
- messageId: 42
943
- })
944
- })
954
+
945
955
  function deliver (packet, cb) {
946
956
  deliverP.brokerId = s.broker.id
947
957
  deliverP.brokerCounter = s.broker.counter
948
- t.same(packet, deliverP, 'packet matches')
958
+ t.assert.deepEqual(structuredClone(packet), deliverP, 'packet matches')
949
959
  cb()
950
960
  }
961
+
962
+ await subscribe(t, s, 'hello', 0)
963
+ await new Promise(resolve => {
964
+ s.broker.subscribe('hello', deliver, () => {
965
+ t.assert.ok(true, 'subscribed')
966
+ resolve()
967
+ })
968
+ })
969
+
970
+ s.inStream.write({
971
+ cmd: 'publish',
972
+ topic: 'hello',
973
+ payload: 'world',
974
+ qos: 0,
975
+ messageId: 42
976
+ })
977
+
978
+ const packet = await nextPacket(s)
979
+ t.assert.deepEqual(structuredClone(packet), expected, 'packet matches')
951
980
  })
952
981
 
953
- test('custom function in broker.subscribe', function (t) {
954
- t.plan(4)
982
+ test('custom function in broker.subscribe', async (t) => {
983
+ t.plan(5)
955
984
 
956
- const broker = aedes()
957
- t.teardown(broker.close.bind(broker))
985
+ const s = await createAndConnect(t, { connect: { clientId: 'my-client-xyz-6' } })
958
986
 
959
- const s = setup(broker)
960
987
  const expected = {
961
988
  cmd: 'publish',
962
989
  topic: 'hello',
@@ -967,44 +994,49 @@ test('custom function in broker.subscribe', function (t) {
967
994
  messageId: undefined,
968
995
  clientId: 'my-client-xyz-6'
969
996
  }
970
- connect(s, { clientId: 'my-client-xyz-6' }, function () {
971
- broker.subscribe('hello', deliver, function () {
972
- t.pass('subscribed')
973
- })
974
- s.inStream.write({
975
- cmd: 'publish',
976
- topic: 'hello',
977
- payload: 'world',
978
- qos: 1,
979
- messageId: 42
980
- })
981
- })
982
- broker.on('publish', function (packet, client) {
983
- if (client) {
984
- t.equal(packet.topic, 'hello')
985
- t.equal(packet.messageId, 42)
986
- }
987
- })
997
+
988
998
  function deliver (packet, cb) {
989
999
  expected.brokerId = s.broker.id
990
1000
  expected.brokerCounter = s.broker.counter
991
- t.same(packet, expected, 'packet matches')
1001
+ t.assert.deepEqual(structuredClone(packet), expected, 'packet matches')
992
1002
  cb()
993
1003
  }
1004
+
1005
+ await new Promise(resolve => {
1006
+ s.broker.subscribe('hello', deliver, () => {
1007
+ t.assert.ok(true, 'subscribed')
1008
+ resolve()
1009
+ })
1010
+ })
1011
+ s.inStream.write({
1012
+ cmd: 'publish',
1013
+ topic: 'hello',
1014
+ payload: 'world',
1015
+ qos: 1,
1016
+ messageId: 42
1017
+ })
1018
+
1019
+ const [packet, client] = await once(s.broker, 'publish')
1020
+ t.assert.ok(client, 'client exists')
1021
+ t.assert.equal(packet.topic, 'hello')
1022
+ t.assert.equal(packet.messageId, 42)
994
1023
  })
995
1024
 
996
- test('custom function in broker.unsubscribe', function (t) {
997
- t.plan(3)
1025
+ test('custom function in broker.unsubscribe', async (t) => {
1026
+ t.plan(4)
1027
+
1028
+ const s = await createAndConnect(t)
998
1029
 
999
- const broker = aedes()
1000
- t.teardown(broker.close.bind(broker))
1030
+ function deliver (packet, cb) {
1031
+ t.assert.fail('should not be called')
1032
+ cb()
1033
+ }
1001
1034
 
1002
- const s = noError(setup(broker))
1003
- connect(s, {}, function () {
1004
- broker.subscribe('hello', deliver, function () {
1005
- t.pass('subscribed')
1006
- broker.unsubscribe('hello', deliver, function () {
1007
- t.pass('unsubscribe')
1035
+ await new Promise(resolve => {
1036
+ s.broker.subscribe('hello', deliver, () => {
1037
+ t.assert.ok(true, 'subscribed')
1038
+ s.broker.unsubscribe('hello', deliver, () => {
1039
+ t.assert.ok(true, 'unsubscribe')
1008
1040
  s.inStream.write({
1009
1041
  cmd: 'publish',
1010
1042
  topic: 'hello',
@@ -1012,16 +1044,11 @@ test('custom function in broker.unsubscribe', function (t) {
1012
1044
  qos: 1,
1013
1045
  messageId: 42
1014
1046
  })
1047
+ resolve()
1015
1048
  })
1016
1049
  })
1017
1050
  })
1018
- broker.on('publish', function (packet, client) {
1019
- if (client) {
1020
- t.pass('publish')
1021
- }
1022
- })
1023
- function deliver (packet, cb) {
1024
- t.fail('should not be called')
1025
- cb()
1026
- }
1051
+ const [packet, client] = await once(s.broker, 'publish')
1052
+ t.assert.ok(client, 'client exists')
1053
+ t.assert.equal(packet.messageId, 42)
1027
1054
  })