mcollective-client 2.9.1 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/lib/mcollective.rb +1 -1
- data/lib/mcollective/application/find.rb +2 -0
- data/lib/mcollective/application/rpc.rb +2 -12
- data/lib/mcollective/client.rb +31 -7
- data/lib/mcollective/connector/activemq.rb +11 -2
- data/lib/mcollective/connector/rabbitmq.rb +8 -2
- data/lib/mcollective/discovery/stdin.rb +4 -2
- data/lib/mcollective/rpc/client.rb +25 -0
- data/lib/mcollective/rpc/helpers.rb +15 -5
- data/lib/mcollective/rpc/stats.rb +47 -8
- data/spec/unit/mcollective/client_spec.rb +131 -38
- data/spec/unit/mcollective/connector/activemq_spec.rb +47 -1
- data/spec/unit/mcollective/connector/rabbitmq_spec.rb +89 -2
- data/spec/unit/mcollective/rpc/client_spec.rb +39 -2
- data/spec/unit/mcollective/rpc/helpers_spec.rb +6 -0
- data/spec/unit/mcollective/rpc/stats_spec.rb +46 -2
- metadata +205 -213
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZWEwMDY2OTlmMTkwOWM4NGRjODVmYzQzMTk1ZGJmN2M4MDA0MTdlZg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MjAyNjQ5NDQxZTE1MmM1NzEwODcwMDU1MTQzNGVlNmNhYjdkZDcyMw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NjNjZWZiZjIzMTk5ODE1ZTNkZDVmYThhMGNmNzFhNzY4ZGViMGJiNWU0OGU3
|
10
|
+
MDcyMTlhNjEyZDI3ZGZiMjE4YzVjNzk2OTVkOGY2ZDdlZjg5MTFjNTcwOWUx
|
11
|
+
N2YzZDU4YTg1MThhZWEwZTVhYjQ4NTk1ZDNlZWU2ZTc0ODRhOWQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Mjc1NjBiNjJjNWMyYjljNDE0OWFiZmE3OWYwOGNmODEzZmE2ZmIxNWJhNDdk
|
14
|
+
NzA0MmQ5ZmI3Y2JjYmI5ODIwMGE4NzcwMjNmZTdkOWJhYmRkOGJjZWVjN2Vk
|
15
|
+
Njg2YzZiNGI2NThjYWQ2MjA4ZTA3NDUyNDA0M2FhOTgxYmI3MGE=
|
data/lib/mcollective.rb
CHANGED
@@ -96,18 +96,8 @@ class MCollective::Application::Rpc<MCollective::Application
|
|
96
96
|
puts "Request sent with id: " + mc.send(configuration[:action], configuration[:arguments])
|
97
97
|
else
|
98
98
|
discover_args = {:verbose => true}
|
99
|
-
|
100
|
-
|
101
|
-
# and someone has piped us some data
|
102
|
-
# Then we assume it's a discovery list - this can be either:
|
103
|
-
# - list of hosts in plaintext
|
104
|
-
# - JSON that came from another rpc or printrpc
|
105
|
-
if mc.default_discovery_method && !STDIN.tty? && !STDIN.eof?
|
106
|
-
# Then we override discovery to try to grok the data on STDIN
|
107
|
-
mc.discovery_method = 'stdin'
|
108
|
-
mc.discovery_options = 'auto'
|
109
|
-
discover_args = {:verbose => false}
|
110
|
-
end
|
99
|
+
|
100
|
+
mc.detect_and_set_stdin_discovery
|
111
101
|
|
112
102
|
mc.discover discover_args
|
113
103
|
|
data/lib/mcollective/client.rb
CHANGED
@@ -159,10 +159,10 @@ module MCollective
|
|
159
159
|
#
|
160
160
|
# It returns a hash of times and timeouts for discovery and total run is taken from the options
|
161
161
|
# hash which in turn is generally built using MCollective::Optionparser
|
162
|
-
def req(body, agent=nil, options=false, waitfor=
|
162
|
+
def req(body, agent=nil, options=false, waitfor=[], &block)
|
163
163
|
if body.is_a?(Message)
|
164
164
|
agent = body.agent
|
165
|
-
waitfor = body.discovered_hosts
|
165
|
+
waitfor = body.discovered_hosts || []
|
166
166
|
@options = body.options
|
167
167
|
end
|
168
168
|
|
@@ -170,12 +170,11 @@ module MCollective
|
|
170
170
|
threaded = @options[:threaded]
|
171
171
|
timeout = @discoverer.discovery_timeout(@options[:timeout], @options[:filter])
|
172
172
|
request = createreq(body, agent, @options[:filter])
|
173
|
-
publish_timeout = @options[:publish_timeout]
|
173
|
+
publish_timeout = @options[:publish_timeout] || @config.publish_timeout
|
174
174
|
stat = {:starttime => Time.now.to_f, :discoverytime => 0, :blocktime => 0, :totaltime => 0}
|
175
175
|
STDOUT.sync = true
|
176
176
|
hosts_responded = 0
|
177
177
|
|
178
|
-
|
179
178
|
begin
|
180
179
|
if threaded
|
181
180
|
hosts_responded = threaded_req(request, publish_timeout, timeout, waitfor, &block)
|
@@ -238,16 +237,41 @@ module MCollective
|
|
238
237
|
def start_receiver(requestid, waitfor, timeout, &block)
|
239
238
|
Log.debug("Starting response receiver with timeout of #{timeout}")
|
240
239
|
hosts_responded = 0
|
240
|
+
|
241
|
+
if (waitfor.is_a?(Array))
|
242
|
+
unfinished = Hash.new(0)
|
243
|
+
waitfor.each {|w| unfinished[w] += 1}
|
244
|
+
else
|
245
|
+
unfinished = []
|
246
|
+
end
|
247
|
+
|
241
248
|
begin
|
242
249
|
Timeout.timeout(timeout) do
|
243
|
-
|
250
|
+
loop do
|
244
251
|
resp = receive(requestid)
|
245
252
|
yield resp.payload
|
246
253
|
hosts_responded += 1
|
247
|
-
|
254
|
+
|
255
|
+
if (waitfor.is_a?(Array))
|
256
|
+
sender = resp.payload[:senderid]
|
257
|
+
if unfinished[sender] <= 1
|
258
|
+
unfinished.delete(sender)
|
259
|
+
else
|
260
|
+
unfinished[sender] -= 1
|
261
|
+
end
|
262
|
+
|
263
|
+
break if !waitfor.empty? && unfinished.empty?
|
264
|
+
else
|
265
|
+
break unless waitfor == 0 || hosts_responded < waitfor
|
266
|
+
end
|
267
|
+
end
|
248
268
|
end
|
249
269
|
rescue Timeout::Error => e
|
250
|
-
if (
|
270
|
+
if waitfor.is_a?(Array)
|
271
|
+
if !unfinished.empty?
|
272
|
+
Log.warn("Could not receive all responses. Did not receive responses from #{unfinished.keys.join(', ')}")
|
273
|
+
end
|
274
|
+
elsif (waitfor > hosts_responded)
|
251
275
|
Log.warn("Could not receive all responses. Expected : #{waitfor}. Received : #{hosts_responded}")
|
252
276
|
end
|
253
277
|
end
|
@@ -541,6 +541,7 @@ module MCollective
|
|
541
541
|
raise("Unknown target type #{type}") unless [:directed, :broadcast, :reply, :request, :direct_request].include?(type)
|
542
542
|
raise("Unknown collective '#{collective}' known collectives are '#{@config.collectives.join ', '}'") unless @config.collectives.include?(collective)
|
543
543
|
|
544
|
+
agents_multiplex = get_bool_option("activemq.agents_multiplex", "false")
|
544
545
|
target = {:name => nil, :headers => {}}
|
545
546
|
|
546
547
|
case type
|
@@ -548,10 +549,18 @@ module MCollective
|
|
548
549
|
target[:name] = ["/queue/" + collective, :reply, "#{Config.instance.identity}_#{$$}", Client.request_sequence].join(".")
|
549
550
|
|
550
551
|
when :broadcast
|
551
|
-
|
552
|
+
if agents_multiplex
|
553
|
+
target[:name] = ["/topic/" + collective, :agents].join(".")
|
554
|
+
else
|
555
|
+
target[:name] = ["/topic/" + collective, agent, :agent].join(".")
|
556
|
+
end
|
552
557
|
|
553
558
|
when :request
|
554
|
-
|
559
|
+
if agents_multiplex
|
560
|
+
target[:name] = ["/topic/" + collective, :agents].join(".")
|
561
|
+
else
|
562
|
+
target[:name] = ["/topic/" + collective, agent, :agent].join(".")
|
563
|
+
end
|
555
564
|
|
556
565
|
when :direct_request
|
557
566
|
target[:name] = ["/queue/" + collective, :nodes].join(".")
|
@@ -387,6 +387,7 @@ module MCollective
|
|
387
387
|
raise("Unknown target type #{type}") unless [:directed, :broadcast, :reply, :request, :direct_request].include?(type)
|
388
388
|
raise("Unknown collective '#{collective}' known collectives are '#{@config.collectives.join ', '}'") unless @config.collectives.include?(collective)
|
389
389
|
|
390
|
+
agents_multiplex = get_bool_option("rabbitmq.agents_multiplex", "false")
|
390
391
|
target = {:name => "", :headers => {}, :id => nil}
|
391
392
|
|
392
393
|
if reply_to
|
@@ -402,13 +403,18 @@ module MCollective
|
|
402
403
|
target[:id] = "mcollective_%s_replies" % agent
|
403
404
|
|
404
405
|
when :broadcast, :request # publishing a request to all nodes with an agent
|
405
|
-
|
406
|
+
if agents_multiplex
|
407
|
+
target[:name] = "/exchange/%s_broadcast" % collective
|
408
|
+
target[:id] = "%s_broadcast" % collective
|
409
|
+
else
|
410
|
+
target[:name] = "/exchange/%s_broadcast/%s" % [collective, agent]
|
411
|
+
target[:id] = "%s_broadcast_%s" % [collective, agent]
|
412
|
+
end
|
406
413
|
if reply_to
|
407
414
|
target[:headers]["reply-to"] = reply_to
|
408
415
|
else
|
409
416
|
target[:headers]["reply-to"] = reply_path
|
410
417
|
end
|
411
|
-
target[:id] = "%s_broadcast_%s" % [collective, agent]
|
412
418
|
|
413
419
|
when :direct_request # a request to a specific node
|
414
420
|
raise "Directed requests need to have a node identity" unless node
|
@@ -18,7 +18,7 @@ module MCollective
|
|
18
18
|
file = STDIN.read
|
19
19
|
|
20
20
|
if file =~ /^\s*$/
|
21
|
-
|
21
|
+
raise("data piped on STDIN contained only whitespace - could not discover hosts from it.")
|
22
22
|
end
|
23
23
|
|
24
24
|
if type == 'auto'
|
@@ -29,8 +29,10 @@ module MCollective
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
Log.debug("Parsing STDIN input as type %s" % type)
|
33
|
+
|
32
34
|
if type == 'json'
|
33
|
-
hosts =
|
35
|
+
hosts = RPC::Helpers.extract_hosts_from_json(file)
|
34
36
|
elsif type == 'text'
|
35
37
|
hosts = file.split("\n")
|
36
38
|
else
|
@@ -119,6 +119,12 @@ module MCollective
|
|
119
119
|
@stdout = STDOUT
|
120
120
|
@stdout.sync = true
|
121
121
|
end
|
122
|
+
|
123
|
+
if initial_options[:stdin]
|
124
|
+
@stdin = initial_options[:stdin]
|
125
|
+
else
|
126
|
+
@stdin = STDIN
|
127
|
+
end
|
122
128
|
end
|
123
129
|
|
124
130
|
# Disconnects cleanly from the middleware
|
@@ -459,6 +465,24 @@ module MCollective
|
|
459
465
|
agent_filter @agent
|
460
466
|
end
|
461
467
|
|
468
|
+
# Detects data on STDIN and sets the STDIN discovery method
|
469
|
+
#
|
470
|
+
# IF the discovery method hasn't been explicitly overridden
|
471
|
+
# and we're not being run interactively,
|
472
|
+
# and someone has piped us some data
|
473
|
+
#
|
474
|
+
# Then we assume it's a discovery list - this can be either:
|
475
|
+
# - list of hosts in plaintext
|
476
|
+
# - JSON that came from another rpc or printrpc
|
477
|
+
#
|
478
|
+
# Then we override discovery to try to grok the data on STDIN
|
479
|
+
def detect_and_set_stdin_discovery
|
480
|
+
if self.default_discovery_method && !@stdin.tty? && !@stdin.eof?
|
481
|
+
self.discovery_method = 'stdin'
|
482
|
+
self.discovery_options = 'auto'
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
462
486
|
# Does discovery based on the filters set, if a discovery was
|
463
487
|
# previously done return that else do a new discovery.
|
464
488
|
#
|
@@ -845,6 +869,7 @@ module MCollective
|
|
845
869
|
end
|
846
870
|
|
847
871
|
@stats.noresponsefrom.concat @client.stats[:noresponsefrom]
|
872
|
+
@stats.unexpectedresponsefrom.concat @client.stats[:unexpectedresponsefrom]
|
848
873
|
@stats.responses += @client.stats[:responses]
|
849
874
|
@stats.blocktime += @client.stats[:blocktime] + sleep_time
|
850
875
|
@stats.totaltime += @client.stats[:totaltime]
|
@@ -2,8 +2,8 @@ module MCollective
|
|
2
2
|
module RPC
|
3
3
|
# Various utilities for the RPC system
|
4
4
|
class Helpers
|
5
|
-
# Parse JSON output as produced by printrpc
|
6
|
-
# the "sender" of each
|
5
|
+
# Parse JSON output as produced by printrpc or puppet query
|
6
|
+
# and extract the "sender" / "certname" of each entry
|
7
7
|
#
|
8
8
|
# The simplist valid JSON based data would be:
|
9
9
|
#
|
@@ -11,6 +11,13 @@ module MCollective
|
|
11
11
|
# {"sender" => "example.com"},
|
12
12
|
# {"sender" => "another.com"}
|
13
13
|
# ]
|
14
|
+
#
|
15
|
+
# or
|
16
|
+
#
|
17
|
+
# [
|
18
|
+
# {"certname" => "example.com"},
|
19
|
+
# {"certname" => "another.com"}
|
20
|
+
# ]
|
14
21
|
def self.extract_hosts_from_json(json)
|
15
22
|
hosts = JSON.parse(json)
|
16
23
|
|
@@ -18,9 +25,12 @@ module MCollective
|
|
18
25
|
|
19
26
|
hosts.map do |host|
|
20
27
|
raise "JSON host list is not an array of Hashes" unless host.is_a?(Hash)
|
21
|
-
raise "JSON host list does not have senders in it" unless host.include?("sender")
|
22
28
|
|
23
|
-
host
|
29
|
+
unless host.include?("sender") || host.include?("certname")
|
30
|
+
raise "JSON host list does not have senders in it"
|
31
|
+
end
|
32
|
+
|
33
|
+
host["sender"] || host["certname"]
|
24
34
|
end.uniq
|
25
35
|
end
|
26
36
|
|
@@ -264,7 +274,7 @@ module MCollective
|
|
264
274
|
parser.on('--one', '-1', 'Send request to only one discovered nodes') do |v|
|
265
275
|
options[:mcollective_limit_targets] = 1
|
266
276
|
end
|
267
|
-
|
277
|
+
|
268
278
|
parser.on('--batch SIZE', 'Do requests in batches') do |v|
|
269
279
|
# validate batch string. Is it x% where x > 0 or is it an integer
|
270
280
|
if ((v =~ /^(\d+)%$/ && Integer($1) != 0) || v =~ /^(\d+)$/)
|
@@ -2,9 +2,9 @@ module MCollective
|
|
2
2
|
module RPC
|
3
3
|
# Class to wrap all the stats and to keep track of some timings
|
4
4
|
class Stats
|
5
|
-
attr_accessor :noresponsefrom, :starttime, :discoverytime, :blocktime, :responses
|
6
|
-
attr_accessor :discovered, :discovered_nodes, :okcount, :failcount, :noresponsefrom
|
7
|
-
attr_accessor :requestid, :aggregate_summary, :ddl, :aggregate_failures
|
5
|
+
attr_accessor :noresponsefrom, :unexpectedresponsefrom, :starttime, :discoverytime, :blocktime, :responses
|
6
|
+
attr_accessor :totaltime, :discovered, :discovered_nodes, :okcount, :failcount, :noresponsefrom
|
7
|
+
attr_accessor :responsesfrom, :requestid, :aggregate_summary, :ddl, :aggregate_failures
|
8
8
|
|
9
9
|
def initialize
|
10
10
|
reset
|
@@ -13,6 +13,7 @@ module MCollective
|
|
13
13
|
# Resets stats, if discovery time is set we keep it as it was
|
14
14
|
def reset
|
15
15
|
@noresponsefrom = []
|
16
|
+
@unexpectedresponsefrom = []
|
16
17
|
@responsesfrom = []
|
17
18
|
@responses = 0
|
18
19
|
@starttime = Time.now.to_f
|
@@ -23,7 +24,6 @@ module MCollective
|
|
23
24
|
@discovered_nodes = []
|
24
25
|
@okcount = 0
|
25
26
|
@failcount = 0
|
26
|
-
@noresponsefrom = []
|
27
27
|
@requestid = nil
|
28
28
|
@aggregate_summary = []
|
29
29
|
@aggregate_failures = []
|
@@ -32,6 +32,7 @@ module MCollective
|
|
32
32
|
# returns a hash of our stats
|
33
33
|
def to_hash
|
34
34
|
{:noresponsefrom => @noresponsefrom,
|
35
|
+
:unexpectedresponsefrom => @unexpectedresponsefrom,
|
35
36
|
:starttime => @starttime,
|
36
37
|
:discoverytime => @discoverytime,
|
37
38
|
:blocktime => @blocktime,
|
@@ -70,6 +71,7 @@ module MCollective
|
|
70
71
|
# Re-initializes the object with stats from the basic client
|
71
72
|
def client_stats=(stats)
|
72
73
|
@noresponsefrom = stats[:noresponsefrom]
|
74
|
+
@unexpectedresponsefrom = stats[:unexpectedresponsefrom]
|
73
75
|
@responses = stats[:responses]
|
74
76
|
@starttime = stats[:starttime]
|
75
77
|
@blocktime = stats[:blocktime]
|
@@ -115,13 +117,19 @@ module MCollective
|
|
115
117
|
def finish_request
|
116
118
|
@totaltime = @blocktime + @discoverytime
|
117
119
|
|
118
|
-
#
|
120
|
+
# figure out who responded unexpectedly
|
121
|
+
rhosts = @responsesfrom.clone
|
122
|
+
@discovered_nodes.each {|d| rhosts.delete(d)}
|
123
|
+
@unexpectedresponsefrom = rhosts
|
124
|
+
|
125
|
+
# figure out who we had no responses from
|
119
126
|
dhosts = @discovered_nodes.clone
|
120
127
|
@responsesfrom.each {|r| dhosts.delete(r)}
|
121
128
|
@noresponsefrom = dhosts
|
122
129
|
rescue
|
123
130
|
@totaltime = 0
|
124
131
|
@noresponsefrom = []
|
132
|
+
@unexpectedresponsefrom = []
|
125
133
|
end
|
126
134
|
|
127
135
|
# Helper to keep track of who we received responses from
|
@@ -225,8 +233,22 @@ module MCollective
|
|
225
233
|
end
|
226
234
|
end
|
227
235
|
|
228
|
-
|
229
|
-
|
236
|
+
no_response_r = no_response_report
|
237
|
+
unexpected_response_r = unexpected_response_report
|
238
|
+
if no_response_r || unexpected_response_r
|
239
|
+
result_text << ""
|
240
|
+
end
|
241
|
+
|
242
|
+
if no_response_r != ""
|
243
|
+
result_text << "" << no_response_r
|
244
|
+
end
|
245
|
+
|
246
|
+
if unexpected_response_r != ""
|
247
|
+
result_text << "" << unexpected_response_r
|
248
|
+
end
|
249
|
+
|
250
|
+
if no_response_r || unexpected_response_r
|
251
|
+
result_text << ""
|
230
252
|
end
|
231
253
|
|
232
254
|
result_text.join("\n")
|
@@ -237,7 +259,6 @@ module MCollective
|
|
237
259
|
result_text = StringIO.new
|
238
260
|
|
239
261
|
if @noresponsefrom.size > 0
|
240
|
-
result_text.puts
|
241
262
|
result_text.puts Util.colorize(:red, "No response from:")
|
242
263
|
result_text.puts
|
243
264
|
|
@@ -248,8 +269,26 @@ module MCollective
|
|
248
269
|
@noresponsefrom.sort.in_groups_of(fields_num) do |c|
|
249
270
|
result_text.puts format % c
|
250
271
|
end
|
272
|
+
end
|
251
273
|
|
274
|
+
result_text.string
|
275
|
+
end
|
276
|
+
|
277
|
+
# Returns a blob of text indicating what nodes responded but weren't discovered
|
278
|
+
def unexpected_response_report
|
279
|
+
result_text = StringIO.new
|
280
|
+
|
281
|
+
if @unexpectedresponsefrom.size > 0
|
282
|
+
result_text.puts Util.colorize(:red, "Unexpected response from:")
|
252
283
|
result_text.puts
|
284
|
+
|
285
|
+
field_size = Util.field_size(@unexpectedresponsefrom, 30)
|
286
|
+
fields_num = Util.field_number(field_size)
|
287
|
+
format = " " + ( " %-#{field_size}s" * fields_num )
|
288
|
+
|
289
|
+
@unexpectedresponsefrom.sort.in_groups_of(fields_num) do |c|
|
290
|
+
result_text.puts format % c
|
291
|
+
end
|
253
292
|
end
|
254
293
|
|
255
294
|
result_text.string
|
@@ -205,14 +205,25 @@ module MCollective
|
|
205
205
|
|
206
206
|
it "should thread the publisher and receiver if configured" do
|
207
207
|
client.instance_variable_get(:@options)[:threaded] = true
|
208
|
-
client.expects(:threaded_req).with(request,
|
208
|
+
client.expects(:threaded_req).with(request, 2, 0, ['rspec'])
|
209
209
|
message.options[:threaded] = true
|
210
210
|
client.req(message)
|
211
211
|
end
|
212
212
|
|
213
213
|
it "should not thread the publisher and receiver if configured" do
|
214
214
|
client.instance_variable_set(:@threaded, false)
|
215
|
-
client.expects(:unthreaded_req).with(request,
|
215
|
+
client.expects(:unthreaded_req).with(request, 2, 0, ['rspec'])
|
216
|
+
client.req(message)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "uses the publish_timeout from options when passed as an option" do
|
220
|
+
client.expects(:unthreaded_req).with(request, 5, 0, ['rspec'])
|
221
|
+
client.req(message, nil, message.options.merge(:publish_timeout => 5))
|
222
|
+
end
|
223
|
+
|
224
|
+
it "uses the publish_timeout from config when passed as a config value" do
|
225
|
+
client.expects(:unthreaded_req).with(request, 10, 0, ['rspec'])
|
226
|
+
client.instance_variable_get(:@config).expects(:publish_timeout).returns(10)
|
216
227
|
client.req(message)
|
217
228
|
end
|
218
229
|
end
|
@@ -267,50 +278,132 @@ module MCollective
|
|
267
278
|
end
|
268
279
|
|
269
280
|
describe "#start_receiver" do
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
281
|
+
describe "waitfor is a number" do
|
282
|
+
it "should go into a receive loop and receive until it reaches waitfor" do
|
283
|
+
results = []
|
284
|
+
Timeout.stubs(:timeout).yields
|
285
|
+
message = mock
|
286
|
+
client.stubs(:receive).with("erfs123").returns(message)
|
287
|
+
message.stubs(:payload).returns("msg1", "msg2", "msg3")
|
288
|
+
client.start_receiver("erfs123", 3, 5) do |msg|
|
289
|
+
results << msg
|
290
|
+
end
|
291
|
+
results.should == ["msg1", "msg2", "msg3"]
|
278
292
|
end
|
279
|
-
results.should == ["msg1", "msg2", "msg3"]
|
280
|
-
end
|
281
293
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
294
|
+
it "should log a warning if a timeout occurs" do
|
295
|
+
results = []
|
296
|
+
Timeout.stubs(:timeout).yields
|
297
|
+
message = mock
|
298
|
+
client.stubs(:receive).with("erfs123").returns(message)
|
299
|
+
message.stubs(:payload).returns("msg1", "msg2", "timeout")
|
300
|
+
Log.expects(:warn).with("Could not receive all responses. Expected : 3. Received : 2")
|
301
|
+
responded = client.start_receiver("erfs123", 3, 5) do |msg|
|
302
|
+
if msg == "timeout"
|
303
|
+
raise Timeout::Error
|
304
|
+
end
|
305
|
+
results << msg
|
306
|
+
end
|
307
|
+
results.should == ["msg1", "msg2"]
|
308
|
+
responded.should == 2
|
309
|
+
end
|
310
|
+
|
311
|
+
it "should not log a warning if a the response count is larger or equal to the expected number of responses" do
|
312
|
+
results = []
|
313
|
+
Timeout.stubs(:timeout).yields
|
314
|
+
message = mock
|
315
|
+
client.stubs(:receive).with("erfs123").returns(message)
|
316
|
+
message.stubs(:payload).returns("msg1", "msg2", "timeout")
|
317
|
+
Log.expects(:warn).never
|
318
|
+
responded = client.start_receiver("erfs123", 2, 5) do |msg|
|
319
|
+
if msg == "timeout"
|
320
|
+
raise Timeout::Error
|
321
|
+
end
|
322
|
+
results << msg
|
292
323
|
end
|
293
|
-
results
|
324
|
+
results.should == ["msg1", "msg2"]
|
325
|
+
responded.should == 2
|
294
326
|
end
|
295
|
-
results.should == ["msg1", "msg2"]
|
296
|
-
responded.should == 2
|
297
327
|
end
|
298
328
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
329
|
+
describe "waitfor is an array" do
|
330
|
+
it "should go into a receive loop and receive until it matches waitfor" do
|
331
|
+
senders = ["sender1", "sender2", "sender3", "sender4"]
|
332
|
+
expected = senders.map {|s| Message.new({:callerid => "caller", :senderid => s}, nil, :type => :reply)}
|
333
|
+
results = []
|
334
|
+
Timeout.stubs(:timeout).yields
|
335
|
+
client.stubs(:receive).with("erfs123").returns(*expected)
|
336
|
+
client.start_receiver("erfs123", senders[0,3], 5) do |msg|
|
337
|
+
results << msg
|
338
|
+
end
|
339
|
+
results.should == expected[0,3].map {|m| m.payload}
|
340
|
+
end
|
341
|
+
|
342
|
+
it "receive until it gets all expected responses" do
|
343
|
+
senders = ["sender1", "sender2", "sender3", "sender4"]
|
344
|
+
expected = senders.map {|s| Message.new({:callerid => "caller", :senderid => s}, nil, :type => :reply)}
|
345
|
+
results = []
|
346
|
+
Timeout.stubs(:timeout).yields
|
347
|
+
client.stubs(:receive).with("erfs123").returns(*expected)
|
348
|
+
client.start_receiver("erfs123", senders[1,3], 5) do |msg|
|
349
|
+
results << msg
|
350
|
+
end
|
351
|
+
results.should == expected.map {|m| m.payload}
|
352
|
+
end
|
353
|
+
|
354
|
+
it "should log a warning if a timeout occurs" do
|
355
|
+
senders = ["sender1", "sender2", "sender3"]
|
356
|
+
messages = ["msg1", "msg2", "timeout"]
|
357
|
+
expected = senders.zip(messages).map {|s, m| Message.new({:callerid => "caller", :senderid => s, :body => m}, nil, :type => :reply)}
|
358
|
+
results = []
|
359
|
+
Timeout.stubs(:timeout).yields
|
360
|
+
client.stubs(:receive).with("erfs123").returns(*expected)
|
361
|
+
Log.expects(:warn).with("Could not receive all responses. Did not receive responses from sender3")
|
362
|
+
responded = client.start_receiver("erfs123", senders, 5) do |msg|
|
363
|
+
if msg[:body] == "timeout"
|
364
|
+
raise Timeout::Error
|
365
|
+
end
|
366
|
+
results << msg
|
367
|
+
end
|
368
|
+
results.should == expected[0,2].map {|m| m.payload}
|
369
|
+
responded.should == 2
|
370
|
+
end
|
371
|
+
|
372
|
+
it "should not log a warning if accepting all responses" do
|
373
|
+
senders = ["sender1", "sender2", "sender3"]
|
374
|
+
messages = ["msg1", "msg2", "timeout"]
|
375
|
+
expected = senders.zip(messages).map {|s, m| Message.new({:callerid => "caller", :senderid => s, :body => m}, nil, :type => :reply)}
|
376
|
+
results = []
|
377
|
+
Timeout.stubs(:timeout).yields
|
378
|
+
client.stubs(:receive).with("erfs123").returns(*expected)
|
379
|
+
Log.expects(:warn).never
|
380
|
+
responded = client.start_receiver("erfs123", [], 1) do |msg|
|
381
|
+
if msg[:body] == "timeout"
|
382
|
+
raise Timeout::Error
|
383
|
+
end
|
384
|
+
results << msg
|
385
|
+
end
|
386
|
+
results.should == expected[0,2].map {|m| m.payload}
|
387
|
+
responded.should == 2
|
388
|
+
end
|
389
|
+
|
390
|
+
it "should not log a warning if the response count is larger or equal to the expected number of responses" do
|
391
|
+
senders = ["sender1", "sender2", "sender3"]
|
392
|
+
messages = ["msg1", "msg2", "timeout"]
|
393
|
+
expected = senders.zip(messages).map {|s, m| Message.new({:callerid => "caller", :senderid => s, :body => m}, nil, :type => :reply)}
|
394
|
+
results = []
|
395
|
+
Timeout.stubs(:timeout).yields
|
396
|
+
client.stubs(:receive).with("erfs123").returns(*expected)
|
397
|
+
Log.expects(:warn).never
|
398
|
+
responded = client.start_receiver("erfs123", senders[0,2], 5) do |msg|
|
399
|
+
if msg[:body] == "timeout"
|
400
|
+
raise Timeout::Error
|
401
|
+
end
|
402
|
+
results << msg
|
309
403
|
end
|
310
|
-
results
|
404
|
+
results.should == expected[0,2].map {|m| m.payload}
|
405
|
+
responded.should == 2
|
311
406
|
end
|
312
|
-
results.should == ["msg1", "msg2"]
|
313
|
-
responded.should == 2
|
314
407
|
end
|
315
408
|
end
|
316
409
|
|