roundhousekiq 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +4 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/Guardfile +44 -0
- data/LICENSE.txt +22 -0
- data/README.md +120 -0
- data/Rakefile +10 -0
- data/bin/roundhousekiq +17 -0
- data/chuck-norris.png +0 -0
- data/lib/roundhousekiq/configuration.rb +15 -0
- data/lib/roundhousekiq/runner.rb +103 -0
- data/lib/roundhousekiq/version.rb +3 -0
- data/lib/roundhousekiq/worker.rb +26 -0
- data/lib/roundhousekiq/worker_definition.rb +32 -0
- data/lib/roundhousekiq/workers.rb +42 -0
- data/lib/roundhousekiq.rb +19 -0
- data/roundhousekiq.gemspec +31 -0
- data/spec/fixtures/dummy_worker.rb +6 -0
- data/spec/roundhousekiq/configuration_spec.rb +17 -0
- data/spec/roundhousekiq/runner_spec.rb +350 -0
- data/spec/roundhousekiq/worker_definition_spec.rb +76 -0
- data/spec/roundhousekiq/worker_spec.rb +64 -0
- data/spec/roundhousekiq/workers_spec.rb +71 -0
- data/spec/roundhousekiq_spec.rb +34 -0
- data/spec/spec_helper.rb +84 -0
- metadata +207 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c3d38ff3867de7878b149a1d42eec8cb890a8e56
|
4
|
+
data.tar.gz: b2b98a7563c1a9b1e5bf6710108f3fcd9f9f39ef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b3a50b8d5dbe7c744d4bcea0cf5a00bc7baf97a70c943dab37ff4b3876fd2ec4e3d7ce372a799f0235411e4494f0d3532445d3ee88c318474983e59fd539241d
|
7
|
+
data.tar.gz: e97745b71d28ded61c9197fefe0a6e93227413c0d82579ae36d0a025a2fe3e624d33a09a6a5bc2a29edaa3189e17434a47aee3f778b29efa4acc77ba271a6e42
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
roundhousekiq
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.2
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
2
|
+
require "guard/rspec/dsl"
|
3
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
4
|
+
|
5
|
+
# Feel free to open issues for suggestions and improvements
|
6
|
+
|
7
|
+
# RSpec files
|
8
|
+
rspec = dsl.rspec
|
9
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
10
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
11
|
+
watch(rspec.spec_files)
|
12
|
+
|
13
|
+
# Ruby files
|
14
|
+
ruby = dsl.ruby
|
15
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
16
|
+
|
17
|
+
# Rails files
|
18
|
+
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
19
|
+
dsl.watch_spec_files_for(rails.app_files)
|
20
|
+
dsl.watch_spec_files_for(rails.views)
|
21
|
+
|
22
|
+
watch(rails.controllers) do |m|
|
23
|
+
[
|
24
|
+
rspec.spec.("routing/#{m[1]}_routing"),
|
25
|
+
rspec.spec.("controllers/#{m[1]}_controller"),
|
26
|
+
rspec.spec.("acceptance/#{m[1]}")
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
# Rails config changes
|
31
|
+
watch(rails.spec_helper) { rspec.spec_dir }
|
32
|
+
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
33
|
+
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
34
|
+
|
35
|
+
# Capybara features specs
|
36
|
+
watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
|
37
|
+
watch(rails.layouts) { |m| rspec.spec.("features/#{m[1]}") }
|
38
|
+
|
39
|
+
# Turnip features and steps
|
40
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
41
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
42
|
+
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
43
|
+
end
|
44
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Moritz Lawitschka
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
![Chuck Norris](chuck-norris.png)
|
2
|
+
|
3
|
+
# Roundhousekiq
|
4
|
+
|
5
|
+
![Gem version](https://img.shields.io/gem/v/roundhousekiq.svg?style=flat)
|
6
|
+
![Build Status](https://img.shields.io/travis/suitepad-gmbh/roundhousekiq.svg?style=flat)
|
7
|
+
![License MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)
|
8
|
+
![CC Score](https://img.shields.io/codeclimate/github/suitepad-gmbh/roundhousekiq.svg?style=flat)
|
9
|
+
![Coverage](https://img.shields.io/codeclimate/coverage/github/suitepad-gmbh/roundhousekiq.svg?style=flat)
|
10
|
+
|
11
|
+
Small AMQP to Sidekiq bridge, allowing Sidekiq jobs to be triggered via AMQP.
|
12
|
+
You define your Sidekiq jobs as usual, but instead of manually invoking the
|
13
|
+
jobs, you define to which AMQP event the worker should listen on.
|
14
|
+
|
15
|
+
Take for example a fleet of services all reporting their current status every
|
16
|
+
once in a while to your central monitoring service. Because these services do
|
17
|
+
not care about when their status report is being processed and by whom, they
|
18
|
+
simple send it via your AMQP server's `status` exchange and let others handle
|
19
|
+
the rest.
|
20
|
+
|
21
|
+
The monitoring service now uses Roundhousekiq to asynchronously process these
|
22
|
+
status reports and to keep the load from the main server process, it does the
|
23
|
+
processing in background using Sidekiq. Simply set up a new Sidekiq worker,
|
24
|
+
specify the AMQP exchange and routing key to listen on, and let Roundhousekiq
|
25
|
+
handle the AMQP bindings and finding the right worker for each message:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
class StatusWorker
|
29
|
+
include Sidekiq::Worker
|
30
|
+
include Roundhousekiq::Worker
|
31
|
+
|
32
|
+
# AMQP configuration
|
33
|
+
exchange_name 'status'
|
34
|
+
exchange_type :topic
|
35
|
+
queue_name 'roundhousekiq_status_worker'
|
36
|
+
routing_key 'status.*'
|
37
|
+
|
38
|
+
# Attributes:
|
39
|
+
# payload: Parsed JSON payload directly from AMQP
|
40
|
+
def perform(payload)
|
41
|
+
# Heavy computing action...
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
## Installation
|
48
|
+
|
49
|
+
Add this line to your application's Gemfile:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
gem 'roundhousekiq'
|
53
|
+
```
|
54
|
+
|
55
|
+
And then execute:
|
56
|
+
|
57
|
+
$ bundle
|
58
|
+
|
59
|
+
Or install it yourself as:
|
60
|
+
|
61
|
+
$ gem install roundhousekiq
|
62
|
+
|
63
|
+
## Usage
|
64
|
+
|
65
|
+
1. Create an initializer in _config/initializers/roundhousekiq.rb_ and specify
|
66
|
+
your AMQP host.
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
Roundhousekiq.configure do |config|
|
70
|
+
# AMQP host address
|
71
|
+
# config.host = '127.0.0.1'
|
72
|
+
|
73
|
+
# AMQP host port
|
74
|
+
# config.port = '5672'
|
75
|
+
|
76
|
+
# AMQP vhost to be connected to
|
77
|
+
# config.vhost = '/'
|
78
|
+
|
79
|
+
# User credentials
|
80
|
+
# config.username = 'guest'
|
81
|
+
# config.password = 'guest'
|
82
|
+
|
83
|
+
# Prefetch count on all queues Roundhousekiq will subscribe to
|
84
|
+
# config.prefetch = 256
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
2. Create your first worker. This worker does only differ from a normal Sidekiq
|
89
|
+
worker in the `Roundhousekiq::Worker` module being included and specifying which
|
90
|
+
exchange and routing key to listen on:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
class Worker
|
94
|
+
include Sidekiq::Worker
|
95
|
+
include Roundhousekiq::Worker
|
96
|
+
|
97
|
+
exchange_name 'amq.topic'
|
98
|
+
exchange_type :topic
|
99
|
+
queue_name 'worker'
|
100
|
+
routing_key 'work'
|
101
|
+
|
102
|
+
def perform(payload)
|
103
|
+
# ...
|
104
|
+
end
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
A persistent queue named _worker_ bound to the _amq.topic_ exchange with the
|
109
|
+
routing key _work_ will be created. Each time a message arrives in that
|
110
|
+
queue, this worker will be triggered.
|
111
|
+
|
112
|
+
You do not have to specify a queue name, if you do not want to have a
|
113
|
+
persistent queue. AMQP will automatically create a queue for that worker,
|
114
|
+
which is being deleted once the Roundhousekiq daemon shuts down.
|
115
|
+
|
116
|
+
3. Run the Roundhousekiq daemon from the root of your Rails project:
|
117
|
+
|
118
|
+
```shell
|
119
|
+
$ bundle exec roundhousekiq
|
120
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
|
4
|
+
# Default directory to look in is `/spec`
|
5
|
+
# Run with `rake spec`
|
6
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
7
|
+
task.rspec_opts = ['--color', '--format', 'documentation']
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default => :spec
|
data/bin/roundhousekiq
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Load Rails environment
|
4
|
+
ENV['RAILS_ENV'] ||= 'development'
|
5
|
+
require File.expand_path('./config/boot')
|
6
|
+
require File.expand_path('./config/environment')
|
7
|
+
|
8
|
+
# Always pre-load Rails application
|
9
|
+
::Rails.application.eager_load!
|
10
|
+
|
11
|
+
runner = Roundhousekiq::Runner.new
|
12
|
+
runner.run
|
13
|
+
|
14
|
+
# Trap `Kill `
|
15
|
+
Signal.trap("TERM") do
|
16
|
+
runner.shutdown
|
17
|
+
end
|
data/chuck-norris.png
ADDED
Binary file
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Roundhousekiq
|
2
|
+
class Configuration < Struct.new(:host, :port, :vhost, :username, :password, :prefetch)
|
3
|
+
def initialize
|
4
|
+
# AMQP connection
|
5
|
+
self.host = '127.0.0.1'
|
6
|
+
self.port = '5672'
|
7
|
+
self.vhost = '/'
|
8
|
+
self.prefetch = 256
|
9
|
+
|
10
|
+
# AMQP auth
|
11
|
+
self.username = 'guest'
|
12
|
+
self.password = 'guest'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Roundhousekiq
|
2
|
+
class Runner
|
3
|
+
|
4
|
+
attr_accessor :connection, :channel, :queue, :consumer, :shutdown_runner,
|
5
|
+
:exchange, :error_exchange, :queues, :queue_worker_map
|
6
|
+
|
7
|
+
##################################
|
8
|
+
# Public API
|
9
|
+
##################################
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
self.queues = []
|
13
|
+
self.queue_worker_map = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
establish_connection
|
18
|
+
create_channel
|
19
|
+
create_exchanges_and_queues
|
20
|
+
setup_subscribers
|
21
|
+
end
|
22
|
+
|
23
|
+
def shutdown
|
24
|
+
# Give runner time to finish its work
|
25
|
+
self.shutdown_runner = true
|
26
|
+
sleep 10
|
27
|
+
|
28
|
+
# Spawn new thread for closing the connection. Connection cannot be closed
|
29
|
+
# from current thread (being in TRAP context).
|
30
|
+
Thread.new { self.connection.try :close }
|
31
|
+
|
32
|
+
# Sleep again to wait for connection close
|
33
|
+
sleep 10
|
34
|
+
end
|
35
|
+
|
36
|
+
def shutdown?
|
37
|
+
self.shutdown_runner
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
##################################
|
42
|
+
# Connection
|
43
|
+
##################################
|
44
|
+
|
45
|
+
def establish_connection
|
46
|
+
options = { properties: self.class.client_settings }
|
47
|
+
|
48
|
+
self.connection = Bunny.new self.class.connection_settings, options
|
49
|
+
self.connection.start
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.connection_settings
|
53
|
+
config = Roundhousekiq.config.to_h
|
54
|
+
config.select { |k, v| %i(host port vhost username password).include? k }
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.client_settings
|
58
|
+
Bunny::Session::DEFAULT_CLIENT_PROPERTIES.merge product: 'Roundhousekiq'
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_channel
|
62
|
+
self.channel = self.connection.create_channel
|
63
|
+
self.channel.prefetch Roundhousekiq.config.prefetch
|
64
|
+
self.channel
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_exchanges_and_queues
|
68
|
+
Workers.definitions.each do |worker, definition|
|
69
|
+
exchange = self.channel.exchange(
|
70
|
+
definition.exchange[:name],
|
71
|
+
type: definition.exchange[:type],
|
72
|
+
durable: true
|
73
|
+
)
|
74
|
+
|
75
|
+
queue = self.channel.queue(
|
76
|
+
definition.queue[:name],
|
77
|
+
auto_delete: definition.queue[:auto_delete],
|
78
|
+
durable: definition.queue[:durable]
|
79
|
+
).bind(exchange, routing_key: definition.queue[:routing_key])
|
80
|
+
|
81
|
+
self.queues << queue
|
82
|
+
self.queue_worker_map[queue] = worker
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def setup_subscribers
|
87
|
+
self.queues.each do |queue|
|
88
|
+
queue.subscribe(manual_ack: true) do |delivery_info, metadata, payload|
|
89
|
+
self.channel.ack delivery_info.delivery_tag
|
90
|
+
process_message queue, payload
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
while not self.shutdown?
|
95
|
+
sleep 5
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def process_message(queue, payload)
|
100
|
+
queue_worker_map[queue].perform_async JSON.parse(payload)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Roundhousekiq
|
2
|
+
module Worker
|
3
|
+
def self.included(base)
|
4
|
+
Workers.register base
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def exchange_name(name)
|
10
|
+
Workers.exchange_name_for self, name
|
11
|
+
end
|
12
|
+
|
13
|
+
def exchange_type(type)
|
14
|
+
Workers.exchange_type_for self, type
|
15
|
+
end
|
16
|
+
|
17
|
+
def queue_name(name)
|
18
|
+
Workers.queue_name_for self, name
|
19
|
+
end
|
20
|
+
|
21
|
+
def routing_key(key)
|
22
|
+
Workers.routing_key_for self, key
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Roundhousekiq
|
2
|
+
class WorkerDefinition
|
3
|
+
|
4
|
+
attr_reader :exchange, :queue
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@exchange = {}
|
8
|
+
@queue = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def exchange_name=(name)
|
12
|
+
exchange[:name] = name
|
13
|
+
end
|
14
|
+
|
15
|
+
def exchange_type=(type)
|
16
|
+
exchange[:type] = type
|
17
|
+
end
|
18
|
+
|
19
|
+
def queue_name=(name)
|
20
|
+
name ||= '' # Default name to empty string
|
21
|
+
|
22
|
+
queue[:name] = name
|
23
|
+
queue[:durable] = name != ''
|
24
|
+
queue[:auto_delete] = name == ''
|
25
|
+
end
|
26
|
+
|
27
|
+
def routing_key=(key)
|
28
|
+
queue[:routing_key] = key
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Roundhousekiq
|
2
|
+
class Workers
|
3
|
+
class << self
|
4
|
+
def register(worker)
|
5
|
+
if definitions.key? worker
|
6
|
+
warn "Worker class #{worker.to_s} already registered"
|
7
|
+
end
|
8
|
+
|
9
|
+
definitions[worker] = WorkerDefinition.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def definitions
|
13
|
+
@@definitions ||= {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def exchange_name_for(worker, name)
|
17
|
+
definition = definitions[worker]
|
18
|
+
fail "Unknown worker class passed: #{worker}" unless definition
|
19
|
+
definition.exchange_name = name
|
20
|
+
end
|
21
|
+
|
22
|
+
def exchange_type_for(worker, type)
|
23
|
+
definition = definitions[worker]
|
24
|
+
fail "Unknown worker class passed: #{worker}" unless definition
|
25
|
+
definition.exchange_type = type
|
26
|
+
end
|
27
|
+
|
28
|
+
def queue_name_for(worker, name)
|
29
|
+
definition = definitions[worker]
|
30
|
+
fail "Unknown worker class passed: #{worker}" unless definition
|
31
|
+
definition.queue_name = name
|
32
|
+
end
|
33
|
+
|
34
|
+
def routing_key_for(worker, key)
|
35
|
+
definition = definitions[worker]
|
36
|
+
fail "Unknown worker class passed: #{worker}" unless definition
|
37
|
+
definition.routing_key = key
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'bunny'
|
2
|
+
require 'roundhousekiq/configuration'
|
3
|
+
require 'roundhousekiq/runner'
|
4
|
+
require 'roundhousekiq/version'
|
5
|
+
require 'roundhousekiq/worker'
|
6
|
+
require 'roundhousekiq/workers'
|
7
|
+
require 'roundhousekiq/worker_definition'
|
8
|
+
|
9
|
+
module Roundhousekiq
|
10
|
+
def self.configure
|
11
|
+
@config = Configuration.new
|
12
|
+
yield(@config) if block_given?
|
13
|
+
@config
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.config
|
17
|
+
@config || configure
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'roundhousekiq/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "roundhousekiq"
|
8
|
+
spec.version = Roundhousekiq::VERSION
|
9
|
+
spec.authors = ["Moritz Lawitschka"]
|
10
|
+
spec.email = ["moritz.lawitschka@suitepad.de"]
|
11
|
+
spec.summary = %q{AMQP to Sidekiq bridge}
|
12
|
+
spec.description = %q{Trigger Sidekiq jobs asynchronously over AMQP}
|
13
|
+
spec.homepage = "https://github.com/suitepad-gmbh/roundhousekiq"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = ['roundhousekiq']
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "bunny", "~> 1.7"
|
22
|
+
spec.add_dependency "sidekiq", "~> 3.0"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.3.0"
|
27
|
+
spec.add_development_dependency "rspec-nc", "~> 0.2.0"
|
28
|
+
spec.add_development_dependency "guard", "~> 2.13.0"
|
29
|
+
spec.add_development_dependency "guard-rspec", "~> 4.6.4"
|
30
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
31
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe Roundhousekiq::Configuration do
|
2
|
+
|
3
|
+
# Method existence
|
4
|
+
it { should respond_to :host }
|
5
|
+
it { should respond_to :host= }
|
6
|
+
it { should respond_to :port }
|
7
|
+
it { should respond_to :port= }
|
8
|
+
it { should respond_to :vhost }
|
9
|
+
it { should respond_to :vhost= }
|
10
|
+
it { should respond_to :username }
|
11
|
+
it { should respond_to :username= }
|
12
|
+
it { should respond_to :password }
|
13
|
+
it { should respond_to :password= }
|
14
|
+
it { should respond_to :prefetch }
|
15
|
+
it { should respond_to :prefetch= }
|
16
|
+
|
17
|
+
end
|