beetle 3.5.1 → 3.5.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2dcaf90eaf1b11b7f6350bb34e17d73591616790ede7b43b6e98cef363dd3770
4
- data.tar.gz: 55348c9ce61cc2f43869f9c12cd26bbc5dc033b0e0a0506c0a821d6a6e24862c
3
+ metadata.gz: a0e823ee91e804e241eefc9057879a94c538c43c45f04af9c0e9491d6bc9e0b3
4
+ data.tar.gz: b211a4cfb395af0a048431fa53f865a0b9b9a61478d5f0527cf8c794a4751273
5
5
  SHA512:
6
- metadata.gz: 6daabfea72ab76b0fa6944d35cee52139678f9a02a272e86a32af6045750496ee81b96ff685eee1bbe9617030b981df3718b7569efabc98df59f894127da29d1
7
- data.tar.gz: 04d599595b4c39e62a78b496b284a67bed1a545e759d9a094facc757e0334ed16e4bdd7bab4f7bfabb7b6f63da0e590351e86d0da55328ab6db898e9ceaaef7f
6
+ metadata.gz: 244515a2a89649e6f09900b910bbe29c4d624b1750051136d26e7f49fcf825910b602f6714438e8a3a8bd9f9822af2a0955afbfe82cd46cb23acd393999346f8
7
+ data.tar.gz: 3735d575d65abbf415e9bad4c74c2c84720144cd3147c6687061413eeaf296ea46a739bfdb731c62c4031bf751869acf4ef8ccc269146067c36a354f69fcb08c
data/Rakefile CHANGED
@@ -98,7 +98,7 @@ namespace :consul do
98
98
  end
99
99
 
100
100
  Cucumber::Rake::Task.new(:cucumber) do |t|
101
- t.cucumber_opts = "features --format progress"
101
+ t.cucumber_opts = ["features", "--format progress"]
102
102
  end
103
103
 
104
104
  task :cucumber => :clean
@@ -115,18 +115,14 @@ Rake::TestTask.new do |t|
115
115
  t.warning = false
116
116
  end
117
117
 
118
- require 'rdoc/task'
119
-
120
- RDoc::Task.new do |rdoc|
121
- rdoc.rdoc_dir = 'site/rdoc'
122
- rdoc.title = 'Beetle'
123
- rdoc.main = 'README.rdoc'
124
- rdoc.options << '--line-numbers' << '--inline-source' << '--quiet'
125
- rdoc.rdoc_files.include('**/*.rdoc')
126
- rdoc.rdoc_files.include('MIT-LICENSE')
127
- rdoc.rdoc_files.include('lib/**/*.rb')
118
+ task :clean do
119
+ sh "rm -f tmp/*.output tmp/*.log tmp/master-dir/* tmp/slave-dir/* tmp/*lock tmp/*pid test.log" unless ENV['GITHUB_ACTIONS']
128
120
  end
129
121
 
130
- task :clean do
131
- sh "rm -f tmp/*.output tmp/*.log tmp/master-dir/* tmp/slave-dir/* tmp/*lock tmp/*pid test.log"
122
+ require 'yard'
123
+
124
+ YARD::Rake::YardocTask.new do |t|
125
+ OTHER_PATHS = %w()
126
+ t.files = ['lib/**/*.rb'] + OTHER_PATHS
127
+ t.options = %w(--markup-provider=redcarpet --markup=markdown --main=README.md --output-dir=site/yard)
132
128
  end
data/beetle.gemspec CHANGED
@@ -31,16 +31,21 @@ Gem::Specification.new do |s|
31
31
  s.add_runtime_dependency "activesupport", ">= 2.3.4"
32
32
 
33
33
  s.add_development_dependency "activerecord", "~> 5.0"
34
- s.add_development_dependency "cucumber", "~> 2.4.0"
34
+ s.add_development_dependency "cucumber", "~> 8.0.0"
35
35
  s.add_development_dependency "daemon_controller", "~> 1.2.0"
36
36
  s.add_development_dependency "daemons", ">= 1.2.0"
37
37
  s.add_development_dependency "i18n"
38
38
  s.add_development_dependency "minitest", "~> 5.1"
39
- s.add_development_dependency "mocha", "~> 1.3.0"
40
- s.add_development_dependency "mysql2", "~> 0.4.4"
39
+ s.add_development_dependency "minitest-reporters"
40
+ s.add_development_dependency "mocha", "~> 1.14"
41
+ s.add_development_dependency "mysql2", "~> 0.5"
41
42
  s.add_development_dependency "rake", "~> 13.0"
