fairway 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|