aedes 0.51.2 → 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.
- package/.github/actions/sticky-pr-comment/action.yml +55 -0
- package/.github/workflows/benchmark-compare-serial.yml +60 -0
- package/.github/workflows/ci.yml +12 -17
- package/.release-it.json +18 -0
- package/.taprc +15 -6
- package/README.md +6 -4
- package/aedes.d.ts +0 -6
- package/aedes.js +270 -238
- package/benchmarks/README.md +33 -0
- package/benchmarks/pingpong.js +94 -25
- package/benchmarks/receiver.js +77 -0
- package/benchmarks/report.js +150 -0
- package/benchmarks/runBenchmarks.js +118 -0
- package/benchmarks/sender.js +86 -0
- package/benchmarks/server.js +19 -18
- package/checkVersion.js +20 -0
- package/docs/Aedes.md +66 -8
- package/docs/Client.md +3 -4
- package/docs/Examples.md +39 -22
- package/docs/MIGRATION.md +50 -0
- package/eslint.config.js +8 -0
- package/example.js +51 -40
- package/examples/clusters/index.js +28 -23
- package/examples/clusters/package.json +10 -6
- package/lib/client.js +405 -306
- package/lib/handlers/connect.js +42 -38
- package/lib/handlers/index.js +9 -11
- package/lib/handlers/ping.js +2 -3
- package/lib/handlers/puback.js +5 -5
- package/lib/handlers/publish.js +29 -14
- package/lib/handlers/pubrec.js +9 -17
- package/lib/handlers/pubrel.js +34 -25
- package/lib/handlers/subscribe.js +54 -43
- package/lib/handlers/unsubscribe.js +16 -19
- package/lib/qos-packet.js +14 -17
- package/lib/utils.js +5 -12
- package/lib/write.js +4 -5
- package/package.json +134 -136
- package/test/auth.js +468 -804
- package/test/basic.js +613 -575
- package/test/bridge.js +44 -40
- package/test/client-pub-sub.js +531 -504
- package/test/close_socket_by_other_party.js +137 -102
- package/test/connect.js +487 -484
- package/test/drain-timeout.js +593 -0
- package/test/drain-toxiproxy.js +620 -0
- package/test/events.js +174 -144
- package/test/helper.js +351 -73
- package/test/keep-alive.js +40 -67
- package/test/meta.js +257 -210
- package/test/not-blocking.js +93 -197
- package/test/qos1.js +464 -554
- package/test/qos2.js +308 -393
- package/test/regr-21.js +39 -21
- package/test/require.cjs +22 -0
- package/test/retain.js +349 -398
- package/test/topics.js +176 -183
- package/test/types/aedes.test-d.ts +4 -8
- package/test/will.js +310 -428
- package/types/instance.d.ts +40 -35
- package/types/packet.d.ts +10 -10
- package/.coveralls.yml +0 -1
- package/benchmarks/bombing.js +0 -34
- package/benchmarks/bombingQoS1.js +0 -36
- package/benchmarks/throughputCounter.js +0 -23
- package/benchmarks/throughputCounterQoS1.js +0 -33
- package/types/.eslintrc.json +0 -47
package/test/will.js
CHANGED
|
@@ -1,134 +1,127 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { test } from 'node:test'
|
|
2
|
+
import { once } from 'node:events'
|
|
3
|
+
import {
|
|
4
|
+
connect,
|
|
5
|
+
createAndConnect,
|
|
6
|
+
delay,
|
|
7
|
+
setup,
|
|
8
|
+
} from './helper.js'
|
|
9
|
+
import memory from 'aedes-persistence'
|
|
10
|
+
import { Aedes } from '../aedes.js'
|
|
11
|
+
|
|
12
|
+
async function memorySetup (opts) {
|
|
13
|
+
const persistence = memory()
|
|
14
|
+
await persistence.setup(opts)
|
|
15
|
+
return persistence
|
|
16
|
+
}
|
|
8
17
|
|
|
9
|
-
function
|
|
10
|
-
opts = opts || {}
|
|
18
|
+
function addWillToOpts (opts = {}) {
|
|
11
19
|
opts.will = {
|
|
12
20
|
topic: 'mywill',
|
|
13
21
|
payload: Buffer.from('last will'),
|
|
14
22
|
qos: 0,
|
|
15
23
|
retain: false
|
|
16
24
|
}
|
|
17
|
-
|
|
18
|
-
return connect(s, opts, connected)
|
|
25
|
+
return opts
|
|
19
26
|
}
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
async function oneWillFromBroker (broker) {
|
|
29
|
+
let received
|
|
30
|
+
const packet = await new Promise(resolve => {
|
|
31
|
+
received = willsFromBroker(broker, resolve)
|
|
32
|
+
})
|
|
33
|
+
return { packet, received }
|
|
34
|
+
}
|
|
23
35
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
function () {
|
|
29
|
-
s.conn.destroy()
|
|
30
|
-
}
|
|
31
|
-
)
|
|
32
|
-
t.teardown(s.broker.close.bind(s.broker))
|
|
33
|
-
|
|
34
|
-
s.broker.mq.on('mywill', function (packet, cb) {
|
|
35
|
-
t.equal(packet.topic, opts.will.topic, 'topic matches')
|
|
36
|
-
t.same(packet.payload, opts.will.payload, 'payload matches')
|
|
37
|
-
t.equal(packet.qos, opts.will.qos, 'qos matches')
|
|
38
|
-
t.equal(packet.retain, opts.will.retain, 'retain matches')
|
|
36
|
+
function willsFromBroker (broker, resolve) {
|
|
37
|
+
const received = []
|
|
38
|
+
broker.mq.on('mywill', (packet, cb) => {
|
|
39
|
+
received.push(packet)
|
|
39
40
|
cb()
|
|
41
|
+
if (resolve) {
|
|
42
|
+
resolve(packet)
|
|
43
|
+
resolve = null
|
|
44
|
+
}
|
|
40
45
|
})
|
|
41
|
-
|
|
46
|
+
return received
|
|
47
|
+
}
|
|
42
48
|
|
|
43
|
-
test('
|
|
49
|
+
test('delivers a will', async (t) => {
|
|
44
50
|
t.plan(4)
|
|
45
51
|
|
|
46
|
-
const opts = {}
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
broker.on('client', function (client) {
|
|
51
|
-
client.close()
|
|
52
|
-
client.close()
|
|
53
|
-
})
|
|
52
|
+
const opts = addWillToOpts({})
|
|
53
|
+
const s = await createAndConnect(t, { connect: opts })
|
|
54
|
+
s.conn.destroy()
|
|
54
55
|
|
|
55
|
-
broker
|
|
56
|
+
const { packet } = await oneWillFromBroker(s.broker)
|
|
57
|
+
t.assert.equal(packet.topic, opts.will.topic, 'topic matches')
|
|
58
|
+
t.assert.deepEqual(packet.payload, opts.will.payload, 'payload matches')
|
|
59
|
+
t.assert.equal(packet.qos, opts.will.qos, 'qos matches')
|
|
60
|
+
t.assert.equal(packet.retain, opts.will.retain, 'retain matches')
|
|
61
|
+
})
|
|
56
62
|
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
test('calling close two times should not deliver two wills', async (t) => {
|
|
64
|
+
t.plan(5)
|
|
59
65
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
const opts = addWillToOpts({})
|
|
67
|
+
const s = await createAndConnect(t, { connect: opts })
|
|
68
|
+
|
|
69
|
+
const received = willsFromBroker(s.broker)
|
|
70
|
+
s.client.close()
|
|
71
|
+
s.client.close()
|
|
72
|
+
await delay(10) // give Aedes some time to process, potentially twice
|
|
73
|
+
t.assert.equal(received.length, 1, 'only one will has been delivered')
|
|
74
|
+
const packet = received[0]
|
|
75
|
+
t.assert.equal(packet.topic, opts.will.topic, 'topic matches')
|
|
76
|
+
t.assert.deepEqual(packet.payload, opts.will.payload, 'payload matches')
|
|
77
|
+
t.assert.equal(packet.qos, opts.will.qos, 'qos matches')
|
|
78
|
+
t.assert.equal(packet.retain, opts.will.retain, 'retain matches')
|
|
72
79
|
})
|
|
73
80
|
|
|
74
|
-
test('delivers old will in case of a crash',
|
|
81
|
+
test('delivers old will in case of a crash', async (t) => {
|
|
75
82
|
t.plan(8)
|
|
76
83
|
|
|
77
|
-
const persistence =
|
|
84
|
+
const persistence = await memorySetup({ id: 'anotherBroker' })
|
|
78
85
|
const will = {
|
|
79
86
|
topic: 'mywill',
|
|
80
87
|
payload: Buffer.from('last will'),
|
|
81
88
|
qos: 0,
|
|
82
89
|
retain: false
|
|
83
90
|
}
|
|
91
|
+
await persistence.putWill({ id: 'myClientId42' }, will)
|
|
84
92
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
let authorized = false
|
|
95
|
-
const interval = 10 // ms, so that the will check happens fast!
|
|
96
|
-
const broker = aedes({
|
|
97
|
-
persistence,
|
|
98
|
-
heartbeatInterval: interval,
|
|
99
|
-
authorizePublish: function (client, packet, callback) {
|
|
100
|
-
t.strictSame(client, null, 'client must be null')
|
|
101
|
-
authorized = true
|
|
102
|
-
callback(null)
|
|
103
|
-
}
|
|
104
|
-
})
|
|
105
|
-
t.teardown(broker.close.bind(broker))
|
|
106
|
-
|
|
107
|
-
const start = Date.now()
|
|
108
|
-
|
|
109
|
-
broker.mq.on('mywill', check)
|
|
110
|
-
|
|
111
|
-
function check (packet, cb) {
|
|
112
|
-
broker.mq.removeListener('mywill', check, function () {
|
|
113
|
-
broker.mq.on('mywill', function (packet) {
|
|
114
|
-
t.fail('the will must be delivered only once')
|
|
115
|
-
})
|
|
116
|
-
})
|
|
117
|
-
t.ok(Date.now() - start >= 3 * interval, 'the will needs to be emitted after 3 heartbeats')
|
|
118
|
-
t.equal(packet.topic, will.topic, 'topic matches')
|
|
119
|
-
t.same(packet.payload, will.payload, 'payload matches')
|
|
120
|
-
t.equal(packet.qos, will.qos, 'qos matches')
|
|
121
|
-
t.equal(packet.retain, will.retain, 'retain matches')
|
|
122
|
-
t.equal(authorized, true, 'authorization called')
|
|
123
|
-
cb()
|
|
93
|
+
let authorized = false
|
|
94
|
+
const interval = 10 // ms, so that the will check happens fast!
|
|
95
|
+
const broker = await Aedes.createBroker({
|
|
96
|
+
persistence,
|
|
97
|
+
heartbeatInterval: interval,
|
|
98
|
+
authorizePublish: (client, packet, callback) => {
|
|
99
|
+
t.assert.equal(client, null, 'client must be null')
|
|
100
|
+
authorized = true
|
|
101
|
+
callback(null)
|
|
124
102
|
}
|
|
125
103
|
})
|
|
104
|
+
|
|
105
|
+
t.after(() => broker.close())
|
|
106
|
+
|
|
107
|
+
const start = Date.now()
|
|
108
|
+
|
|
109
|
+
const { packet, received } = await oneWillFromBroker(broker)
|
|
110
|
+
t.assert.ok(Date.now() - start >= 3 * interval, 'the will needs to be emitted after 3 heartbeats')
|
|
111
|
+
t.assert.equal(packet.topic, will.topic, 'topic matches')
|
|
112
|
+
t.assert.deepEqual(packet.payload, will.payload, 'payload matches')
|
|
113
|
+
t.assert.equal(packet.qos, will.qos, 'qos matches')
|
|
114
|
+
t.assert.equal(packet.retain, will.retain, 'retain matches')
|
|
115
|
+
t.assert.equal(authorized, true, 'authorization called')
|
|
116
|
+
await delay(10) // give Aedes some time to process, potentially twice
|
|
117
|
+
t.assert.equal(received.length, 1, 'only one will has been delivered')
|
|
126
118
|
})
|
|
127
119
|
|
|
128
|
-
test('deliver old will without authorization in case of a crash',
|
|
129
|
-
t.plan(
|
|
120
|
+
test('deliver old will without authorization in case of a crash', async (t) => {
|
|
121
|
+
t.plan(1)
|
|
122
|
+
|
|
123
|
+
const persistence = await memorySetup({ id: 'anotherBroker' })
|
|
130
124
|
|
|
131
|
-
const persistence = memory()
|
|
132
125
|
const will = {
|
|
133
126
|
topic: 'mywill',
|
|
134
127
|
payload: Buffer.from('last will'),
|
|
@@ -136,346 +129,257 @@ test('deliver old will without authorization in case of a crash', function (t) {
|
|
|
136
129
|
retain: false
|
|
137
130
|
}
|
|
138
131
|
|
|
139
|
-
persistence.
|
|
140
|
-
id: 'anotherBroker'
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
persistence.putWill({
|
|
144
|
-
id: 'myClientId42'
|
|
145
|
-
}, will, function (err) {
|
|
146
|
-
t.error(err, 'no error')
|
|
147
|
-
|
|
148
|
-
const interval = 10 // ms, so that the will check happens fast!
|
|
149
|
-
const broker = aedes({
|
|
150
|
-
persistence,
|
|
151
|
-
heartbeatInterval: interval,
|
|
152
|
-
authorizePublish: function (client, packet, callback) {
|
|
153
|
-
t.strictSame(client, null, 'client must be null')
|
|
154
|
-
callback(new Error())
|
|
155
|
-
}
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
t.teardown(broker.close.bind(broker))
|
|
132
|
+
await persistence.putWill({ id: 'myClientId42' }, will)
|
|
159
133
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
134
|
+
const interval = 10 // ms, so that the will check happens fast!
|
|
135
|
+
const broker = await Aedes.createBroker({
|
|
136
|
+
persistence,
|
|
137
|
+
heartbeatInterval: interval,
|
|
138
|
+
authorizePublish: function (client, packet, callback) {
|
|
139
|
+
t.assert.equal(client, null, 'client must be null')
|
|
140
|
+
callback(new Error())
|
|
165
141
|
}
|
|
166
142
|
})
|
|
143
|
+
t.after(() => broker.close())
|
|
144
|
+
const received = willsFromBroker(broker)
|
|
145
|
+
await delay(10) // give Aedes some time to process to ensure that no will is send
|
|
146
|
+
t.assert.equal(received.length, 0, 'no will has been delivered')
|
|
167
147
|
})
|
|
168
148
|
|
|
169
|
-
test('delete old broker',
|
|
149
|
+
test('delete old broker', async (t) => {
|
|
170
150
|
t.plan(1)
|
|
171
151
|
|
|
172
|
-
const clock = Faketimers.install()
|
|
173
|
-
|
|
174
152
|
const heartbeatInterval = 100
|
|
175
|
-
const broker =
|
|
153
|
+
const broker = await Aedes.createBroker({
|
|
176
154
|
heartbeatInterval
|
|
177
155
|
})
|
|
178
|
-
t.
|
|
156
|
+
t.after(() => broker.close())
|
|
179
157
|
|
|
180
158
|
const brokerId = 'dummyBroker'
|
|
181
159
|
|
|
182
160
|
broker.brokers[brokerId] = Date.now() - heartbeatInterval * 3.5
|
|
183
161
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}, heartbeatInterval * 4)
|
|
187
|
-
|
|
188
|
-
clock.tick(heartbeatInterval * 4)
|
|
189
|
-
|
|
190
|
-
clock.uninstall()
|
|
162
|
+
await delay(heartbeatInterval * 4)
|
|
163
|
+
t.assert.equal(broker.brokers[brokerId], undefined, 'Broker deleted')
|
|
191
164
|
})
|
|
192
165
|
|
|
193
|
-
test('store the will in the persistence',
|
|
194
|
-
t.plan(
|
|
166
|
+
test('store the will in the persistence', async (t) => {
|
|
167
|
+
t.plan(4)
|
|
195
168
|
|
|
196
|
-
const opts = {
|
|
169
|
+
const opts = addWillToOpts({
|
|
197
170
|
clientId: 'abcde'
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// willConnect populates opts with a will
|
|
201
|
-
const s = willConnect(setup(), opts)
|
|
202
|
-
t.teardown(s.broker.close.bind(s.broker))
|
|
203
|
-
|
|
204
|
-
s.broker.on('client', function () {
|
|
205
|
-
// this is connack
|
|
206
|
-
s.broker.persistence.getWill({
|
|
207
|
-
id: opts.clientId
|
|
208
|
-
}, function (err, packet) {
|
|
209
|
-
t.error(err, 'no error')
|
|
210
|
-
t.same(packet.topic, opts.will.topic, 'will topic matches')
|
|
211
|
-
t.same(packet.payload, opts.will.payload, 'will payload matches')
|
|
212
|
-
t.same(packet.qos, opts.will.qos, 'will qos matches')
|
|
213
|
-
t.same(packet.retain, opts.will.retain, 'will retain matches')
|
|
214
|
-
})
|
|
215
171
|
})
|
|
216
|
-
})
|
|
217
172
|
|
|
218
|
-
|
|
219
|
-
t.plan(2)
|
|
173
|
+
const s = await createAndConnect(t, { connect: opts })
|
|
220
174
|
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
175
|
+
const packet = await s.broker.persistence.getWill({ id: opts.clientId })
|
|
176
|
+
t.assert.deepEqual(structuredClone(packet).topic, opts.will.topic, 'will topic matches')
|
|
177
|
+
t.assert.deepEqual(structuredClone(packet).payload, opts.will.payload, 'will payload matches')
|
|
178
|
+
t.assert.deepEqual(structuredClone(packet).qos, opts.will.qos, 'will qos matches')
|
|
179
|
+
t.assert.deepEqual(structuredClone(packet).retain, opts.will.retain, 'will retain matches')
|
|
180
|
+
})
|
|
224
181
|
|
|
225
|
-
|
|
226
|
-
t.
|
|
182
|
+
test('delete the will in the persistence after publish', async (t) => {
|
|
183
|
+
t.plan(1)
|
|
227
184
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
client.close()
|
|
231
|
-
})
|
|
185
|
+
const opts = addWillToOpts({
|
|
186
|
+
clientId: 'abcde'
|
|
232
187
|
})
|
|
233
188
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
// willConnect populates opts with a will
|
|
237
|
-
willConnect(setup(broker), opts)
|
|
189
|
+
const s = await createAndConnect(t, { connect: opts })
|
|
238
190
|
|
|
239
|
-
|
|
240
|
-
broker
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
t.notOk(p, 'packet is empty')
|
|
246
|
-
})
|
|
247
|
-
})
|
|
248
|
-
cb()
|
|
249
|
-
}
|
|
191
|
+
await new Promise(resolve => {
|
|
192
|
+
willsFromBroker(s.broker, resolve) // setup the listener
|
|
193
|
+
s.client.close()
|
|
194
|
+
})
|
|
195
|
+
const packet = await s.broker.persistence.getWill({ id: opts.clientId })
|
|
196
|
+
t.assert.ok(!packet, 'packet is empty')
|
|
250
197
|
})
|
|
251
198
|
|
|
252
|
-
test('delivers a will with authorization',
|
|
253
|
-
t.plan(
|
|
199
|
+
test('delivers a will with authorization', async (t) => {
|
|
200
|
+
t.plan(7)
|
|
254
201
|
|
|
255
202
|
let authorized = false
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const s =
|
|
259
|
-
|
|
203
|
+
|
|
204
|
+
const opts = addWillToOpts({})
|
|
205
|
+
const s = await createAndConnect(t, {
|
|
206
|
+
broker: {
|
|
260
207
|
authorizePublish: (client, packet, callback) => {
|
|
261
208
|
authorized = true
|
|
262
209
|
callback(null)
|
|
263
210
|
}
|
|
264
|
-
}
|
|
265
|
-
opts
|
|
266
|
-
function () {
|
|
267
|
-
s.conn.destroy()
|
|
268
|
-
}
|
|
269
|
-
)
|
|
270
|
-
t.teardown(s.broker.close.bind(s.broker))
|
|
271
|
-
|
|
272
|
-
s.broker.on('clientDisconnect', function (client) {
|
|
273
|
-
t.equal(client.connected, false)
|
|
211
|
+
},
|
|
212
|
+
connect: opts
|
|
274
213
|
})
|
|
275
214
|
|
|
276
|
-
s.broker
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
215
|
+
const received = willsFromBroker(s.broker)
|
|
216
|
+
s.conn.destroy()
|
|
217
|
+
|
|
218
|
+
const [client] = await once(s.broker, 'clientDisconnect')
|
|
219
|
+
t.assert.equal(client.connected, false)
|
|
220
|
+
t.assert.equal(received.length, 1, 'only one will has been delivered')
|
|
221
|
+
const packet = received[0]
|
|
222
|
+
t.assert.equal(packet.topic, opts.will.topic, 'topic matches')
|
|
223
|
+
t.assert.deepEqual(packet.payload, opts.will.payload, 'payload matches')
|
|
224
|
+
t.assert.equal(packet.qos, opts.will.qos, 'qos matches')
|
|
225
|
+
t.assert.equal(packet.retain, opts.will.retain, 'retain matches')
|
|
226
|
+
t.assert.equal(authorized, true, 'authorization called')
|
|
284
227
|
})
|
|
285
228
|
|
|
286
|
-
test('delivers a will waits for authorization',
|
|
287
|
-
t.plan(
|
|
229
|
+
test('delivers a will waits for authorization', async (t) => {
|
|
230
|
+
t.plan(7)
|
|
288
231
|
|
|
289
232
|
let authorized = false
|
|
290
|
-
const opts = {}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
setup(aedes({
|
|
233
|
+
const opts = addWillToOpts({})
|
|
234
|
+
const s = await createAndConnect(t, {
|
|
235
|
+
broker: {
|
|
294
236
|
authorizePublish: (client, packet, callback) => {
|
|
295
237
|
authorized = true
|
|
296
238
|
setImmediate(() => { callback(null) })
|
|
297
239
|
}
|
|
298
|
-
}
|
|
299
|
-
opts
|
|
300
|
-
function () {
|
|
301
|
-
s.conn.destroy()
|
|
302
|
-
}
|
|
303
|
-
)
|
|
304
|
-
t.teardown(s.broker.close.bind(s.broker))
|
|
305
|
-
|
|
306
|
-
s.broker.on('clientDisconnect', function () {
|
|
307
|
-
t.pass('client is disconnected')
|
|
308
|
-
})
|
|
309
|
-
|
|
310
|
-
s.broker.mq.on('mywill', function (packet, cb) {
|
|
311
|
-
t.equal(packet.topic, opts.will.topic, 'topic matches')
|
|
312
|
-
t.same(packet.payload, opts.will.payload, 'payload matches')
|
|
313
|
-
t.equal(packet.qos, opts.will.qos, 'qos matches')
|
|
314
|
-
t.equal(packet.retain, opts.will.retain, 'retain matches')
|
|
315
|
-
t.equal(authorized, true, 'authorization called')
|
|
316
|
-
cb()
|
|
240
|
+
},
|
|
241
|
+
connect: opts
|
|
317
242
|
})
|
|
243
|
+
const received = willsFromBroker(s.broker)
|
|
244
|
+
s.conn.destroy()
|
|
245
|
+
|
|
246
|
+
const [client] = await once(s.broker, 'clientDisconnect')
|
|
247
|
+
t.assert.equal(client.connected, false)
|
|
248
|
+
t.assert.equal(authorized, true, 'authorization called')
|
|
249
|
+
await delay(10) // give Aedes time to complete authorizePublish
|
|
250
|
+
t.assert.equal(received.length, 1, 'only one will has been delivered')
|
|
251
|
+
const packet = received[0]
|
|
252
|
+
t.assert.equal(packet.topic, opts.will.topic, 'topic matches')
|
|
253
|
+
t.assert.deepEqual(structuredClone(packet).payload, opts.will.payload, 'payload matches')
|
|
254
|
+
t.assert.equal(packet.qos, opts.will.qos, 'qos matches')
|
|
255
|
+
t.assert.equal(packet.retain, opts.will.retain, 'retain matches')
|
|
318
256
|
})
|
|
319
257
|
|
|
320
|
-
test('does not deliver a will without authorization',
|
|
321
|
-
t.plan(
|
|
258
|
+
test('does not deliver a will without authorization', async (t) => {
|
|
259
|
+
t.plan(2)
|
|
322
260
|
|
|
323
261
|
let authorized = false
|
|
324
|
-
const opts = {}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
authorizePublish: (username, packet, callback) => {
|
|
262
|
+
const opts = addWillToOpts({})
|
|
263
|
+
const s = await createAndConnect(t, {
|
|
264
|
+
broker: {
|
|
265
|
+
authorizePublish: (client, packet, callback) => {
|
|
329
266
|
authorized = true
|
|
330
267
|
callback(new Error())
|
|
331
268
|
}
|
|
332
|
-
}
|
|
333
|
-
opts
|
|
334
|
-
function () {
|
|
335
|
-
s.conn.destroy()
|
|
336
|
-
}
|
|
337
|
-
)
|
|
338
|
-
t.teardown(s.broker.close.bind(s.broker))
|
|
339
|
-
|
|
340
|
-
s.broker.on('clientDisconnect', function () {
|
|
341
|
-
t.equal(authorized, true, 'authorization called')
|
|
269
|
+
},
|
|
270
|
+
connect: opts
|
|
342
271
|
})
|
|
272
|
+
const received = willsFromBroker(s.broker)
|
|
273
|
+
s.conn.destroy()
|
|
343
274
|
|
|
344
|
-
s.broker
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
275
|
+
await once(s.broker, 'clientDisconnect')
|
|
276
|
+
t.assert.equal(authorized, true, 'authorization called')
|
|
277
|
+
await delay(10) // give Aedes time to complete authorizePublish
|
|
278
|
+
t.assert.equal(received.length, 0, 'received no will without authorization')
|
|
348
279
|
})
|
|
349
280
|
|
|
350
|
-
test('does not deliver a will without authentication',
|
|
351
|
-
t.plan(
|
|
281
|
+
test('does not deliver a will without authentication', async (t) => {
|
|
282
|
+
t.plan(2)
|
|
352
283
|
|
|
353
284
|
let authenticated = false
|
|
354
|
-
const opts = {}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
setup(aedes({
|
|
285
|
+
const opts = addWillToOpts({})
|
|
286
|
+
const s = await createAndConnect(t, {
|
|
287
|
+
broker: {
|
|
358
288
|
authenticate: (client, username, password, callback) => {
|
|
359
289
|
authenticated = true
|
|
360
290
|
callback(new Error(), false)
|
|
361
291
|
}
|
|
362
|
-
}
|
|
363
|
-
opts
|
|
364
|
-
|
|
365
|
-
t.teardown(s.broker.close.bind(s.broker))
|
|
366
|
-
|
|
367
|
-
s.broker.on('clientError', function () {
|
|
368
|
-
t.equal(authenticated, true, 'authentication called')
|
|
369
|
-
t.end()
|
|
370
|
-
})
|
|
371
|
-
|
|
372
|
-
s.broker.mq.on('mywill', function (packet, cb) {
|
|
373
|
-
t.fail('received will without authentication')
|
|
374
|
-
cb()
|
|
292
|
+
},
|
|
293
|
+
connect: opts,
|
|
294
|
+
expectedReturnCode: 5
|
|
375
295
|
})
|
|
296
|
+
const received = willsFromBroker(s.broker)
|
|
297
|
+
await once(s.broker, 'clientError')
|
|
298
|
+
t.assert.equal(authenticated, true, 'authentication called')
|
|
299
|
+
await delay(10) // give Aedes time to complete authenticate
|
|
300
|
+
t.assert.equal(received.length, 0, 'received no will without authentication')
|
|
376
301
|
})
|
|
377
302
|
|
|
378
|
-
test('does not deliver will if broker is closed during authentication',
|
|
379
|
-
t.plan(
|
|
303
|
+
test('does not deliver will if broker is closed during authentication', async (t) => {
|
|
304
|
+
t.plan(2)
|
|
380
305
|
|
|
381
|
-
const opts = { keepalive: 1 }
|
|
306
|
+
const opts = addWillToOpts({ keepalive: 1 })
|
|
382
307
|
|
|
383
|
-
const broker =
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
})
|
|
308
|
+
const broker = await Aedes.createBroker()
|
|
309
|
+
broker.authenticate = (client, username, password, callback) => {
|
|
310
|
+
setImmediate(() => {
|
|
311
|
+
callback(null, true)
|
|
312
|
+
})
|
|
313
|
+
broker.close()
|
|
314
|
+
}
|
|
391
315
|
|
|
392
|
-
broker.on('keepaliveTimeout',
|
|
393
|
-
t.fail('keepalive timer shoud not be set')
|
|
316
|
+
broker.on('keepaliveTimeout', () => {
|
|
317
|
+
t.assert.fail('keepalive timer shoud not be set')
|
|
394
318
|
})
|
|
395
319
|
|
|
396
|
-
|
|
397
|
-
t.fail('Received will when it was not expected')
|
|
398
|
-
cb()
|
|
399
|
-
})
|
|
320
|
+
const received = willsFromBroker(broker)
|
|
400
321
|
|
|
401
|
-
|
|
322
|
+
const s = setup(broker)
|
|
323
|
+
await connect(s, { connect: opts, noWait: true })
|
|
324
|
+
await delay(1) // give Aedes some time to close the broker
|
|
325
|
+
t.assert.equal(broker.closed, true, 'broker closed')
|
|
326
|
+
t.assert.equal(received.length, 0, 'received no will')
|
|
402
327
|
})
|
|
403
328
|
|
|
404
329
|
// [MQTT-3.14.4-3]
|
|
405
|
-
test('does not deliver will when client sends a DISCONNECT',
|
|
406
|
-
t.plan(
|
|
407
|
-
|
|
408
|
-
const broker = aedes()
|
|
409
|
-
t.teardown(broker.close.bind(broker))
|
|
410
|
-
|
|
411
|
-
const s = noError(willConnect(setup(broker), {}, function () {
|
|
412
|
-
s.inStream.end({
|
|
413
|
-
cmd: 'disconnect'
|
|
414
|
-
})
|
|
415
|
-
}), t)
|
|
330
|
+
test('does not deliver will when client sends a DISCONNECT', async (t) => {
|
|
331
|
+
t.plan(2)
|
|
416
332
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
333
|
+
const opts = addWillToOpts({ keepalive: 1 })
|
|
334
|
+
const s = await createAndConnect(t, { connect: opts })
|
|
335
|
+
const received = willsFromBroker(s.broker)
|
|
336
|
+
s.inStream.write({
|
|
337
|
+
cmd: 'disconnect'
|
|
420
338
|
})
|
|
339
|
+
|
|
340
|
+
await once(s.broker, 'clientDisconnect')
|
|
341
|
+
t.assert.ok(!s.client.connected, 'disconnected')
|
|
342
|
+
t.assert.equal(received.length, 0, 'received no will')
|
|
421
343
|
})
|
|
422
344
|
|
|
423
|
-
test('deletes from persistence on DISCONNECT',
|
|
424
|
-
t.plan(
|
|
345
|
+
test('deletes from persistence on DISCONNECT', async (t) => {
|
|
346
|
+
t.plan(1)
|
|
425
347
|
|
|
426
|
-
const opts = {
|
|
348
|
+
const opts = addWillToOpts({
|
|
427
349
|
clientId: 'abcde'
|
|
428
|
-
}
|
|
429
|
-
const broker = aedes()
|
|
430
|
-
t.teardown(broker.close.bind(broker))
|
|
431
|
-
|
|
432
|
-
const s = noError(willConnect(setup(broker), opts, function () {
|
|
433
|
-
s.inStream.end({
|
|
434
|
-
cmd: 'disconnect'
|
|
435
|
-
})
|
|
436
|
-
}), t)
|
|
437
|
-
|
|
438
|
-
s.broker.persistence.getWill({
|
|
439
|
-
id: opts.clientId
|
|
440
|
-
}, function (err, packet) {
|
|
441
|
-
t.error(err, 'no error')
|
|
442
|
-
t.notOk(packet)
|
|
443
350
|
})
|
|
351
|
+
const s = await createAndConnect(t, { connect: opts })
|
|
352
|
+
s.inStream.end({
|
|
353
|
+
cmd: 'disconnect'
|
|
354
|
+
})
|
|
355
|
+
await once(s.broker, 'clientDisconnect')
|
|
356
|
+
const packet = await s.broker.persistence.getWill({ id: opts.clientId })
|
|
357
|
+
t.assert.ok(!packet, 'no packet present')
|
|
444
358
|
})
|
|
445
359
|
|
|
446
|
-
test('does not store multiple will with same clientid',
|
|
447
|
-
t.plan(
|
|
448
|
-
|
|
449
|
-
const opts = { clientId: 'abcde' }
|
|
450
|
-
|
|
451
|
-
const broker = aedes()
|
|
360
|
+
test('does not store multiple will with same clientid', async (t) => {
|
|
361
|
+
t.plan(2)
|
|
452
362
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
s.inStream.end({
|
|
456
|
-
cmd: 'disconnect'
|
|
457
|
-
})
|
|
458
|
-
}), t)
|
|
459
|
-
|
|
460
|
-
broker.on('clientDisconnect', function (client) {
|
|
461
|
-
// reconnect same client with will
|
|
462
|
-
s = willConnect(setup(broker), opts, function () {
|
|
463
|
-
// check that there are not 2 will messages for the same clientid
|
|
464
|
-
s.broker.persistence.delWill({ id: opts.clientId }, function (err, packet) {
|
|
465
|
-
t.error(err, 'no error')
|
|
466
|
-
t.equal(packet.clientId, opts.clientId, 'will packet found')
|
|
467
|
-
s.broker.persistence.delWill({ id: opts.clientId }, function (err, packet) {
|
|
468
|
-
t.error(err, 'no error')
|
|
469
|
-
t.equal(!!packet, false, 'no duplicated packets')
|
|
470
|
-
broker.close()
|
|
471
|
-
})
|
|
472
|
-
})
|
|
473
|
-
})
|
|
363
|
+
const opts = addWillToOpts({
|
|
364
|
+
clientId: 'abcde'
|
|
474
365
|
})
|
|
366
|
+
const s = await createAndConnect(t, { connect: opts })
|
|
367
|
+
s.inStream.end({
|
|
368
|
+
cmd: 'disconnect'
|
|
369
|
+
})
|
|
370
|
+
await once(s.broker, 'clientDisconnect')
|
|
371
|
+
const s2 = setup(s.broker)
|
|
372
|
+
await connect(s2, { connect: opts })
|
|
373
|
+
|
|
374
|
+
// check that there are not 2 will messages for the same clientid
|
|
375
|
+
const packet1 = await s.broker.persistence.delWill({ id: opts.clientId })
|
|
376
|
+
t.assert.equal(packet1.clientId, opts.clientId, 'will packet found')
|
|
377
|
+
const packet2 = await s.broker.persistence.delWill({ id: opts.clientId })
|
|
378
|
+
t.assert.ok(!packet2, 'no duplicate will packets')
|
|
475
379
|
})
|
|
476
380
|
|
|
477
|
-
test('don\'t
|
|
478
|
-
|
|
381
|
+
test('don\'t deliver a will if broker alive', async (t) => {
|
|
382
|
+
t.plan(6)
|
|
479
383
|
const will = {
|
|
480
384
|
topic: 'mywill',
|
|
481
385
|
payload: Buffer.from('last will'),
|
|
@@ -485,50 +389,42 @@ test('don\'t delivers a will if broker alive', function (t) {
|
|
|
485
389
|
|
|
486
390
|
const oldBroker = 'broker1'
|
|
487
391
|
|
|
488
|
-
persistence
|
|
489
|
-
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
persistence.putWill({
|
|
493
|
-
id: 'myClientId42'
|
|
494
|
-
}, will, function (err) {
|
|
495
|
-
t.error(err, 'no error')
|
|
496
|
-
|
|
497
|
-
const opts = {
|
|
498
|
-
persistence,
|
|
499
|
-
heartbeatInterval: 10
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
let count = 0
|
|
503
|
-
|
|
504
|
-
const broker = aedes(opts)
|
|
505
|
-
t.teardown(broker.close.bind(broker))
|
|
392
|
+
const persistence = await memorySetup({ id: oldBroker })
|
|
393
|
+
await persistence.putWill({ id: 'myClientId42' }, will)
|
|
506
394
|
|
|
507
|
-
|
|
508
|
-
persistence
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
}
|
|
395
|
+
const opts = {
|
|
396
|
+
persistence,
|
|
397
|
+
heartbeatInterval: 10
|
|
398
|
+
}
|
|
512
399
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
cb()
|
|
516
|
-
})
|
|
400
|
+
const broker = await Aedes.createBroker(opts)
|
|
401
|
+
t.after(() => broker.close())
|
|
517
402
|
|
|
518
|
-
|
|
519
|
-
|
|
403
|
+
const streamWill = persistence.streamWill
|
|
404
|
+
persistence.streamWill = () => {
|
|
405
|
+
// don't pass broker.brokers to streamWill
|
|
406
|
+
return streamWill.call(persistence)
|
|
407
|
+
}
|
|
408
|
+
// catch any wills published
|
|
409
|
+
const received = willsFromBroker(broker)
|
|
410
|
+
|
|
411
|
+
// let the broker run for 5 heartbeats
|
|
412
|
+
let count = 0
|
|
413
|
+
await new Promise((resolve) => {
|
|
414
|
+
broker.mq.on('$SYS/+/heartbeat', () => {
|
|
415
|
+
t.assert.ok(true, 'Heartbeat received')
|
|
520
416
|
broker.brokers[oldBroker] = Date.now()
|
|
521
|
-
|
|
522
417
|
if (++count === 5) {
|
|
523
|
-
|
|
418
|
+
resolve()
|
|
524
419
|
}
|
|
525
420
|
})
|
|
526
421
|
})
|
|
422
|
+
t.assert.equal(received.length, 0, 'received no will')
|
|
527
423
|
})
|
|
528
424
|
|
|
529
|
-
test('handle will publish error',
|
|
530
|
-
t.plan(
|
|
531
|
-
|
|
425
|
+
test('handle will publish error', async (t) => {
|
|
426
|
+
t.plan(1)
|
|
427
|
+
|
|
532
428
|
const will = {
|
|
533
429
|
topic: 'mywill',
|
|
534
430
|
payload: Buffer.from('last will'),
|
|
@@ -536,36 +432,29 @@ test('handle will publish error', function (t) {
|
|
|
536
432
|
retain: false
|
|
537
433
|
}
|
|
538
434
|
|
|
539
|
-
persistence
|
|
540
|
-
|
|
541
|
-
}
|
|
435
|
+
const persistence = await memorySetup({ id: 'broker1' })
|
|
436
|
+
await persistence.putWill({ id: 'myClientId42' }, will)
|
|
542
437
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
const opts = {
|
|
549
|
-
persistence,
|
|
550
|
-
heartbeatInterval: 10
|
|
551
|
-
}
|
|
438
|
+
const opts = {
|
|
439
|
+
persistence,
|
|
440
|
+
heartbeatInterval: 10
|
|
441
|
+
}
|
|
552
442
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
443
|
+
// fake an error
|
|
444
|
+
persistence.delWill = async client => {
|
|
445
|
+
throw new Error('Throws error')
|
|
446
|
+
}
|
|
556
447
|
|
|
557
|
-
|
|
558
|
-
|
|
448
|
+
const broker = await Aedes.createBroker(opts)
|
|
449
|
+
t.after(() => broker.close())
|
|
559
450
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
})
|
|
563
|
-
})
|
|
451
|
+
const [err] = await once(broker, 'error')
|
|
452
|
+
t.assert.equal('Throws error', err.message, 'throws error')
|
|
564
453
|
})
|
|
565
454
|
|
|
566
|
-
test('handle will publish error 2',
|
|
567
|
-
t.plan(
|
|
568
|
-
|
|
455
|
+
test('handle will publish error 2', async (t) => {
|
|
456
|
+
t.plan(1)
|
|
457
|
+
|
|
569
458
|
const will = {
|
|
570
459
|
topic: 'mywill',
|
|
571
460
|
payload: Buffer.from('last will'),
|
|
@@ -573,29 +462,22 @@ test('handle will publish error 2', function (t) {
|
|
|
573
462
|
retain: true
|
|
574
463
|
}
|
|
575
464
|
|
|
576
|
-
persistence
|
|
577
|
-
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
persistence.putWill({
|
|
581
|
-
id: 'myClientId42'
|
|
582
|
-
}, will, function (err) {
|
|
583
|
-
t.error(err, 'no error')
|
|
465
|
+
const persistence = await memorySetup({ id: 'broker1' })
|
|
466
|
+
await persistence.putWill({ id: 'myClientId42' }, will)
|
|
584
467
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
468
|
+
const opts = {
|
|
469
|
+
persistence,
|
|
470
|
+
heartbeatInterval: 10
|
|
471
|
+
}
|
|
589
472
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
473
|
+
// fake error
|
|
474
|
+
persistence.storeRetained = async packet => {
|
|
475
|
+
throw new Error('Throws error')
|
|
476
|
+
}
|
|
593
477
|
|
|
594
|
-
|
|
595
|
-
|
|
478
|
+
const broker = await Aedes.createBroker(opts)
|
|
479
|
+
t.after(() => broker.close())
|
|
596
480
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
})
|
|
600
|
-
})
|
|
481
|
+
const [err] = await once(broker, 'error')
|
|
482
|
+
t.assert.equal('Throws error', err.message, 'throws error')
|
|
601
483
|
})
|