42
- s.add_development_dependency "rdoc", "~> 4.0"
43
43
  s.add_development_dependency "simplecov", "~> 0.15"
44
44
  s.add_development_dependency "webmock", "~> 3.0"
45
45
  s.add_development_dependency "websocket-eventmachine-client"
46
+ s.add_development_dependency 'yard'
47
+ s.add_development_dependency 'redcarpet'
48
+ s.add_development_dependency 'github-markup'
49
+ s.add_development_dependency 'byebug'
50
+ s.add_development_dependency 'appraisal'
46
51
  end
@@ -17,7 +17,7 @@ Beetle.config.logger.level = Logger::INFO
17
17
  client = Beetle::Client.new
18
18
 
19
19
  # use two servers
20
- Beetle.config.servers = "localhost:5672, localhost:5673"
20
+ Beetle.config.servers = ENV["RABBITMQ_SERVERS"] || "localhost:5672, localhost:5673"
21
21
  # instantiate a client
22
22
  client = Beetle::Client.new
23
23
 
data/examples/rpc.rb CHANGED
@@ -4,7 +4,7 @@ require File.expand_path(File.dirname(__FILE__)+"/../lib/beetle")
4
4
 
5
5
  # suppress debug messages
6
6
  Beetle.config.logger.level = Logger::INFO
7
- Beetle.config.servers = "localhost:5672, localhost:5673"
7
+ Beetle.config.servers = ENV["RABBITMQ_SERVERS"] || "localhost:5672, localhost:5673"
8
8
  # instantiate a client
9
9
 
10
10
  client = Beetle::Client.new
@@ -24,6 +24,26 @@ Feature: Redis auto failover
24
24
  Given a redis server "redis-1" exists as master
25
25
  Then the role of redis server "redis-1" should be "slave"
26
26
 
27
+ Scenario: Successful redis master switch with multiple slaves
28
+ And a redis server "redis-3" exists as slave of "redis-3"
29
+ Given a redis configuration server using redis servers "redis-1,redis-2,redis-3" with clients "rc-client-1,rc-client-2" exists
30
+ And a redis configuration client "rc-client-1" using redis servers "redis-1,redis-2,redis-3" exists
31
+ And a redis configuration client "rc-client-2" using redis servers "redis-1,redis-2,redis-3" exists
32
+ And a beetle handler using the redis-master file from "rc-client-1" exists
33
+ And redis server "redis-1" is down
34
+ And the retry timeout for the redis master check is reached
35
+ Then a system notification for "redis-1" not being available should be sent
36
+ And the role of redis server "redis-2" should be "master"
37
+ And the redis master file of the redis configuration server should contain "redis-2"
38
+ And the redis master of "rc-client-1" should be "redis-2"
39
+ And the redis master of "rc-client-2" should be "redis-2"
40
+ And the redis master of the beetle handler should be "redis-2"
41
+ And a system notification for switching from "redis-1" to "redis-2" should be sent
42
+ Given a redis server "redis-1" exists as master
43
+ Then the role of redis server "redis-1" should be "slave"
44
+ And the redis server "redis-1" is a slave of "redis-2"
45
+ And the redis server "redis-3" is a slave of "redis-2"
46
+
27
47
  Scenario: Successful single redis master switch with multiple failover sets
28
48
  Given a redis server "redis-3" exists as master
29
49
  And a redis server "redis-4" exists as slave of "redis-3"
@@ -1,8 +1,9 @@
1
1
  Given /^consul state has been cleared$/ do
2
+ consul_host = ENV["CONSUL_HOST"] || "localhost:8500"
2
3
  system "killall beetle beetle_handler >/dev/null 2>/dev/null"
3
- system "curl --silent --request PUT http://localhost:8500/v1/kv/apps/beetle/config/ >/dev/null"
4
- system "curl --silent --request PUT http://localhost:8500/v1/kv/shared/config/ >/dev/null"
5
- system "curl --silent --request DELETE http://localhost:8500/v1/kv/apps/beetle/state/redis_master_file_content >/dev/null"
4
+ system "curl --silent --request PUT http://#{consul_host}/v1/kv/apps/beetle/config/ >/dev/null"
5
+ system "curl --silent --request PUT http://#{consul_host}/v1/kv/shared/config/ >/dev/null"
6
+ system "curl --silent --request DELETE http://#{consul_host}/v1/kv/apps/beetle/state/redis_master_file_content >/dev/null"
6
7
  end
