beetle 3.5.1 → 3.5.5

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 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