spec/mqtt_client_spec.rb in mqtt-0.5.0 vs spec/mqtt_client_spec.rb in mqtt-0.6.0
- old
+ new
@@ -21,10 +21,21 @@
else
socket
end
end
+ if Process.const_defined? :CLOCK_MONOTONIC
+ def now
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ end
+ else
+ # Support older Ruby
+ def now
+ Time.now.to_f
+ end
+ end
+
describe "initializing a client" do
it "with no arguments, it should use the defaults" do
client = MQTT::Client.new
expect(client.host).to eq(nil)
expect(client.port).to eq(1883)
@@ -569,14 +580,52 @@
client.disconnect
end
end
describe "when calling the 'publish' method" do
+ class ClientWithPubackInjection < MQTT::Client
+ def initialize
+ super(:host => 'localhost')
+ @injected_pubacks = {}
+ end
+
+ def inject_puback(packet)
+ @injected_pubacks[packet.id] = packet
+ end
+
+ def wait_for_puback(id, queue)
+ packet = @injected_pubacks.fetch(id) {
+ return super
+ }
+ queue << packet
+ end
+ end
+
+ let(:client) { ClientWithPubackInjection.new }
+
before(:each) do
client.instance_variable_set('@socket', socket)
end
+ it "should respect timeouts" do
+ require "socket"
+ rd, wr = UNIXSocket.pair
+ client = MQTT::Client.new(:host => 'localhost', :ack_timeout => 1.0)
+ client.instance_variable_set('@socket', rd)
+ t = Thread.new {
+ Thread.current[:parent] = Thread.main
+ loop do
+ client.send :receive_packet
+ end
+ }
+ start = now
+ expect(client.publish('topic','payload', false, 1)).to eq(-1)
+ elapsed = now - start
+ t.kill
+ expect(elapsed).to be_within(0.1).of(1.0)
+ end
+
it "should write a valid PUBLISH packet to the socket without the retain flag" do
client.publish('topic','payload', false, 0)
expect(socket.string).to eq("\x30\x0e\x00\x05topicpayload")
end
@@ -589,10 +638,23 @@
inject_puback(1)
client.publish('topic','payload', false, 1)
expect(socket.string).to eq("\x32\x10\x00\x05topic\x00\x01payload")
end
+ it "should wrap the packet id after 65535" do
+ 0xffff.times do |n|
+ inject_puback(n + 1)
+ client.publish('topic','payload', false, 1)
+ end
+ expect(client.instance_variable_get(:@last_packet_id)).to eq(0xffff)
+
+ socket.string = ""
+ inject_puback(1)
+ client.publish('topic','payload', false, 1)
+ expect(socket.string).to eq("\x32\x10\x00\x05topic\x00\x01payload")
+ end
+
it "should write a valid PUBLISH packet to the socket with the QoS set to 2" do
inject_puback(1)
client.publish('topic','payload', false, 2)
expect(socket.string).to eq("\x34\x10\x00\x05topic\x00\x01payload")
end
@@ -688,10 +750,19 @@
inject_packet(:topic => 'topic0', :payload => 'payload0', :qos => 0)
expect(client.queue_empty?).to be_falsey
end
end
+ describe "when calling the 'clear_queue' method" do
+ it "should clear the waiting incoming messages" do
+ inject_packet(:topic => 'topic0', :payload => 'payload0', :qos => 0)
+ expect(client.queue_length).to eq(1)
+ client.clear_queue
+ expect(client.queue_length).to eq(0)
+ end
+ end
+
describe "when calling the 'get' method" do
before(:each) do
client.instance_variable_set('@socket', socket)
end
@@ -866,34 +937,34 @@
it "should update last_ping_response when receiving a Pingresp" do
allow(MQTT::Packet).to receive(:read).and_return MQTT::Packet::Pingresp.new
client.instance_variable_set '@last_ping_response', Time.at(0)
client.send :receive_packet
- expect(client.last_ping_response).to be_within(1).of Time.now
+ expect(client.last_ping_response).to be_within(1).of now
end
end
describe "when calling the 'keep_alive!' method" do
before(:each) do
client.instance_variable_set('@socket', socket)
end
it "should send a ping packet if one is due" do
- client.instance_variable_set('@last_ping_request', Time.at(0))
+ client.instance_variable_set('@last_ping_request', 0.0)
client.send('keep_alive!')
expect(socket.string).to eq("\xC0\x00")
end
it "should update the time a ping was last sent" do
- client.instance_variable_set('@last_ping_request', Time.at(0))
+ client.instance_variable_set('@last_ping_request', 0.0)
client.send('keep_alive!')
- expect(client.instance_variable_get('@last_ping_request')).not_to eq(0)
+ expect(client.instance_variable_get('@last_ping_request')).to be_within(0.01).of(now)
end
it "should raise an exception if no ping response has been received" do
- client.instance_variable_set('@last_ping_request', Time.now)
- client.instance_variable_set('@last_ping_response', Time.at(0))
+ client.instance_variable_set('@last_ping_request', now)
+ client.instance_variable_set('@last_ping_response', 0.0)
expect {
client.send('keep_alive!')
}.to raise_error(
MQTT::ProtocolException,
/No Ping Response received for \d+ seconds/
@@ -949,9 +1020,9 @@
client.instance_variable_get('@read_queue').push(packet)
end
def inject_puback(packet_id)
packet = MQTT::Packet::Puback.new(:id => packet_id)
- client.instance_variable_get('@pubacks')[packet_id] = packet
+ client.inject_puback packet
end
end