7
8
 
8
9
  Given /^a redis server "([^\"]*)" exists as master$/ do |redis_name|
@@ -93,7 +94,6 @@ Given /^an old redis master file for "([^\"]*)" with master "([^\"]*)" exists$/
93
94
  end
94
95
  end
95
96
 
96
-
97
97
  Then /^the role of redis server "([^\"]*)" should be "(master|slave)"$/ do |redis_name, role|
98
98
  expected_role = false
99
99
  10.times do
@@ -103,6 +103,16 @@ Then /^the role of redis server "([^\"]*)" should be "(master|slave)"$/ do |redi
103
103
  assert expected_role, "#{redis_name} is not a #{role}"
104
104
  end
105
105
 
106
+ Then /^the redis server "([^\"]*)" is a slave of "([^\"]*)"$/ do |redis_name, redis_master_name|
107
+ master = TestDaemons::Redis[redis_master_name].redis
108
+ slave = TestDaemons::Redis[redis_name].redis
109
+ 3.times do
110
+ sleep 1
111
+ break if slave.slave_of?(master.host, master.port)
112
+ end
113
+ assert slave.slave_of?(master.host, master.port)
114
+ end
115
+
106
116
  Then /^the redis master of "([^\"]*)" (?:in system "([^"]*)" )?should be "([^\"]*)"$/ do |redis_configuration_client_name, system_name, redis_name|
107
117
  system_name ||= "system"
108
118
  master_file = redis_master_file(redis_configuration_client_name)
@@ -143,11 +153,21 @@ end
143
153
  Then /^the redis master of the beetle handler should be "([^\"]*)"$/ do |redis_name|
144
154
  Beetle.config.servers = "127.0.0.1:5672" # rabbitmq
145
155
  Beetle.config.logger.level = Logger::INFO
146
- client = Beetle::Client.new.configure :auto_delete => true do |config|
147
- config.queue(:echo, :lazy => true, :dead_lettering => true)
148
- config.message(:echo)
156
+ redis_master = TestDaemons::Redis[redis_name].ip_with_port
157
+ response = nil
158
+ expected_response = ['OK', redis_master]
159
+ 3.times do |i|
160
+ client = Beetle::Client.new.configure :auto_delete => true do |config|
161
+ config.queue(:echo, :lazy => true, :dead_lettering => true)
162
+ config.message(:echo)
163
+ end
164
+ t1 = Time.now
165
+ response = client.rpc(:echo, 'echo')
166
+ t2 = Time.now
167
+ # puts "OK,#{redis_master} =?= #{response.join(',')} after #{t2-t1}, attempt #{i+1}"
168
+ break if expected_response == response
149
169
  end
150
- assert_match /#{TestDaemons::Redis[redis_name].ip_with_port}/, client.rpc(:echo, 'nil').second
170
+ assert_equal expected_response, response
151
171
  end
152
172
 
153
173
  Then /^a system notification for "([^\"]*)" not being available should be sent$/ do |redis_name|
@@ -166,8 +186,12 @@ end
166
186
 
167
187
  Then /^a system notification for no slave available to become new master should be sent$/ do
168
188
  text = "Redis master could not be switched, no slave available to become new master"
169
- lines = File.readlines(system_notification_log_path)
170
- tail = (["","",""]+lines)[-3..-1].join("\n")
189
+ tail = ""
190
+ 3.times do
191
+ lines = File.readlines(system_notification_log_path)
192
+ tail = (["","",""]+lines)[-3..-1].join("\n")
193
+ sleep 0.1 unless tail =~ /#{text}/
194
+ end
171
195
  assert_match /#{text}/, tail
172
196
  end
173
197
 
@@ -179,7 +203,7 @@ end
179
203
 
180
204
  Given /^an immediate master switch is initiated and responds with (\d+)$/ do |response_code|
181
205
  response = TestDaemons::RedisConfigurationServer.initiate_master_switch
182
- assert_equal response_code, response.code, "unexpected response code #{response.code}, message: #{response.body}"
206
+ assert_equal response_code.to_s, response.code, "unexpected response code #{response.code}, message: #{response.body}"
183
207
  sleep 1
184
208
  end
185
209
 
@@ -25,9 +25,10 @@ module TestDaemons
25
25
 
26
26
  def self.daemon_controller
27
27
  clients_parameter_string = @@redis_configuration_clients.blank? ? "" : "--client-ids #{@@redis_configuration_clients}"
28
+ consul_host = ENV["CONSUL_HOST"] || "localhost:8500"
28
29
  DaemonController.new(
29
30
  :identifier => "Redis configuration test server",
30
- :start_command => "./beetle configuration_server -v -d --redis-master-file #{redis_master_file} --redis-servers '#{@@redis_servers}' #{clients_parameter_string} --redis-master-retry-interval 1 --pid-file #{pid_file} --log-file #{log_file} --redis-failover-confidence-level #{@@confidence_level} --consul http://localhost:8500",
31
+ :start_command => "./beetle configuration_server -v -d --redis-master-file #{redis_master_file} --redis-servers '#{@@redis_servers}' #{clients_parameter_string} --redis-master-retry-interval 1 --pid-file #{pid_file} --log-file #{log_file} --redis-failover-confidence-level #{@@confidence_level} --consul http://#{consul_host}",
31
32
  :ping_command => lambda{ answers_text_requests? },
32
33
  :pid_file => pid_file,
33
34
  :log_file => log_file,
@@ -33,6 +33,12 @@ module Beetle
33
33
  attr_accessor :redis_servers
34
34
  # redis database number to use for the message deduplication store (defaults to <tt>4</tt>)
35
35
  attr_accessor :redis_db
36
+ # redis connect timeout. defaults to 5 seconds.
37
+ attr_accessor :redis_connect_timeout
38
+ # redis read timeout. defaults to 5 seconds.
39
+ attr_accessor :redis_read_timeout
40
+ # redis write timeout. defaults to 5 seconds.
41
+ attr_accessor :redis_write_timeout
36
42
 
37
43
  # how long we should repeatedly retry a redis operation before giving up, with a one
38
44
  # second sleep between retries (defaults to <tt>180.seconds</tt>). this value needs to be
@@ -157,6 +163,9 @@ module Beetle
157
163
  self.redis_server = "localhost:6379"
158
164
  self.redis_servers = ""
159
165
  self.redis_db = 4
166
+ self.redis_connect_timeout = 5.0
167
+ self.redis_read_timeout = 5.0
168
+ self.redis_write_timeout = 5.0
160
169
  self.redis_failover_timeout = 180.seconds
161
170
  self.redis_status_key_expiry_interval = 0.seconds
162
171
  self.redis_failover_client_heartbeat_interval = 10.seconds
@@ -217,6 +226,17 @@ module Beetle
217
226
  end
218
227
  end
219
228
 
229
+ # redis optins to be passed to Redis.new
230
+ def redis_options
231
+ {
232
+ db: redis_db,
233
+ connect_timeout: redis_connect_timeout,
234
+ read_timeout: redis_read_timeout,
235
+ write_timeout: redis_write_timeout,
236
+ logger: redis_logger,
237
+ }
238
+ end
239
+
220
240
  private
221
241
  def load_config
222
242
  raw = ERB.new(IO.read(config_file)).result
@@ -62,7 +62,7 @@ module Beetle
62
62
  # store completion status for given <tt>msg_id</tt> if it doesn't exist yet. Returns whether the
63
63
  # operation was successful.
64
64
  def setnx_completed!(msg_id)
65
- expiry = @config.redis_status_key_expiry_interval
65
+ expiry = @config.redis_status_key_expiry_interval.to_i
66
66
  return true if expiry == 0
67
67
  with_failover do
68
68
  redis.set(
@@ -109,7 +109,7 @@ module Beetle
109
109
 
110
110
  # delete all keys associated with the given <tt>msg_id</tt>.
111
111
  def del_keys(msg_id)
112
- expiry = @config.redis_status_key_expiry_interval
112
+ expiry = @config.redis_status_key_expiry_interval.to_i
113
113
  keys = keys(msg_id)
114
114
  status_key = keys.shift if expiry > 0
115
115
  with_failover do
@@ -150,7 +150,7 @@ module Beetle
150
150
 
151
151
  # set current redis master instance (as specified in the Beetle::Configuration)
152
152
  def redis_master_from_server_string
153
- @current_master ||= Redis.from_server_string(@config.redis_server, :db => @config.redis_db, :logger => @config.redis_logger)
153
+ @current_master ||= Redis.from_server_string(@config.redis_server, @config.redis_options)
154
154
  end
155
155
 
156
156
  # set current redis master from master file
@@ -168,7 +168,7 @@ module Beetle
168
168
  def set_current_redis_master_from_master_file
169
169
  @last_time_master_file_changed = File.mtime(@config.redis_server)
170
170
  server_string = extract_redis_master(read_master_file)
171
- @current_master = !server_string.blank? ? Redis.from_server_string(server_string, :db => @config.redis_db, :logger => @config.redis_logger) : nil
171
+ @current_master = !server_string.blank? ? Redis.from_server_string(server_string, @config.redis_options ) : nil
172
172
  end
173
173
 
174
174
  # extract redis master from file content and return the server for our system
@@ -72,15 +72,15 @@ module Beetle
72
72
 
73
73
  def setup(opts) #:nodoc:
74
74
  @server = opts[:server]
75
- @timeout = opts[:timeout] || DEFAULT_HANDLER_TIMEOUT
76
- @delay = opts[:delay] || DEFAULT_HANDLER_EXECUTION_ATTEMPTS_DELAY
75
+ @timeout = opts[:timeout] || DEFAULT_HANDLER_TIMEOUT.to_i
76
+ @delay = (opts[:delay] || DEFAULT_HANDLER_EXECUTION_ATTEMPTS_DELAY).ceil
77
77
  @attempts_limit = opts[:attempts] || DEFAULT_HANDLER_EXECUTION_ATTEMPTS
78
78
  @exceptions_limit = opts[:exceptions] || DEFAULT_EXCEPTION_LIMIT
79
79
  @attempts_limit = @exceptions_limit + 1 if @attempts_limit <= @exceptions_limit
80
80
  @retry_on = opts[:retry_on] || nil
81
81
  @store = opts[:store]
82
82
  max_delay = opts[:max_delay] || @delay
83
- @max_delay = max_delay if max_delay >= 2*@delay
83
+ @max_delay = max_delay.ceil if max_delay >= 2*@delay
84
84
  end
85
85
 
86
86
  # extracts various values from the AMQP header properties
@@ -101,7 +101,7 @@ module Beetle
101
101
  def self.publishing_options(opts = {}) #:nodoc:
102
102
  flags = 0
103
103
  flags |= FLAG_REDUNDANT if opts[:redundant]
104
- expires_at = now + (opts[:ttl] || DEFAULT_TTL)
104
+ expires_at = now + (opts[:ttl] || DEFAULT_TTL).to_i
105
105
  opts = opts.slice(*PUBLISHING_KEYS)
106
106
  opts[:message_id] = generate_uuid.to_s
107
107
  opts[:timestamp] = now
@@ -165,7 +165,7 @@ module Beetle
165
165
 
166
166
  # store handler timeout timestamp in the deduplication store
167
167
  def set_timeout!
168
- @store.set(msg_id, :timeout, now + timeout)
168
+ @store.set(msg_id, :timeout, (now + timeout).ceil)
169
169
  end
170
170
 
171
171
  # handler timed out?
@@ -230,7 +230,7 @@ module Beetle
230
230
  # have we already seen this message? if not, set the status to "incomplete" and store
231
231
  # the message exipration timestamp in the deduplication store.
232
232
  def key_exists?
233
- old_message = !@store.msetnx(msg_id, :status =>"incomplete", :expires => @expires_at, :timeout => now + timeout)
233
+ old_message = !@store.msetnx(msg_id, :status =>"incomplete", :expires => @expires_at.to_i, :timeout => (now + timeout).to_i)
234
234
  if old_message
235
235
  logger.debug "Beetle: received duplicate message: #{msg_id} on queue: #{@queue}"
236
236
  end
@@ -34,7 +34,7 @@ module Beetle
34
34
  Bunny::ConnectionError, Bunny::ForcedChannelCloseError, Bunny::ForcedConnectionCloseError,
35
35
  Bunny::MessageError, Bunny::ProtocolError, Bunny::ServerDownError, Bunny::UnsubscribeError,
36
36
  Bunny::AcknowledgementError, Qrack::BufferOverflowError, Qrack::InvalidTypeError,
37
- Errno::EHOSTUNREACH, Errno::ECONNRESET, Timeout::Error
37
+ Errno::EHOSTUNREACH, Errno::ECONNRESET, Errno::ETIMEDOUT, Timeout::Error
38
38
  ]
39
39
  end
40
40
 
@@ -66,6 +66,7 @@ module Beetle
66
66
  logger.debug "Beetle: message sent!"
67
67
  published = 1
68
68
  rescue *bunny_exceptions => e
69
+ logger.warn("Beetle: publishing exception #{e} #{e.backtrace[0..4].join("\n")}")
69
70
  stop!(e)
70
71
  tries -= 1
71
72
  # retry same server on receiving the first exception for it (might have been a normal restart)
@@ -98,6 +99,7 @@ module Beetle
98
99
  published << @server
99
100
  logger.debug "Beetle: message sent (#{published})!"
100
101
  rescue *bunny_exceptions => e
102
+ logger.warn("Beetle: publishing exception #{e} #{e.backtrace[0..4].join("\n")}")
101
103
  stop!(e)
102
104
  retry if (tries += 1) == 1
103
105
  mark_server_dead
@@ -3,6 +3,7 @@ class Redis #:nodoc:
3
3
  def self.from_server_string(server_string, options = {})
4
4
  host, port = server_string.split(':')
5
5
  options = {:host => host, :port => port}.update(options)
6
+ options.delete(:logger) if Redis::VERSION >= "5.0"
6
7
  new(options)
7
8
  end
8
9
 
@@ -79,6 +80,19 @@ class Redis #:nodoc:
79
80
  super != 0
80
81
  end
81
82
 
83
+ elsif Redis::VERSION >= "5.0.0"
84
+
85
+ # redis 5.0.0 has a shutdown method which raises if a connection to the redis server
86
+ # cannot be established.
87
+ module SaneShutdown
88
+ def shutdown
89
+ super
90
+ rescue RedisClient::CannotConnectError
91
+ nil
92
+ end
93
+ end
94
+ prepend SaneShutdown
95
+
82
96
  elsif Redis::VERSION >= "4.0.0"
83
97
 
84
98
  # redis 4.0.0 has a shutdown method which raises if a connection to the redis server
@@ -1,3 +1,3 @@
1
1
  module Beetle
2
- VERSION = "3.5.1"
2
+ VERSION = "3.5.5"
3
3
  end
data/lib/beetle.rb CHANGED
@@ -1,8 +1,13 @@
1
1
  $:.unshift(File.expand_path('..', __FILE__))
2
2
  require 'bunny' # which bunny picks up
3
3
  require 'qrack/errors' # needed by the publisher
4
- require 'redis/connection/hiredis' # require *before* redis as specified in the redis-rb gem docs
5
- require 'redis'
4
+ begin
5
+ require 'redis/connection/hiredis' # require *before* redis as specified in the redis-rb gem docs
6
+ require 'redis'
7
+ rescue LoadError
8
+ require 'redis'
9
+ require 'hiredis-client'
10
+ end
6
11
  require 'active_support/all'
7
12
  require 'set'
8
13
  require 'socket'
@@ -39,12 +44,8 @@ module Beetle
39
44
  # determine the fully qualified domainname of the host we're running on
40
45
  def self.hostname
41
46
  name = Socket.gethostname
42
- parts = name.split('.')
43
- if parts.size > 1
44
- name
45
- else
46
- Socket.gethostbyname(parts.first).first rescue name
47
- end
47
+ host = name.split('.').first
48
+ Addrinfo.getaddrinfo(host, nil, nil, :STREAM, nil, Socket::AI_CANONNAME).first.canonname rescue name
48
49
  end
49
50
 
50
51
  # use ruby's autoload mechanism for loading beetle classes
@@ -7,7 +7,7 @@ class AMQPGemBehaviorTest < Minitest::Test
7
7
  begin
8
8
  exception = nil
9
9
  EM.run do
10
- AMQP.start(:logging => false) do |connection|
10
+ AMQP.start(logging: false, host: ENV['RABBITMQ_SERVERS'] || 'localhost') do |connection|
11
11
  EM::Timer.new(1){ connection.close { EM.stop }}
12
12
  channel = AMQP::Channel.new(connection)
13
13
  channel.on_error { puts "woot"}
@@ -26,7 +26,7 @@ module Beetle
26
26
  end
27
27
 
28
28
  test "server should be initialized" do
29
- assert_equal @bs.servers.first, @bs.server
29
+ assert @bs.server
30
30
  end
31
31
 
32
32
  test "current_host should return the hostname of the current server" do
@@ -2,15 +2,18 @@ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
2
 
3
3
  module Beetle
4
4
  class HostnameTest < Minitest::Test
5
- test "should use Socket.gethostname if returned name name is fully qualified" do
5
+ test "should use canonical name if possible " do
6
+ addr = mock("addr")
7
+ addr.expects(:canonname).returns("a.b.com")
6
8
  Socket.expects(:gethostname).returns("a.b.com")
9
+ Addrinfo.expects(:getaddrinfo).with("a", nil, nil, :STREAM, nil, Socket::AI_CANONNAME).returns([addr])
7
10
  assert_equal "a.b.com", Beetle.hostname
8
11
  end
9
12
 
10
- test "should use Socket.gethosbyname if returned name name is not fully qualified" do
13
+ test "should use Socket.gethostbyname if Addrinfo raises" do
11
14
  Socket.expects(:gethostname).returns("a")
12
- Socket.expects(:gethostbyname).with("a").returns(["a.b.com"])
13
- assert_equal "a.b.com", Beetle.hostname
15
+ Addrinfo.expects(:getaddrinfo).with("a", nil, nil, :STREAM, nil, Socket::AI_CANONNAME).raises("murks")
16
+ assert_equal "a", Beetle.hostname
14
17
  end
15
18
  end
16
19
  end
@@ -8,7 +8,7 @@ module Beetle
8
8
  end
9
9
 
10
10
  test "should have a default server" do
11
- assert_equal ["localhost:5672"], @client.servers
11
+ assert !@client.servers.empty?
12
12
  end
13
13
 
14
14
  test "should have no additional subscription servers" do
@@ -327,7 +327,9 @@ module Beetle
327
327
  client.register_queue("b_queue")
328
328
  client.register_queue("a_queue")
329
329
  client.send(:subscriber).expects(:listen_queues).with {|value| value.include?("a_queue") && value.include?("b_queue")}.yields
330
- client.listen
330
+ called = false
331
+ client.listen { called = true }
332
+ assert called
331
333
  end
332
334
 
333
335
  test "trying to listen to a message is no longer supported and should raise an exception" do
@@ -338,7 +340,9 @@ module Beetle
338
340
  client = Client.new
339
341
  client.register_queue(:test)
340
342
  client.send(:subscriber).expects(:listen_queues).with(['test']).yields
341
- client.listen_queues([:test])
343
+ called = false
344
+ client.listen_queues([:test]) { called = true }
345
+ assert called
342
346
  end
343
347
 
344
348
  test "trying to listen to an unknown queue should raise an exception" do
@@ -87,7 +87,7 @@ module Beetle
87
87
  private
88
88
  def redis_test_master_file(server_string)
89
89
  tmp_dir = File.expand_path("../../../tmp", __FILE__)
90
- Dir.mkdir(tmp_dir) unless File.exists?(tmp_dir)
90
+ Dir.mkdir(tmp_dir) unless File.exist?(tmp_dir)
91
91
  path = tmp_dir + "/redis-master-for-unit-tests"
92
92
  File.open(path, "w"){|f| f.puts server_string}
93
93
  path
@@ -77,7 +77,9 @@ module Beetle
77
77
 
78
78
  class PublisherPublishingTest < Minitest::Test
79
79
  def setup
80
- @client = Client.new
80
+ @config = Configuration.new
81
+ @config.servers = ENV['RABBITMQ_SERVERS'].split(',').first if ENV['RABBITMQ_SERVERS']
82
+ @client = Client.new(@config)
81
83
  @pub = Publisher.new(@client)
82
84
  @pub.stubs(:bind_queues_for_exchange)
83
85
  @client.register_queue("mama", :exchange => "mama-exchange")
@@ -277,6 +279,7 @@ module Beetle
277
279
  class PublisherQueueManagementTest < Minitest::Test
278
280
  def setup
279
281
  @config = Configuration.new
282
+ @config.servers = ENV['RABBITMQ_SERVERS'] if ENV['RABBITMQ_SERVERS']
280
283
  @client = Client.new(@config)
281
284
  @pub = Publisher.new(@client)
282
285
  end
@@ -305,7 +308,9 @@ module Beetle
305
308
  @client.register_queue('test_queue_2', :exchange => 'test_exchange')
306
309
  @client.register_queue('test_queue_3', :exchange => 'test_exchange_2')
307
310
  queue = mock("queue")
308
- queue.expects(:bind).times(3)
311
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "test_queue_1"}).once
312
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "test_queue_2"}).once
313
+ @pub.expects(:bind_queue!).with(queue, "test_exchange_2", {:key => "test_queue_3"}).once
309
314
  @pub.expects(:declare_queue!).returns(queue).times(3)
