sidekiq-bus 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe Heartbeat do
5
+ def now_attributes
6
+ {
7
+ "epoch_seconds" => (Time.now.to_i / 60) * 60, # rounded
8
+ "epoch_minutes" => Time.now.to_i / 60,
9
+ "epoch_hours" => Time.now.to_i / (60*60),
10
+ "epoch_days" => Time.now.to_i / (60*60*24),
11
+ "minute" => Time.now.min,
12
+ "hour" => Time.now.hour,
13
+ "day" => Time.now.day,
14
+ "month" => Time.now.month,
15
+ "year" => Time.now.year,
16
+ "yday" => Time.now.yday,
17
+ "wday" => Time.now.wday
18
+ }
19
+ end
20
+
21
+ it "should publish the current time once" do
22
+ Timecop.freeze "12/12/2013 12:01:19" do
23
+ QueueBus.should_receive(:publish).with("heartbeat_minutes", now_attributes)
24
+ Heartbeat.perform
25
+ end
26
+
27
+ Timecop.freeze "12/12/2013 12:01:40" do
28
+ Heartbeat.perform
29
+ end
30
+ end
31
+
32
+ it "should publish a minute later" do
33
+ Timecop.freeze "12/12/2013 12:01:19" do
34
+ QueueBus.should_receive(:publish).with("heartbeat_minutes", now_attributes)
35
+ Heartbeat.perform
36
+ end
37
+
38
+ Timecop.freeze "12/12/2013 12:02:01" do
39
+ QueueBus.should_receive(:publish).with("heartbeat_minutes", now_attributes)
40
+ Heartbeat.perform
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe "Integration" do
5
+ it "should round trip attributes" do
6
+ write1 = Subscription.new("default", "key1", "MyClass1", {"bus_event_type" => "event_one"})
7
+ write2 = Subscription.new("else_ok", "key2", "MyClass2", {"bus_event_type" => /^[ab]here/}) #regex
8
+
9
+ write1.matches?("bus_event_type" => "event_one").should == true
10
+ write1.matches?("bus_event_type" => "event_one1").should == false
11
+ write1.matches?("bus_event_type" => "aevent_one").should == false
12
+
13
+ write2.matches?("bus_event_type" => "ahere").should == true
14
+ write2.matches?("bus_event_type" => "bhere").should == true
15
+ write2.matches?("bus_event_type" => "qhere").should == false
16
+ write2.matches?("bus_event_type" => "abhere").should == false
17
+ write2.matches?("bus_event_type" => "[ab]here").should == false
18
+
19
+ write = SubscriptionList.new
20
+ write.add(write1)
21
+ write.add(write2)
22
+
23
+ app = Application.new("test")
24
+ app.subscribe(write)
25
+
26
+ reset_test_adapter # reset to make sure we read from redis
27
+ app = Application.new("test")
28
+ read = app.send(:subscriptions)
29
+
30
+ read.size.should == 2
31
+ read1 = read.key("key1")
32
+ read2 = read.key("key2")
33
+ read1.should_not be_nil
34
+ read2.should_not be_nil
35
+
36
+ read1.queue_name.should == "default"
37
+ read1.class_name.should == "MyClass1"
38
+ read2.queue_name.should == "else_ok"
39
+ read2.class_name.should == "MyClass2"
40
+
41
+ read1.matches?("bus_event_type" => "event_one").should == true
42
+ read1.matches?("bus_event_type" => "event_one1").should == false
43
+ read1.matches?("bus_event_type" => "aevent_one").should == false
44
+
45
+ read2.matches?("bus_event_type" => "ahere").should == true
46
+ read2.matches?("bus_event_type" => "bhere").should == true
47
+ read2.matches?("bus_event_type" => "qhere").should == false
48
+ read2.matches?("bus_event_type" => "abhere").should == false
49
+ read2.matches?("bus_event_type" => "[ab]here").should == false
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe Matcher do
5
+ it "should already return false on empty filters" do
6
+ matcher = Matcher.new({})
7
+ matcher.matches?({}).should == false
8
+ matcher.matches?(nil).should == false
9
+ matcher.matches?("name" => "val").should == false
10
+ end
11
+
12
+ it "should not crash if nil inputs" do
13
+ matcher = Matcher.new("name" => "val")
14
+ matcher.matches?(nil).should == false
15
+ end
16
+
17
+ it "string filter to/from redis" do
18
+ matcher = Matcher.new("name" => "val")
19
+ matcher.matches?("name" => "val").should == true
20
+ matcher.matches?("name" => " val").should == false
21
+ matcher.matches?("name" => "zval").should == false
22
+ end
23
+
24
+ it "regex filter" do
25
+ matcher = Matcher.new("name" => /^[cb]a+t/)
26
+ matcher.matches?("name" => "cat").should == true
27
+ matcher.matches?("name" => "bat").should == true
28
+ matcher.matches?("name" => "caaaaat").should == true
29
+ matcher.matches?("name" => "ct").should == false
30
+ matcher.matches?("name" => "bcat").should == false
31
+ end
32
+
33
+ it "present filter" do
34
+ matcher = Matcher.new("name" => :present)
35
+ matcher.matches?("name" => "").should == false
36
+ matcher.matches?("name" => "cat").should == true
37
+ matcher.matches?("name" => "bear").should == true
38
+ matcher.matches?("other" => "bear").should == false
39
+ end
40
+
41
+ it "blank filter" do
42
+ matcher = Matcher.new("name" => :blank)
43
+ matcher.matches?("name" => nil).should == true
44
+ matcher.matches?("other" => "bear").should == true
45
+ matcher.matches?("name" => "").should == true
46
+ matcher.matches?("name" => " ").should == true
47
+ matcher.matches?("name" => "bear").should == false
48
+ matcher.matches?("name" => " s ").should == false
49
+ end
50
+
51
+ it "nil filter" do
52
+ matcher = Matcher.new("name" => :nil)
53
+ matcher.matches?("name" => nil).should == true
54
+ matcher.matches?("other" => "bear").should == true
55
+ matcher.matches?("name" => "").should == false
56
+ matcher.matches?("name" => " ").should == false
57
+ matcher.matches?("name" => "bear").should == false
58
+ end
59
+
60
+ it "key filter" do
61
+ matcher = Matcher.new("name" => :key)
62
+ matcher.matches?("name" => nil).should == true
63
+ matcher.matches?("other" => "bear").should == false
64
+ matcher.matches?("name" => "").should == true
65
+ matcher.matches?("name" => " ").should == true
66
+ matcher.matches?("name" => "bear").should == true
67
+ end
68
+
69
+ it "empty filter" do
70
+ matcher = Matcher.new("name" => :empty)
71
+ matcher.matches?("name" => nil).should == false
72
+ matcher.matches?("other" => "bear").should == false
73
+ matcher.matches?("name" => "").should == true
74
+ matcher.matches?("name" => " ").should == false
75
+ matcher.matches?("name" => "bear").should == false
76
+ matcher.matches?("name" => " s ").should == false
77
+ end
78
+
79
+ it "value filter" do
80
+ matcher = Matcher.new("name" => :value)
81
+ matcher.matches?("name" => nil).should == false
82
+ matcher.matches?("other" => "bear").should == false
83
+ matcher.matches?("name" => "").should == true
84
+ matcher.matches?("name" => " ").should == true
85
+ matcher.matches?("name" => "bear").should == true
86
+ matcher.matches?("name" => " s ").should == true
87
+ end
88
+
89
+ it "multiple filters" do
90
+ matcher = Matcher.new("name" => /^[cb]a+t/, "state" => "sleeping")
91
+ matcher.matches?("state" => "sleeping", "name" => "cat").should == true
92
+ matcher.matches?("state" => "awake", "name" => "cat").should == false
93
+ matcher.matches?("state" => "sleeping", "name" => "bat").should == true
94
+ matcher.matches?("state" => "sleeping", "name" => "bear").should == false
95
+ matcher.matches?("state" => "awake", "name" => "bear").should == false
96
+ end
97
+
98
+ it "regex should go back and forth into redis" do
99
+ matcher = Matcher.new("name" => /^[cb]a+t/)
100
+ matcher.matches?("name" => "cat").should == true
101
+ matcher.matches?("name" => "bat").should == true
102
+ matcher.matches?("name" => "caaaaat").should == true
103
+ matcher.matches?("name" => "ct").should == false
104
+ matcher.matches?("name" => "bcat").should == false
105
+
106
+ QueueBus.redis { |redis| redis.set("temp1", QueueBus::Util.encode(matcher.to_redis) ) }
107
+ redis = QueueBus.redis { |redis| redis.get("temp1") }
108
+ matcher = Matcher.new(QueueBus::Util.decode(redis))
109
+ matcher.matches?("name" => "cat").should == true
110
+ matcher.matches?("name" => "bat").should == true
111
+ matcher.matches?("name" => "caaaaat").should == true
112
+ matcher.matches?("name" => "ct").should == false
113
+ matcher.matches?("name" => "bcat").should == false
114
+
115
+ QueueBus.redis { |redis| redis.set("temp2", QueueBus::Util.encode(matcher.to_redis) ) }
116
+ redis = QueueBus.redis { |redis| redis.get("temp2") }
117
+ matcher = Matcher.new(QueueBus::Util.decode(redis))
118
+ matcher.matches?("name" => "cat").should == true
119
+ matcher.matches?("name" => "bat").should == true
120
+ matcher.matches?("name" => "caaaaat").should == true
121
+ matcher.matches?("name" => "ct").should == false
122
+ matcher.matches?("name" => "bcat").should == false
123
+ end
124
+
125
+ it "special value should go back and forth into redis" do
126
+ matcher = Matcher.new("name" => :blank)
127
+ matcher.matches?("name" => "cat").should == false
128
+ matcher.matches?("name" => "").should == true
129
+
130
+ QueueBus.redis { |redis| redis.set("temp1", QueueBus::Util.encode(matcher.to_redis) ) }
131
+ redis= QueueBus.redis { |redis| redis.get("temp1") }
132
+ matcher = Matcher.new(QueueBus::Util.decode(redis))
133
+ matcher.matches?("name" => "cat").should == false
134
+ matcher.matches?("name" => "").should == true
135
+
136
+ QueueBus.redis { |redis| redis.set("temp2", QueueBus::Util.encode(matcher.to_redis) ) }
137
+ redis= QueueBus.redis { |redis| redis.get("temp2") }
138
+ matcher = Matcher.new(QueueBus::Util.decode(redis))
139
+ matcher.matches?("name" => "cat").should == false
140
+ matcher.matches?("name" => "").should == true
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Publishing an event" do
4
+
5
+ before(:each) do
6
+ Timecop.freeze
7
+ QueueBus.stub(:generate_uuid).and_return("idfhlkj")
8
+ end
9
+ after(:each) do
10
+ Timecop.return
11
+ end
12
+ let(:bus_attrs) { {"bus_class_proxy"=>"QueueBus::Driver",
13
+ "bus_published_at" => Time.now.to_i,
14
+ "bus_id"=>"#{Time.now.to_i}-idfhlkj",
15
+ "bus_app_hostname" => `hostname 2>&1`.strip.sub(/.local/,'')} }
16
+
17
+ it "should add it to Redis" do
18
+ hash = {:one => 1, "two" => "here", "id" => 12 }
19
+ event_name = "event_name"
20
+
21
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
22
+ val.should == nil
23
+
24
+ QueueBus.publish(event_name, hash)
25
+
26
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
27
+ hash = JSON.parse(val)
28
+ hash["class"].should == "QueueBus::Worker"
29
+ hash["args"].size.should == 1
30
+ JSON.parse(hash["args"].first).should == {"bus_event_type" => event_name, "two"=>"here", "one"=>1, "id" => 12}.merge(bus_attrs)
31
+
32
+ end
33
+
34
+ it "should use the id if given" do
35
+ hash = {:one => 1, "two" => "here", "bus_id" => "app-given" }
36
+ event_name = "event_name"
37
+
38
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
39
+ val.should == nil
40
+
41
+ QueueBus.publish(event_name, hash)
42
+
43
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
44
+ hash = JSON.parse(val)
45
+ hash["class"].should == "QueueBus::Worker"
46
+ hash["args"].size.should == 1
47
+ JSON.parse(hash["args"].first).should == {"bus_event_type" => event_name, "two"=>"here", "one"=>1}.merge(bus_attrs).merge("bus_id" => 'app-given')
48
+ end
49
+
50
+ it "should add metadata via callback" do
51
+ myval = 0
52
+ QueueBus.before_publish = lambda { |att|
53
+ att["mine"] = 4
54
+ myval += 1
55
+ }
56
+
57
+ hash = {:one => 1, "two" => "here", "bus_id" => "app-given" }
58
+ event_name = "event_name"
59
+
60
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
61
+ val.should == nil
62
+
63
+ QueueBus.publish(event_name, hash)
64
+
65
+
66
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
67
+ hash = JSON.parse(val)
68
+ att = JSON.parse(hash["args"].first)
69
+ att["mine"].should == 4
70
+ myval.should == 1
71
+ end
72
+
73
+ it "should set the timezone and locale if available" do
74
+ defined?(I18n).should be_nil
75
+ Time.respond_to?(:zone).should eq(false)
76
+
77
+ stub_const("I18n", Class.new)
78
+ I18n.stub(:locale).and_return("jp")
79
+
80
+ Time.stub(:zone).and_return(double('zone', :name => "EST"))
81
+
82
+ hash = {:one => 1, "two" => "here", "bus_id" => "app-given" }
83
+ event_name = "event_name"
84
+
85
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
86
+ val.should == nil
87
+
88
+ QueueBus.publish(event_name, hash)
89
+
90
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
91
+ hash = JSON.parse(val)
92
+ hash["class"].should == "QueueBus::Worker"
93
+ att = JSON.parse(hash["args"].first)
94
+ att["bus_locale"].should == "jp"
95
+ att["bus_timezone"].should == "EST"
96
+ end
97
+
98
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe Publisher do
5
+ it "should call publish as expected"
6
+ end
7
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe Rider do
5
+ it "should call execute" do
6
+ QueueBus.should_receive(:dispatcher_execute)
7
+ Rider.perform("bus_rider_app_key" => "app", "bus_rider_sub_key" => "sub", "ok" => true, "bus_event_type" => "event_name")
8
+ end
9
+
10
+ it "should change the value" do
11
+ QueueBus.dispatch("r1") do
12
+ subscribe "event_name" do |attributes|
13
+ Runner1.run(attributes)
14
+ end
15
+ end
16
+ Runner1.value.should == 0
17
+ Rider.perform("bus_locale" => "en", "bus_timezone" => "PST", "bus_rider_app_key" => "r1", "bus_rider_sub_key" => "event_name", "ok" => true, "bus_event_type" => "event_name")
18
+ Rider.perform("bus_rider_app_key" => "other", "bus_rider_sub_key" => "event_name", "ok" => true, "bus_event_type" => "event_name")
19
+ Runner1.value.should == 1
20
+ end
21
+
22
+ it "should set the timezone and locale if present" do
23
+ QueueBus.dispatch("r1") do
24
+ subscribe "event_name" do |attributes|
25
+ Runner1.run(attributes)
26
+ end
27
+ end
28
+
29
+ defined?(I18n).should be_nil
30
+ Time.respond_to?(:zone).should eq(false)
31
+
32
+ stub_const("I18n", Class.new)
33
+ I18n.should_receive(:locale=).with("en")
34
+ Time.should_receive(:zone=).with("PST")
35
+
36
+ Rider.perform("bus_locale" => "en", "bus_timezone" => "PST", "bus_rider_app_key" => "r1", "bus_rider_sub_key" => "event_name", "ok" => true, "bus_event_type" => "event_name")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,69 @@
1
+ require 'timecop'
2
+ require 'queue-bus'
3
+ require 'adapter/support'
4
+
5
+ reset_test_adapter
6
+
7
+ module QueueBus
8
+ class Runner
9
+ def self.value
10
+ @value ||= 0
11
+ end
12
+
13
+ def self.attributes
14
+ @attributes
15
+ end
16
+
17
+ def self.run(attrs)
18
+ @value ||= 0
19
+ @value += 1
20
+ @attributes = attrs
21
+ end
22
+
23
+ def self.reset
24
+ @value = nil
25
+ @attributes = nil
26
+ end
27
+ end
28
+
29
+ class Runner1 < Runner
30
+ end
31
+
32
+ class Runner2 < Runner
33
+ end
34
+ end
35
+
36
+ def test_sub(event_name, queue="default")
37
+ matcher = {"bus_event_type" => event_name}
38
+ QueueBus::Subscription.new(queue, event_name, "::QueueBus::Rider", matcher, nil)
39
+ end
40
+
41
+ def test_list(*args)
42
+ out = QueueBus::SubscriptionList.new
43
+ args.each do |sub|
44
+ out.add(sub)
45
+ end
46
+ out
47
+ end
48
+
49
+ RSpec.configure do |config|
50
+ config.mock_with :rspec do |c|
51
+ c.syntax = :should
52
+ end
53
+ config.expect_with :rspec do |c|
54
+ c.syntax = :should
55
+ end
56
+
57
+ config.before(:each) do
58
+ reset_test_adapter
59
+ end
60
+ config.after(:each) do
61
+ begin
62
+ QueueBus.redis { |redis| redis.flushall }
63
+ rescue
64
+ end
65
+ QueueBus.send(:reset)
66
+ QueueBus::Runner1.reset
67
+ QueueBus::Runner2.reset
68
+ end
69
+ end