fairway 0.0.1
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.
- data/.rbenv-gemsets +1 -0
- data/.rspec +1 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +50 -0
- data/README.markdown +123 -0
- data/Rakefile +1 -0
- data/boot.rb +7 -0
- data/fairway.gemspec +24 -0
- data/lib/fairway/channeled_connection.rb +17 -0
- data/lib/fairway/config.rb +57 -0
- data/lib/fairway/connection.rb +28 -0
- data/lib/fairway/queue_reader.rb +12 -0
- data/lib/fairway/scripts.rb +43 -0
- data/lib/fairway/sidekiq/composite_fetch.rb +37 -0
- data/lib/fairway/sidekiq/fetcher.rb +37 -0
- data/lib/fairway/sidekiq/fetcher_factory.rb +23 -0
- data/lib/fairway/sidekiq/non_blocking_fetch.rb +64 -0
- data/lib/fairway/sidekiq/queue_fetch.rb +33 -0
- data/lib/fairway/sidekiq.rb +20 -0
- data/lib/fairway/version.rb +3 -0
- data/lib/fairway.rb +22 -0
- data/redis/fairway_deliver.lua +25 -0
- data/redis/fairway_pull.lua +21 -0
- data/redis/fairway_register_queue.lua +5 -0
- data/spec/lib/fairway/channeled_connection_spec.rb +75 -0
- data/spec/lib/fairway/config_spec.rb +55 -0
- data/spec/lib/fairway/connection_spec.rb +79 -0
- data/spec/lib/fairway/queue_reader_spec.rb +101 -0
- data/spec/lib/fairway/scripts_spec.rb +28 -0
- data/spec/lib/fairway/sidekiq/composite_fetch_spec.rb +50 -0
- data/spec/lib/fairway/sidekiq/fetcher_spec.rb +31 -0
- data/spec/lib/fairway/sidekiq/non_blocking_fetch_spec.rb +31 -0
- data/spec/lib/fairway/sidekiq/queue_fetch_spec.rb +35 -0
- data/spec/lib/fairway/subscription_spec.rb +16 -0
- data/spec/spec_helper.rb +35 -0
- metadata +155 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fairway
|
4
|
+
describe ChanneledConnection do
|
5
|
+
let(:config) do
|
6
|
+
Config.new do |c|
|
7
|
+
c.facet { |message| message[:facet] }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
let(:connection) do
|
11
|
+
ChanneledConnection.new(Connection.new(config)) do |message|
|
12
|
+
message[:topic]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
let(:redis) { config.redis }
|
16
|
+
let(:message) { { facet: 1, topic: "event:helloworld" } }
|
17
|
+
|
18
|
+
describe "#deliver" do
|
19
|
+
context "multiple queues exist for message type" do
|
20
|
+
it "adds message for both queues" do
|
21
|
+
config.register_queue("myqueue", ".*:helloworld")
|
22
|
+
config.register_queue("yourqueue", "event:.*world")
|
23
|
+
connection.deliver(message)
|
24
|
+
redis.llen("myqueue:1").should == 1
|
25
|
+
redis.llen("yourqueue:1").should == 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "registered queue exists for message type" do
|
30
|
+
before do
|
31
|
+
config.register_queue("myqueue", "event:helloworld")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "adds message to the environment facet for the queue" do
|
35
|
+
connection.deliver(message)
|
36
|
+
redis.llen("myqueue:1").should == 1
|
37
|
+
redis.lindex("myqueue:1", 0).should == message.to_json
|
38
|
+
end
|
39
|
+
|
40
|
+
it "adds facet to list of active facets" do
|
41
|
+
connection.deliver(message)
|
42
|
+
redis.smembers("myqueue:active_facets").should == ["1"]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "pushes facet onto facet queue" do
|
46
|
+
connection.deliver(message)
|
47
|
+
redis.llen("myqueue:facet_queue").should == 1
|
48
|
+
redis.lindex("myqueue:facet_queue", 0).should == "1"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "doesn't push onto to facet queue if currently active" do
|
52
|
+
redis.sadd("myqueue:active_facets", "1")
|
53
|
+
connection.deliver(message)
|
54
|
+
redis.llen("myqueue:facet_queue").should == 0
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "registered queue exists for another message type" do
|
59
|
+
before do
|
60
|
+
config.register_queue("myqueue", "foo")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "doesn't add message to the queue" do
|
64
|
+
connection.deliver(message)
|
65
|
+
redis.llen("myqueue:1").should == 0
|
66
|
+
end
|
67
|
+
|
68
|
+
it "doesn't add facet to list of active facets" do
|
69
|
+
connection.deliver(message)
|
70
|
+
redis.smembers("myqueue:active_facets").should == []
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fairway
|
4
|
+
describe Config do
|
5
|
+
describe "#initialize" do
|
6
|
+
it "yields itself to a block" do
|
7
|
+
config = Config.new do |c|
|
8
|
+
c.namespace = "x"
|
9
|
+
end
|
10
|
+
config.namespace.should == "x"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#facet" do
|
15
|
+
context "when called with a block" do
|
16
|
+
it "sets the facet" do
|
17
|
+
config = Config.new
|
18
|
+
config.facet do |message|
|
19
|
+
"foo"
|
20
|
+
end
|
21
|
+
config.facet.call({}).should == "foo"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "allows setting of redis connection options" do
|
27
|
+
Config.new do |config|
|
28
|
+
config.redis = { host: "127.0.0.1", port: 6379 }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "allows setting of redis namespace" do
|
33
|
+
config = Config.new do |config|
|
34
|
+
config.namespace = "ns"
|
35
|
+
end
|
36
|
+
|
37
|
+
config.namespace.should == "ns"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "sets the default facet" do
|
41
|
+
config = Config.new
|
42
|
+
config.facet.call(environment_id: 5, facet: 1).should == Config::DEFAULT_FACET
|
43
|
+
end
|
44
|
+
|
45
|
+
it "allows custom faceting" do
|
46
|
+
config = Config.new do |config|
|
47
|
+
config.facet do |message|
|
48
|
+
message[:environment_id]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
config.facet.call(environment_id: 5, facet: 1).should == 5
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fairway
|
4
|
+
describe Connection do
|
5
|
+
let(:config) do
|
6
|
+
Config.new do |c|
|
7
|
+
c.facet { |message| message[:facet] }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:connection) { Connection.new(config) }
|
12
|
+
let(:redis) { config.redis }
|
13
|
+
let(:message) { { facet: 1, topic: "event:helloworld" } }
|
14
|
+
|
15
|
+
describe "#initialize" do
|
16
|
+
it "registers queues from the config" do
|
17
|
+
config = Config.new
|
18
|
+
config.register_queue("myqueue", ".*")
|
19
|
+
config.redis.hgetall("registered_queues").should == {}
|
20
|
+
Connection.new(config)
|
21
|
+
|
22
|
+
config.redis.hgetall("registered_queues").should == {
|
23
|
+
"myqueue" => ".*"
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when an existing queue definition does not match" do
|
28
|
+
it "raises a QueueMismatchError"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#deliver" do
|
33
|
+
it "publishes message over the message topic channel" do
|
34
|
+
redis = Redis.new
|
35
|
+
|
36
|
+
redis.psubscribe("*") do |on|
|
37
|
+
on.psubscribe do |pattern, total|
|
38
|
+
connection.deliver(message)
|
39
|
+
end
|
40
|
+
|
41
|
+
on.pmessage do |pattern, channel, received_message|
|
42
|
+
received_message.should == message.to_json
|
43
|
+
channel.should == "default"
|
44
|
+
redis.punsubscribe(pattern)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "registered queue exists for message type" do
|
50
|
+
before do
|
51
|
+
config.register_queue("myqueue")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "adds message to the environment facet for the queue" do
|
55
|
+
connection.deliver(message)
|
56
|
+
redis.llen("myqueue:1").should == 1
|
57
|
+
redis.lindex("myqueue:1", 0).should == message.to_json
|
58
|
+
end
|
59
|
+
|
60
|
+
it "adds facet to list of active facets" do
|
61
|
+
connection.deliver(message)
|
62
|
+
redis.smembers("myqueue:active_facets").should == ["1"]
|
63
|
+
end
|
64
|
+
|
65
|
+
it "pushes facet onto facet queue" do
|
66
|
+
connection.deliver(message)
|
67
|
+
redis.llen("myqueue:facet_queue").should == 1
|
68
|
+
redis.lindex("myqueue:facet_queue", 0).should == "1"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "doesn't push onto to facet queue if currently active" do
|
72
|
+
redis.sadd("myqueue:active_facets", "1")
|
73
|
+
connection.deliver(message)
|
74
|
+
redis.llen("myqueue:facet_queue").should == 0
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fairway
|
4
|
+
describe QueueReader do
|
5
|
+
let(:config) do
|
6
|
+
Config.new do |c|
|
7
|
+
c.facet { |message| message[:facet] }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
let(:connection) do
|
11
|
+
c = Connection.new(config)
|
12
|
+
ChanneledConnection.new(c) do |message|
|
13
|
+
message[:topic]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
let(:message) { { facet: 1, topic: "event:helloworld" } }
|
17
|
+
|
18
|
+
describe "#initialize" do
|
19
|
+
it "requires a Connection and queue names" do
|
20
|
+
lambda { QueueReader.new }.should raise_error(ArgumentError)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#pull" do
|
25
|
+
before do
|
26
|
+
config.register_queue("myqueue", "event:helloworld")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "pulls a message off the queue using FIFO strategy" do
|
30
|
+
connection.deliver(message1 = message.merge(message: 1))
|
31
|
+
connection.deliver(message2 = message.merge(message: 2))
|
32
|
+
|
33
|
+
reader = QueueReader.new(connection, "myqueue")
|
34
|
+
reader.pull.should == ["myqueue", message1.to_json]
|
35
|
+
reader.pull.should == ["myqueue", message2.to_json]
|
36
|
+
end
|
37
|
+
|
38
|
+
it "pulls from facets of the queue in a round-robin nature" do
|
39
|
+
connection.deliver(message1 = message.merge(facet: 1, message: 1))
|
40
|
+
connection.deliver(message2 = message.merge(facet: 1, message: 2))
|
41
|
+
connection.deliver(message3 = message.merge(facet: 2, message: 3))
|
42
|
+
|
43
|
+
reader = QueueReader.new(connection, "myqueue")
|
44
|
+
reader.pull.should == ["myqueue", message1.to_json]
|
45
|
+
reader.pull.should == ["myqueue", message3.to_json]
|
46
|
+
reader.pull.should == ["myqueue", message2.to_json]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "removes facet from active list if it becomes empty" do
|
50
|
+
connection.deliver(message)
|
51
|
+
|
52
|
+
config.redis.smembers("myqueue:active_facets").should == ["1"]
|
53
|
+
reader = QueueReader.new(connection, "myqueue")
|
54
|
+
reader.pull
|
55
|
+
config.redis.smembers("myqueue:active_facets").should be_empty
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns nil if there are no messages to retrieve" do
|
59
|
+
connection.deliver(message)
|
60
|
+
|
61
|
+
reader = QueueReader.new(connection, "myqueue")
|
62
|
+
reader.pull.should == ["myqueue", message.to_json]
|
63
|
+
reader.pull.should be_nil
|
64
|
+
end
|
65
|
+
|
66
|
+
context "pulling from multiple queues" do
|
67
|
+
before do
|
68
|
+
config.register_queue("myqueue1", "event:1")
|
69
|
+
config.register_queue("myqueue2", "event:2")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "pulls messages off first queue with a message" do
|
73
|
+
connection.deliver(message1 = message.merge(topic: "event:1"))
|
74
|
+
connection.deliver(message2 = message.merge(topic: "event:2"))
|
75
|
+
|
76
|
+
reader = QueueReader.new(connection, "myqueue2", "myqueue1")
|
77
|
+
reader.pull.should == ["myqueue2", message2.to_json]
|
78
|
+
reader.pull.should == ["myqueue1", message1.to_json]
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns nil if no queues have messages" do
|
82
|
+
reader = QueueReader.new(connection, "myqueue2", "myqueue1")
|
83
|
+
reader.pull.should be_nil
|
84
|
+
end
|
85
|
+
|
86
|
+
it "pulls from facets of the queue in a round-robin nature" do
|
87
|
+
connection.deliver(message1 = message.merge(facet: 1, topic: "event:1"))
|
88
|
+
connection.deliver(message2 = message.merge(facet: 1, topic: "event:1"))
|
89
|
+
connection.deliver(message3 = message.merge(facet: 2, topic: "event:1"))
|
90
|
+
connection.deliver(message4 = message.merge(facet: 1, topic: "event:2"))
|
91
|
+
|
92
|
+
reader = QueueReader.new(connection, "myqueue2", "myqueue1")
|
93
|
+
reader.pull.should == ["myqueue2", message4.to_json]
|
94
|
+
reader.pull.should == ["myqueue1", message1.to_json]
|
95
|
+
reader.pull.should == ["myqueue1", message3.to_json]
|
96
|
+
reader.pull.should == ["myqueue1", message2.to_json]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fairway
|
4
|
+
describe Scripts do
|
5
|
+
describe "#initialize" do
|
6
|
+
it "requires a redis client" do
|
7
|
+
lambda {
|
8
|
+
Scripts.new
|
9
|
+
}.should raise_error(ArgumentError)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#method_missing" do
|
14
|
+
let(:scripts) { Scripts.new(Redis.new, "foo") }
|
15
|
+
|
16
|
+
it "runs the script" do
|
17
|
+
scripts.fairway_register_queue("namespace", "name", "topic")
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when the script does not exist" do
|
21
|
+
it "loads the script" do
|
22
|
+
Redis.new.script(:flush)
|
23
|
+
scripts.fairway_register_queue("namespace", "name", "topic")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fairway::Sidekiq
|
4
|
+
describe CompositeFetch do
|
5
|
+
describe "#initialize" do
|
6
|
+
it "accepts a hash of fetches with priority" do
|
7
|
+
fetcher = CompositeFetch.new(fetcherA: 10, fetcherB: 1)
|
8
|
+
fetcher.fetches.should == [Array.new(10, :fetcherA), :fetcherB].flatten
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#fetch_order" do
|
13
|
+
let(:fetcher) { CompositeFetch.new(fetcherA: 10, fetcherB: 1) }
|
14
|
+
|
15
|
+
it "should shuffle and uniq fetches" do
|
16
|
+
fetcher.fetches.should_receive(:shuffle).and_return(fetcher.fetches)
|
17
|
+
fetcher.fetch_order
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should unique fetches list" do
|
21
|
+
fetcher.fetches.length.should == 11
|
22
|
+
fetcher.fetch_order.length.should == 2
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#retrieve_work" do
|
27
|
+
let(:work) { mock(:work) }
|
28
|
+
let(:fetcherA) { mock(:fetcher) }
|
29
|
+
let(:fetcherB) { mock(:fetcher) }
|
30
|
+
let(:fetcher) { CompositeFetch.new(fetcherA => 10, fetcherB => 1) }
|
31
|
+
|
32
|
+
before do
|
33
|
+
fetcher.stub(fetch_order: [fetcherA, fetcherB])
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns work from the first fetcher who has work" do
|
37
|
+
fetcherA.stub(retrieve_work: work)
|
38
|
+
fetcherB.should_not_receive(:retrieve_work)
|
39
|
+
|
40
|
+
fetcher.retrieve_work.should == work
|
41
|
+
end
|
42
|
+
|
43
|
+
it "attempts to retrieve work from each fetcher if no work is found" do
|
44
|
+
fetcherA.should_receive(:retrieve_work)
|
45
|
+
fetcherB.should_receive(:retrieve_work)
|
46
|
+
fetcher.retrieve_work.should be_nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fairway::Sidekiq
|
4
|
+
describe Fetcher do
|
5
|
+
let(:manager) { mock(:manager) }
|
6
|
+
let(:fetch) { mock(:fetch) }
|
7
|
+
|
8
|
+
it "accepts a manager and a fetch strategy" do
|
9
|
+
fetcher = Fetcher.new(manager, fetch)
|
10
|
+
fetcher.mgr.should == manager
|
11
|
+
fetcher.strategy.should == fetch
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#fetch" do
|
15
|
+
let(:fetcher) { Fetcher.new(manager, fetch) }
|
16
|
+
|
17
|
+
it "retrieves work from fetch strategy" do
|
18
|
+
fetch.should_receive(:retrieve_work)
|
19
|
+
fetcher.fetch
|
20
|
+
end
|
21
|
+
|
22
|
+
it "tells manager to assign work if work is fetched" do
|
23
|
+
work = mock(:work)
|
24
|
+
fetch.stub(retrieve_work: work)
|
25
|
+
manager.stub(async: manager)
|
26
|
+
manager.should_receive(:assign).with(work)
|
27
|
+
fetcher.fetch
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fairway::Sidekiq
|
4
|
+
describe NonBlockingFetch do
|
5
|
+
let(:queues) { [:critical, :critical, :default] }
|
6
|
+
let(:fetch) { NonBlockingFetch.new(queues: queues) }
|
7
|
+
|
8
|
+
it "accepts options with a list of queues and their weights" do
|
9
|
+
fetch.queues.should == ["queue:critical", "queue:critical", "queue:default"]
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#retrieve_work" do
|
13
|
+
it "calls rpop script with queue order" do
|
14
|
+
fetch.stub(queues_cmd: ["queue:default", "queue:critical"])
|
15
|
+
|
16
|
+
::Sidekiq.redis do |conn|
|
17
|
+
conn.lpush("queue:default", "default")
|
18
|
+
conn.lpush("queue:critical", "critical")
|
19
|
+
end
|
20
|
+
|
21
|
+
unit_of_work = fetch.retrieve_work
|
22
|
+
unit_of_work.queue_name.should == "default"
|
23
|
+
unit_of_work.message.should == "default"
|
24
|
+
|
25
|
+
unit_of_work = fetch.retrieve_work
|
26
|
+
unit_of_work.queue_name.should == "critical"
|
27
|
+
unit_of_work.message.should == "critical"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Fairway
|
4
|
+
module Sidekiq
|
5
|
+
describe QueueFetch do
|
6
|
+
let(:reader) { QueueReader.new(Connection.new, "fairway") }
|
7
|
+
let(:work) { { queue: "golf_events", type: "swing", name: "putt" }.to_json }
|
8
|
+
|
9
|
+
it "requests work from the queue reader" do
|
10
|
+
fetch = QueueFetch.new(reader)
|
11
|
+
|
12
|
+
reader.stub(pull: ["fairway", work])
|
13
|
+
|
14
|
+
unit_of_work = fetch.retrieve_work
|
15
|
+
unit_of_work.queue_name.should == "golf_events"
|
16
|
+
unit_of_work.message.should == work
|
17
|
+
end
|
18
|
+
|
19
|
+
it "allows transforming of the message into a job" do
|
20
|
+
fetch = QueueFetch.new(reader) do |fairway_queue, message|
|
21
|
+
message.tap do |message|
|
22
|
+
message["queue"] = "my_#{message["queue"]}"
|
23
|
+
message["class"] = "GolfEventJob"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
reader.stub(pull: ["fairway", work])
|
28
|
+
|
29
|
+
unit_of_work = fetch.retrieve_work
|
30
|
+
unit_of_work.queue_name.should == "my_golf_events"
|
31
|
+
unit_of_work.message.should == JSON.parse(work).merge("queue" => "my_golf_events", "class" => "GolfEventJob").to_json
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
# module Fairway
|
4
|
+
# describe Subscription do
|
5
|
+
# describe "#initialize" do
|
6
|
+
# it "requires a Connection"
|
7
|
+
# it "requires a pattern"
|
8
|
+
# it "requires a block"
|
9
|
+
# it "subscribes to the pattern"
|
10
|
+
# end
|
11
|
+
|
12
|
+
# context "when a message is published" do
|
13
|
+
# it "calls the block"
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
# end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require_relative "../boot"
|
7
|
+
require "rspec/autorun"
|
8
|
+
|
9
|
+
Bundler.require(:default, :test)
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
13
|
+
end
|
14
|
+
|
15
|
+
require "sidekiq"
|
16
|
+
require "sidekiq/manager"
|
17
|
+
require "fairway/sidekiq"
|
18
|
+
|
19
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
20
|
+
# in spec/support/ and its subdirectories.
|
21
|
+
Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each {|f| require f}
|
22
|
+
|
23
|
+
RSpec.configure do |config|
|
24
|
+
config.before(:each) do
|
25
|
+
Fairway.configure do |config|
|
26
|
+
config.namespace = "test:backbone"
|
27
|
+
end
|
28
|
+
|
29
|
+
Fairway::Config.new.redis.flushdb
|
30
|
+
end
|
31
|
+
|
32
|
+
config.after(:each) do
|
33
|
+
Fairway::Config.new.redis.flushdb
|
34
|
+
end
|
35
|
+
end
|