310
315
  @pub.send(:bind_queues_for_exchange, 'test_exchange')
311
316
  @pub.send(:bind_queues_for_exchange, 'test_exchange_2')
@@ -315,18 +320,21 @@ module Beetle
315
320
  @client.register_queue('test_queue_1', :exchange => 'test_exchange')
316
321
  @client.register_queue('test_queue_2', :exchange => 'test_exchange')
317
322
  queue = mock("queue")
318
- queue.expects(:bind).twice
319
323
  @pub.expects(:declare_queue!).returns(queue).twice
324
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "test_queue_1"}).once
325
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "test_queue_2"}).once
320
326
  @pub.send(:bind_queues_for_exchange, 'test_exchange')
321
327
  @pub.send(:bind_queues_for_exchange, 'test_exchange')
322
328
  end
323
329
 
324
330
  test "should declare queues only once even with many bindings" do
331
+
325
332
  @client.register_queue('test_queue', :exchange => 'test_exchange')
326
333
  @client.register_binding('test_queue', :exchange => 'test_exchange', :key => 'sir-message-a-lot')
327
334
  queue = mock("queue")
328
- queue.expects(:bind).twice
329
335
  @pub.expects(:declare_queue!).returns(queue).once
336
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "test_queue"}).once
337
+ @pub.expects(:bind_queue!).with(queue, "test_exchange", {:key => "sir-message-a-lot"}).once
330
338
  @pub.send(:bind_queues_for_exchange, 'test_exchange')
