em-zmq-tp10 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
data/tests/test_req.rb ADDED
@@ -0,0 +1,229 @@
1
+ require 'eventmachine'
2
+ require 'minitest/autorun'
3
+ require File.expand_path('../helper.rb', __FILE__)
4
+
5
+ require 'em/protocols/zmq2/req'
6
+
7
+ describe 'Req' do
8
+ let(:connected) do
9
+ EM::DefaultDeferrable.new
10
+ end
11
+
12
+ describe EM::Protocols::Zmq2::PreReq do
13
+ class MyPreReq < EM::Protocols::Zmq2::PreReq
14
+ attr :incoming_queue
15
+ def initialize(opts={})
16
+ super
17
+ @connected = opts[:connected]
18
+ @incoming_queue = []
19
+ end
20
+ def peer_free(peer_identity, connection)
21
+ super
22
+ @connected.succeed
23
+ end
24
+ def receive_reply(message, data, request_id)
25
+ message.first.must_equal 'world'
26
+ message.last.must_equal data.to_s
27
+ @incoming_queue << ['hello', message.last]
28
+ end
29
+ end
30
+
31
+ attr :req
32
+ before do
33
+ @req = MyPreReq.new(identity: 'REQ', connected: connected)
34
+ @req.connect(Native::ZBIND_ADDR)
35
+ end
36
+
37
+ let(:messages){
38
+ 300.times.map{|i| ['hello', i.to_s]} << ['hello', 'xxx']
39
+ }
40
+
41
+ it 'should send requests' do
42
+ Native.with_socket('REP') do |zrep|
43
+ thrd = Thread.new do
44
+ messages.size.times do
45
+ ar = []
46
+ zrep.recv_strings ar
47
+ ar[0] = 'world'
48
+ zrep.send_strings ar
49
+ end
50
+ end
51
+ EM.run {
52
+ connected.callback {
53
+ dup = messages.dup
54
+ cb = lambda {
55
+ if dup.empty?
56
+ EM.add_timer(0.3){
57
+ EM.next_tick{ EM.stop }
58
+ }
59
+ else
60
+ message = dup.first
61
+ if String === req.send_request(message, message.last)
62
+ dup.shift
63
+ EM.next_tick cb
64
+ else
65
+ EM.add_timer 0.1, cb
66
+ end
67
+ end
68
+ }
69
+ cb.call
70
+ }
71
+ }
72
+ thrd.join
73
+ end
74
+ (req.incoming_queue - messages).must_be_empty
75
+ (messages - req.incoming_queue).must_be_empty
76
+ end
77
+ end
78
+
79
+ describe EM::Protocols::Zmq2::Req do
80
+ class MyReq < EM::Protocols::Zmq2::Req
81
+ attr :incoming_queue, :canceled_requests
82
+ def initialize(opts={}, defered_conn, defered_mess)
83
+ super opts
84
+ @defered_conn = defered_conn
85
+ @defered_mess = defered_mess
86
+ @incoming_queue = []
87
+ @canceled_requests = []
88
+ end
89
+ def peer_free(peer_identity, connection)
90
+ super
91
+ @defered_conn.succeed
92
+ end
93
+ def receive_reply(message, data, request_id)
94
+ message.first.must_equal 'world'
95
+ message.last.must_equal data.to_s
96
+ @incoming_queue << ['hello', message.last]
97
+ @defered_mess.succeed if message.last == 'xxx'
98
+ end
99
+ def cancel_request(request_id)
100
+ @canceled_requests << request_id
101
+ end
102
+ end
103
+
104
+ let(:finished){ EM::DefaultDeferrable.new }
105
+ attr :req
106
+ before do
107
+ @req = MyReq.new({identity: 'REQ'}, connected, finished)
108
+ @req.connect(Native::ZBIND_ADDR)
109
+ end
110
+ let(:messages){
111
+ 5000.times.map{|i| ['hello', i.to_s]} << ['hello', 'xxx']
112
+ }
113
+
114
+ it 'should send a lot of requests' do
115
+ Native.with_socket('REP') do |zrep|
116
+ thrd = Thread.new do
117
+ messages.size.times do
118
+ ar = []
119
+ zrep.recv_strings ar
120
+ ar[0] = 'world'
121
+ zrep.send_strings ar
122
+ end
123
+ end
124
+ EM.run {
125
+ connected.callback {
126
+ messages.each{|message|
127
+ req.send_request(message, message.last)
128
+ }
129
+ }
130
+ finished.callback {
131
+ EM.next_tick{ EM.stop }
132
+ }
133
+ }
134
+ thrd.join
135
+ end
136
+ (req.incoming_queue - messages).must_be_empty
137
+ (messages - req.incoming_queue).must_be_empty
138
+ end
139
+
140
+ it "should not accept message on low hwm with strategy :drop_last" do
141
+ req.hwm = 2
142
+ req.hwm_strategy = :drop_last
143
+ EM.run {
144
+ req.send_request(['hi', 'ho1'], nil).must_be_kind_of String
145
+ req.send_request(['hi', 'ho2'], nil).must_be_kind_of String
146
+ req.send_request(['hi', 'ho3'], nil).wont_be_kind_of String
147
+ EM.stop
148
+ }
149
+ end
150
+
151
+ it "should cancel earlier message on low hwm with strategy :drop_first" do
152
+ req.hwm = 2
153
+ req.hwm_strategy = :drop_first
154
+ first_req = nil
155
+ EM.run {
156
+ first_req = req.send_request(['hi', 'ho1'], nil)
157
+ first_req.must_be_kind_of String
158
+ req.send_request(['hi', 'ho2'], nil).must_be_kind_of String
159
+ req.send_request(['hi', 'ho3'], nil).must_be_kind_of String
160
+ EM.stop
161
+ }
162
+ req.canceled_requests.must_equal [first_req]
163
+ end
164
+ end
165
+
166
+ describe EM::Protocols::Zmq2::ReqDefer do
167
+ class TSTRep < EM::Protocols::Zmq2::Rep
168
+ include DeferredMixin
169
+ def receive_request(message, environment)
170
+ send_reply([message.first, 'yeah'], environment)
171
+ end
172
+ def peer_free(peer, conn)
173
+ super
174
+ @connected.succeed
175
+ end
176
+ end
177
+ it "should correctly setup and call deferrable" do
178
+ req = EM::Protocols::Zmq2::ReqDefer.new
179
+ def req.send_message(message, even = false)
180
+ res = super
181
+ res
182
+ end
183
+ rep = TSTRep.new(connected: connected)
184
+ rep.bind('inproc://tst')
185
+ first_success, first_error = nil, nil
186
+ second_success, second_error = nil, nil
187
+ require 'pp'
188
+ EM.run {
189
+ uniq = Object.new.freeze
190
+ first = nil
191
+ follow = proc do |null, data|
192
+ data.must_equal uniq
193
+ null.must_be_nil
194
+ req.connect('inproc://tst')
195
+ connected.callback do
196
+ stop = proc{ EM.next_tick{ EM.stop } }
197
+ second = req.send_request(['hi', 'ho'], uniq) do |reply, data|
198
+ second_success = true
199
+ reply.must_equal ['hi', 'yeah']
200
+ data.must_equal uniq
201
+ end
202
+ second.must_be_kind_of EM::Deferrable
203
+ second.errback do
204
+ second_error = true
205
+ end
206
+ second.callback &stop
207
+ second.errback &stop
208
+ end
209
+ end
210
+ first = req.send_request(['hi', 'ho'], uniq) do |reply, data|
211
+ first_success = true
212
+ reply.must_equal ['hi', 'yeah']
213
+ data.must_equal uniq
214
+ end
215
+ first.must_be_kind_of EM::Deferrable
216
+ first.timeout(0.3, 1, uniq)
217
+ first.errback do
218
+ first_error = true
219
+ end
220
+ first.callback &follow
221
+ first.errback &follow
222
+ }
223
+ first_success.must_equal nil
224
+ first_error.must_equal true
225
+ second_success.must_equal true
226
+ second_error.must_equal nil
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,221 @@
1
+ require 'eventmachine'
2
+ require 'minitest/autorun'
3
+ require File.expand_path('../helper.rb', __FILE__)
4
+
5
+ require 'em/protocols/zmq2/router'
6
+
7
+ describe 'Router' do
8
+
9
+ let(:connected) do
10
+ EM::DefaultDeferrable.new
11
+ end
12
+
13
+ let(:finished) do
14
+ EM::DefaultDeferrable.new
15
+ end
16
+
17
+ class DealerCollector
18
+ attr :res_a, :res_b
19
+ def initialize(till)
20
+ @till = till
21
+ @res_a, @res_b = [], []
22
+ end
23
+ def full?
24
+ @res_a.size + @res_b.size >= @till
25
+ end
26
+ def full_res
27
+ @res_a + @res_b
28
+ end
29
+ def set_sockets(zbind, zconnect)
30
+ @zbind = zbind
31
+ @zconnect = zconnect
32
+ end
33
+ def thread
34
+ Thread.new do
35
+ begin
36
+ result = []
37
+ until full?
38
+ while @zbind.recv_strings(result, ZMQ::NOBLOCK) != -1
39
+ result.first.must_equal 'hello'
40
+ @res_a << result
41
+ result = []
42
+ end
43
+ while @zconnect.recv_strings(result, ZMQ::NOBLOCK) != -1
44
+ result.first.must_equal 'hello'
45
+ @res_b << result
46
+ result = []
47
+ end
48
+ sleep(0.01)
49
+ end
50
+ rescue
51
+ puts $!
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ describe EM::Protocols::Zmq2::PreRouter do
58
+ class MyPreRouter < EM::Protocols::Zmq2::PreRouter
59
+ attr :incoming_queue
60
+ def initialize(connected, finished, opts={})
61
+ super opts
62
+ @connected = connected
63
+ @finished = finished
64
+ @incoming_queue = {}
65
+ end
66
+ def peer_free(peer_ident, connection)
67
+ super
68
+ @connected.succeed if @free_peers.size == 2
69
+ end
70
+ def receive_message(message)
71
+ (@incoming_queue[message.first] ||= []) << message[1..-1]
72
+ @finished.succeed if message.last == 'xxx'
73
+ end
74
+ end
75
+
76
+ attr :router
77
+ before do
78
+ @router = MyPreRouter.new(connected, finished, identity: 'MyRouter')
79
+ @router.bind(Native::ZCONNECT_ADDR)
80
+ @router.connect(Native::ZBIND_ADDR)
81
+ end
82
+
83
+ let(:messages) do
84
+ 62.times.map{|n| ['hello', n.to_s] } << ['hello', 'xxx']
85
+ end
86
+
87
+ it "should be able to receive messages" do
88
+ halves = messages[0...(messages.size/2)], messages[(messages.size/2)..-1]
89
+ Native.with_socket_pair('DEALER') do |zbind, zconnect|
90
+ EM.run {
91
+ connected.callback do
92
+ halves[0].each do |message|
93
+ zbind.send_strings(message)
94
+ end
95
+ halves[1].each do |message|
96
+ zconnect.send_strings(message)
97
+ end
98
+ end
99
+ finished.callback do
100
+ EM.next_tick{ EM.stop }
101
+ end
102
+ }
103
+ end
104
+ router.incoming_queue['BIND_DEALER'].must_equal halves[0]
105
+ router.incoming_queue['CONNECT_DEALER'].must_equal halves[1]
106
+ end
107
+
108
+ it "should be able to route messages" do
109
+ collector = DealerCollector.new(messages.size)
110
+ halves = messages[0...(messages.size/2)], messages[(messages.size/2)..-1]
111
+ Native.with_socket_pair('DEALER') do |zbind, zconnect|
112
+ collector.set_sockets zbind, zconnect
113
+ thrd = collector.thread
114
+ EM.run {
115
+ dup_halves = halves.map(&:dup)
116
+ connected.callback do
117
+ dup_halves[0].each do |message|
118
+ router.send_message(['BIND_DEALER', *message]).must_equal true
119
+ end
120
+ dup_halves[1].each do |message|
121
+ router.send_message(['CONNECT_DEALER', *message]).must_equal true
122
+ end
123
+ EM.defer(proc do thrd.join end, proc do
124
+ EM.next_tick{ EM.stop }
125
+ end)
126
+ end
127
+ }
128
+ end
129
+ collector.res_a.must_equal halves[0]
130
+ collector.res_b.must_equal halves[1]
131
+ end
132
+ end
133
+
134
+ describe EM::Protocols::Zmq2::Router do
135
+ class MyRouter < EM::Protocols::Zmq2::Router
136
+ attr :incoming_queue, :canceled_messages
137
+ def initialize(connected, finished, opts={})
138
+ super opts
139
+ @connected = connected
140
+ @finished = finished
141
+ @incoming_queue = {}
142
+ @canceled_messages = []
143
+ end
144
+ def peer_free(peer_ident, connection)
145
+ super
146
+ @connected.succeed if @free_peers.size == 2
147
+ end
148
+ def receive_message(message)
149
+ (@incoming_queue[message.first] ||= []) << message[1..-1]
150
+ @finished.succeed if message.last == 'xxx'
151
+ end
152
+ def cancel_message(message)
153
+ @canceled_messages << message
154
+ end
155
+ end
156
+
157
+ attr :router
158
+ before do
159
+ @router = MyRouter.new(connected, finished, identity: 'MyRouter')
160
+ @router.bind(Native::ZCONNECT_ADDR)
161
+ @router.connect(Native::ZBIND_ADDR)
162
+ end
163
+
164
+ let(:messages) do
165
+ 10000.times.map{|n| ['hello', n.to_s] } << ['hello', 'xxx']
166
+ end
167
+
168
+ it "should be able to route a lot of messages" do
169
+ collector = DealerCollector.new(messages.size)
170
+ halves = messages[0...(messages.size/2)], messages[(messages.size/2)..-1]
171
+ Native.with_socket_pair('DEALER') do |zbind, zconnect|
172
+ collector.set_sockets zbind, zconnect
173
+ thrd = collector.thread
174
+ EM.run {
175
+ dup_halves = halves.map(&:dup)
176
+ connected.callback do
177
+ dup_halves[0].each do |message|
178
+ router.send_message(['BIND_DEALER', *message])
179
+ end
180
+ dup_halves[1].each do |message|
181
+ router.send_message(['CONNECT_DEALER', *message])
182
+ end
183
+ EM.defer(proc do thrd.join end, proc do
184
+ EM.next_tick{ EM.stop }
185
+ end)
186
+ end
187
+ }
188
+ thrd.join
189
+ end
190
+ collector.res_a.must_equal halves[0]
191
+ collector.res_b.must_equal halves[1]
192
+ end
193
+
194
+ it "should not accept message on low hwm with strategy :drop_last" do
195
+ router.hwm = 1
196
+ router.hwm_strategy = :drop_last
197
+ EM.run {
198
+ router.send_message(['FIRST_PEER', 'hi', 'ho1']).must_equal true
199
+ router.send_message(['FIRST_PEER', 'hi', 'ho2']).wont_equal true
200
+ router.send_message(['SECOND_PEER', 'hi', 'ho1']).must_equal true
201
+ router.send_message(['SECOND_PEER', 'hi', 'ho2']).wont_equal true
202
+ EM.stop
203
+ }
204
+ end
205
+
206
+ it "should cancel earlier message on low hwm with strategy :drop_first" do
207
+ router.hwm = 1
208
+ router.hwm_strategy = :drop_first
209
+ EM.run {
210
+ router.send_message(['FIRST_PEER', 'hi', 'ho1']).must_equal true
211
+ router.send_message(['FIRST_PEER', 'hi', 'ho2']).must_equal true
212
+ router.send_message(['SECOND_PEER', 'hi', 'ho1']).must_equal true
213
+ router.send_message(['SECOND_PEER', 'hi', 'ho2']).must_equal true
214
+ EM.stop
215
+ }
216
+ router.canceled_messages.count.must_equal 2
217
+ router.canceled_messages.must_include ['FIRST_PEER', 'hi', 'ho1']
218
+ router.canceled_messages.must_include ['SECOND_PEER', 'hi', 'ho1']
219
+ end
220
+ end
221
+ end