chasqui 0.0.1 → 0.1.0

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.
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Chasqui resque integration" do
4
+
5
+ PUBLISH_EVENTS = [
6
+ { event: 'user.signup', data: ['Kelly'] },
7
+ { event: 'account.credit', data: [1337, 'Kelly'] },
8
+ { event: 'account.debit', data: [10, 'Kelly'] },
9
+ { event: 'user.signup', data: ['Travis'] },
10
+ { event: 'account.debit', data: [9000, 'Kelly'] },
11
+ { event: 'user.cancel', data: ['Kelly'] },
12
+ { event: 'account.credit', data: [42, 'Travis'] },
13
+ ]
14
+
15
+ EXPECTED_EVENTS = {
16
+ 'app1' => [
17
+ { event: 'user.signup', data: ['Kelly'] },
18
+ { event: 'user.signup', data: ['Travis'] },
19
+ ],
20
+ 'app2' => [
21
+ { event: 'account.credit', data: [1337, 'Kelly'] },
22
+ { event: 'account.debit', data: [10, 'Kelly'] },
23
+ { event: 'account.debit', data: [9000, 'Kelly'] },
24
+ { event: 'user.cancel', data: ['Kelly'] },
25
+ { event: 'account.credit', data: [42, 'Travis'] },
26
+ ],
27
+ }
28
+
29
+ before do
30
+ @subscriber_queues = %w(app1 app2)
31
+ @redis_url = 'redis://localhost:6379/13'
32
+ @redis = Redis.new url: @redis_url
33
+ @redis.keys('*').each { |k| @redis.del k }
34
+
35
+ Chasqui.configure do |c|
36
+ c.channel = 'integration'
37
+ c.redis = @redis_url
38
+ end
39
+
40
+ @pids = []
41
+ start_resque_workers
42
+
43
+ # Wait for subscribers to register before starting the broker so we don't miss events.
44
+ sleep 1
45
+
46
+ start_chasqui_broker
47
+ end
48
+
49
+ after do
50
+ terminate_child_processes
51
+ end
52
+
53
+ it 'works' do
54
+ PUBLISH_EVENTS.each do |event|
55
+ Chasqui.publish event[:event], *event[:data]
56
+ end
57
+
58
+ begin
59
+ Timeout::timeout(10) do
60
+ EXPECTED_EVENTS.each do |subscriber_queue, events|
61
+ events.each do |expected|
62
+ _, payload = @redis.blpop "chasqui:#{subscriber_queue}:event_log"
63
+ actual = JSON.parse payload
64
+ expect(actual['event']).to eq(expected[:event])
65
+ expect(actual['data']).to eq(expected[:data])
66
+ end
67
+ end
68
+ end
69
+ rescue TimeoutError
70
+ fail "Failed to process all events in a timely manner."
71
+ end
72
+ end
73
+
74
+ def start_chasqui_broker
75
+ @pids << fork do
76
+ exec './bin/chasqui',
77
+ '--logfile', 'tmp/resque-spec.log',
78
+ '--redis', @redis_url,
79
+ '--debug'
80
+ end
81
+ end
82
+
83
+ def start_resque_workers
84
+ @subscriber_queues.each do |queue|
85
+ @pids << fork do
86
+ ENV['CHASQUI_ENV'] = 'test'
87
+ ENV['QUEUE'] = queue
88
+ ENV['TERM_CHILD'] = '1'
89
+ ENV['INTERVAL'] = '0.1'
90
+ ENV['REDIS_NAMESPACE'] = "resque:#{queue}"
91
+ ENV['REDIS_URL'] = @redis_url
92
+ exec 'bundle', 'exec', 'rake', 'resque:work'
93
+ end
94
+ end
95
+ end
96
+
97
+ def terminate_child_processes
98
+ Timeout::timeout(10) do
99
+ @pids.each { |pid| kill 'TERM', pid rescue nil }
100
+ end
101
+ rescue TimeoutError
102
+ @pids.each { |pid| kill 'KILL', pid rescue nil }
103
+ fail "One or more child processes failed to terminate in a timely manner"
104
+ end
105
+
106
+ def kill(signal, pid)
107
+ Process.kill signal, pid
108
+ unless signal == 'KILL'
109
+ pid, status = Process.waitpid2 pid, 0
110
+ expect(status.exitstatus).to eq(0)
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,14 @@
1
+ def log_event subscriber, args
2
+ event = subscriber.current_event
3
+ payload = { event: event['event'], data: args }.to_json
4
+ subscriber.redis.rpush "#{subscriber.queue}:event_log", payload
5
+ end
6
+
7
+ Chasqui.subscribe queue: 'app1', channel: 'integration' do
8
+ on('user.signup') { |*args| log_event self, args }
9
+ end
10
+
11
+ Chasqui.subscribe queue: 'app2', channel: 'integration' do
12
+ on('account.*') { |*args| log_event self, args }
13
+ on('user.cancel') { |*args| log_event self, args }
14
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chasqui::Broker do
4
+ let(:broker) { Chasqui::Broker.new }
5
+ before { reset_chasqui }
6
+
7
+ it 'forwards events to subscriber queues' do
8
+ expect(-> { broker.forward_event }).to raise_error(NotImplementedError)
9
+ end
10
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+ require 'chasqui/cli'
3
+
4
+ describe Chasqui::CLI do
5
+
6
+ describe 'options' do
7
+ before { reset_config }
8
+
9
+ context do
10
+ before { Chasqui.config.broker_poll_interval = 1 }
11
+ after { File.unlink 'tmp/test.log' if File.exists? 'tmp/test.log' }
12
+
13
+ it 'changes the logfile' do
14
+ cli = Chasqui::CLI.new ['chasqui', '-f', 'tmp/test.log']
15
+ expect(cli.logfile).to eq('tmp/test.log')
16
+
17
+ cli.configure
18
+ Chasqui.logger.warn 'tmp/test.log message'
19
+ expect(File.read('tmp/test.log')).to match('tmp/test.log message')
20
+ end
21
+ end
22
+
23
+ it 'changes the redis connection' do
24
+ cli = Chasqui::CLI.new ['chasqui', '-r', 'redis://10.0.0.23:6379/5']
25
+ expect(cli.redis_url).to eq('redis://10.0.0.23:6379/5')
26
+
27
+ cli.configure
28
+ expect(Chasqui.redis.redis.client.host).to eq('10.0.0.23')
29
+ end
30
+
31
+ it 'changes the inbox queue' do
32
+ cli = Chasqui::CLI.new ['chasqui', '-q', 'inbox2']
33
+ expect(cli.inbox_queue).to eq('inbox2')
34
+
35
+ cli.configure
36
+ expect(Chasqui.inbox).to eq('inbox2')
37
+ end
38
+
39
+ it 'enables verbose mode (debug logging)' do
40
+ cli = Chasqui::CLI.new ['chasqui', '--debug']
41
+ expect(cli.debug).to be true
42
+
43
+ cli.configure
44
+ expect(Chasqui.logger.level).to eq(Logger::DEBUG)
45
+ end
46
+
47
+ it 'displays the version' do
48
+ cli = Chasqui::CLI.new ['chasqui', '-v']
49
+ cli.run
50
+ expect { cli.run }.to output(/chasqui #{Chasqui::VERSION}/).to_stdout
51
+ end
52
+
53
+ it 'displays help' do
54
+ cli = Chasqui::CLI.new ['chasqui', '-h', '--help']
55
+ expect { cli.run }.to output(/Usage: chasqui \[options\]/).to_stdout
56
+ end
57
+ end
58
+
59
+ describe '#run' do
60
+ before { reset_chasqui }
61
+
62
+ it 'configures and starts the broker' do
63
+ expect(Chasqui::Broker).to receive(:start)
64
+
65
+ argv = %w(chasqui -f tmp/test.log --debug -q inbox2 -r redis://127.0.0.1:6379/0)
66
+ Chasqui::CLI.new(argv).run
67
+
68
+ expect(Chasqui.logger.level).to eq(Logger::DEBUG)
69
+ expect(Chasqui.inbox_queue).to eq('inbox2')
70
+ expect(Chasqui.redis.client.host).to eq('127.0.0.1')
71
+ end
72
+ end
73
+
74
+ end
File without changes
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chasqui::MultiBroker do
4
+ let(:broker) { Chasqui::MultiBroker.new }
5
+ before { reset_chasqui }
6
+
7
+ describe '#forward_event' do
8
+ before do
9
+ Chasqui.config.channel = 'app1'
10
+ Chasqui.subscribe queue: 'queue1', channel: 'app1'
11
+ Chasqui.subscribe queue: 'queue2', channel: 'app2'
12
+ Chasqui.subscribe queue: 'queue3', channel: 'app1'
13
+ end
14
+
15
+ it 'places the event on all subscriber queues' do
16
+ Chasqui.publish 'foo.bar', 'A'
17
+ broker.forward_event
18
+
19
+ expect(redis.llen('inbox')).to eq(0)
20
+
21
+ expect(redis.llen('queue:queue1')).to eq(1)
22
+ expect(redis.llen('queue:queue2')).to eq(0)
23
+ expect(redis.llen('queue:queue3')).to eq(1)
24
+
25
+ event = { 'event' => 'foo.bar', 'channel' => 'app1', 'data' => ['A'] }
26
+
27
+ job1 = JSON.parse redis.rpop('queue:queue1')
28
+ expect(job1['args']).to include(event)
29
+
30
+ job3 = JSON.parse redis.rpop('queue:queue3')
31
+ expect(job3['args']).to include(event)
32
+ end
33
+
34
+ it 'blocks on empty queues' do
35
+ thread = Thread.new { broker.forward_event }
36
+
37
+ begin
38
+ Timeout::timeout(1) do
39
+ Chasqui.config.redis = Redis.new
40
+ Chasqui.config.channel = 'app2'
41
+ Chasqui.publish 'foo.bar', 'A'
42
+
43
+ job = JSON.parse redis.brpop('queue:queue2')[1]
44
+ expect(job).to include('class' => 'Chasqui::Subscriber__queue2')
45
+ expect(job).to include('args' =>
46
+ [{ 'event' => 'foo.bar', 'channel' => 'app2', 'data' => ['A'] }])
47
+ end
48
+ ensure
49
+ thread.kill
50
+ end
51
+ end
52
+
53
+ it "doesn't lose events if the broker fails" do
54
+ Chasqui.config.channel = 'app2'
55
+ Chasqui.publish 'foo', 'process'
56
+ Chasqui.publish 'foo', 'keep in queue'
57
+ allow(broker.redis).to receive(:smembers).and_raise(Redis::ConnectionError)
58
+
59
+ expect(-> { broker.forward_event }).to raise_error(Redis::ConnectionError)
60
+ expect(redis.llen('queue:queue2')).to eq(0)
61
+ expect(redis.llen(broker.in_progress_queue)).to eq(1)
62
+
63
+ allow(broker.redis).to receive(:smembers).and_call_original
64
+ broker.forward_event
65
+ expect(redis.llen('queue:queue2')).to eq(1)
66
+
67
+ job = JSON.parse redis.rpop('queue:queue2')
68
+ expect(job['args']).to include(
69
+ 'event' => 'foo', 'channel' => 'app2', 'data' => ['process'])
70
+ expect(redis.llen(broker.in_progress_queue)).to eq(0)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chasqui::Subscriber do
4
+ let(:subscriber) { Chasqui::Subscriber.new 'my-queue', 'my.channel' }
5
+
6
+ it { expect(subscriber.queue).to eq('my-queue') }
7
+ it { expect(subscriber.channel).to eq('my.channel') }
8
+
9
+ describe '#on' do
10
+ it 'registers the event handlers' do
11
+ subscriber.on('foo') { |foo| foo }
12
+ subscriber.on('zig.zag') { |*args| args }
13
+
14
+ pattern = subscriber.matching_handler_patterns_for('foo').first
15
+ expect(subscriber.call_handler(pattern, 'bar')).to eq('bar')
16
+
17
+ pattern = subscriber.matching_handler_patterns_for('zig.zag').first
18
+ expect(subscriber.call_handler(pattern, 1, 2, 3, 4)).to eq([1, 2, 3, 4])
19
+ end
20
+
21
+ it 'raises when registering duplicate handlers' do
22
+ subscriber.on('foo') { |foo| foo }
23
+ expect(-> {
24
+ subscriber.on('foo') { |a, b| a + b }
25
+ }).to raise_error(Chasqui::HandlerAlreadyRegistered)
26
+ end
27
+ end
28
+
29
+ describe '#matching_handler_patterns_for' do
30
+ it 'always returns an array' do
31
+ expect(subscriber.matching_handler_patterns_for('unknown')).to eq([])
32
+ end
33
+
34
+ it 'matches single event' do
35
+ p = Proc.new { }
36
+ subscriber.on('foo', &p)
37
+ expect(subscriber.matching_handler_patterns_for('foo')).to eq([/\Afoo\z/])
38
+ end
39
+
40
+ it 'matches wildcards' do
41
+ p = 6.times.map { Proc.new { } }
42
+ subscriber.on('foo*', &p[0])
43
+ subscriber.on('bar', &p[1])
44
+ subscriber.on('*bar', &p[2])
45
+ subscriber.on('*', &p[3])
46
+ subscriber.on('*a*', &p[4])
47
+ subscriber.on('*z*', &p[5])
48
+ expect(subscriber.matching_handler_patterns_for('foo.bar')).to eq([
49
+ /\Afoo.*\z/,
50
+ /\A.*bar\z/,
51
+ /\A.*\z/,
52
+ /\A.*a.*\z/
53
+ ])
54
+ end
55
+ end
56
+
57
+ describe '#perform' do
58
+ it 'calls the matching event handlers' do
59
+ calls = []
60
+ subscriber.on('foo.bar') { |a, b| calls << a + b }
61
+ subscriber.on('foo.*') { |a, b| calls << a ** b }
62
+ subscriber.perform(redis, { 'event' => 'foo.bar', 'data' => [3, 4] })
63
+ expect(calls.sort).to eq([7, 81])
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ require 'resque'
3
+
4
+ describe Chasqui::ResqueWorker do
5
+ let(:subscriber) { FakeSubscriber.new 'my-queue', 'my.channel'}
6
+
7
+ describe '.create' do
8
+ it 'configures a new worker' do
9
+ worker_class = Chasqui::ResqueWorker.create(subscriber)
10
+ expect(worker_class.name).to eq('Chasqui::Subscriber__my_queue')
11
+ expect(worker_class.ancestors).to include(Chasqui::ResqueWorker)
12
+ expect(worker_class.instance_variable_get(:@queue)).to eq('my-queue')
13
+ end
14
+ end
15
+
16
+ describe '.perform' do
17
+ let(:worker) { Chasqui::ResqueWorker.create(subscriber) }
18
+
19
+ it 'delegates to the subscriber' do
20
+ event = { 'event' => 'foo', 'data' => ['bar'] }
21
+ worker.perform event
22
+ received_event = subscriber.events.shift
23
+ expect(received_event).to eq(event)
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ if sidekiq_supported_ruby_version?
4
+
5
+ describe Chasqui::SidekiqWorker do
6
+ let(:subscriber) { FakeSubscriber.new 'my-queue', 'my.channel'}
7
+
8
+ describe '.create' do
9
+ it 'configures a new worker' do
10
+ worker_class = Chasqui::SidekiqWorker.create(subscriber)
11
+ expect(worker_class.included_modules).to include(Sidekiq::Worker)
12
+ expect(worker_class.sidekiq_options).to include('queue' => 'my-queue')
13
+ expect(worker_class.new).to be_kind_of(Chasqui::SidekiqWorker)
14
+ end
15
+ end
16
+
17
+ describe '#perform' do
18
+ let(:worker_class) { Chasqui::SidekiqWorker.create(subscriber) }
19
+
20
+ it 'delegates to the subscriber' do
21
+ event = { 'event' => 'foo', 'data' => ['bar'] }
22
+ worker = worker_class.new
23
+ worker.perform event
24
+ received_event = subscriber.events.shift
25
+ expect(received_event).to eq(event)
26
+ end
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,185 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chasqui do
4
+ it 'has a version number' do
5
+ expect(Chasqui::VERSION).not_to be nil
6
+ end
7
+
8
+ describe '.configure' do
9
+ before { reset_config }
10
+
11
+ context 'defaults' do
12
+ it { expect(Chasqui.channel).to eq('__default') }
13
+ it { expect(Chasqui.inbox_queue).to eq('inbox') }
14
+ it { expect(Chasqui.redis.client.db).to eq(0) }
15
+ it { expect(Chasqui.config.broker_poll_interval).to eq(3) }
16
+ it { expect(Chasqui.config.worker_backend).to eq(nil) }
17
+
18
+ it do
19
+ # remove chasqui's test environment logger
20
+ Chasqui.config[:logger] = nil
21
+ expect(Chasqui.logger).to be_kind_of(Logger)
22
+ end
23
+
24
+ it { expect(Chasqui.logger.level).to eq(Logger::INFO) }
25
+ it { expect(Chasqui.logger.progname).to eq('chasqui') }
26
+ end
27
+
28
+ it 'configures the channel' do
29
+ Chasqui.config.channel = 'com.example.test'
30
+ expect(Chasqui.channel).to eq('com.example.test')
31
+ end
32
+
33
+ it 'accepts a block' do
34
+ Chasqui.configure { |config| config.channel = 'com.example.test' }
35
+ expect(Chasqui.channel).to eq('com.example.test')
36
+ end
37
+
38
+ it 'configures the inbox queue' do
39
+ Chasqui.config.inbox_queue = 'foo'
40
+ expect(Chasqui.inbox).to eq('foo')
41
+ end
42
+
43
+ it 'configures the broker poll interval' do
44
+ Chasqui.config.broker_poll_interval = 1
45
+ expect(Chasqui.config.broker_poll_interval).to eq(1)
46
+ end
47
+
48
+ context 'redis' do
49
+ it 'accepts config options' do
50
+ redis_config = { host: '10.0.3.24' }
51
+ Chasqui.config.redis = redis_config
52
+ expect(Chasqui.redis.client.host).to eq('10.0.3.24')
53
+ end
54
+
55
+ it 'accepts an initialized client' do
56
+ redis = Redis.new db: 2
57
+ Chasqui.config.redis = redis
58
+ expect(Chasqui.redis.client.db).to eq(2)
59
+ end
60
+
61
+ it 'accepts URLs' do
62
+ Chasqui.config.redis = 'redis://10.0.1.21:12345/0'
63
+ expect(Chasqui.redis.client.host).to eq('10.0.1.21')
64
+ end
65
+
66
+ it 'uses a namespace' do
67
+ Chasqui.redis.set 'foo', 'bar'
68
+ expect(Chasqui.redis.redis.get 'chasqui:foo').to eq('bar')
69
+ end
70
+ end
71
+
72
+ describe 'logger' do
73
+ it 'accepts a log device' do
74
+ logs = StringIO.new
75
+ Chasqui.config.logger = logs
76
+ Chasqui.logger.info "status"
77
+ Chasqui.logger.warn "error"
78
+
79
+ logs.rewind
80
+ output = logs.read
81
+
82
+ %w(chasqui INFO status WARN error).each do |text|
83
+ expect(output).to match(text)
84
+ end
85
+ end
86
+
87
+ it 'accepts a logger-like object' do
88
+ fake_logger = FakeLogger.new
89
+ Chasqui.config.logger = fake_logger
90
+ expect(Chasqui.logger).to eq(fake_logger)
91
+ expect(Chasqui.logger.progname).to eq('chasqui')
92
+ end
93
+ end
94
+ end
95
+
96
+ describe '.publish' do
97
+ before { reset_chasqui }
98
+
99
+ it 'pushes messages to the inbox queue' do
100
+ payloads = [
101
+ [1, 2, {'foo'=>'bar'}],
102
+ [3, 4, {'biz'=>'baz'}]
103
+ ]
104
+
105
+ payloads.each do |args|
106
+ Chasqui.publish 'test.event', *args
107
+ end
108
+
109
+ payloads.each do |data|
110
+ event = JSON.load Chasqui.redis.rpop('inbox')
111
+ expect(event['event']).to eq('test.event')
112
+ expect(event['channel']).to eq('__default')
113
+ expect(event['data']).to eq(data)
114
+ end
115
+ end
116
+
117
+ it 'supports channels' do
118
+ Chasqui.config.channel = 'my.app'
119
+ Chasqui.publish 'test.event', :foo
120
+ event = JSON.load Chasqui.redis.rpop('inbox')
121
+ expect(event['event']).to eq('test.event')
122
+ expect(event['channel']).to eq('my.app')
123
+ expect(event['data']).to eq(['foo'])
124
+ end
125
+ end
126
+
127
+ describe '.subscribe' do
128
+ before { reset_chasqui }
129
+
130
+ it 'saves subscriptions' do
131
+ sub1 = Chasqui.subscribe queue: 'app1-queue', channel: 'com.example.admin'
132
+ sub2 = Chasqui.subscribe queue: 'app2-queue', channel: 'com.example.admin'
133
+ sub3 = Chasqui.subscribe queue: 'app1-queue', channel: 'com.example.video'
134
+
135
+ queues = Chasqui.redis.smembers "subscribers:com.example.admin"
136
+ expect(queues.sort).to eq(['app1-queue', 'app2-queue'])
137
+
138
+ queues = Chasqui.redis.smembers "subscribers:com.example.video"
139
+ expect(queues).to eq(['app1-queue'])
140
+
141
+ expect(Chasqui.subscriber('app1-queue')).to eq(sub1)
142
+ expect(Chasqui.subscriber('app2-queue')).to eq(sub2)
143
+ expect(sub1).to eq(sub3)
144
+ end
145
+
146
+ it 'returns a subscriber' do
147
+ subscriber = Chasqui.subscribe queue: 'app1-queue', channel: 'com.example.admin'
148
+ expect(subscriber).to be_kind_of(Chasqui::Subscriber)
149
+ end
150
+
151
+ it 'yields a subscriber configuration context' do
152
+ $context = nil
153
+ Chasqui.subscribe queue: 'foo', channel: 'bar' do
154
+ $context = self
155
+ end
156
+ expect($context).to be_kind_of(Chasqui::Subscriber)
157
+ end
158
+ end
159
+
160
+ describe '.create_worker' do
161
+ let(:subscriber) { j }
162
+
163
+ it 'raises when no worker backend configured' do
164
+ expect(-> {
165
+ Chasqui.create_worker nil
166
+ }).to raise_error(Chasqui::ConfigurationError)
167
+ end
168
+
169
+ it 'creates a resque worker' do
170
+ subscriber = FakeSubscriber.new 'resque-queue', 'fake-channel'
171
+ Chasqui.config.worker_backend = :resque
172
+ worker = Chasqui.create_worker subscriber
173
+ expect(worker.new).to be_kind_of(Chasqui::ResqueWorker)
174
+ end
175
+
176
+ if sidekiq_supported_ruby_version?
177
+ it 'creates a sidekiq worker' do
178
+ subscriber = FakeSubscriber.new 'sidekiq-queue', 'fake-channel'
179
+ Chasqui.config.worker_backend = :sidekiq
180
+ worker = Chasqui.create_worker subscriber
181
+ expect(worker.new).to be_kind_of(Chasqui::SidekiqWorker)
182
+ end
183
+ end
184
+ end
185
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,23 +1,10 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
  require 'chasqui'
3
+ require 'resque'
4
+ require 'pp'
3
5
 
4
- class FakeRedis
5
- def initialize
6
- @queues = {}
7
- end
6
+ Dir['spec/support/*.rb'].each { |file| require File.expand_path(file) }
8
7
 
9
- def rpush(key, value)
10
- queue(key) << value
11
- end
12
-
13
- def lpop(key)
14
- queue(key).shift
15
- end
16
-
17
- private
18
-
19
- def queue(key)
20
- @queues[key] ||= []
21
- @queues[key]
22
- end
8
+ RSpec.configure do |c|
9
+ c.include ChasquiSpecHelpers
23
10
  end
@@ -0,0 +1,21 @@
1
+ module ChasquiSpecHelpers
2
+
3
+ def reset_chasqui
4
+ reset_config
5
+ flush_redis
6
+ end
7
+
8
+ def reset_config
9
+ Chasqui.instance_variable_set(:@config, nil)
10
+ Chasqui.config.logger = open('/dev/null', 'w+')
11
+ end
12
+
13
+ def redis
14
+ Chasqui.redis
15
+ end
16
+
17
+ def flush_redis
18
+ redis.keys('*').each { |k| redis.del k }
19
+ end
20
+
21
+ end
@@ -0,0 +1,5 @@
1
+ class FakeLogger
2
+ attr_accessor :progname
3
+ def info(*args, &block)
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ class FakeSubscriber < Chasqui::Subscriber
2
+ attr_reader :events
3
+
4
+ def initialize(queue, channel)
5
+ super
6
+ @events ||= []
7
+ end
8
+
9
+ def perform(redis, event)
10
+ @events << event
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ # Newer versions of sidekiq only support newer versions of ruby
2
+ # https://github.com/mperham/sidekiq/blob/master/Changes.md#322
3
+ def sidekiq_supported_ruby_version?
4
+ Gem::Version.new(RUBY_VERSION.dup) > Gem::Version.new('1.9.3')
5
+ end
6
+
7
+ if sidekiq_supported_ruby_version?
8
+ require 'sidekiq'
9
+ end
data/tmp/.keep ADDED
File without changes