331
339
  end
332
340
 
@@ -549,10 +557,11 @@ module Beetle
549
557
  end
550
558
  end
551
559
 
552
-
553
560
  class RPCTest < Minitest::Test
554
561
  def setup
555
- @client = Client.new
562
+ @config = Configuration.new
563
+ @config.servers = ENV['RABBITMQ_SERVERS'].split(',').first if ENV['RABBITMQ_SERVERS']
564
+ @client = Client.new(@config)
556
565
  @pub = Publisher.new(@client)
557
566
  @client.register_message(:test, :exchange => :some_exchange)
558
567
  end
@@ -57,7 +57,11 @@ module Beetle
57
57
 
58
58
  class HiredisLoadedTest < Minitest::Test
59
59
  test "should be using hiredis instead of the redis ruby backend" do
60
- assert defined?(Hiredis)
60
+ if Redis::VERSION < "5.0"
61
+ assert defined?(Hiredis)
62
+ else
63
+ assert_equal RedisClient.default_driver, RedisClient::HiredisConnection
64
+ end
61
65
  end
62
66
  end
63
67
 
@@ -41,9 +41,9 @@ module Beetle
41
41
 
42
42
  test "stop! should close all connections if the reactor is not running" do
43
43
  connection1 = mock('conection1')
44
- connection1.expects(:close).yields
44
+ connection1.expects(:close)
45
45
  connection2 = mock('connection2')
46
- connection2.expects(:close).yields
46
+ connection2.expects(:close)
47
47
  @sub.instance_variable_set "@connections", [["server1", connection1], ["server2", connection2]]
48
48
  EM.expects(:reactor_running?).returns(false)
49
49
  @sub.send(:stop!)
@@ -52,7 +52,9 @@ module Beetle
52
52
 
53
53
  class SubscriberPauseAndResumeTest < Minitest::Test
54
54
  def setup
55
- @client = Client.new
55
+ @config = Configuration.new
56
+ @config.servers = "localhost:5672"
57
+ @client = Client.new(@config)
56
58
  @sub = @client.send(:subscriber)
57
59
  @sub.servers << "localhost:7777"
58
60
  @server1, @server2 = @sub.servers
@@ -342,7 +344,9 @@ module Beetle
342
344
 
343
345
  class SubscriptionTest < Minitest::Test
344
346
  def setup
345
- @client = Client.new
347
+ @config = Configuration.new
348
+ @config.servers = "locahost:5672"
349
+ @client = Client.new(@config)
346
350
  @sub = @client.send(:subscriber)
347
351
  end
348
352