go-mqtt 0.0.1
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.
- checksums.yaml +7 -0
- data/LICENSE.md +21 -0
- data/NEWS.md +150 -0
- data/README.md +237 -0
- data/lib/mqtt/client.rb +755 -0
- data/lib/mqtt/openssl_fix.rb +29 -0
- data/lib/mqtt/packet.rb +1049 -0
- data/lib/mqtt/proxy.rb +115 -0
- data/lib/mqtt/sn/packet.rb +720 -0
- data/lib/mqtt/version.rb +4 -0
- data/lib/mqtt.rb +48 -0
- data/spec/mqtt_client_spec.rb +1124 -0
- data/spec/mqtt_packet_spec.rb +2012 -0
- data/spec/mqtt_proxy_spec.rb +8 -0
- data/spec/mqtt_sn_packet_spec.rb +1721 -0
- data/spec/mqtt_version_spec.rb +23 -0
- data/spec/zz_client_integration_spec.rb +177 -0
- metadata +152 -0
@@ -0,0 +1,2012 @@
|
|
1
|
+
# encoding: BINARY
|
2
|
+
# Encoding is set to binary, so that the binary packets aren't validated as UTF-8
|
3
|
+
|
4
|
+
$:.unshift(File.dirname(__FILE__))
|
5
|
+
|
6
|
+
require 'spec_helper'
|
7
|
+
|
8
|
+
describe MQTT::Packet do
|
9
|
+
|
10
|
+
describe "when creating a new packet" do
|
11
|
+
it "should allow you to set the packet flags as a hash parameter" do
|
12
|
+
packet = MQTT::Packet.new( :flags => [true, false, true, false] )
|
13
|
+
expect(packet.flags).to eq([true, false, true, false])
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have a custom inspect method" do
|
17
|
+
packet = MQTT::Packet.new
|
18
|
+
expect(packet.inspect).to eq('#<MQTT::Packet>')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have a type_id method to get the integer ID of the packet type" do
|
22
|
+
packet = MQTT::Packet::Pingreq.new
|
23
|
+
expect(packet.type_id).to eq(12)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should let you change attributes using the update_attributes method" do
|
28
|
+
packet = MQTT::Packet.new(:flags => [false, false, false, true])
|
29
|
+
packet.update_attributes(:flags => [false, false, true, true])
|
30
|
+
expect(packet.flags).to eq([false, false, true, true])
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "protected methods" do
|
34
|
+
let(:packet) { MQTT::Packet.new }
|
35
|
+
|
36
|
+
it "should provide a encode_bytes method to get some bytes as Integers" do
|
37
|
+
data = packet.send(:encode_bytes, 0x48, 0x65, 0x6c, 0x6c, 'o'.unpack('C1')[0])
|
38
|
+
expect(data).to eq('Hello')
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should provide a encode_bits method to encode an array of bits to a string" do
|
42
|
+
data = packet.send(:encode_bits, [false, true, true, false, true, false, true, false])
|
43
|
+
expect(data).to eq('V')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should provide a add_short method to get a big-endian unsigned 16-bit integer" do
|
47
|
+
data = packet.send(:encode_short, 1024)
|
48
|
+
expect(data).to eq("\x04\x00")
|
49
|
+
expect(data.encoding.to_s).to eq("ASCII-8BIT")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should raise an error if too big argument for encode_short" do
|
53
|
+
expect {
|
54
|
+
data = packet.send(:encode_short, 0x10000)
|
55
|
+
}.to raise_error(
|
56
|
+
'Value too big for short'
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should provide a add_string method to get a string preceeded by its length" do
|
61
|
+
data = packet.send(:encode_string, 'quack')
|
62
|
+
expect(data).to eq("\x00\x05quack")
|
63
|
+
expect(data.encoding.to_s).to eq("ASCII-8BIT")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should provide a shift_short method to get a 16-bit unsigned integer" do
|
67
|
+
buffer = "\x22\x8Bblahblah"
|
68
|
+
expect(packet.send(:shift_short,buffer)).to eq(8843)
|
69
|
+
expect(buffer).to eq('blahblah')
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should provide a shift_byte method to get one byte as integers" do
|
73
|
+
buffer = "\x01blahblah"
|
74
|
+
expect(packet.send(:shift_byte,buffer)).to eq(1)
|
75
|
+
expect(buffer).to eq('blahblah')
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should provide a shift_byte method to get one byte as integers" do
|
79
|
+
buffer = "Yblahblah"
|
80
|
+
expect(packet.send(:shift_bits, buffer)).to eq([true, false, false, true, true, false, true, false])
|
81
|
+
expect(buffer).to eq('blahblah')
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should provide a shift_string method to get a string preceeded by its length" do
|
85
|
+
buffer = "\x00\x05Hello World"
|
86
|
+
expect(packet.send(:shift_string,buffer)).to eq("Hello")
|
87
|
+
expect(buffer).to eq(' World')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "deprecated attributes" do
|
92
|
+
it "should still have a message_id method that is that same as id" do
|
93
|
+
packet = MQTT::Packet.new
|
94
|
+
packet.message_id = 1234
|
95
|
+
expect(packet.message_id).to eq(1234)
|
96
|
+
expect(packet.id).to eq(1234)
|
97
|
+
packet.id = 4321
|
98
|
+
expect(packet.message_id).to eq(4321)
|
99
|
+
expect(packet.id).to eq(4321)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe MQTT::Packet::Publish do
|
105
|
+
describe "when creating a packet" do
|
106
|
+
it "should allow you to set the packet QoS level as a hash parameter" do
|
107
|
+
packet = MQTT::Packet::Publish.new( :qos => 2 )
|
108
|
+
expect(packet.qos).to eq(2)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should allow you to set the packet retain flag as a hash parameter" do
|
112
|
+
packet = MQTT::Packet::Publish.new( :retain => true )
|
113
|
+
expect(packet.retain).to be_truthy
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should raise an exception the QoS is greater than 2" do
|
117
|
+
expect {
|
118
|
+
packet = MQTT::Packet::Publish.new( :qos => 3 )
|
119
|
+
}.to raise_error(
|
120
|
+
'Invalid QoS value: 3'
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should raise an exception the QoS is less than 0" do
|
125
|
+
expect {
|
126
|
+
packet = MQTT::Packet::Publish.new( :qos => -1 )
|
127
|
+
}.to raise_error(
|
128
|
+
'Invalid QoS value: -1'
|
129
|
+
)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "when setting attributes on a packet" do
|
134
|
+
let(:packet) {
|
135
|
+
MQTT::Packet::Publish.new(
|
136
|
+
:duplicate => false,
|
137
|
+
:qos => 0,
|
138
|
+
:retain => false
|
139
|
+
)
|
140
|
+
}
|
141
|
+
|
142
|
+
it "should let you change the dup flag of a packet" do
|
143
|
+
packet.duplicate = true
|
144
|
+
expect(packet.duplicate).to be_truthy
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should let you change the dup flag of a packet using an integer" do
|
148
|
+
packet.duplicate = 1
|
149
|
+
expect(packet.duplicate).to be_truthy
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should let you change the QoS value of a packet" do
|
153
|
+
packet.qos = 1
|
154
|
+
expect(packet.qos).to eq(1)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should let you change the retain flag of a packet" do
|
158
|
+
packet.retain = true
|
159
|
+
expect(packet.retain).to be_truthy
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should let you change the retain flag of a packet using an integer" do
|
163
|
+
packet.retain = 1
|
164
|
+
expect(packet.retain).to be_truthy
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "when serialising a packet" do
|
169
|
+
it "should output the correct bytes for a packet with default QoS and no flags" do
|
170
|
+
packet = MQTT::Packet::Publish.new( :topic => 'test', :payload => 'hello world' )
|
171
|
+
expect(packet.to_s).to eq("\x30\x11\x00\x04testhello world")
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should output the correct bytes for a packet with QoS 1 and no flags" do
|
175
|
+
packet = MQTT::Packet::Publish.new( :id => 5, :qos => 1, :topic => 'a/b', :payload => 'hello world' )
|
176
|
+
expect(packet.to_s).to eq("\x32\x12\x00\x03a/b\x00\x05hello world")
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should output the correct bytes for a packet with QoS 2 and retain flag set" do
|
180
|
+
packet = MQTT::Packet::Publish.new( :id => 5, :qos => 2, :retain => true, :topic => 'c/d', :payload => 'hello world' )
|
181
|
+
expect(packet.to_s).to eq("\x35\x12\x00\x03c/d\x00\x05hello world")
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should output the correct bytes for a packet with QoS 2 and dup flag set" do
|
185
|
+
packet = MQTT::Packet::Publish.new( :id => 5, :qos => 2, :duplicate => true, :topic => 'c/d', :payload => 'hello world' )
|
186
|
+
expect(packet.to_s).to eq("\x3C\x12\x00\x03c/d\x00\x05hello world")
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should output the correct bytes for a packet with an empty payload" do
|
190
|
+
packet = MQTT::Packet::Publish.new( :topic => 'test' )
|
191
|
+
expect(packet.to_s).to eq("\x30\x06\x00\x04test")
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should output a string as binary / 8-bit ASCII" do
|
195
|
+
packet = MQTT::Packet::Publish.new( :topic => 'test', :payload => 'hello world' )
|
196
|
+
expect(packet.to_s.encoding.to_s).to eq("ASCII-8BIT")
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should support passing in non-strings to the topic and payload" do
|
200
|
+
packet = MQTT::Packet::Publish.new( :topic => :symbol, :payload => 1234 )
|
201
|
+
expect(packet.to_s).to eq("\x30\x0c\x00\x06symbol1234")
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should raise an exception when there is no topic name" do
|
205
|
+
expect {
|
206
|
+
MQTT::Packet::Publish.new.to_s
|
207
|
+
}.to raise_error(
|
208
|
+
'Invalid topic name when serialising packet'
|
209
|
+
)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should raise an exception when there is an empty topic name" do
|
213
|
+
expect {
|
214
|
+
MQTT::Packet::Publish.new( :topic => '' ).to_s
|
215
|
+
}.to raise_error(
|
216
|
+
'Invalid topic name when serialising packet'
|
217
|
+
)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
describe "when serialising an oversized packet" do
|
222
|
+
it "should raise an exception when body is bigger than 256MB" do
|
223
|
+
expect {
|
224
|
+
packet = MQTT::Packet::Publish.new( :topic => 'test', :payload => 'x'*268435455 )
|
225
|
+
packet.to_s
|
226
|
+
}.to raise_error(
|
227
|
+
'Error serialising packet: body is more than 256MB'
|
228
|
+
)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe "when parsing a packet with QoS 0" do
|
233
|
+
let(:packet) { MQTT::Packet.parse( "\x30\x11\x00\x04testhello world" ) }
|
234
|
+
|
235
|
+
it "should correctly create the right type of packet object" do
|
236
|
+
expect(packet.class).to eq(MQTT::Packet::Publish)
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should set the QoS level correctly" do
|
240
|
+
expect(packet.qos).to eq(0)
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should set the RETAIN flag correctly" do
|
244
|
+
expect(packet.retain).to be_falsey
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should set the DUP flag correctly" do
|
248
|
+
expect(packet.duplicate).to be_falsey
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should set the topic name correctly" do
|
252
|
+
expect(packet.topic).to eq('test')
|
253
|
+
expect(packet.topic.encoding.to_s).to eq('UTF-8')
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should set the payload correctly" do
|
257
|
+
expect(packet.payload).to eq('hello world')
|
258
|
+
expect(packet.payload.encoding.to_s).to eq('ASCII-8BIT')
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
describe "when parsing a packet with QoS 2 and retain and dup flags set" do
|
263
|
+
let(:packet) { MQTT::Packet.parse( "\x3D\x12\x00\x03c/d\x00\x05hello world" ) }
|
264
|
+
|
265
|
+
it "should correctly create the right type of packet object" do
|
266
|
+
expect(packet.class).to eq(MQTT::Packet::Publish)
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should set the QoS level correctly" do
|
270
|
+
expect(packet.qos).to eq(2)
|
271
|
+
end
|
272
|
+
|
273
|
+
it "should set the RETAIN flag correctly" do
|
274
|
+
expect(packet.retain).to be_truthy
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should set the DUP flag correctly" do
|
278
|
+
expect(packet.duplicate).to be_truthy
|
279
|
+
end
|
280
|
+
|
281
|
+
it "should set the topic name correctly" do
|
282
|
+
expect(packet.topic).to eq('c/d')
|
283
|
+
expect(packet.topic.encoding.to_s).to eq('UTF-8')
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should set the payload correctly" do
|
287
|
+
expect(packet.payload).to eq('hello world')
|
288
|
+
expect(packet.payload.encoding.to_s).to eq('ASCII-8BIT')
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
describe "when parsing a packet with an empty payload" do
|
293
|
+
let(:packet) { MQTT::Packet.parse( "\x30\x06\x00\x04test" ) }
|
294
|
+
|
295
|
+
it "should correctly create the right type of packet object" do
|
296
|
+
expect(packet.class).to eq(MQTT::Packet::Publish)
|
297
|
+
end
|
298
|
+
|
299
|
+
it "should set the topic name correctly" do
|
300
|
+
expect(packet.topic).to eq('test')
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should set the payload correctly" do
|
304
|
+
expect(packet.payload).to be_empty
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
describe "when parsing a packet with a QoS value of 3" do
|
309
|
+
it "should raise an exception" do
|
310
|
+
expect {
|
311
|
+
packet = MQTT::Packet.parse( "\x36\x12\x00\x03a/b\x00\x05hello world" )
|
312
|
+
}.to raise_error(
|
313
|
+
MQTT::ProtocolException,
|
314
|
+
'Invalid packet: QoS value of 3 is not allowed'
|
315
|
+
)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe "when parsing a packet with QoS value of 0 and DUP set" do
|
320
|
+
it "should raise an exception" do
|
321
|
+
expect {
|
322
|
+
packet = MQTT::Packet.parse( "\x38\x10\x00\x03a/bhello world" )
|
323
|
+
}.to raise_error(
|
324
|
+
MQTT::ProtocolException,
|
325
|
+
'Invalid packet: DUP cannot be set for QoS 0'
|
326
|
+
)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
describe "when parsing a packet with a body of 314 bytes" do
|
331
|
+
let(:packet) {
|
332
|
+
# 0x30 = publish
|
333
|
+
# 0xC1 = (65 * 1)
|
334
|
+
# 0x02 = (2 * 128)
|
335
|
+
MQTT::Packet.parse( "\x30\xC1\x02\x00\x05topic" + ('x' * 314) )
|
336
|
+
}
|
337
|
+
|
338
|
+
it "should parse the packet type correctly" do
|
339
|
+
expect(packet.class).to eq(MQTT::Packet::Publish)
|
340
|
+
end
|
341
|
+
|
342
|
+
it "should get the topic name correctly" do
|
343
|
+
expect(packet.topic).to eq('topic')
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should get the body length correctly" do
|
347
|
+
expect(packet.payload.bytesize).to eq(314)
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
describe "when parsing a packet with a body of 16kbytes" do
|
352
|
+
let(:packet) do
|
353
|
+
# 0x30 = publish
|
354
|
+
# 0x87 = (7 * 1)
|
355
|
+
# 0x80 = (0 * 128)
|
356
|
+
# 0x01 = (1 * 16384)
|
357
|
+
MQTT::Packet.parse( "\x30\x87\x80\x01\x00\x05topic" + ('x'*16384) )
|
358
|
+
end
|
359
|
+
|
360
|
+
it "should parse the packet type correctly" do
|
361
|
+
expect(packet.class).to eq(MQTT::Packet::Publish)
|
362
|
+
end
|
363
|
+
|
364
|
+
it "should get the topic name correctly" do
|
365
|
+
expect(packet.topic).to eq('topic')
|
366
|
+
end
|
367
|
+
|
368
|
+
it "should get the body length correctly" do
|
369
|
+
expect(packet.payload.bytesize).to eq(16384)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
describe "processing a packet containing UTF-8 character" do
|
374
|
+
let(:packet) do
|
375
|
+
MQTT::Packet::Publish.new(
|
376
|
+
:topic => "Test ①".force_encoding("UTF-8"),
|
377
|
+
:payload => "Snowman: ☃".force_encoding("UTF-8")
|
378
|
+
)
|
379
|
+
end
|
380
|
+
|
381
|
+
it "should have the correct topic byte length" do
|
382
|
+
expect(packet.topic.bytesize).to eq(8)
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should have the correct topic string length" do
|
386
|
+
expect(packet.topic.length).to eq(6)
|
387
|
+
end
|
388
|
+
|
389
|
+
it "should have the correct payload byte length" do
|
390
|
+
expect(packet.payload.bytesize).to eq(12)
|
391
|
+
end
|
392
|
+
|
393
|
+
it "should have the correct payload string length" do
|
394
|
+
expect(packet.payload.length).to eq(10)
|
395
|
+
end
|
396
|
+
|
397
|
+
it "should encode to MQTT packet correctly" do
|
398
|
+
expect(packet.to_s).to eq("\x30\x16\x00\x08Test \xE2\x91\xA0Snowman: \xE2\x98\x83".force_encoding('BINARY'))
|
399
|
+
end
|
400
|
+
|
401
|
+
it "should parse the serialised packet" do
|
402
|
+
packet2 = MQTT::Packet.parse( packet.to_s )
|
403
|
+
expect(packet2.topic).to eq("Test ①".force_encoding('UTF-8'))
|
404
|
+
expect(packet2.payload).to eq("Snowman: ☃".force_encoding('BINARY'))
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
describe "reading a packet from a socket" do
|
409
|
+
let(:socket) { StringIO.new("\x30\x11\x00\x04testhello world") }
|
410
|
+
let(:packet) { MQTT::Packet.read(socket) }
|
411
|
+
|
412
|
+
it "should correctly create the right type of packet object" do
|
413
|
+
expect(packet.class).to eq(MQTT::Packet::Publish)
|
414
|
+
end
|
415
|
+
|
416
|
+
it "should set the body length is read correctly" do
|
417
|
+
expect(packet.body_length).to eq(17)
|
418
|
+
end
|
419
|
+
|
420
|
+
it "should set the QoS level correctly" do
|
421
|
+
expect(packet.qos).to eq(0)
|
422
|
+
end
|
423
|
+
|
424
|
+
it "should set the RETAIN flag correctly" do
|
425
|
+
expect(packet.retain).to be_falsey
|
426
|
+
end
|
427
|
+
|
428
|
+
it "should set the DUP flag correctly" do
|
429
|
+
expect(packet.duplicate).to be_falsey
|
430
|
+
end
|
431
|
+
|
432
|
+
it "should set the topic name correctly" do
|
433
|
+
expect(packet.topic).to eq('test')
|
434
|
+
expect(packet.topic.encoding.to_s).to eq('UTF-8')
|
435
|
+
end
|
436
|
+
|
437
|
+
it "should set the payload correctly" do
|
438
|
+
expect(packet.payload).to eq('hello world')
|
439
|
+
expect(packet.payload.encoding.to_s).to eq('ASCII-8BIT')
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
describe "when calling the inspect method" do
|
444
|
+
it "should output the payload, if it is less than 16 bytes" do
|
445
|
+
packet = MQTT::Packet::Publish.new( :topic => "topic", :payload => "payload" )
|
446
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Publish: d0, q0, r0, m0, 'topic', 'payload'>")
|
447
|
+
end
|
448
|
+
|
449
|
+
it "should output the length of the payload, if it is more than 16 bytes" do
|
450
|
+
packet = MQTT::Packet::Publish.new( :topic => "topic", :payload => 'x'*32 )
|
451
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Publish: d0, q0, r0, m0, 'topic', ... (32 bytes)>")
|
452
|
+
end
|
453
|
+
|
454
|
+
it "should only output the length of a binary payload" do
|
455
|
+
packet = MQTT::Packet.parse("\x31\x12\x00\x04test\x8D\xF8\x09\x40\xC4\xE7\x4f\xF0\xFF\x30\xE0\xE7")
|
456
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Publish: d0, q0, r1, m0, 'test', ... (12 bytes)>")
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
describe MQTT::Packet::Connect do
|
462
|
+
describe "when serialising a packet" do
|
463
|
+
it "should output the correct bytes for a packet with no flags" do
|
464
|
+
packet = MQTT::Packet::Connect.new( :client_id => 'myclient' )
|
465
|
+
expect(packet.to_s).to eq("\020\026\x00\x06MQIsdp\x03\x02\x00\x0f\x00\x08myclient")
|
466
|
+
end
|
467
|
+
|
468
|
+
it "should output the correct bytes for a packet with clean session turned off" do
|
469
|
+
packet = MQTT::Packet::Connect.new(
|
470
|
+
:client_id => 'myclient',
|
471
|
+
:clean_session => false
|
472
|
+
)
|
473
|
+
expect(packet.to_s).to eq("\020\026\x00\x06MQIsdp\x03\x00\x00\x0f\x00\x08myclient")
|
474
|
+
end
|
475
|
+
|
476
|
+
context "protocol version 3.1.0" do
|
477
|
+
it "should raise an exception when there is no client identifier" do
|
478
|
+
expect {
|
479
|
+
MQTT::Packet::Connect.new(:version => '3.1.0', :client_id => '').to_s
|
480
|
+
}.to raise_error(
|
481
|
+
'Client identifier too short while serialising packet'
|
482
|
+
)
|
483
|
+
end
|
484
|
+
|
485
|
+
it "should raise an exception when the client identifier is too long" do
|
486
|
+
expect {
|
487
|
+
client_id = '0EB8D2FE7C254715B4467C5B2ECAD100'
|
488
|
+
MQTT::Packet::Connect.new(:version => '3.1.0', :client_id => client_id).to_s
|
489
|
+
}.to raise_error(
|
490
|
+
'Client identifier too long when serialising packet'
|
491
|
+
)
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
context "protocol version 3.1.1" do
|
496
|
+
it "should allow no client identifier" do
|
497
|
+
packet = MQTT::Packet::Connect.new(
|
498
|
+
:version => '3.1.1',
|
499
|
+
:client_id => '',
|
500
|
+
:clean_session => true
|
501
|
+
)
|
502
|
+
expect(packet.to_s).to eq("\020\014\x00\x04MQTT\x04\x02\x00\x0f\x00\x00")
|
503
|
+
end
|
504
|
+
|
505
|
+
it "should allow a 32 character client identifier" do
|
506
|
+
client_id = '0EB8D2FE7C254715B4467C5B2ECAD100'
|
507
|
+
packet = MQTT::Packet::Connect.new(
|
508
|
+
:version => '3.1.1',
|
509
|
+
:client_id => client_id,
|
510
|
+
:clean_session => true
|
511
|
+
)
|
512
|
+
expect(packet.to_s).to eq("\x10,\x00\x04MQTT\x04\x02\x00\x0F\x00\x200EB8D2FE7C254715B4467C5B2ECAD100")
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
it "should raise an exception if the keep alive value is less than 0" do
|
517
|
+
expect {
|
518
|
+
MQTT::Packet::Connect.new(:client_id => 'test', :keep_alive => -2).to_s
|
519
|
+
}.to raise_error(
|
520
|
+
'Invalid keep-alive value: cannot be less than 0'
|
521
|
+
)
|
522
|
+
end
|
523
|
+
|
524
|
+
it "should output the correct bytes for a packet with a Will" do
|
525
|
+
packet = MQTT::Packet::Connect.new(
|
526
|
+
:client_id => 'myclient',
|
527
|
+
:clean_session => true,
|
528
|
+
:will_qos => 1,
|
529
|
+
:will_retain => false,
|
530
|
+
:will_topic => 'topic',
|
531
|
+
:will_payload => 'hello'
|
532
|
+
)
|
533
|
+
expect(packet.to_s).to eq(
|
534
|
+
"\x10\x24"+
|
535
|
+
"\x00\x06MQIsdp"+
|
536
|
+
"\x03\x0e\x00\x0f"+
|
537
|
+
"\x00\x08myclient"+
|
538
|
+
"\x00\x05topic\x00\x05hello"
|
539
|
+
)
|
540
|
+
end
|
541
|
+
|
542
|
+
it "should output the correct bytes for a packet with a username and password" do
|
543
|
+
packet = MQTT::Packet::Connect.new(
|
544
|
+
:client_id => 'myclient',
|
545
|
+
:username => 'username',
|
546
|
+
:password => 'password'
|
547
|
+
)
|
548
|
+
expect(packet.to_s).to eq(
|
549
|
+
"\x10\x2A"+
|
550
|
+
"\x00\x06MQIsdp"+
|
551
|
+
"\x03\xC2\x00\x0f"+
|
552
|
+
"\x00\x08myclient"+
|
553
|
+
"\x00\x08username"+
|
554
|
+
"\x00\x08password"
|
555
|
+
)
|
556
|
+
end
|
557
|
+
|
558
|
+
it "should output the correct bytes for a packet with everything" do
|
559
|
+
packet = MQTT::Packet::Connect.new(
|
560
|
+
:client_id => '12345678901234567890123',
|
561
|
+
:clean_session => true,
|
562
|
+
:keep_alive => 65535,
|
563
|
+
:will_qos => 2,
|
564
|
+
:will_retain => true,
|
565
|
+
:will_topic => 'will_topic',
|
566
|
+
:will_payload => 'will_message',
|
567
|
+
:username => 'user0123456789',
|
568
|
+
:password => 'pass0123456789'
|
569
|
+
)
|
570
|
+
expect(packet.to_s).to eq(
|
571
|
+
"\x10\x5F"+ # fixed header (2)
|
572
|
+
"\x00\x06MQIsdp"+ # protocol name (8)
|
573
|
+
"\x03\xf6"+ # protocol level + flags (2)
|
574
|
+
"\xff\xff"+ # keep alive (2)
|
575
|
+
"\x00\x1712345678901234567890123"+ # client identifier (25)
|
576
|
+
"\x00\x0Awill_topic"+ # will topic (12)
|
577
|
+
"\x00\x0Cwill_message"+ # will message (14)
|
578
|
+
"\x00\x0Euser0123456789"+ # username (16)
|
579
|
+
"\x00\x0Epass0123456789"
|
580
|
+
) # password (16)
|
581
|
+
end
|
582
|
+
|
583
|
+
context 'protocol version 3.1.1' do
|
584
|
+
it "should output the correct bytes for a packet with no flags" do
|
585
|
+
packet = MQTT::Packet::Connect.new( :version => '3.1.1', :client_id => 'myclient' )
|
586
|
+
expect(packet.to_s).to eq("\020\024\x00\x04MQTT\x04\x02\x00\x0f\x00\x08myclient")
|
587
|
+
end
|
588
|
+
end
|
589
|
+
|
590
|
+
context 'an invalid protocol version number' do
|
591
|
+
it "should raise a protocol exception" do
|
592
|
+
expect {
|
593
|
+
packet = MQTT::Packet::Connect.new( :version => 'x.x.x', :client_id => 'myclient' )
|
594
|
+
}.to raise_error(
|
595
|
+
ArgumentError,
|
596
|
+
"Unsupported protocol version: x.x.x"
|
597
|
+
)
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
end
|
602
|
+
|
603
|
+
describe "when parsing a simple 3.1.0 Connect packet" do
|
604
|
+
let(:packet) do
|
605
|
+
MQTT::Packet.parse(
|
606
|
+
"\x10\x16\x00\x06MQIsdp\x03\x00\x00\x0a\x00\x08myclient"
|
607
|
+
)
|
608
|
+
end
|
609
|
+
|
610
|
+
it "should correctly create the right type of packet object" do
|
611
|
+
expect(packet.class).to eq(MQTT::Packet::Connect)
|
612
|
+
end
|
613
|
+
|
614
|
+
it "should set the fixed header flags of the packet correctly" do
|
615
|
+
expect(packet.flags).to eq([false, false, false, false])
|
616
|
+
end
|
617
|
+
|
618
|
+
it "should set the Protocol Name of the packet correctly" do
|
619
|
+
expect(packet.protocol_name).to eq('MQIsdp')
|
620
|
+
expect(packet.protocol_name.encoding.to_s).to eq('UTF-8')
|
621
|
+
end
|
622
|
+
|
623
|
+
it "should set the Protocol Level of the packet correctly" do
|
624
|
+
expect(packet.protocol_level).to eq(3)
|
625
|
+
end
|
626
|
+
|
627
|
+
it "should set the Protocol version of the packet correctly" do
|
628
|
+
expect(packet.version).to eq('3.1.0')
|
629
|
+
end
|
630
|
+
|
631
|
+
it "should set the Client Identifier of the packet correctly" do
|
632
|
+
expect(packet.client_id).to eq('myclient')
|
633
|
+
expect(packet.client_id.encoding.to_s).to eq('UTF-8')
|
634
|
+
end
|
635
|
+
|
636
|
+
it "should set the Keep Alive timer of the packet correctly" do
|
637
|
+
expect(packet.keep_alive).to eq(10)
|
638
|
+
end
|
639
|
+
|
640
|
+
it "should set not have the clean session flag set" do
|
641
|
+
expect(packet.clean_session).to be_falsey
|
642
|
+
end
|
643
|
+
|
644
|
+
it "should set the the username field of the packet to nil" do
|
645
|
+
expect(packet.username).to be_nil
|
646
|
+
end
|
647
|
+
|
648
|
+
it "should set the the password field of the packet to nil" do
|
649
|
+
expect(packet.password).to be_nil
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
describe "when parsing a simple 3.1.1 Connect packet" do
|
654
|
+
let(:packet) do
|
655
|
+
MQTT::Packet.parse(
|
656
|
+
"\x10\x14\x00\x04MQTT\x04\x00\x00\x0a\x00\x08myclient"
|
657
|
+
)
|
658
|
+
end
|
659
|
+
|
660
|
+
it "should correctly create the right type of packet object" do
|
661
|
+
expect(packet.class).to eq(MQTT::Packet::Connect)
|
662
|
+
end
|
663
|
+
|
664
|
+
it "should set the fixed header flags of the packet correctly" do
|
665
|
+
expect(packet.flags).to eq([false, false, false, false])
|
666
|
+
end
|
667
|
+
|
668
|
+
it "should set the Protocol Name of the packet correctly" do
|
669
|
+
expect(packet.protocol_name).to eq('MQTT')
|
670
|
+
expect(packet.protocol_name.encoding.to_s).to eq('UTF-8')
|
671
|
+
end
|
672
|
+
|
673
|
+
it "should set the Protocol Level of the packet correctly" do
|
674
|
+
expect(packet.protocol_level).to eq(4)
|
675
|
+
end
|
676
|
+
|
677
|
+
it "should set the Protocol version of the packet correctly" do
|
678
|
+
expect(packet.version).to eq('3.1.1')
|
679
|
+
end
|
680
|
+
|
681
|
+
it "should set the Client Identifier of the packet correctly" do
|
682
|
+
expect(packet.client_id).to eq('myclient')
|
683
|
+
expect(packet.client_id.encoding.to_s).to eq('UTF-8')
|
684
|
+
end
|
685
|
+
|
686
|
+
it "should set the Keep Alive timer of the packet correctly" do
|
687
|
+
expect(packet.keep_alive).to eq(10)
|
688
|
+
end
|
689
|
+
|
690
|
+
it "should set not have the clean session flag set" do
|
691
|
+
expect(packet.clean_session).to be_falsey
|
692
|
+
end
|
693
|
+
|
694
|
+
it "should set the the username field of the packet to nil" do
|
695
|
+
expect(packet.username).to be_nil
|
696
|
+
end
|
697
|
+
|
698
|
+
it "should set the the password field of the packet to nil" do
|
699
|
+
expect(packet.password).to be_nil
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
describe "when parsing a Connect packet with the clean session flag set" do
|
704
|
+
let(:packet) do
|
705
|
+
MQTT::Packet.parse(
|
706
|
+
"\x10\x16\x00\x06MQIsdp\x03\x02\x00\x0a\x00\x08myclient"
|
707
|
+
)
|
708
|
+
end
|
709
|
+
|
710
|
+
it "should set the clean session flag" do
|
711
|
+
expect(packet.clean_session).to be_truthy
|
712
|
+
end
|
713
|
+
end
|
714
|
+
|
715
|
+
describe "when parsing a Connect packet with a Will and Testament" do
|
716
|
+
let(:packet) do
|
717
|
+
MQTT::Packet.parse(
|
718
|
+
"\x10\x24\x00\x06MQIsdp\x03\x0e\x00\x0a\x00\x08myclient\x00\x05topic\x00\x05hello"
|
719
|
+
)
|
720
|
+
end
|
721
|
+
|
722
|
+
it "should correctly create the right type of packet object" do
|
723
|
+
expect(packet.class).to eq(MQTT::Packet::Connect)
|
724
|
+
end
|
725
|
+
|
726
|
+
it "should set the fixed header flags of the packet correctly" do
|
727
|
+
expect(packet.flags).to eq([false, false, false, false])
|
728
|
+
end
|
729
|
+
|
730
|
+
it "should set the Protocol Name of the packet correctly" do
|
731
|
+
expect(packet.protocol_name).to eq('MQIsdp')
|
732
|
+
expect(packet.protocol_name.encoding.to_s).to eq('UTF-8')
|
733
|
+
end
|
734
|
+
|
735
|
+
it "should set the Protocol Level of the packet correctly" do
|
736
|
+
expect(packet.protocol_level).to eq(3)
|
737
|
+
end
|
738
|
+
|
739
|
+
it "should set the Protocol version of the packet correctly" do
|
740
|
+
expect(packet.version).to eq('3.1.0')
|
741
|
+
end
|
742
|
+
|
743
|
+
it "should set the Client Identifier of the packet correctly" do
|
744
|
+
expect(packet.client_id).to eq('myclient')
|
745
|
+
expect(packet.client_id.encoding.to_s).to eq('UTF-8')
|
746
|
+
end
|
747
|
+
|
748
|
+
it "should set the clean session flag should be set" do
|
749
|
+
expect(packet.clean_session).to be_truthy
|
750
|
+
end
|
751
|
+
|
752
|
+
it "should set the QoS of the Will should be 1" do
|
753
|
+
expect(packet.will_qos).to eq(1)
|
754
|
+
end
|
755
|
+
|
756
|
+
it "should set the Will retain flag should be false" do
|
757
|
+
expect(packet.will_retain).to be_falsey
|
758
|
+
end
|
759
|
+
|
760
|
+
it "should set the Will topic of the packet correctly" do
|
761
|
+
expect(packet.will_topic).to eq('topic')
|
762
|
+
expect(packet.will_topic.encoding.to_s).to eq('UTF-8')
|
763
|
+
end
|
764
|
+
|
765
|
+
it "should set the Will payload of the packet correctly" do
|
766
|
+
expect(packet.will_payload).to eq('hello')
|
767
|
+
expect(packet.will_payload.encoding.to_s).to eq('UTF-8')
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
describe "when parsing a Connect packet with a username and password" do
|
772
|
+
let(:packet) do
|
773
|
+
MQTT::Packet.parse(
|
774
|
+
"\x10\x2A"+
|
775
|
+
"\x00\x06MQIsdp"+
|
776
|
+
"\x03\xC0\x00\x0a"+
|
777
|
+
"\x00\x08myclient"+
|
778
|
+
"\x00\x08username"+
|
779
|
+
"\x00\x08password"
|
780
|
+
)
|
781
|
+
end
|
782
|
+
|
783
|
+
it "should correctly create the right type of packet object" do
|
784
|
+
expect(packet.class).to eq(MQTT::Packet::Connect)
|
785
|
+
end
|
786
|
+
|
787
|
+
it "should set the fixed header flags of the packet correctly" do
|
788
|
+
expect(packet.flags).to eq([false, false, false, false])
|
789
|
+
end
|
790
|
+
|
791
|
+
it "should set the Protocol Name of the packet correctly" do
|
792
|
+
expect(packet.protocol_name).to eq('MQIsdp')
|
793
|
+
expect(packet.protocol_name.encoding.to_s).to eq('UTF-8')
|
794
|
+
end
|
795
|
+
|
796
|
+
it "should set the Protocol Level of the packet correctly" do
|
797
|
+
expect(packet.protocol_level).to eq(3)
|
798
|
+
end
|
799
|
+
|
800
|
+
it "should set the Protocol version of the packet correctly" do
|
801
|
+
expect(packet.version).to eq('3.1.0')
|
802
|
+
end
|
803
|
+
|
804
|
+
it "should set the Client Identifier of the packet correctly" do
|
805
|
+
expect(packet.client_id).to eq('myclient')
|
806
|
+
expect(packet.client_id.encoding.to_s).to eq('UTF-8')
|
807
|
+
end
|
808
|
+
|
809
|
+
it "should set the Keep Alive Timer of the packet correctly" do
|
810
|
+
expect(packet.keep_alive).to eq(10)
|
811
|
+
end
|
812
|
+
|
813
|
+
it "should set the Username of the packet correctly" do
|
814
|
+
expect(packet.username).to eq('username')
|
815
|
+
expect(packet.username.encoding.to_s).to eq('UTF-8')
|
816
|
+
end
|
817
|
+
|
818
|
+
it "should set the Username of the packet correctly" do
|
819
|
+
expect(packet.password).to eq('password')
|
820
|
+
expect(packet.password.encoding.to_s).to eq('UTF-8')
|
821
|
+
end
|
822
|
+
end
|
823
|
+
|
824
|
+
describe "when parsing a Connect that has a username but no password" do
|
825
|
+
let(:packet) do
|
826
|
+
MQTT::Packet.parse(
|
827
|
+
"\x10\x20\x00\x06MQIsdp\x03\x80\x00\x0a\x00\x08myclient\x00\x08username"
|
828
|
+
)
|
829
|
+
end
|
830
|
+
|
831
|
+
it "should set the Username of the packet correctly" do
|
832
|
+
expect(packet.username).to eq('username')
|
833
|
+
expect(packet.username.encoding.to_s).to eq('UTF-8')
|
834
|
+
end
|
835
|
+
|
836
|
+
it "should set the Username of the packet correctly" do
|
837
|
+
expect(packet.password).to be_nil
|
838
|
+
end
|
839
|
+
end
|
840
|
+
|
841
|
+
describe "when parsing a Connect that has a password but no username" do
|
842
|
+
let(:packet) do
|
843
|
+
MQTT::Packet.parse(
|
844
|
+
"\x10\x20\x00\x06MQIsdp\x03\x40\x00\x0a\x00\x08myclient\x00\x08password"
|
845
|
+
)
|
846
|
+
end
|
847
|
+
|
848
|
+
it "should set the Username of the packet correctly" do
|
849
|
+
expect(packet.username).to be_nil
|
850
|
+
end
|
851
|
+
|
852
|
+
it "should set the Username of the packet correctly" do
|
853
|
+
expect(packet.password).to eq('password')
|
854
|
+
expect(packet.password.encoding.to_s).to eq('UTF-8')
|
855
|
+
end
|
856
|
+
end
|
857
|
+
|
858
|
+
describe "when parsing a Connect packet has the username and password flags set but doesn't have the fields" do
|
859
|
+
let(:packet) do
|
860
|
+
MQTT::Packet.parse(
|
861
|
+
"\x10\x16\x00\x06MQIsdp\x03\xC0\x00\x0a\x00\x08myclient"
|
862
|
+
)
|
863
|
+
end
|
864
|
+
|
865
|
+
it "should set the Username of the packet correctly" do
|
866
|
+
expect(packet.username).to be_nil
|
867
|
+
end
|
868
|
+
|
869
|
+
it "should set the Username of the packet correctly" do
|
870
|
+
expect(packet.password).to be_nil
|
871
|
+
end
|
872
|
+
end
|
873
|
+
|
874
|
+
describe "when parsing a Connect packet with every option set" do
|
875
|
+
let(:packet) do
|
876
|
+
MQTT::Packet.parse(
|
877
|
+
"\x10\x5F"+ # fixed header (2)
|
878
|
+
"\x00\x06MQIsdp"+ # protocol name (8)
|
879
|
+
"\x03\xf6"+ # protocol level + flags (2)
|
880
|
+
"\xff\xff"+ # keep alive (2)
|
881
|
+
"\x00\x1712345678901234567890123"+ # client identifier (25)
|
882
|
+
"\x00\x0Awill_topic"+ # will topic (12)
|
883
|
+
"\x00\x0Cwill_message"+ # will message (14)
|
884
|
+
"\x00\x0Euser0123456789"+ # username (16)
|
885
|
+
"\x00\x0Epass0123456789" # password (16)
|
886
|
+
)
|
887
|
+
end
|
888
|
+
|
889
|
+
it "should correctly create the right type of packet object" do
|
890
|
+
expect(packet.class).to eq(MQTT::Packet::Connect)
|
891
|
+
end
|
892
|
+
|
893
|
+
it "should set the fixed header flags of the packet correctly" do
|
894
|
+
expect(packet.flags).to eq([false, false, false, false])
|
895
|
+
end
|
896
|
+
|
897
|
+
it "should set the Protocol Name of the packet correctly" do
|
898
|
+
expect(packet.protocol_name).to eq('MQIsdp')
|
899
|
+
expect(packet.protocol_name.encoding.to_s).to eq('UTF-8')
|
900
|
+
end
|
901
|
+
|
902
|
+
it "should set the Protocol Level of the packet correctly" do
|
903
|
+
expect(packet.protocol_level).to eq(3)
|
904
|
+
end
|
905
|
+
|
906
|
+
it "should set the Protocol version of the packet correctly" do
|
907
|
+
expect(packet.version).to eq('3.1.0')
|
908
|
+
end
|
909
|
+
|
910
|
+
it "should set the Keep Alive Timer of the packet correctly" do
|
911
|
+
expect(packet.keep_alive).to eq(65535)
|
912
|
+
end
|
913
|
+
|
914
|
+
it "should set the Client Identifier of the packet correctly" do
|
915
|
+
expect(packet.client_id).to eq('12345678901234567890123')
|
916
|
+
expect(packet.client_id.encoding.to_s).to eq('UTF-8')
|
917
|
+
end
|
918
|
+
|
919
|
+
it "should set the Will QoS of the packet correctly" do
|
920
|
+
expect(packet.will_qos).to eq(2)
|
921
|
+
end
|
922
|
+
|
923
|
+
it "should set the Will retain flag of the packet correctly" do
|
924
|
+
expect(packet.will_retain).to be_truthy
|
925
|
+
end
|
926
|
+
|
927
|
+
it "should set the Will topic of the packet correctly" do
|
928
|
+
expect(packet.will_topic).to eq('will_topic')
|
929
|
+
expect(packet.will_topic.encoding.to_s).to eq('UTF-8')
|
930
|
+
end
|
931
|
+
|
932
|
+
it "should set the Will payload of the packet correctly" do
|
933
|
+
expect(packet.will_payload).to eq('will_message')
|
934
|
+
expect(packet.will_payload.encoding.to_s).to eq('UTF-8')
|
935
|
+
end
|
936
|
+
|
937
|
+
it "should set the Username of the packet correctly" do
|
938
|
+
expect(packet.username).to eq('user0123456789')
|
939
|
+
expect(packet.username.encoding.to_s).to eq('UTF-8')
|
940
|
+
end
|
941
|
+
|
942
|
+
it "should set the Username of the packet correctly" do
|
943
|
+
expect(packet.password).to eq('pass0123456789')
|
944
|
+
expect(packet.password.encoding.to_s).to eq('UTF-8')
|
945
|
+
end
|
946
|
+
end
|
947
|
+
|
948
|
+
describe "when parsing packet with an unknown protocol name" do
|
949
|
+
it "should raise a protocol exception" do
|
950
|
+
expect {
|
951
|
+
packet = MQTT::Packet.parse(
|
952
|
+
"\x10\x16\x00\x06FooBar\x03\x00\x00\x0a\x00\x08myclient"
|
953
|
+
)
|
954
|
+
}.to raise_error(
|
955
|
+
MQTT::ProtocolException,
|
956
|
+
"Unsupported protocol: FooBar/3"
|
957
|
+
)
|
958
|
+
end
|
959
|
+
end
|
960
|
+
|
961
|
+
describe "when parsing packet with an unknown protocol level" do
|
962
|
+
it "should raise a protocol exception" do
|
963
|
+
expect {
|
964
|
+
packet = MQTT::Packet.parse(
|
965
|
+
"\x10\x16\x00\x06MQIsdp\x02\x00\x00\x0a\x00\x08myclient"
|
966
|
+
)
|
967
|
+
}.to raise_error(
|
968
|
+
MQTT::ProtocolException,
|
969
|
+
"Unsupported protocol: MQIsdp/2"
|
970
|
+
)
|
971
|
+
end
|
972
|
+
end
|
973
|
+
|
974
|
+
describe "when parsing packet with invalid fixed header flags" do
|
975
|
+
it "should raise a protocol exception" do
|
976
|
+
expect {
|
977
|
+
MQTT::Packet.parse(
|
978
|
+
"\x13\x16\x00\x06MQIsdp\x03\x00\x00\x0a\x00\x08myclient"
|
979
|
+
)
|
980
|
+
}.to raise_error(
|
981
|
+
MQTT::ProtocolException,
|
982
|
+
"Invalid flags in CONNECT packet header"
|
983
|
+
)
|
984
|
+
end
|
985
|
+
end
|
986
|
+
|
987
|
+
describe "when calling the inspect method" do
|
988
|
+
it "should output correct string for the default options" do
|
989
|
+
packet = MQTT::Packet::Connect.new
|
990
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Connect: keep_alive=15, clean, client_id=''>")
|
991
|
+
end
|
992
|
+
|
993
|
+
it "should output correct string when parameters are given" do
|
994
|
+
packet = MQTT::Packet::Connect.new(
|
995
|
+
:keep_alive => 10,
|
996
|
+
:client_id => 'c123',
|
997
|
+
:clean_session => false,
|
998
|
+
:username => 'foo'
|
999
|
+
)
|
1000
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Connect: keep_alive=10, client_id='c123', username='foo'>")
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
describe "deprecated attributes" do
|
1005
|
+
it "should still have a protocol_version method that is that same as protocol_level" do
|
1006
|
+
packet = MQTT::Packet::Connect.new
|
1007
|
+
packet.protocol_version = 5
|
1008
|
+
expect(packet.protocol_version).to eq(5)
|
1009
|
+
expect(packet.protocol_level).to eq(5)
|
1010
|
+
packet.protocol_version = 4
|
1011
|
+
expect(packet.protocol_version).to eq(4)
|
1012
|
+
expect(packet.protocol_level).to eq(4)
|
1013
|
+
end
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
describe MQTT::Packet::Connack do
|
1018
|
+
|
1019
|
+
describe "when setting attributes on a packet" do
|
1020
|
+
let(:packet) { MQTT::Packet::Connack.new }
|
1021
|
+
|
1022
|
+
it "should let you change the session present flag of a packet" do
|
1023
|
+
packet.session_present = true
|
1024
|
+
expect(packet.session_present).to be_truthy
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
it "should let you change the session present flag of a packet using an integer" do
|
1028
|
+
packet.session_present = 1
|
1029
|
+
expect(packet.session_present).to be_truthy
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
it "should let you change the return code of a packet" do
|
1033
|
+
packet.return_code = 3
|
1034
|
+
expect(packet.return_code).to eq(3)
|
1035
|
+
end
|
1036
|
+
end
|
1037
|
+
|
1038
|
+
describe "when serialising a packet" do
|
1039
|
+
it "should output the correct bytes for a sucessful connection acknowledgement packet without Session Present set" do
|
1040
|
+
packet = MQTT::Packet::Connack.new( :return_code => 0x00, :session_present => false )
|
1041
|
+
expect(packet.to_s).to eq("\x20\x02\x00\x00")
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
it "should output the correct bytes for a sucessful connection acknowledgement packet with Session Present set" do
|
1045
|
+
packet = MQTT::Packet::Connack.new( :return_code => 0x00, :session_present => true )
|
1046
|
+
expect(packet.to_s).to eq("\x20\x02\x01\x00")
|
1047
|
+
end
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
describe "when parsing a successful Connection Accepted packet" do
|
1051
|
+
let(:packet) do
|
1052
|
+
MQTT::Packet.parse( "\x20\x02\x00\x00" )
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
it "should correctly create the right type of packet object" do
|
1056
|
+
expect(packet.class).to eq(MQTT::Packet::Connack)
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
it "should set the fixed header flags of the packet correctly" do
|
1060
|
+
expect(packet.flags).to eq([false, false, false, false])
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
it "should set the Session Pression flag of the packet correctly" do
|
1064
|
+
expect(packet.session_present).to eq(false)
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
it "should set the return code of the packet correctly" do
|
1068
|
+
expect(packet.return_code).to eq(0x00)
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
it "should set the return message of the packet correctly" do
|
1072
|
+
expect(packet.return_msg).to match(/Connection Accepted/i)
|
1073
|
+
end
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
describe "when parsing a successful Connection Accepted packet with Session Present set" do
|
1077
|
+
let(:packet) do
|
1078
|
+
MQTT::Packet.parse( "\x20\x02\x01\x00" )
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
it "should correctly create the right type of packet object" do
|
1082
|
+
expect(packet.class).to eq(MQTT::Packet::Connack)
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
it "should set the fixed header flags of the packet correctly" do
|
1086
|
+
expect(packet.flags).to eq([false, false, false, false])
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
it "should set the Session Pression flag of the packet correctly" do
|
1090
|
+
expect(packet.session_present).to eq(true)
|
1091
|
+
end
|
1092
|
+
|
1093
|
+
it "should set the return code of the packet correctly" do
|
1094
|
+
expect(packet.return_code).to eq(0x00)
|
1095
|
+
end
|
1096
|
+
|
1097
|
+
it "should set the return message of the packet correctly" do
|
1098
|
+
expect(packet.return_msg).to match(/Connection Accepted/i)
|
1099
|
+
end
|
1100
|
+
end
|
1101
|
+
|
1102
|
+
describe "when parsing a unacceptable protocol version packet" do
|
1103
|
+
let(:packet) do
|
1104
|
+
MQTT::Packet.parse( "\x20\x02\x00\x01" )
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
it "should correctly create the right type of packet object" do
|
1108
|
+
expect(packet.class).to eq(MQTT::Packet::Connack)
|
1109
|
+
end
|
1110
|
+
|
1111
|
+
it "should set the return code of the packet correctly" do
|
1112
|
+
expect(packet.return_code).to eq(0x01)
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
it "should set the return message of the packet correctly" do
|
1116
|
+
expect(packet.return_msg).to match(/unacceptable protocol version/i)
|
1117
|
+
end
|
1118
|
+
end
|
1119
|
+
|
1120
|
+
describe "when parsing a client identifier rejected packet" do
|
1121
|
+
let(:packet) { MQTT::Packet.parse( "\x20\x02\x00\x02" ) }
|
1122
|
+
|
1123
|
+
it "should correctly create the right type of packet object" do
|
1124
|
+
expect(packet.class).to eq(MQTT::Packet::Connack)
|
1125
|
+
end
|
1126
|
+
|
1127
|
+
it "should set the return code of the packet correctly" do
|
1128
|
+
expect(packet.return_code).to eq(0x02)
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
it "should set the return message of the packet correctly" do
|
1132
|
+
expect(packet.return_msg).to match(/client identifier rejected/i)
|
1133
|
+
end
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
describe "when parsing a server unavailable packet" do
|
1137
|
+
let(:packet) do
|
1138
|
+
MQTT::Packet.parse( "\x20\x02\x00\x03" )
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
it "should correctly create the right type of packet object" do
|
1142
|
+
expect(packet.class).to eq(MQTT::Packet::Connack)
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
it "should set the return code of the packet correctly" do
|
1146
|
+
expect(packet.return_code).to eq(0x03)
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
it "should set the return message of the packet correctly" do
|
1150
|
+
expect(packet.return_msg).to match(/server unavailable/i)
|
1151
|
+
end
|
1152
|
+
end
|
1153
|
+
|
1154
|
+
describe "when parsing a server unavailable packet" do
|
1155
|
+
let(:packet) do
|
1156
|
+
MQTT::Packet.parse( "\x20\x02\x00\x04" )
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
it "should correctly create the right type of packet object" do
|
1160
|
+
expect(packet.class).to eq(MQTT::Packet::Connack)
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
it "should set the return code of the packet correctly" do
|
1164
|
+
expect(packet.return_code).to eq(0x04)
|
1165
|
+
end
|
1166
|
+
|
1167
|
+
it "should set the return message of the packet correctly" do
|
1168
|
+
expect(packet.return_msg).to match(/bad user name or password/i)
|
1169
|
+
end
|
1170
|
+
end
|
1171
|
+
|
1172
|
+
describe "when parsing a server unavailable packet" do
|
1173
|
+
let(:packet) do
|
1174
|
+
MQTT::Packet.parse( "\x20\x02\x00\x05" )
|
1175
|
+
end
|
1176
|
+
|
1177
|
+
it "should correctly create the right type of packet object" do
|
1178
|
+
expect(packet.class).to eq(MQTT::Packet::Connack)
|
1179
|
+
end
|
1180
|
+
|
1181
|
+
it "should set the return code of the packet correctly" do
|
1182
|
+
expect(packet.return_code).to eq(0x05)
|
1183
|
+
end
|
1184
|
+
|
1185
|
+
it "should set the return message of the packet correctly" do
|
1186
|
+
expect(packet.return_msg).to match(/not authorised/i)
|
1187
|
+
end
|
1188
|
+
end
|
1189
|
+
|
1190
|
+
describe "when parsing an unknown connection refused packet" do
|
1191
|
+
let(:packet) { MQTT::Packet.parse( "\x20\x02\x00\x10" ) }
|
1192
|
+
|
1193
|
+
it "should correctly create the right type of packet object" do
|
1194
|
+
expect(packet.class).to eq(MQTT::Packet::Connack)
|
1195
|
+
end
|
1196
|
+
|
1197
|
+
it "should set the return code of the packet correctly" do
|
1198
|
+
expect(packet.return_code).to eq(0x10)
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
it "should set the return message of the packet correctly" do
|
1202
|
+
expect(packet.return_msg).to match(/Connection refused: error code 16/i)
|
1203
|
+
end
|
1204
|
+
end
|
1205
|
+
|
1206
|
+
describe "when parsing packet with invalid Connack flags set" do
|
1207
|
+
it "should raise an exception" do
|
1208
|
+
expect {
|
1209
|
+
packet = MQTT::Packet.parse( "\x20\x02\xff\x05" )
|
1210
|
+
}.to raise_error(
|
1211
|
+
MQTT::ProtocolException,
|
1212
|
+
"Invalid flags in Connack variable header"
|
1213
|
+
)
|
1214
|
+
end
|
1215
|
+
end
|
1216
|
+
|
1217
|
+
describe "when parsing packet with extra bytes on the end" do
|
1218
|
+
it "should raise an exception" do
|
1219
|
+
expect {
|
1220
|
+
packet = MQTT::Packet.parse( "\x20\x03\x00\x00\x00" )
|
1221
|
+
}.to raise_error(
|
1222
|
+
MQTT::ProtocolException,
|
1223
|
+
"Extra bytes at end of Connect Acknowledgment packet"
|
1224
|
+
)
|
1225
|
+
end
|
1226
|
+
end
|
1227
|
+
|
1228
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1229
|
+
it "should raise a protocol exception" do
|
1230
|
+
expect {
|
1231
|
+
MQTT::Packet.parse( "\x23\x02\x00\x00" )
|
1232
|
+
}.to raise_error(
|
1233
|
+
MQTT::ProtocolException,
|
1234
|
+
"Invalid flags in CONNACK packet header"
|
1235
|
+
)
|
1236
|
+
end
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
describe "when calling the inspect method" do
|
1240
|
+
it "should output the right string when the return code is 0" do
|
1241
|
+
packet = MQTT::Packet::Connack.new( :return_code => 0x00 )
|
1242
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Connack: 0x00>")
|
1243
|
+
end
|
1244
|
+
it "should output the right string when the return code is 0x0F" do
|
1245
|
+
packet = MQTT::Packet::Connack.new( :return_code => 0x0F )
|
1246
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Connack: 0x0F>")
|
1247
|
+
end
|
1248
|
+
end
|
1249
|
+
end
|
1250
|
+
|
1251
|
+
describe MQTT::Packet::Puback do
|
1252
|
+
describe "when serialising a packet" do
|
1253
|
+
it "should output the correct bytes for a packet with no flags" do
|
1254
|
+
packet = MQTT::Packet::Puback.new( :id => 0x1234 )
|
1255
|
+
expect(packet.to_s).to eq("\x40\x02\x12\x34")
|
1256
|
+
end
|
1257
|
+
end
|
1258
|
+
|
1259
|
+
describe "when parsing a packet" do
|
1260
|
+
let(:packet) { MQTT::Packet.parse( "\x40\x02\x12\x34" ) }
|
1261
|
+
|
1262
|
+
it "should correctly create the right type of packet object" do
|
1263
|
+
expect(packet.class).to eq(MQTT::Packet::Puback)
|
1264
|
+
end
|
1265
|
+
|
1266
|
+
it "should set the message id of the packet correctly" do
|
1267
|
+
expect(packet.id).to eq(0x1234)
|
1268
|
+
end
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
describe "when parsing packet with extra bytes on the end" do
|
1272
|
+
it "should raise an exception" do
|
1273
|
+
expect {
|
1274
|
+
packet = MQTT::Packet.parse( "\x40\x03\x12\x34\x00" )
|
1275
|
+
}.to raise_error(
|
1276
|
+
MQTT::ProtocolException,
|
1277
|
+
"Extra bytes at end of Publish Acknowledgment packet"
|
1278
|
+
)
|
1279
|
+
end
|
1280
|
+
end
|
1281
|
+
|
1282
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1283
|
+
it "should raise a protocol exception" do
|
1284
|
+
expect {
|
1285
|
+
MQTT::Packet.parse( "\x43\x02\x12\x34" )
|
1286
|
+
}.to raise_error(
|
1287
|
+
MQTT::ProtocolException,
|
1288
|
+
"Invalid flags in PUBACK packet header"
|
1289
|
+
)
|
1290
|
+
end
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
it "should output the right string when calling inspect" do
|
1294
|
+
packet = MQTT::Packet::Puback.new( :id => 0x1234 )
|
1295
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Puback: 0x1234>")
|
1296
|
+
end
|
1297
|
+
end
|
1298
|
+
|
1299
|
+
describe MQTT::Packet::Pubrec do
|
1300
|
+
describe "when serialising a packet" do
|
1301
|
+
it "should output the correct bytes for a packet with no flags" do
|
1302
|
+
packet = MQTT::Packet::Pubrec.new( :id => 0x1234 )
|
1303
|
+
expect(packet.to_s).to eq("\x50\x02\x12\x34")
|
1304
|
+
end
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
describe "when parsing a packet" do
|
1308
|
+
let(:packet) { MQTT::Packet.parse( "\x50\x02\x12\x34" ) }
|
1309
|
+
|
1310
|
+
it "should correctly create the right type of packet object" do
|
1311
|
+
expect(packet.class).to eq(MQTT::Packet::Pubrec)
|
1312
|
+
end
|
1313
|
+
|
1314
|
+
it "should set the message id of the packet correctly" do
|
1315
|
+
expect(packet.id).to eq(0x1234)
|
1316
|
+
end
|
1317
|
+
end
|
1318
|
+
|
1319
|
+
describe "when parsing packet with extra bytes on the end" do
|
1320
|
+
it "should raise an exception" do
|
1321
|
+
expect {
|
1322
|
+
packet = MQTT::Packet.parse( "\x50\x03\x12\x34\x00" )
|
1323
|
+
}.to raise_error(
|
1324
|
+
MQTT::ProtocolException,
|
1325
|
+
"Extra bytes at end of Publish Received packet"
|
1326
|
+
)
|
1327
|
+
end
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1331
|
+
it "should raise a protocol exception" do
|
1332
|
+
expect {
|
1333
|
+
MQTT::Packet.parse( "\x53\x02\x12\x34" )
|
1334
|
+
}.to raise_error(
|
1335
|
+
MQTT::ProtocolException,
|
1336
|
+
"Invalid flags in PUBREC packet header"
|
1337
|
+
)
|
1338
|
+
end
|
1339
|
+
end
|
1340
|
+
|
1341
|
+
it "should output the right string when calling inspect" do
|
1342
|
+
packet = MQTT::Packet::Pubrec.new( :id => 0x1234 )
|
1343
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Pubrec: 0x1234>")
|
1344
|
+
end
|
1345
|
+
end
|
1346
|
+
|
1347
|
+
describe MQTT::Packet::Pubrel do
|
1348
|
+
describe "when serialising a packet" do
|
1349
|
+
it "should output the correct bytes for a packet with no flags" do
|
1350
|
+
packet = MQTT::Packet::Pubrel.new( :id => 0x1234 )
|
1351
|
+
expect(packet.to_s).to eq("\x62\x02\x12\x34")
|
1352
|
+
end
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
describe "when parsing a packet" do
|
1356
|
+
let(:packet) { MQTT::Packet.parse( "\x62\x02\x12\x34" ) }
|
1357
|
+
|
1358
|
+
it "should correctly create the right type of packet object" do
|
1359
|
+
expect(packet.class).to eq(MQTT::Packet::Pubrel)
|
1360
|
+
end
|
1361
|
+
|
1362
|
+
it "should set the message id of the packet correctly" do
|
1363
|
+
expect(packet.id).to eq(0x1234)
|
1364
|
+
end
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
describe "when parsing packet with extra bytes on the end" do
|
1368
|
+
it "should raise an exception" do
|
1369
|
+
expect {
|
1370
|
+
packet = MQTT::Packet.parse( "\x62\x03\x12\x34\x00" )
|
1371
|
+
}.to raise_error(
|
1372
|
+
MQTT::ProtocolException,
|
1373
|
+
"Extra bytes at end of Publish Release packet"
|
1374
|
+
)
|
1375
|
+
end
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1379
|
+
it "should raise a protocol exception" do
|
1380
|
+
expect {
|
1381
|
+
MQTT::Packet.parse( "\x60\x02\x12\x34" )
|
1382
|
+
}.to raise_error(
|
1383
|
+
MQTT::ProtocolException,
|
1384
|
+
"Invalid flags in PUBREL packet header"
|
1385
|
+
)
|
1386
|
+
end
|
1387
|
+
end
|
1388
|
+
|
1389
|
+
it "should output the right string when calling inspect" do
|
1390
|
+
packet = MQTT::Packet::Pubrel.new( :id => 0x1234 )
|
1391
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Pubrel: 0x1234>")
|
1392
|
+
end
|
1393
|
+
end
|
1394
|
+
|
1395
|
+
describe MQTT::Packet::Pubcomp do
|
1396
|
+
describe "when serialising a packet" do
|
1397
|
+
it "should output the correct bytes for a packet with no flags" do
|
1398
|
+
packet = MQTT::Packet::Pubcomp.new( :id => 0x1234 )
|
1399
|
+
expect(packet.to_s).to eq("\x70\x02\x12\x34")
|
1400
|
+
end
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
describe "when parsing a packet" do
|
1404
|
+
let(:packet) { MQTT::Packet.parse( "\x70\x02\x12\x34" ) }
|
1405
|
+
|
1406
|
+
it "should correctly create the right type of packet object" do
|
1407
|
+
expect(packet.class).to eq(MQTT::Packet::Pubcomp)
|
1408
|
+
end
|
1409
|
+
|
1410
|
+
it "should set the message id of the packet correctly" do
|
1411
|
+
expect(packet.id).to eq(0x1234)
|
1412
|
+
end
|
1413
|
+
end
|
1414
|
+
|
1415
|
+
describe "when parsing packet with extra bytes on the end" do
|
1416
|
+
it "should raise an exception" do
|
1417
|
+
expect {
|
1418
|
+
MQTT::Packet.parse( "\x70\x03\x12\x34\x00" )
|
1419
|
+
}.to raise_error(
|
1420
|
+
MQTT::ProtocolException,
|
1421
|
+
"Extra bytes at end of Publish Complete packet"
|
1422
|
+
)
|
1423
|
+
end
|
1424
|
+
end
|
1425
|
+
|
1426
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1427
|
+
it "should raise a protocol exception" do
|
1428
|
+
expect {
|
1429
|
+
MQTT::Packet.parse( "\x72\x02\x12\x34" )
|
1430
|
+
}.to raise_error(
|
1431
|
+
MQTT::ProtocolException,
|
1432
|
+
"Invalid flags in PUBCOMP packet header"
|
1433
|
+
)
|
1434
|
+
end
|
1435
|
+
end
|
1436
|
+
|
1437
|
+
it "should output the right string when calling inspect" do
|
1438
|
+
packet = MQTT::Packet::Pubcomp.new( :id => 0x1234 )
|
1439
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Pubcomp: 0x1234>")
|
1440
|
+
end
|
1441
|
+
end
|
1442
|
+
|
1443
|
+
describe MQTT::Packet::Subscribe do
|
1444
|
+
describe "setting the packet's topics" do
|
1445
|
+
let(:packet) { MQTT::Packet::Subscribe.new }
|
1446
|
+
|
1447
|
+
it "should be able to set the topics from a String 'a/b'" do
|
1448
|
+
packet.topics = 'a/b'
|
1449
|
+
expect(packet.topics).to eq([["a/b", 0]])
|
1450
|
+
end
|
1451
|
+
|
1452
|
+
it "should be able to set the multiple topics from an array ['a/b', 'b/c']" do
|
1453
|
+
packet.topics = ['a/b', 'b/c']
|
1454
|
+
expect(packet.topics).to eq([["a/b", 0], ['b/c', 0]])
|
1455
|
+
end
|
1456
|
+
|
1457
|
+
it "should be able to set the topics from a Hash {'a/b' => 0, 'b/c' => 1}" do
|
1458
|
+
packet.topics = {'a/b' => 0, 'b/c' => 1}
|
1459
|
+
expect(packet.topics).to eq([["a/b", 0], ["b/c", 1]])
|
1460
|
+
end
|
1461
|
+
|
1462
|
+
it "should be able to set the topics from a single level array ['a/b', 0]" do
|
1463
|
+
packet.topics = ['a/b', 0]
|
1464
|
+
expect(packet.topics).to eq([["a/b", 0]])
|
1465
|
+
end
|
1466
|
+
|
1467
|
+
it "should be able to set the topics from a two level array [['a/b' => 0], ['b/c' => 1]]" do
|
1468
|
+
packet.topics = [['a/b', 0], ['b/c', 1]]
|
1469
|
+
expect(packet.topics).to eq([['a/b', 0], ['b/c', 1]])
|
1470
|
+
end
|
1471
|
+
|
1472
|
+
it "should raise an exception when setting topic with a non-string" do
|
1473
|
+
expect {
|
1474
|
+
packet.topics = 56
|
1475
|
+
}.to raise_error(
|
1476
|
+
'Invalid topics input: 56'
|
1477
|
+
)
|
1478
|
+
end
|
1479
|
+
end
|
1480
|
+
|
1481
|
+
describe "when serialising a packet" do
|
1482
|
+
it "should output the correct bytes for a packet with a single topic" do
|
1483
|
+
packet = MQTT::Packet::Subscribe.new( :id => 1, :topics => 'a/b' )
|
1484
|
+
expect(packet.to_s).to eq("\x82\x08\x00\x01\x00\x03a/b\x00")
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
it "should output the correct bytes for a packet with multiple topics" do
|
1488
|
+
packet = MQTT::Packet::Subscribe.new( :id => 6, :topics => [['a/b', 0], ['c/d', 1]] )
|
1489
|
+
expect(packet.to_s).to eq("\x82\x0e\000\x06\x00\x03a/b\x00\x00\x03c/d\x01")
|
1490
|
+
end
|
1491
|
+
|
1492
|
+
it "should raise an exception when no topics are given" do
|
1493
|
+
expect {
|
1494
|
+
MQTT::Packet::Subscribe.new.to_s
|
1495
|
+
}.to raise_error(
|
1496
|
+
'no topics given when serialising packet'
|
1497
|
+
)
|
1498
|
+
end
|
1499
|
+
end
|
1500
|
+
|
1501
|
+
describe "when parsing a packet with a single topic" do
|
1502
|
+
let(:packet) { MQTT::Packet.parse( "\x82\x08\x00\x01\x00\x03a/b\x00" ) }
|
1503
|
+
|
1504
|
+
it "should correctly create the right type of packet object" do
|
1505
|
+
expect(packet.class).to eq(MQTT::Packet::Subscribe)
|
1506
|
+
end
|
1507
|
+
|
1508
|
+
it "should set the fixed header flags of the packet correctly" do
|
1509
|
+
expect(packet.flags).to eq([false, true, false, false])
|
1510
|
+
end
|
1511
|
+
|
1512
|
+
it "should set the Message ID correctly" do
|
1513
|
+
expect(packet.id).to eq(1)
|
1514
|
+
end
|
1515
|
+
|
1516
|
+
it "should set the topic name correctly" do
|
1517
|
+
expect(packet.topics).to eq([['a/b',0]])
|
1518
|
+
end
|
1519
|
+
end
|
1520
|
+
|
1521
|
+
describe "when parsing a packet with a two topics" do
|
1522
|
+
let(:packet) { MQTT::Packet.parse( "\x82\x0e\000\x06\x00\x03a/b\x00\x00\x03c/d\x01" ) }
|
1523
|
+
|
1524
|
+
it "should correctly create the right type of packet object" do
|
1525
|
+
expect(packet.class).to eq(MQTT::Packet::Subscribe)
|
1526
|
+
end
|
1527
|
+
|
1528
|
+
it "should set the fixed header flags of the packet correctly" do
|
1529
|
+
expect(packet.flags).to eq([false, true, false, false])
|
1530
|
+
end
|
1531
|
+
|
1532
|
+
it "should set the Message ID correctly" do
|
1533
|
+
expect(packet.id).to eq(6)
|
1534
|
+
end
|
1535
|
+
|
1536
|
+
it "should set the topic name correctly" do
|
1537
|
+
expect(packet.topics).to eq([['a/b',0],['c/d',1]])
|
1538
|
+
end
|
1539
|
+
end
|
1540
|
+
|
1541
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1542
|
+
it "should raise a protocol exception" do
|
1543
|
+
expect {
|
1544
|
+
MQTT::Packet.parse( "\x80\x08\x00\x01\x00\x03a/b\x00" )
|
1545
|
+
}.to raise_error(
|
1546
|
+
MQTT::ProtocolException,
|
1547
|
+
"Invalid flags in SUBSCRIBE packet header"
|
1548
|
+
)
|
1549
|
+
end
|
1550
|
+
end
|
1551
|
+
|
1552
|
+
describe "when calling the inspect method" do
|
1553
|
+
it "should output correct string for a single topic" do
|
1554
|
+
packet = MQTT::Packet::Subscribe.new(:topics => 'test')
|
1555
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Subscribe: 0x00, 'test':0>")
|
1556
|
+
end
|
1557
|
+
|
1558
|
+
it "should output correct string for multiple topics" do
|
1559
|
+
packet = MQTT::Packet::Subscribe.new(:topics => {'a' => 1, 'b' => 0, 'c' => 2})
|
1560
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Subscribe: 0x00, 'a':1, 'b':0, 'c':2>")
|
1561
|
+
end
|
1562
|
+
end
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
describe MQTT::Packet::Suback do
|
1566
|
+
describe "when serialising a packet" do
|
1567
|
+
it "should output the correct bytes for an acknowledgement to a single topic" do
|
1568
|
+
packet = MQTT::Packet::Suback.new( :id => 5, :return_codes => 0 )
|
1569
|
+
expect(packet.to_s).to eq("\x90\x03\x00\x05\x00")
|
1570
|
+
end
|
1571
|
+
|
1572
|
+
it "should output the correct bytes for an acknowledgement to a two topics" do
|
1573
|
+
packet = MQTT::Packet::Suback.new( :id => 6 , :return_codes => [0,1] )
|
1574
|
+
expect(packet.to_s).to eq("\x90\x04\x00\x06\x00\x01")
|
1575
|
+
end
|
1576
|
+
|
1577
|
+
it "should raise an exception when no granted QoSs are given" do
|
1578
|
+
expect {
|
1579
|
+
MQTT::Packet::Suback.new( :id => 7 ).to_s
|
1580
|
+
}.to raise_error(
|
1581
|
+
'no granted QoS given when serialising packet'
|
1582
|
+
)
|
1583
|
+
end
|
1584
|
+
|
1585
|
+
it "should raise an exception if the granted QoS is not an integer" do
|
1586
|
+
expect {
|
1587
|
+
MQTT::Packet::Suback.new( :id => 8, :return_codes => :foo ).to_s
|
1588
|
+
}.to raise_error(
|
1589
|
+
'return_codes should be an integer or an array of return codes'
|
1590
|
+
)
|
1591
|
+
end
|
1592
|
+
end
|
1593
|
+
|
1594
|
+
describe "when parsing a packet with a single QoS value of 0" do
|
1595
|
+
let(:packet) { MQTT::Packet.parse( "\x90\x03\x12\x34\x00" ) }
|
1596
|
+
|
1597
|
+
it "should correctly create the right type of packet object" do
|
1598
|
+
expect(packet.class).to eq(MQTT::Packet::Suback)
|
1599
|
+
end
|
1600
|
+
|
1601
|
+
it "should set the message id of the packet correctly" do
|
1602
|
+
expect(packet.id).to eq(0x1234)
|
1603
|
+
end
|
1604
|
+
|
1605
|
+
it "should set the Granted QoS of the packet correctly" do
|
1606
|
+
expect(packet.return_codes).to eq([0])
|
1607
|
+
end
|
1608
|
+
end
|
1609
|
+
|
1610
|
+
describe "when parsing a packet with two QoS values" do
|
1611
|
+
let(:packet) { MQTT::Packet.parse( "\x90\x04\x12\x34\x01\x01" ) }
|
1612
|
+
|
1613
|
+
it "should correctly create the right type of packet object" do
|
1614
|
+
expect(packet.class).to eq(MQTT::Packet::Suback)
|
1615
|
+
end
|
1616
|
+
|
1617
|
+
it "should set the message id of the packet correctly" do
|
1618
|
+
expect(packet.id).to eq(0x1234)
|
1619
|
+
end
|
1620
|
+
|
1621
|
+
it "should set the Granted QoS of the packet correctly" do
|
1622
|
+
expect(packet.return_codes).to eq([1,1])
|
1623
|
+
end
|
1624
|
+
end
|
1625
|
+
|
1626
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1627
|
+
it "should raise a protocol exception" do
|
1628
|
+
expect {
|
1629
|
+
MQTT::Packet.parse( "\x92\x03\x12\x34\x00" )
|
1630
|
+
}.to raise_error(
|
1631
|
+
MQTT::ProtocolException,
|
1632
|
+
"Invalid flags in SUBACK packet header"
|
1633
|
+
)
|
1634
|
+
end
|
1635
|
+
end
|
1636
|
+
|
1637
|
+
describe "when calling the inspect method" do
|
1638
|
+
it "should output correct string for a single granted qos" do
|
1639
|
+
packet = MQTT::Packet::Suback.new(:id => 0x1234, :return_codes => 0)
|
1640
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Suback: 0x1234, rc=0x00>")
|
1641
|
+
end
|
1642
|
+
|
1643
|
+
it "should output correct string for multiple topics" do
|
1644
|
+
packet = MQTT::Packet::Suback.new(:id => 0x1235, :return_codes => [0,1,2])
|
1645
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Suback: 0x1235, rc=0x00,0x01,0x02>")
|
1646
|
+
end
|
1647
|
+
end
|
1648
|
+
|
1649
|
+
describe "deprecated attributes" do
|
1650
|
+
it "should still have a granted_qos method that is that same as return_codes" do
|
1651
|
+
packet = MQTT::Packet::Suback.new
|
1652
|
+
packet.granted_qos = [0,1,2]
|
1653
|
+
expect(packet.granted_qos).to eq([0,1,2])
|
1654
|
+
expect(packet.return_codes).to eq([0,1,2])
|
1655
|
+
packet.return_codes = [0,1,0]
|
1656
|
+
expect(packet.granted_qos).to eq([0,1,0])
|
1657
|
+
expect(packet.return_codes).to eq([0,1,0])
|
1658
|
+
end
|
1659
|
+
end
|
1660
|
+
end
|
1661
|
+
|
1662
|
+
describe MQTT::Packet::Unsubscribe do
|
1663
|
+
describe "when serialising a packet" do
|
1664
|
+
it "should output the correct bytes for a packet with single topic" do
|
1665
|
+
packet = MQTT::Packet::Unsubscribe.new( :id => 5, :topics => 'a/b' )
|
1666
|
+
expect(packet.to_s).to eq("\xa2\x07\x00\x05\x00\x03a/b")
|
1667
|
+
end
|
1668
|
+
|
1669
|
+
it "should output the correct bytes for a packet with multiple topics" do
|
1670
|
+
packet = MQTT::Packet::Unsubscribe.new( :id => 6, :topics => ['a/b','c/d'] )
|
1671
|
+
expect(packet.to_s).to eq("\xa2\x0c\000\006\000\003a/b\000\003c/d")
|
1672
|
+
end
|
1673
|
+
|
1674
|
+
it "should raise an exception when no topics are given" do
|
1675
|
+
expect {
|
1676
|
+
MQTT::Packet::Unsubscribe.new.to_s
|
1677
|
+
}.to raise_error(
|
1678
|
+
'no topics given when serialising packet'
|
1679
|
+
)
|
1680
|
+
end
|
1681
|
+
end
|
1682
|
+
|
1683
|
+
describe "when parsing a packet" do
|
1684
|
+
let(:packet) { MQTT::Packet.parse( "\xa2\f\000\005\000\003a/b\000\003c/d" ) }
|
1685
|
+
|
1686
|
+
it "should correctly create the right type of packet object" do
|
1687
|
+
expect(packet.class).to eq(MQTT::Packet::Unsubscribe)
|
1688
|
+
end
|
1689
|
+
|
1690
|
+
it "should set the fixed header flags of the packet correctly" do
|
1691
|
+
expect(packet.flags).to eq([false, true, false, false])
|
1692
|
+
end
|
1693
|
+
|
1694
|
+
it "should set the topic name correctly" do
|
1695
|
+
expect(packet.topics).to eq(['a/b','c/d'])
|
1696
|
+
end
|
1697
|
+
end
|
1698
|
+
|
1699
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1700
|
+
it "should raise a protocol exception" do
|
1701
|
+
expect {
|
1702
|
+
MQTT::Packet.parse( "\xa0\x07\x00\x05\x00\x03a/b" )
|
1703
|
+
}.to raise_error(
|
1704
|
+
MQTT::ProtocolException,
|
1705
|
+
"Invalid flags in UNSUBSCRIBE packet header"
|
1706
|
+
)
|
1707
|
+
end
|
1708
|
+
end
|
1709
|
+
|
1710
|
+
describe "when calling the inspect method" do
|
1711
|
+
it "should output correct string for a single topic" do
|
1712
|
+
packet = MQTT::Packet::Unsubscribe.new(:topics => 'test')
|
1713
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Unsubscribe: 0x00, 'test'>")
|
1714
|
+
end
|
1715
|
+
|
1716
|
+
it "should output correct string for multiple topics" do
|
1717
|
+
packet = MQTT::Packet::Unsubscribe.new( :id => 42, :topics => ['a', 'b', 'c'] )
|
1718
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Unsubscribe: 0x2A, 'a', 'b', 'c'>")
|
1719
|
+
end
|
1720
|
+
end
|
1721
|
+
end
|
1722
|
+
|
1723
|
+
describe MQTT::Packet::Unsuback do
|
1724
|
+
describe "when serialising a packet" do
|
1725
|
+
it "should output the correct bytes for a packet with no flags" do
|
1726
|
+
packet = MQTT::Packet::Unsuback.new( :id => 0x1234 )
|
1727
|
+
expect(packet.to_s).to eq("\xB0\x02\x12\x34")
|
1728
|
+
end
|
1729
|
+
end
|
1730
|
+
|
1731
|
+
describe "when parsing a packet" do
|
1732
|
+
let(:packet) do
|
1733
|
+
MQTT::Packet.parse( "\xB0\x02\x12\x34" )
|
1734
|
+
end
|
1735
|
+
|
1736
|
+
it "should correctly create the right type of packet object" do
|
1737
|
+
expect(packet.class).to eq(MQTT::Packet::Unsuback)
|
1738
|
+
end
|
1739
|
+
|
1740
|
+
it "should set the message id of the packet correctly" do
|
1741
|
+
expect(packet.id).to eq(0x1234)
|
1742
|
+
end
|
1743
|
+
end
|
1744
|
+
|
1745
|
+
describe "when parsing packet with extra bytes on the end" do
|
1746
|
+
it "should raise an exception" do
|
1747
|
+
expect {
|
1748
|
+
packet = MQTT::Packet.parse( "\xB0\x03\x12\x34\x00" )
|
1749
|
+
}.to raise_error(
|
1750
|
+
MQTT::ProtocolException,
|
1751
|
+
"Extra bytes at end of Unsubscribe Acknowledgment packet"
|
1752
|
+
)
|
1753
|
+
end
|
1754
|
+
end
|
1755
|
+
|
1756
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1757
|
+
it "should raise a protocol exception" do
|
1758
|
+
expect {
|
1759
|
+
MQTT::Packet.parse( "\xB2\x02\x12\x34" )
|
1760
|
+
}.to raise_error(
|
1761
|
+
MQTT::ProtocolException,
|
1762
|
+
"Invalid flags in UNSUBACK packet header"
|
1763
|
+
)
|
1764
|
+
end
|
1765
|
+
end
|
1766
|
+
|
1767
|
+
it "should output the right string when calling inspect" do
|
1768
|
+
packet = MQTT::Packet::Unsuback.new( :id => 0x1234 )
|
1769
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Unsuback: 0x1234>")
|
1770
|
+
end
|
1771
|
+
end
|
1772
|
+
|
1773
|
+
describe MQTT::Packet::Pingreq do
|
1774
|
+
describe "when serialising a packet" do
|
1775
|
+
it "should output the correct bytes for a packet with no flags" do
|
1776
|
+
packet = MQTT::Packet::Pingreq.new
|
1777
|
+
expect(packet.to_s).to eq("\xC0\x00")
|
1778
|
+
end
|
1779
|
+
end
|
1780
|
+
|
1781
|
+
describe "when parsing a packet" do
|
1782
|
+
it "should correctly create the right type of packet object" do
|
1783
|
+
packet = MQTT::Packet.parse( "\xC0\x00" )
|
1784
|
+
expect(packet.class).to eq(MQTT::Packet::Pingreq)
|
1785
|
+
end
|
1786
|
+
|
1787
|
+
it "should raise an exception if the packet has a payload" do
|
1788
|
+
expect {
|
1789
|
+
MQTT::Packet.parse( "\xC0\x05hello" )
|
1790
|
+
}.to raise_error(
|
1791
|
+
'Extra bytes at end of Ping Request packet'
|
1792
|
+
)
|
1793
|
+
end
|
1794
|
+
end
|
1795
|
+
|
1796
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1797
|
+
it "should raise a protocol exception" do
|
1798
|
+
expect {
|
1799
|
+
MQTT::Packet.parse( "\xC2\x00" )
|
1800
|
+
}.to raise_error(
|
1801
|
+
MQTT::ProtocolException,
|
1802
|
+
"Invalid flags in PINGREQ packet header"
|
1803
|
+
)
|
1804
|
+
end
|
1805
|
+
end
|
1806
|
+
|
1807
|
+
it "should output the right string when calling inspect" do
|
1808
|
+
packet = MQTT::Packet::Pingreq.new
|
1809
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Pingreq>")
|
1810
|
+
end
|
1811
|
+
end
|
1812
|
+
|
1813
|
+
describe MQTT::Packet::Pingresp do
|
1814
|
+
describe "when serialising a packet" do
|
1815
|
+
it "should output the correct bytes for a packet with no flags" do
|
1816
|
+
packet = MQTT::Packet::Pingresp.new
|
1817
|
+
expect(packet.to_s).to eq("\xD0\x00")
|
1818
|
+
end
|
1819
|
+
end
|
1820
|
+
|
1821
|
+
describe "when parsing a packet" do
|
1822
|
+
it "should correctly create the right type of packet object" do
|
1823
|
+
packet = MQTT::Packet.parse( "\xD0\x00" )
|
1824
|
+
expect(packet.class).to eq(MQTT::Packet::Pingresp)
|
1825
|
+
end
|
1826
|
+
|
1827
|
+
it "should raise an exception if the packet has a payload" do
|
1828
|
+
expect {
|
1829
|
+
MQTT::Packet.parse( "\xD0\x05hello" )
|
1830
|
+
}.to raise_error(
|
1831
|
+
'Extra bytes at end of Ping Response packet'
|
1832
|
+
)
|
1833
|
+
end
|
1834
|
+
end
|
1835
|
+
|
1836
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1837
|
+
it "should raise a protocol exception" do
|
1838
|
+
expect {
|
1839
|
+
MQTT::Packet.parse( "\xD2\x00" )
|
1840
|
+
}.to raise_error(
|
1841
|
+
MQTT::ProtocolException,
|
1842
|
+
"Invalid flags in PINGRESP packet header"
|
1843
|
+
)
|
1844
|
+
end
|
1845
|
+
end
|
1846
|
+
|
1847
|
+
it "should output the right string when calling inspect" do
|
1848
|
+
packet = MQTT::Packet::Pingresp.new
|
1849
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Pingresp>")
|
1850
|
+
end
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
|
1854
|
+
describe MQTT::Packet::Disconnect do
|
1855
|
+
describe "when serialising a packet" do
|
1856
|
+
it "should output the correct bytes for a packet with no flags" do
|
1857
|
+
packet = MQTT::Packet::Disconnect.new
|
1858
|
+
expect(packet.to_s).to eq("\xE0\x00")
|
1859
|
+
end
|
1860
|
+
end
|
1861
|
+
|
1862
|
+
describe "when parsing a packet" do
|
1863
|
+
it "should correctly create the right type of packet object" do
|
1864
|
+
packet = MQTT::Packet.parse( "\xE0\x00" )
|
1865
|
+
expect(packet.class).to eq(MQTT::Packet::Disconnect)
|
1866
|
+
end
|
1867
|
+
|
1868
|
+
it "should raise an exception if the packet has a payload" do
|
1869
|
+
expect {
|
1870
|
+
MQTT::Packet.parse( "\xE0\x05hello" )
|
1871
|
+
}.to raise_error(
|
1872
|
+
'Extra bytes at end of Disconnect packet'
|
1873
|
+
)
|
1874
|
+
end
|
1875
|
+
end
|
1876
|
+
|
1877
|
+
describe "when parsing packet with invalid fixed header flags" do
|
1878
|
+
it "should raise a protocol exception" do
|
1879
|
+
expect {
|
1880
|
+
MQTT::Packet.parse( "\xE2\x00" )
|
1881
|
+
}.to raise_error(
|
1882
|
+
MQTT::ProtocolException,
|
1883
|
+
"Invalid flags in DISCONNECT packet header"
|
1884
|
+
)
|
1885
|
+
end
|
1886
|
+
end
|
1887
|
+
|
1888
|
+
it "should output the right string when calling inspect" do
|
1889
|
+
packet = MQTT::Packet::Disconnect.new
|
1890
|
+
expect(packet.inspect).to eq("#<MQTT::Packet::Disconnect>")
|
1891
|
+
end
|
1892
|
+
end
|
1893
|
+
|
1894
|
+
|
1895
|
+
describe "Serialising an invalid packet" do
|
1896
|
+
context "that has a no type" do
|
1897
|
+
it "should raise an exception" do
|
1898
|
+
expect {
|
1899
|
+
MQTT::Packet.new.to_s
|
1900
|
+
}.to raise_error(
|
1901
|
+
RuntimeError,
|
1902
|
+
"Invalid packet type: MQTT::Packet"
|
1903
|
+
)
|
1904
|
+
end
|
1905
|
+
end
|
1906
|
+
end
|
1907
|
+
|
1908
|
+
describe "Reading in an invalid packet from a socket" do
|
1909
|
+
context "that has 0 length" do
|
1910
|
+
it "should raise an exception" do
|
1911
|
+
expect {
|
1912
|
+
socket = StringIO.new
|
1913
|
+
MQTT::Packet.read(socket)
|
1914
|
+
}.to raise_error(
|
1915
|
+
MQTT::ProtocolException,
|
1916
|
+
"Failed to read byte from socket"
|
1917
|
+
)
|
1918
|
+
end
|
1919
|
+
end
|
1920
|
+
|
1921
|
+
context "that has an incomplete packet length header" do
|
1922
|
+
it "should raise an exception" do
|
1923
|
+
expect {
|
1924
|
+
socket = StringIO.new("\x30\xFF")
|
1925
|
+
MQTT::Packet.read(socket)
|
1926
|
+
}.to raise_error(
|
1927
|
+
MQTT::ProtocolException,
|
1928
|
+
"Failed to read byte from socket"
|
1929
|
+
)
|
1930
|
+
end
|
1931
|
+
end
|
1932
|
+
|
1933
|
+
context "that has the maximum number of bytes in the length header" do
|
1934
|
+
it "should raise an exception" do
|
1935
|
+
expect {
|
1936
|
+
socket = StringIO.new("\x30\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF")
|
1937
|
+
MQTT::Packet.read(socket)
|
1938
|
+
}.to raise_error(
|
1939
|
+
MQTT::ProtocolException,
|
1940
|
+
"Failed to parse packet - input buffer (4) is not the same as the body length header (268435455)"
|
1941
|
+
)
|
1942
|
+
end
|
1943
|
+
end
|
1944
|
+
end
|
1945
|
+
|
1946
|
+
describe "Parsing an invalid packet" do
|
1947
|
+
context "that has no length" do
|
1948
|
+
it "should raise an exception" do
|
1949
|
+
expect {
|
1950
|
+
MQTT::Packet.parse( "" )
|
1951
|
+
}.to raise_error(
|
1952
|
+
MQTT::ProtocolException,
|
1953
|
+
"Invalid packet: less than 2 bytes long"
|
1954
|
+
)
|
1955
|
+
end
|
1956
|
+
end
|
1957
|
+
|
1958
|
+
context "that has an invalid type identifier" do
|
1959
|
+
it "should raise an exception" do
|
1960
|
+
expect {
|
1961
|
+
MQTT::Packet.parse( "\x00\x00" )
|
1962
|
+
}.to raise_error(
|
1963
|
+
MQTT::ProtocolException,
|
1964
|
+
"Invalid packet type identifier: 0"
|
1965
|
+
)
|
1966
|
+
end
|
1967
|
+
end
|
1968
|
+
|
1969
|
+
context "that has an incomplete packet length header" do
|
1970
|
+
it "should raise an exception" do
|
1971
|
+
expect {
|
1972
|
+
MQTT::Packet.parse( "\x30\xFF" )
|
1973
|
+
}.to raise_error(
|
1974
|
+
MQTT::ProtocolException,
|
1975
|
+
"The packet length header is incomplete"
|
1976
|
+
)
|
1977
|
+
end
|
1978
|
+
end
|
1979
|
+
|
1980
|
+
context "that has too many bytes in the length field" do
|
1981
|
+
it "should raise an exception" do
|
1982
|
+
expect {
|
1983
|
+
MQTT::Packet.parse( "\x30\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" )
|
1984
|
+
}.to raise_error(
|
1985
|
+
MQTT::ProtocolException,
|
1986
|
+
'Failed to parse packet - input buffer (4) is not the same as the body length header (268435455)'
|
1987
|
+
)
|
1988
|
+
end
|
1989
|
+
end
|
1990
|
+
|
1991
|
+
context "that has a bigger buffer than expected" do
|
1992
|
+
it "should raise an exception" do
|
1993
|
+
expect {
|
1994
|
+
MQTT::Packet.parse( "\x30\x11\x00\x04testhello big world" )
|
1995
|
+
}.to raise_error(
|
1996
|
+
MQTT::ProtocolException,
|
1997
|
+
"Failed to parse packet - input buffer (21) is not the same as the body length header (17)"
|
1998
|
+
)
|
1999
|
+
end
|
2000
|
+
end
|
2001
|
+
|
2002
|
+
context "that has a smaller buffer than expected" do
|
2003
|
+
it "should raise an exception" do
|
2004
|
+
expect {
|
2005
|
+
MQTT::Packet.parse( "\x30\x11\x00\x04testhello" )
|
2006
|
+
}.to raise_error(
|
2007
|
+
MQTT::ProtocolException,
|
2008
|
+
"Failed to parse packet - input buffer (11) is not the same as the body length header (17)"
|
2009
|
+
)
|
2010
|
+
end
|
2011
|
+
end
|
2012
|
+
end
|