zss 0.0.2 → 0.0.3
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 +5 -13
- data/.travis.yml +5 -5
- data/Gemfile.lock +12 -4
- data/README.md +10 -1
- data/lib/zss/client.rb +12 -10
- data/lib/zss/configuration.rb +4 -1
- data/lib/zss/error.rb +23 -2
- data/lib/zss/errors.json +59 -0
- data/lib/zss/message.rb +4 -0
- data/lib/zss/message/smi.rb +43 -0
- data/lib/zss/router.rb +42 -0
- data/lib/zss/runner.rb +37 -0
- data/lib/zss/service.rb +147 -0
- data/lib/zss/socket.rb +12 -9
- data/lib/zss/version.rb +1 -1
- data/spec/integration/client_spec.rb +3 -2
- data/spec/integration/service_spec.rb +48 -0
- data/spec/integration/socket_spec.rb +3 -2
- data/spec/spec_broker_helper.rb +55 -7
- data/spec/spec_helper.rb +9 -0
- data/spec/unit/client_spec.rb +1 -1
- data/spec/unit/error_spec.rb +25 -12
- data/spec/unit/message_spec.rb +14 -0
- data/spec/unit/router_spec.rb +97 -0
- data/spec/unit/service_spec.rb +314 -0
- data/spec/unit/socket_spec.rb +40 -30
- data/zss.gemspec +2 -0
- metadata +69 -30
data/lib/zss/socket.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ffi-rzmq'
|
2
|
+
require 'timeout'
|
2
3
|
|
3
4
|
module ZSS
|
4
5
|
class Socket
|
@@ -39,30 +40,32 @@ module ZSS
|
|
39
40
|
private
|
40
41
|
|
41
42
|
def context
|
42
|
-
|
43
|
-
fail Socket::Error, 'failed to create
|
44
|
-
yield
|
43
|
+
ctx = ZMQ::Context.create(1)
|
44
|
+
fail Socket::Error, 'failed to create create_context' unless ctx
|
45
|
+
yield ctx
|
45
46
|
ensure
|
46
|
-
check!(
|
47
|
+
check!(ctx.terminate) if ctx
|
47
48
|
end
|
48
49
|
|
49
|
-
def socket
|
50
|
+
def socket(context)
|
50
51
|
socket = context.socket ZMQ::DEALER
|
51
52
|
fail Socket::Error, 'failed to create socket' unless socket
|
52
53
|
socket.identity = "#{identity}##{SecureRandom.uuid}"
|
53
54
|
socket.setsockopt(ZMQ::LINGER, 0)
|
54
|
-
socket.
|
55
|
+
socket.connect(socket_address)
|
55
56
|
yield socket
|
56
57
|
ensure
|
57
|
-
check!
|
58
|
+
check!(socket.close) if socket
|
58
59
|
end
|
59
60
|
|
60
61
|
def send_message socket, message
|
61
62
|
frames = message.to_frames
|
62
|
-
|
63
|
+
|
64
|
+
# if it's a reply should send identity
|
65
|
+
frames.shift if message.req?
|
63
66
|
last = frames.pop
|
64
67
|
frames.each { |f| check! socket.send_string f.to_s, ZMQ::SNDMORE }
|
65
|
-
check! socket.send_string last
|
68
|
+
check! socket.send_string last.to_s
|
66
69
|
end
|
67
70
|
|
68
71
|
def receive_message socket
|
data/lib/zss/version.rb
CHANGED
@@ -16,7 +16,8 @@ describe ZSS::Client do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
after :each do
|
19
|
-
|
19
|
+
return unless @broker
|
20
|
+
@broker.join
|
20
21
|
@broker = nil
|
21
22
|
end
|
22
23
|
|
@@ -25,7 +26,7 @@ describe ZSS::Client do
|
|
25
26
|
end
|
26
27
|
|
27
28
|
it('returns service response') do
|
28
|
-
@broker =
|
29
|
+
@broker = run_broker_for_client(broker_frontend) do |msg|
|
29
30
|
expect(msg.payload).to eq("ping")
|
30
31
|
msg.status = 200
|
31
32
|
msg.payload = "PONG"
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'spec_broker_helper'
|
3
|
+
require 'em-zeromq'
|
4
|
+
require 'zss/service'
|
5
|
+
|
6
|
+
describe ZSS::Service do
|
7
|
+
include BrokerHelper
|
8
|
+
|
9
|
+
class DummyService
|
10
|
+
def ping payload, headers
|
11
|
+
headers[:took] = "0s"
|
12
|
+
return "PONG"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:broker_backend) { "ipc://socket_test" }
|
17
|
+
|
18
|
+
let(:config) do
|
19
|
+
Hashie::Mash.new(
|
20
|
+
backend: broker_backend,
|
21
|
+
heartbeat: 2000
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
let(:address) { ZSS::Message::Address.new(sid: "pong", verb: "ping") }
|
26
|
+
|
27
|
+
let(:message) { ZSS::Message.new(address: address, payload: "PING") }
|
28
|
+
|
29
|
+
subject { described_class.new(:pong, config) }
|
30
|
+
|
31
|
+
it('handles request') do
|
32
|
+
EM.run do
|
33
|
+
run_broker_for_service(broker_backend, message) do |msg|
|
34
|
+
expect(msg.payload).to eq("PONG")
|
35
|
+
expect(msg.status).to eq(200)
|
36
|
+
expect(msg.headers).to eq({ "took" => "0s" })
|
37
|
+
subject.stop
|
38
|
+
EM.stop
|
39
|
+
end
|
40
|
+
|
41
|
+
service = DummyService.new
|
42
|
+
subject.add_route(service, :ping)
|
43
|
+
subject.run
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -14,7 +14,8 @@ describe ZSS::Socket do
|
|
14
14
|
let(:message) { ZSS::Message.new(address: address, payload: "PING") }
|
15
15
|
|
16
16
|
after :each do
|
17
|
-
|
17
|
+
return unless @broker
|
18
|
+
@broker.join
|
18
19
|
@broker = nil
|
19
20
|
end
|
20
21
|
|
@@ -23,7 +24,7 @@ describe ZSS::Socket do
|
|
23
24
|
subject { ZSS::Socket.new(config) }
|
24
25
|
|
25
26
|
it('returns service response') do
|
26
|
-
@broker =
|
27
|
+
@broker = run_broker_for_client(broker_frontend) do |msg|
|
27
28
|
msg.status = 200
|
28
29
|
msg.payload = "PONG"
|
29
30
|
end
|
data/spec/spec_broker_helper.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require '
|
1
|
+
require 'em-zeromq'
|
2
2
|
require 'msgpack'
|
3
3
|
|
4
4
|
module BrokerHelper
|
5
5
|
|
6
6
|
LOG_BROKER_INFO = false
|
7
7
|
|
8
|
-
def
|
8
|
+
def run_broker_for_client(endpoint)
|
9
9
|
|
10
10
|
Thread.new do
|
11
11
|
puts "broker running" if LOG_BROKER_INFO
|
@@ -16,7 +16,7 @@ module BrokerHelper
|
|
16
16
|
context = ZMQ::Context.create
|
17
17
|
socket = context.socket ZMQ::ROUTER
|
18
18
|
socket.setsockopt(ZMQ::LINGER, 0)
|
19
|
-
socket.
|
19
|
+
socket.bind(endpoint)
|
20
20
|
puts "broker connected" if LOG_BROKER_INFO
|
21
21
|
|
22
22
|
socket.recv_strings(frames = [])
|
@@ -31,11 +31,8 @@ module BrokerHelper
|
|
31
31
|
frames = msg.to_frames
|
32
32
|
socket.send_strings(frames)
|
33
33
|
|
34
|
-
puts "broker
|
34
|
+
puts "broker reply #{frames}" if LOG_BROKER_INFO
|
35
35
|
end
|
36
|
-
|
37
|
-
Thread.stop
|
38
|
-
|
39
36
|
rescue => e
|
40
37
|
puts "WTF => #{e}"
|
41
38
|
ensure
|
@@ -49,4 +46,55 @@ module BrokerHelper
|
|
49
46
|
end
|
50
47
|
|
51
48
|
end
|
49
|
+
|
50
|
+
def run_broker_for_service(endpoint, send_message = nil)
|
51
|
+
context = EM::ZeroMQ::Context.new(1)
|
52
|
+
socket = context.socket(ZMQ::ROUTER)
|
53
|
+
socket.setsockopt(ZMQ::LINGER, 0)
|
54
|
+
socket.on(:message) do |*frames|
|
55
|
+
frames = get_frames_and_close_message(frames)
|
56
|
+
puts "broker received #{frames}" if LOG_BROKER_INFO
|
57
|
+
service_id = frames.shift if frames.length == 9
|
58
|
+
msg = ZSS::Message.parse(frames)
|
59
|
+
|
60
|
+
if msg.address.sid == 'SMI'
|
61
|
+
handle_smi_verbs(socket, msg, send_message)
|
62
|
+
else
|
63
|
+
puts "check service response" if LOG_BROKER_INFO
|
64
|
+
yield(msg) if block_given?
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
socket.bind(endpoint)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def handle_smi_verbs(socket, msg, send_message)
|
75
|
+
|
76
|
+
if msg.address.verb == 'UP'
|
77
|
+
msg.status = 200
|
78
|
+
msg.type = ZSS::Message::Type::REP
|
79
|
+
puts "broker reply to UP" if LOG_BROKER_INFO
|
80
|
+
socket.send_msg(*msg.to_frames)
|
81
|
+
|
82
|
+
if send_message
|
83
|
+
send_message.identity = msg.identity
|
84
|
+
puts "broker sending emulated client request" if LOG_BROKER_INFO
|
85
|
+
# emulate client request
|
86
|
+
socket.send_msg(*send_message.to_frames)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def get_frames_and_close_message(frames)
|
93
|
+
frames.map do |frame|
|
94
|
+
out_frame = frame.copy_out_string
|
95
|
+
frame.close
|
96
|
+
out_frame
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
52
100
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -15,5 +15,14 @@ $:.push '.'
|
|
15
15
|
require 'rspec'
|
16
16
|
require 'pry'
|
17
17
|
require 'zss'
|
18
|
+
require 'timeout'
|
18
19
|
|
19
20
|
Dir['spec/support/**/*.rb'].each &method(:require)
|
21
|
+
|
22
|
+
RSpec.configure do |c|
|
23
|
+
c.around(:each) do |example|
|
24
|
+
Timeout::timeout(2) {
|
25
|
+
example.run
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
data/spec/unit/client_spec.rb
CHANGED
data/spec/unit/error_spec.rb
CHANGED
@@ -6,22 +6,35 @@ describe ZSS::Error do
|
|
6
6
|
Hashie::Mash.new(userMessage: "user info", developerMessage: "dev info")
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
described_class.new(500, response)
|
11
|
-
end
|
9
|
+
describe('#ctor') do
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
subject do
|
12
|
+
described_class.new(500, response)
|
13
|
+
end
|
14
|
+
|
15
|
+
it('returns a fullfilled error.message') do
|
16
|
+
expect(subject.code).to eq(500)
|
17
|
+
expect(subject.developer_message).to eq("dev info")
|
18
|
+
expect(subject.user_message).to eq("user info")
|
19
|
+
end
|
20
|
+
|
21
|
+
it('returns error with dev info as error.message') do
|
22
|
+
expect(subject.message).to eq("dev info")
|
23
|
+
end
|
24
|
+
|
25
|
+
it('returns error with stacktrace') do
|
26
|
+
expect(subject.backtrace).not_to be_nil
|
27
|
+
end
|
18
28
|
|
19
|
-
it('returns error with dev info as error.message') do
|
20
|
-
expect(subject.message).to eq("dev info")
|
21
29
|
end
|
22
30
|
|
23
|
-
|
24
|
-
|
31
|
+
describe('.[]') do
|
32
|
+
|
33
|
+
it('returns the error') do
|
34
|
+
result = described_class[500]
|
35
|
+
expect(result.code).to eq(500)
|
36
|
+
end
|
37
|
+
|
25
38
|
end
|
26
39
|
|
27
40
|
end
|
data/spec/unit/message_spec.rb
CHANGED
@@ -183,4 +183,18 @@ describe ZSS::Message do
|
|
183
183
|
|
184
184
|
end
|
185
185
|
|
186
|
+
describe('.req?') do
|
187
|
+
|
188
|
+
it('returns true on request message') do
|
189
|
+
message.type = ZSS::Message::Type::REQ
|
190
|
+
expect(message.req?).to eq(true)
|
191
|
+
end
|
192
|
+
|
193
|
+
it('returns false on response message') do
|
194
|
+
message.type = ZSS::Message::Type::REP
|
195
|
+
expect(message.req?).to eq(false)
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
186
200
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'zss/router'
|
3
|
+
|
4
|
+
describe ZSS::Router do
|
5
|
+
|
6
|
+
class Dummy
|
7
|
+
|
8
|
+
def print(payload); end
|
9
|
+
|
10
|
+
def print_with_headers(payload, header); end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
subject { described_class.new }
|
15
|
+
|
16
|
+
let(:context_object) { Dummy.new }
|
17
|
+
|
18
|
+
describe('#ctor') do
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe('#add_route') do
|
23
|
+
|
24
|
+
it('register route successfully') do
|
25
|
+
subject.add(context_object, "print", :print)
|
26
|
+
end
|
27
|
+
|
28
|
+
it('register route successfully without handler') do
|
29
|
+
subject.add(context_object, :print)
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
context('on error') do
|
34
|
+
|
35
|
+
it('raises a Error on invalid context') do
|
36
|
+
expect { subject.add(nil, :route) }.
|
37
|
+
to raise_exception
|
38
|
+
end
|
39
|
+
|
40
|
+
it('raises a Error on invalid route') do
|
41
|
+
expect { subject.add(context_object, nil) }.
|
42
|
+
to raise_exception
|
43
|
+
end
|
44
|
+
|
45
|
+
it('raises a Error on invalid handler') do
|
46
|
+
expect { subject.add(context_object, :route) }.
|
47
|
+
to raise_exception
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe('#get_route') do
|
55
|
+
|
56
|
+
before(:each) do
|
57
|
+
subject.add(context_object, "print", :print)
|
58
|
+
subject.add(context_object, "print_with_headers", :print_with_headers)
|
59
|
+
end
|
60
|
+
|
61
|
+
context('on error') do
|
62
|
+
|
63
|
+
it('raises a ZSS::Error on invalid verb') do
|
64
|
+
expect { subject.get("route") }.
|
65
|
+
to raise_exception(ZSS::Error)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
context('on success') do
|
71
|
+
|
72
|
+
it('returns route handler') do
|
73
|
+
expect(subject.get("print")).to be_truthy
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
context('call route handler') do
|
79
|
+
|
80
|
+
it('successfully call with payload') do
|
81
|
+
expect(context_object).to receive(:print).with("print")
|
82
|
+
subject.get("print").call("print")
|
83
|
+
end
|
84
|
+
|
85
|
+
it('successfully call with payload and headers') do
|
86
|
+
expect(context_object).to receive(:print_with_headers)
|
87
|
+
.with("print_with_headers", { header: "x" })
|
88
|
+
|
89
|
+
subject.get("print_with_headers")
|
90
|
+
.call("print_with_headers", { header: "x" })
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,314 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'zss'
|
3
|
+
require 'zss/service'
|
4
|
+
require 'em-zeromq'
|
5
|
+
|
6
|
+
describe ZSS::Service do
|
7
|
+
|
8
|
+
let(:socket_address) { "ipc://socket_spec" }
|
9
|
+
|
10
|
+
let :config do
|
11
|
+
Hashie::Mash.new(
|
12
|
+
backend: socket_address,
|
13
|
+
heartbeat: 60000
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
class DummyService
|
18
|
+
def ping payload, headers
|
19
|
+
headers[:took] = "0s"
|
20
|
+
return "PONG"
|
21
|
+
end
|
22
|
+
|
23
|
+
def ping_fail payload, headers
|
24
|
+
fail 'should raise exception'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def done
|
29
|
+
subject.stop
|
30
|
+
EM.stop
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:context) { double('EM::ZeroMQ::Context').as_null_object }
|
34
|
+
let(:socket) { double('EM::ZMQ::Socket').as_null_object }
|
35
|
+
|
36
|
+
before :each do
|
37
|
+
allow(EM::ZeroMQ::Context).to receive(:new) { context }
|
38
|
+
allow(context).to receive(:socket) { socket }
|
39
|
+
allow(SecureRandom).to receive(:uuid) { "uuid" }
|
40
|
+
config.heartbeat = 60000
|
41
|
+
end
|
42
|
+
|
43
|
+
after :each do
|
44
|
+
EM.stop if EM.reactor_running?
|
45
|
+
end
|
46
|
+
|
47
|
+
subject do
|
48
|
+
described_class.new(:pong, config)
|
49
|
+
end
|
50
|
+
|
51
|
+
describe('#ctor') do
|
52
|
+
|
53
|
+
it('returns a service with default config') do
|
54
|
+
subject = described_class.new(:pong)
|
55
|
+
expect(subject.sid).to eq("PONG")
|
56
|
+
expect(subject.backend).to eq(ZSS::Configuration.default.backend)
|
57
|
+
expect(subject.heartbeat).to eq(1000)
|
58
|
+
end
|
59
|
+
|
60
|
+
it('returns a service with config') do
|
61
|
+
config = Hashie::Mash.new(
|
62
|
+
backend: "socket",
|
63
|
+
heartbeat: 2000
|
64
|
+
)
|
65
|
+
subject = described_class.new(:pong, config)
|
66
|
+
expect(subject.sid).to eq("PONG")
|
67
|
+
expect(subject.backend).to eq("socket")
|
68
|
+
expect(subject.heartbeat).to eq(2000)
|
69
|
+
end
|
70
|
+
|
71
|
+
it('raises an error on invalid sid') do
|
72
|
+
|
73
|
+
expect do
|
74
|
+
described_class.new(nil, nil)
|
75
|
+
end.to raise_exception(ZSS::Error) do |error|
|
76
|
+
expect(error.code).to eq(500)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
describe('#run') do
|
84
|
+
|
85
|
+
context('on error') do
|
86
|
+
|
87
|
+
it('raises RuntimeError on invalid context') do
|
88
|
+
expect(EM::ZeroMQ::Context).to receive(:new) { nil }
|
89
|
+
expect { subject.run }.to raise_exception(RuntimeError)
|
90
|
+
end
|
91
|
+
|
92
|
+
it('raises RuntimeError on invalid socket') do
|
93
|
+
expect(context).to receive(:socket) { nil }
|
94
|
+
expect { subject.run }.to raise_exception(RuntimeError)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
context('open ZMQ Socket') do
|
100
|
+
|
101
|
+
it('with dealer type') do
|
102
|
+
expect(context).to receive(:socket).with(ZMQ::DEALER) do
|
103
|
+
done
|
104
|
+
socket
|
105
|
+
end
|
106
|
+
subject.run
|
107
|
+
end
|
108
|
+
|
109
|
+
it('with identity set') do
|
110
|
+
expect(socket).to receive(:identity=).with("pong#uuid") { done }
|
111
|
+
subject.run
|
112
|
+
end
|
113
|
+
|
114
|
+
it('with linger set to 0') do
|
115
|
+
expect(socket).to receive(:setsockopt).with(ZMQ::LINGER, 0) { done }
|
116
|
+
subject.run
|
117
|
+
end
|
118
|
+
|
119
|
+
it('connect to socket address') do
|
120
|
+
expect(socket).to receive(:connect).with(socket_address) { done }
|
121
|
+
subject.run
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
it('register service on broker') do
|
127
|
+
expect(socket).to receive(:send_msg) do |*frames|
|
128
|
+
message = ZSS::Message.parse(frames)
|
129
|
+
expect(message.address.sid).to eq('SMI')
|
130
|
+
expect(message.address.verb).to eq('UP')
|
131
|
+
expect(message.payload).to eq('PONG')
|
132
|
+
done
|
133
|
+
true
|
134
|
+
end
|
135
|
+
|
136
|
+
subject.run
|
137
|
+
end
|
138
|
+
|
139
|
+
context('handling requests') do
|
140
|
+
|
141
|
+
let(:address) { ZSS::Message::Address.new(sid: "PONG", verb: "PING") }
|
142
|
+
|
143
|
+
let(:message) { ZSS::Message.new(address: address, payload: "PING") }
|
144
|
+
|
145
|
+
let :message_parts do
|
146
|
+
message.to_frames.map { |f| ZMQ::Message.new(f) }
|
147
|
+
end
|
148
|
+
|
149
|
+
it('returns payload and headers') do
|
150
|
+
service = DummyService.new
|
151
|
+
subject.add_route(service, :ping)
|
152
|
+
|
153
|
+
EM.run do
|
154
|
+
allow(socket).to receive(:on) do |event, &block|
|
155
|
+
EM.add_timer { block.call *message_parts }
|
156
|
+
end
|
157
|
+
|
158
|
+
subject.run
|
159
|
+
|
160
|
+
expect(socket).to receive(:send_msg) do |*frames|
|
161
|
+
message = ZSS::Message.parse(frames)
|
162
|
+
|
163
|
+
expect(message.type).to eq(ZSS::Message::Type::REP)
|
164
|
+
expect(message.status).to eq(200)
|
165
|
+
expect(message.headers).to eq({ "took" => "0s" })
|
166
|
+
|
167
|
+
done
|
168
|
+
|
169
|
+
true
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
context('on error') do
|
176
|
+
|
177
|
+
it('returns 404 on invalid sid') do
|
178
|
+
message.address.sid = "something"
|
179
|
+
|
180
|
+
EM.run do
|
181
|
+
allow(socket).to receive(:on) do |event, &block|
|
182
|
+
EM.add_timer { block.call *message_parts }
|
183
|
+
end
|
184
|
+
|
185
|
+
subject.run
|
186
|
+
|
187
|
+
expect(socket).to receive(:send_msg) do |*frames|
|
188
|
+
message = ZSS::Message.parse(frames)
|
189
|
+
|
190
|
+
expect(message.type).to eq(ZSS::Message::Type::REP)
|
191
|
+
expect(message.status).to eq(404)
|
192
|
+
|
193
|
+
done
|
194
|
+
|
195
|
+
true
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
it('returns 404 on invalid verb') do
|
202
|
+
|
203
|
+
message.address.verb = "something"
|
204
|
+
|
205
|
+
EM.run do
|
206
|
+
allow(socket).to receive(:on) do |event, &block|
|
207
|
+
EM.add_timer { block.call *message_parts }
|
208
|
+
end
|
209
|
+
|
210
|
+
subject.run
|
211
|
+
|
212
|
+
expect(socket).to receive(:send_msg) do |*frames|
|
213
|
+
message = ZSS::Message.parse(frames)
|
214
|
+
|
215
|
+
expect(message.type).to eq(ZSS::Message::Type::REP)
|
216
|
+
expect(message.status).to eq(404)
|
217
|
+
|
218
|
+
done
|
219
|
+
|
220
|
+
true
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
it('returns 500 when an error occurred while handling request') do
|
227
|
+
|
228
|
+
service = DummyService.new
|
229
|
+
subject.add_route(service, "PING/FAIL", :ping_fail)
|
230
|
+
message.address.verb = "PING/FAIL"
|
231
|
+
|
232
|
+
EM.run do
|
233
|
+
allow(socket).to receive(:on) do |event, &block|
|
234
|
+
EM.add_timer { block.call *message_parts }
|
235
|
+
end
|
236
|
+
|
237
|
+
subject.run
|
238
|
+
|
239
|
+
expect(socket).to receive(:send_msg) do |*frames|
|
240
|
+
message = ZSS::Message.parse(frames)
|
241
|
+
|
242
|
+
expect(message.type).to eq(ZSS::Message::Type::REP)
|
243
|
+
expect(message.status).to eq(500)
|
244
|
+
|
245
|
+
done
|
246
|
+
|
247
|
+
true
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
it('sends heartbeat message') do
|
258
|
+
config.heartbeat = 500
|
259
|
+
subject = described_class.new(:pong, config)
|
260
|
+
|
261
|
+
EM.run do
|
262
|
+
|
263
|
+
subject.run
|
264
|
+
|
265
|
+
expect(socket).to receive(:send_msg) do |*frames|
|
266
|
+
message = ZSS::Message.parse(frames)
|
267
|
+
|
268
|
+
expect(message.type).to eq(ZSS::Message::Type::REQ)
|
269
|
+
expect(message.address.sid).to eq('SMI')
|
270
|
+
expect(message.address.verb).to eq('HEARTBEAT')
|
271
|
+
expect(message.payload).to eq('PONG')
|
272
|
+
|
273
|
+
done
|
274
|
+
|
275
|
+
true
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
describe('#stop') do
|
283
|
+
|
284
|
+
it('disconnects the socket') do
|
285
|
+
EM.run do
|
286
|
+
subject.run
|
287
|
+
|
288
|
+
expect(socket).to receive(:disconnect) { done }
|
289
|
+
|
290
|
+
subject.stop
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
it('unregister service on broker') do
|
295
|
+
EM.run do
|
296
|
+
|
297
|
+
subject.run
|
298
|
+
|
299
|
+
expect(socket).to receive(:send_msg) do |*frames|
|
300
|
+
message = ZSS::Message.parse(frames)
|
301
|
+
expect(message.address.sid).to eq('SMI')
|
302
|
+
expect(message.address.verb).to eq('DOWN')
|
303
|
+
expect(message.payload).to eq('PONG')
|
304
|
+
done
|
305
|
+
1
|
306
|
+
end
|
307
|
+
|
308
|
+
subject.stop
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
313
|
+
|
314
|
+
end
|