rapns 1.0.7 → 2.0.0rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +7 -0
- data/LICENSE +7 -0
- data/README.md +58 -41
- data/bin/rapns +23 -5
- data/lib/generators/rapns_generator.rb +2 -4
- data/lib/generators/templates/add_app_to_rapns.rb +11 -0
- data/lib/generators/templates/create_rapns_apps.rb +15 -0
- data/lib/rapns/app.rb +9 -0
- data/lib/rapns/daemon/app_runner.rb +131 -0
- data/lib/rapns/daemon/connection.rb +5 -3
- data/lib/rapns/daemon/delivery_handler.rb +13 -15
- data/lib/rapns/daemon/delivery_handler_pool.rb +8 -10
- data/lib/rapns/daemon/delivery_queue.rb +36 -4
- data/lib/rapns/daemon/feedback_receiver.rb +19 -12
- data/lib/rapns/daemon/feeder.rb +8 -10
- data/lib/rapns/daemon/logger.rb +5 -3
- data/lib/rapns/daemon.rb +52 -38
- data/lib/rapns/notification.rb +16 -5
- data/lib/rapns/patches.rb +2 -2
- data/lib/rapns/version.rb +1 -1
- data/lib/rapns.rb +2 -1
- data/spec/rapns/daemon/app_runner_spec.rb +207 -0
- data/spec/rapns/daemon/connection_spec.rb +177 -236
- data/spec/rapns/daemon/delivery_handler_pool_spec.rb +10 -14
- data/spec/rapns/daemon/delivery_handler_spec.rb +92 -79
- data/spec/rapns/daemon/feedback_receiver_spec.rb +29 -23
- data/spec/rapns/daemon/feeder_spec.rb +40 -44
- data/spec/rapns/daemon/logger_spec.rb +21 -3
- data/spec/rapns/daemon_spec.rb +65 -125
- data/spec/rapns/notification_spec.rb +16 -0
- data/spec/spec_helper.rb +4 -1
- metadata +14 -15
- data/History.md +0 -5
- data/lib/generators/templates/rapns.yml +0 -31
- data/lib/rapns/daemon/certificate.rb +0 -27
- data/lib/rapns/daemon/configuration.rb +0 -98
- data/lib/rapns/daemon/pool.rb +0 -36
- data/spec/rapns/daemon/certificate_spec.rb +0 -22
- data/spec/rapns/daemon/configuration_spec.rb +0 -231
@@ -1,178 +1,191 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Rapns::Daemon::DeliveryHandler do
|
4
|
-
let(:
|
4
|
+
let(:queue) { Rapns::Daemon::DeliveryQueue.new }
|
5
|
+
let(:name) { 'my_app:0' }
|
6
|
+
let(:host) { 'localhost' }
|
7
|
+
let(:port) { 2195 }
|
8
|
+
let(:certificate) { stub }
|
9
|
+
let(:password) { stub }
|
10
|
+
let(:delivery_handler) { Rapns::Daemon::DeliveryHandler.new(queue, name, host, port, certificate, password) }
|
11
|
+
let(:connection) { stub(:select => false, :write => nil, :reconnect => nil, :close => nil, :connect => nil) }
|
12
|
+
let(:logger) { stub(:error => nil, :info => nil) }
|
13
|
+
let(:notification) { stub.as_null_object }
|
14
|
+
let(:config) { stub(:check_for_errors => true) }
|
15
|
+
let(:delivery_queues) { [] }
|
5
16
|
|
6
17
|
before do
|
7
|
-
|
8
|
-
Rapns::Daemon.stub(:
|
9
|
-
|
10
|
-
@connection = mock("Connection", :connect => nil, :write => nil, :close => nil, :select => nil, :read => nil)
|
11
|
-
Rapns::Daemon::Connection.stub(:new).and_return(@connection)
|
12
|
-
configuration = mock("Configuration", :push => stub(:host => "gateway.push.apple.com", :port => 2195))
|
13
|
-
Rapns::Daemon.stub(:configuration).and_return(configuration)
|
14
|
-
@logger = mock("Logger", :error => nil, :info => nil)
|
15
|
-
Rapns::Daemon.stub(:logger).and_return(@logger)
|
18
|
+
Rapns::Daemon::Connection.stub(:new => connection)
|
19
|
+
Rapns::Daemon.stub(:delivery_queues => delivery_queues, :logger => logger, :config => config)
|
20
|
+
queue.push(notification)
|
16
21
|
end
|
17
22
|
|
18
23
|
it "instantiates a new connection" do
|
19
|
-
Rapns::Daemon::Connection.should_receive(:new).with(
|
24
|
+
Rapns::Daemon::Connection.should_receive(:new).with("DeliveryHandler:#{name}", host, port, certificate, password)
|
20
25
|
delivery_handler
|
21
26
|
end
|
22
27
|
|
23
28
|
it "connects the socket when started" do
|
24
|
-
|
29
|
+
connection.should_receive(:connect)
|
25
30
|
delivery_handler.start
|
26
31
|
delivery_handler.stop
|
27
32
|
end
|
28
33
|
|
29
|
-
it "
|
30
|
-
|
34
|
+
it "instructs the queue to wakeup the thread when told to stop" do
|
35
|
+
thread = stub
|
36
|
+
Thread.stub(:new => thread)
|
37
|
+
queue.should_receive(:wakeup).with(thread)
|
38
|
+
delivery_handler.start
|
31
39
|
delivery_handler.stop
|
32
40
|
end
|
33
41
|
|
34
|
-
it "
|
35
|
-
|
42
|
+
it "sends the binary version of the notification" do
|
43
|
+
notification.stub(:to_binary => "hi mom")
|
44
|
+
connection.should_receive(:write).with("hi mom")
|
36
45
|
delivery_handler.send(:handle_next_notification)
|
37
46
|
end
|
38
47
|
|
39
|
-
it "
|
40
|
-
|
48
|
+
it "logs the notification delivery" do
|
49
|
+
notification.stub(:id => 666, :device_token => 'abc123')
|
50
|
+
logger.should_receive(:info).with("[DeliveryHandler:my_app:0] 666 sent to abc123")
|
41
51
|
delivery_handler.send(:handle_next_notification)
|
42
52
|
end
|
43
53
|
|
44
|
-
it "
|
45
|
-
|
46
|
-
delivery_handler.should_not_receive(:deliver)
|
47
|
-
Rapns::Daemon.delivery_queue.push(Rapns::Daemon::DeliveryHandler::STOP)
|
54
|
+
it "marks the notification as delivered" do
|
55
|
+
notification.should_receive(:delivered=).with(true)
|
48
56
|
delivery_handler.send(:handle_next_notification)
|
49
57
|
end
|
50
58
|
|
51
|
-
it "
|
52
|
-
|
53
|
-
|
59
|
+
it "sets the time the notification was delivered" do
|
60
|
+
now = Time.now
|
61
|
+
Time.stub(:now).and_return(now)
|
62
|
+
notification.should_receive(:delivered_at=).with(now)
|
54
63
|
delivery_handler.send(:handle_next_notification)
|
55
64
|
end
|
56
65
|
|
57
|
-
it "
|
58
|
-
|
66
|
+
it "does not trigger validations when saving the notification" do
|
67
|
+
notification.should_receive(:save!).with(:validate => false)
|
59
68
|
delivery_handler.send(:handle_next_notification)
|
60
69
|
end
|
61
70
|
|
62
|
-
it "
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
it "should set the time the notification was delivered" do
|
67
|
-
@notification.delivered_at.should be_nil
|
71
|
+
it "updates notification with the ability to reconnect the database" do
|
72
|
+
delivery_handler.should_receive(:with_database_reconnect_and_retry)
|
68
73
|
delivery_handler.send(:handle_next_notification)
|
69
|
-
@notification.reload
|
70
|
-
@notification.delivered_at.should be_kind_of(Time)
|
71
74
|
end
|
72
75
|
|
73
|
-
it "
|
74
|
-
|
76
|
+
it "logs if an error is raised when updating the notification" do
|
77
|
+
e = StandardError.new("bork!")
|
78
|
+
notification.stub(:save!).and_raise(e)
|
79
|
+
Rapns::Daemon.logger.should_receive(:error).with(e)
|
75
80
|
delivery_handler.send(:handle_next_notification)
|
76
81
|
end
|
77
82
|
|
78
|
-
it "
|
79
|
-
|
83
|
+
it "notifies the delivery queue the notification has been processed" do
|
84
|
+
queue.should_receive(:notification_processed)
|
80
85
|
delivery_handler.send(:handle_next_notification)
|
81
86
|
end
|
82
87
|
|
83
|
-
it
|
84
|
-
|
85
|
-
|
86
|
-
Rapns::Daemon.logger.should_receive(:error).with(e)
|
88
|
+
it 'does not check for errors if check_for_errors config option is false' do
|
89
|
+
config.stub(:check_for_errors => false)
|
90
|
+
delivery_handler.should_not_receive(:check_for_error)
|
87
91
|
delivery_handler.send(:handle_next_notification)
|
88
92
|
end
|
89
93
|
|
90
|
-
|
91
|
-
|
92
|
-
|
94
|
+
describe "when being stopped" do
|
95
|
+
before { queue.pop }
|
96
|
+
|
97
|
+
it "closes the connection when a DeliveryQueue::WakeupError is raised" do
|
98
|
+
connection.should_receive(:close)
|
99
|
+
queue.stub(:pop).and_raise(Rapns::Daemon::DeliveryQueue::WakeupError)
|
100
|
+
delivery_handler.send(:handle_next_notification)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "does not attempt to deliver a notification when a DeliveryQueue::::WakeupError is raised" do
|
104
|
+
queue.stub(:pop).and_raise(Rapns::Daemon::DeliveryQueue::WakeupError)
|
105
|
+
delivery_handler.should_not_receive(:deliver)
|
106
|
+
delivery_handler.send(:handle_next_notification)
|
107
|
+
end
|
93
108
|
end
|
94
109
|
|
95
110
|
describe "when delivery fails" do
|
96
|
-
before
|
97
|
-
@connection.stub(:select => true, :read => [8, 4, 69].pack("ccN"), :reconnect => nil)
|
98
|
-
end
|
111
|
+
before { connection.stub(:select => true, :read => [8, 4, 69].pack("ccN")) }
|
99
112
|
|
100
|
-
it "
|
113
|
+
it "updates notification with the ability to reconnect the database" do
|
101
114
|
delivery_handler.should_receive(:with_database_reconnect_and_retry)
|
102
115
|
delivery_handler.send(:handle_next_notification)
|
103
116
|
end
|
104
117
|
|
105
|
-
it "
|
106
|
-
|
118
|
+
it "sets the notification as not delivered" do
|
119
|
+
notification.should_receive(:delivered=).with(false)
|
107
120
|
delivery_handler.send(:handle_next_notification)
|
108
121
|
end
|
109
122
|
|
110
|
-
it "
|
111
|
-
|
123
|
+
it "sets the notification delivered_at timestamp to nil" do
|
124
|
+
notification.should_receive(:delivered_at=).with(nil)
|
112
125
|
delivery_handler.send(:handle_next_notification)
|
113
126
|
end
|
114
127
|
|
115
|
-
it "
|
116
|
-
|
128
|
+
it "sets the notification as failed" do
|
129
|
+
notification.should_receive(:failed=).with(true)
|
117
130
|
delivery_handler.send(:handle_next_notification)
|
118
131
|
end
|
119
132
|
|
120
|
-
it "
|
133
|
+
it "sets the notification failed_at timestamp" do
|
121
134
|
now = Time.now
|
122
135
|
Time.stub(:now).and_return(now)
|
123
|
-
|
136
|
+
notification.should_receive(:failed_at=).with(now)
|
124
137
|
delivery_handler.send(:handle_next_notification)
|
125
138
|
end
|
126
139
|
|
127
|
-
it "
|
128
|
-
|
140
|
+
it "sets the notification error code" do
|
141
|
+
notification.should_receive(:error_code=).with(4)
|
129
142
|
delivery_handler.send(:handle_next_notification)
|
130
143
|
end
|
131
144
|
|
132
|
-
it "
|
145
|
+
it "logs the delivery error" do
|
133
146
|
error = Rapns::DeliveryError.new(4, 12, "Missing payload")
|
134
147
|
Rapns::DeliveryError.stub(:new => error)
|
135
|
-
|
148
|
+
logger.should_receive(:error).with(error)
|
136
149
|
delivery_handler.send(:handle_next_notification)
|
137
150
|
end
|
138
151
|
|
139
|
-
it "
|
140
|
-
|
152
|
+
it "sets the notification error description" do
|
153
|
+
notification.should_receive(:error_description=).with("Missing payload")
|
141
154
|
delivery_handler.send(:handle_next_notification)
|
142
155
|
end
|
143
156
|
|
144
|
-
it "
|
145
|
-
|
157
|
+
it "skips validation when saving the notification" do
|
158
|
+
notification.should_receive(:save!).with(:validate => false)
|
146
159
|
delivery_handler.send(:handle_next_notification)
|
147
160
|
end
|
148
161
|
|
149
|
-
it "
|
150
|
-
|
162
|
+
it "reads 6 bytes from the socket" do
|
163
|
+
connection.should_receive(:read).with(6).and_return(nil)
|
151
164
|
delivery_handler.send(:handle_next_notification)
|
152
165
|
end
|
153
166
|
|
154
|
-
it "
|
155
|
-
|
156
|
-
|
167
|
+
it "does not attempt to read from the socket if the socket was not selected for reading after the timeout" do
|
168
|
+
connection.stub(:select => nil)
|
169
|
+
connection.should_not_receive(:read)
|
157
170
|
delivery_handler.send(:handle_next_notification)
|
158
171
|
end
|
159
172
|
|
160
|
-
it "
|
161
|
-
|
173
|
+
it "reconnects the socket" do
|
174
|
+
connection.should_receive(:reconnect)
|
162
175
|
delivery_handler.send(:handle_next_notification)
|
163
176
|
end
|
164
177
|
|
165
|
-
it "
|
166
|
-
Rapns::Daemon.logger.should_receive(:error).with("[DeliveryHandler
|
178
|
+
it "logs that the connection is being reconnected" do
|
179
|
+
Rapns::Daemon.logger.should_receive(:error).with("[DeliveryHandler:my_app:0] Error received, reconnecting...")
|
167
180
|
delivery_handler.send(:handle_next_notification)
|
168
181
|
end
|
169
182
|
|
170
183
|
context "when the APNs disconnects without returning an error" do
|
171
184
|
before do
|
172
|
-
|
185
|
+
connection.stub(:read => nil)
|
173
186
|
end
|
174
187
|
|
175
|
-
it '
|
188
|
+
it 'raises a DisconnectError error if the connection is closed without an error being returned' do
|
176
189
|
error = Rapns::DisconnectionError.new
|
177
190
|
Rapns::DisconnectionError.should_receive(:new).and_return(error)
|
178
191
|
Rapns::Daemon.logger.should_receive(:error).with(error)
|
@@ -180,12 +193,12 @@ describe Rapns::Daemon::DeliveryHandler do
|
|
180
193
|
end
|
181
194
|
|
182
195
|
it 'does not set the error code on the notification' do
|
183
|
-
|
196
|
+
notification.should_receive(:error_code=).with(nil)
|
184
197
|
delivery_handler.send(:handle_next_notification)
|
185
198
|
end
|
186
199
|
|
187
200
|
it 'sets the error descriptipon on the notification' do
|
188
|
-
|
201
|
+
notification.should_receive(:error_description=).with("APNs disconnected without returning an error.")
|
189
202
|
delivery_handler.send(:handle_next_notification)
|
190
203
|
end
|
191
204
|
end
|
@@ -1,16 +1,22 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Rapns::Daemon::FeedbackReceiver, 'check_for_feedback' do
|
4
|
+
let(:host) { 'feedback.push.apple.com' }
|
5
|
+
let(:port) { 2196 }
|
6
|
+
let(:poll) { 60 }
|
7
|
+
let(:certificate) { stub }
|
8
|
+
let(:password) { stub }
|
9
|
+
let(:app) { 'my_app' }
|
4
10
|
let(:connection) { stub(:connect => nil, :read => nil, :close => nil) }
|
5
11
|
let(:logger) { stub(:error => nil, :info => nil) }
|
12
|
+
let(:receiever) { Rapns::Daemon::FeedbackReceiver.new(app, host, port, poll, certificate, password) }
|
6
13
|
|
7
14
|
before do
|
8
|
-
|
15
|
+
receiever.stub(:interruptible_sleep)
|
9
16
|
Rapns::Daemon.logger = logger
|
10
17
|
Rapns::Daemon::Connection.stub(:new => connection)
|
11
18
|
Rapns::Feedback.stub(:create!)
|
12
|
-
|
13
|
-
Rapns::Daemon::FeedbackReceiver.instance_variable_set("@stop", false)
|
19
|
+
receiever.instance_variable_set("@stop", false)
|
14
20
|
end
|
15
21
|
|
16
22
|
def stub_connection_read_with_tuple
|
@@ -25,62 +31,62 @@ describe Rapns::Daemon::FeedbackReceiver, 'check_for_feedback' do
|
|
25
31
|
end
|
26
32
|
|
27
33
|
it 'instantiates a new connection' do
|
28
|
-
Rapns::Daemon::Connection.should_receive(:new).with("FeedbackReceiver",
|
29
|
-
|
34
|
+
Rapns::Daemon::Connection.should_receive(:new).with("FeedbackReceiver:#{app}", host, port, certificate, password)
|
35
|
+
receiever.check_for_feedback
|
30
36
|
end
|
31
37
|
|
32
38
|
it 'connects to the feeback service' do
|
33
39
|
connection.should_receive(:connect)
|
34
|
-
|
40
|
+
receiever.check_for_feedback
|
35
41
|
end
|
36
42
|
|
37
43
|
it 'closes the connection' do
|
38
44
|
connection.should_receive(:close)
|
39
|
-
|
45
|
+
receiever.check_for_feedback
|
40
46
|
end
|
41
47
|
|
42
48
|
it 'reads from the connection' do
|
43
49
|
connection.should_receive(:read).with(38)
|
44
|
-
|
50
|
+
receiever.check_for_feedback
|
45
51
|
end
|
46
52
|
|
47
53
|
it 'logs the feedback' do
|
48
54
|
stub_connection_read_with_tuple
|
49
|
-
Rapns::Daemon.logger.should_receive(:info).with("[FeedbackReceiver] Delivery failed at 2011-12-10 16:08:45 UTC for 834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17")
|
50
|
-
|
55
|
+
Rapns::Daemon.logger.should_receive(:info).with("[FeedbackReceiver:my_app] Delivery failed at 2011-12-10 16:08:45 UTC for 834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17")
|
56
|
+
receiever.check_for_feedback
|
51
57
|
end
|
52
58
|
|
53
59
|
it 'creates the feedback' do
|
54
60
|
stub_connection_read_with_tuple
|
55
|
-
Rapns::Feedback.should_receive(:create!).with(:failed_at => Time.at(1323533325), :device_token => '834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17')
|
56
|
-
|
61
|
+
Rapns::Feedback.should_receive(:create!).with(:failed_at => Time.at(1323533325), :device_token => '834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17', :app => 'my_app')
|
62
|
+
receiever.check_for_feedback
|
57
63
|
end
|
58
64
|
|
59
65
|
it 'logs errors' do
|
60
66
|
error = StandardError.new('bork!')
|
61
67
|
connection.stub(:read).and_raise(error)
|
62
68
|
Rapns::Daemon.logger.should_receive(:error).with(error)
|
63
|
-
|
69
|
+
receiever.check_for_feedback
|
64
70
|
end
|
65
71
|
|
66
72
|
it 'sleeps for the feedback poll period' do
|
67
|
-
|
68
|
-
|
73
|
+
receiever.stub(:check_for_feedback)
|
74
|
+
receiever.should_receive(:interruptible_sleep).with(60).at_least(:once)
|
69
75
|
Thread.stub(:new).and_yield
|
70
|
-
|
71
|
-
|
76
|
+
receiever.stub(:loop).and_yield
|
77
|
+
receiever.start
|
72
78
|
end
|
73
79
|
|
74
80
|
it 'checks for feedback when started' do
|
75
|
-
|
81
|
+
receiever.should_receive(:check_for_feedback).at_least(:once)
|
76
82
|
Thread.stub(:new).and_yield
|
77
|
-
|
78
|
-
|
83
|
+
receiever.stub(:loop).and_yield
|
84
|
+
receiever.start
|
79
85
|
end
|
80
86
|
|
81
87
|
it 'interrupts sleep when stopped' do
|
82
|
-
|
83
|
-
|
84
|
-
|
88
|
+
receiever.stub(:check_for_feedback)
|
89
|
+
receiever.should_receive(:interrupt_sleep)
|
90
|
+
receiever.stop
|
85
91
|
end
|
86
92
|
end
|
@@ -1,79 +1,75 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Rapns::Daemon::Feeder do
|
4
|
+
let(:poll) { 2 }
|
5
|
+
let(:config) { stub(:batch_size => 5000) }
|
6
|
+
let(:notification) { Rapns::Notification.create!(:device_token => "a" * 64, :app => 'my_app') }
|
7
|
+
let(:logger) { stub }
|
8
|
+
|
4
9
|
before do
|
5
10
|
Rapns::Daemon::Feeder.stub(:sleep)
|
6
11
|
Rapns::Daemon::Feeder.stub(:interruptible_sleep)
|
7
|
-
|
8
|
-
@logger = mock("Logger", :info => nil, :error => nil, :warn => nil)
|
9
|
-
Rapns::Daemon.stub(:logger).and_return(@logger)
|
10
|
-
@queue = mock(:push => nil, :notifications_processed? => true)
|
11
|
-
Rapns::Daemon.stub(:delivery_queue).and_return(@queue)
|
12
|
-
Rapns::Daemon.stub(:configuration => mock("Configuration", :push => stub(:poll => 2)))
|
12
|
+
Rapns::Daemon.stub(:logger => logger, :config => config)
|
13
13
|
Rapns::Daemon::Feeder.instance_variable_set("@stop", false)
|
14
|
+
Rapns::Daemon::AppRunner.stub(:ready => ['my_app'])
|
15
|
+
Rapns::Daemon::AppRunner.stub(:ready => ['my_app'])
|
14
16
|
end
|
15
17
|
|
16
|
-
it "
|
17
|
-
Rapns::Daemon::Feeder.stub(:loop)
|
18
|
-
Rapns::Daemon::Feeder.should_receive(:reconnect_database)
|
19
|
-
Rapns::Daemon::Feeder.start(false)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should check for new notifications with the ability to reconnect the database" do
|
18
|
+
it "checks for new notifications with the ability to reconnect the database" do
|
23
19
|
Rapns::Daemon::Feeder.should_receive(:with_database_reconnect_and_retry)
|
24
20
|
Rapns::Daemon::Feeder.enqueue_notifications
|
25
21
|
end
|
26
22
|
|
27
|
-
it
|
28
|
-
|
29
|
-
|
30
|
-
Rapns::
|
23
|
+
it 'loads notifications in batches' do
|
24
|
+
relation = stub
|
25
|
+
relation.should_receive(:find_each).with(:batch_size => 5000)
|
26
|
+
Rapns::Notification.stub(:ready_for_delivery => relation)
|
27
|
+
Rapns::Daemon::Feeder.enqueue_notifications
|
31
28
|
end
|
32
29
|
|
33
|
-
it "
|
34
|
-
|
35
|
-
Rapns::Daemon.
|
30
|
+
it "delivers the notification" do
|
31
|
+
notification.update_attributes!(:delivered => false)
|
32
|
+
Rapns::Daemon::AppRunner.should_receive(:deliver).with(notification)
|
36
33
|
Rapns::Daemon::Feeder.enqueue_notifications
|
37
34
|
end
|
38
35
|
|
39
|
-
it
|
40
|
-
|
41
|
-
Rapns::Daemon.
|
36
|
+
it 'does not enqueue the notification if the app runner is still processing the previous batch' do
|
37
|
+
Rapns::Daemon::AppRunner.stub(:ready => [])
|
38
|
+
Rapns::Daemon::AppRunner.should_not_receive(:deliver)
|
42
39
|
Rapns::Daemon::Feeder.enqueue_notifications
|
43
40
|
end
|
44
41
|
|
45
|
-
it "
|
46
|
-
|
47
|
-
Rapns::Daemon.
|
42
|
+
it "enqueues an undelivered notification without deliver_after set" do
|
43
|
+
notification.update_attributes!(:delivered => false, :deliver_after => nil)
|
44
|
+
Rapns::Daemon::AppRunner.should_receive(:deliver).with(notification)
|
48
45
|
Rapns::Daemon::Feeder.enqueue_notifications
|
49
46
|
end
|
50
47
|
|
51
|
-
it "
|
52
|
-
|
53
|
-
Rapns::Daemon.
|
48
|
+
it "enqueues a notification with a deliver_after time in the past" do
|
49
|
+
notification.update_attributes!(:delivered => false, :deliver_after => 1.hour.ago)
|
50
|
+
Rapns::Daemon::AppRunner.should_receive(:deliver).with(notification)
|
54
51
|
Rapns::Daemon::Feeder.enqueue_notifications
|
55
52
|
end
|
56
53
|
|
57
|
-
it "
|
58
|
-
|
59
|
-
Rapns::Daemon.
|
54
|
+
it "does not enqueue a notification with a deliver_after time in the future" do
|
55
|
+
notification.update_attributes!(:delivered => false, :deliver_after => 1.hour.from_now)
|
56
|
+
Rapns::Daemon::AppRunner.should_not_receive(:deliver)
|
60
57
|
Rapns::Daemon::Feeder.enqueue_notifications
|
61
58
|
end
|
62
59
|
|
63
|
-
it "
|
64
|
-
|
65
|
-
Rapns::Daemon.
|
60
|
+
it "does not enqueue a previously delivered notification" do
|
61
|
+
notification.update_attributes!(:delivered => true, :delivered_at => Time.now)
|
62
|
+
Rapns::Daemon::AppRunner.should_not_receive(:deliver)
|
66
63
|
Rapns::Daemon::Feeder.enqueue_notifications
|
67
64
|
end
|
68
65
|
|
69
|
-
it "
|
70
|
-
|
71
|
-
Rapns::
|
72
|
-
Rapns::Daemon.delivery_queue.should_not_receive(:push)
|
66
|
+
it "does not enqueue a notification that has previously failed delivery" do
|
67
|
+
notification.update_attributes!(:delivered => false, :failed => true)
|
68
|
+
Rapns::Daemon::AppRunner.should_not_receive(:deliver)
|
73
69
|
Rapns::Daemon::Feeder.enqueue_notifications
|
74
70
|
end
|
75
71
|
|
76
|
-
it "
|
72
|
+
it "logs errors" do
|
77
73
|
e = StandardError.new("bork")
|
78
74
|
Rapns::Notification.stub(:ready_for_delivery).and_raise(e)
|
79
75
|
Rapns::Daemon.logger.should_receive(:error).with(e)
|
@@ -88,12 +84,12 @@ describe Rapns::Daemon::Feeder do
|
|
88
84
|
it "enqueues notifications when started" do
|
89
85
|
Rapns::Daemon::Feeder.should_receive(:enqueue_notifications).at_least(:once)
|
90
86
|
Rapns::Daemon::Feeder.stub(:loop).and_yield
|
91
|
-
Rapns::Daemon::Feeder.start(
|
87
|
+
Rapns::Daemon::Feeder.start(poll)
|
92
88
|
end
|
93
89
|
|
94
|
-
it "
|
95
|
-
Rapns::Daemon::Feeder.should_receive(:interruptible_sleep).with(
|
90
|
+
it "sleeps for the given period" do
|
91
|
+
Rapns::Daemon::Feeder.should_receive(:interruptible_sleep).with(poll)
|
96
92
|
Rapns::Daemon::Feeder.stub(:loop).and_yield
|
97
|
-
Rapns::Daemon::Feeder.start(
|
93
|
+
Rapns::Daemon::Feeder.start(poll)
|
98
94
|
end
|
99
95
|
end
|
@@ -21,17 +21,30 @@ module Airbrake
|
|
21
21
|
end
|
22
22
|
|
23
23
|
describe Rapns::Daemon::Logger do
|
24
|
+
let(:log) { stub(:sync= => true) }
|
25
|
+
let(:config) { stub(:airbrake_notify => true) }
|
26
|
+
|
24
27
|
before do
|
25
28
|
Rails.stub(:root).and_return("/rails_root")
|
26
29
|
@buffered_logger = mock("BufferedLogger", :info => nil, :error => nil, :level => 0, :auto_flushing => 1, :auto_flushing= => nil)
|
27
30
|
Rails.logger = @buffered_logger
|
28
31
|
ActiveSupport::BufferedLogger.stub(:new).and_return(@buffered_logger)
|
29
|
-
|
30
|
-
|
32
|
+
Rapns::Daemon.stub(:config => config)
|
33
|
+
File.stub(:open => log)
|
31
34
|
end
|
32
35
|
|
33
36
|
it "should open the a log file in the Rails log directory" do
|
34
|
-
|
37
|
+
File.should_receive(:open).with('/rails_root/log/rapns.log', 'w')
|
38
|
+
Rapns::Daemon::Logger.new(:foreground => true)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'sets sync mode on the log descriptor' do
|
42
|
+
log.should_receive(:sync=).with(true)
|
43
|
+
Rapns::Daemon::Logger.new(:foreground => true)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'instantiates the BufferedLogger' do
|
47
|
+
ActiveSupport::BufferedLogger.should_receive(:new).with(log, Rails.logger.level)
|
35
48
|
Rapns::Daemon::Logger.new(:foreground => true)
|
36
49
|
end
|
37
50
|
|
@@ -69,6 +82,7 @@ describe Rapns::Daemon::Logger do
|
|
69
82
|
|
70
83
|
it "should handle an Exception instance" do
|
71
84
|
e = RuntimeError.new("hi mom")
|
85
|
+
e.stub(:backtrace => [])
|
72
86
|
logger = Rapns::Daemon::Logger.new(:foreground => false)
|
73
87
|
@buffered_logger.should_receive(:error).with(/RuntimeError, hi mom/)
|
74
88
|
logger.error(e)
|
@@ -76,6 +90,7 @@ describe Rapns::Daemon::Logger do
|
|
76
90
|
|
77
91
|
it "should notify Airbrake of the exception" do
|
78
92
|
e = RuntimeError.new("hi mom")
|
93
|
+
e.stub(:backtrace => [])
|
79
94
|
logger = Rapns::Daemon::Logger.new(:foreground => false, :airbrake_notify => true)
|
80
95
|
Airbrake.should_receive(:notify_or_ignore).with(e)
|
81
96
|
logger.error(e)
|
@@ -95,6 +110,7 @@ describe Rapns::Daemon::Logger do
|
|
95
110
|
|
96
111
|
it "should notify using HoptoadNotifier" do
|
97
112
|
e = RuntimeError.new("hi mom")
|
113
|
+
e.stub(:backtrace => [])
|
98
114
|
logger = Rapns::Daemon::Logger.new(:foreground => false, :airbrake_notify => true)
|
99
115
|
HoptoadNotifier.should_receive(:notify_or_ignore).with(e)
|
100
116
|
logger.error(e)
|
@@ -103,6 +119,7 @@ describe Rapns::Daemon::Logger do
|
|
103
119
|
|
104
120
|
it "should not notify Airbrake of the exception if the airbrake_notify option is false" do
|
105
121
|
e = RuntimeError.new("hi mom")
|
122
|
+
e.stub(:backtrace => [])
|
106
123
|
logger = Rapns::Daemon::Logger.new(:foreground => false, :airbrake_notify => false)
|
107
124
|
Airbrake.should_not_receive(:notify_or_ignore).with(e)
|
108
125
|
logger.error(e)
|
@@ -110,6 +127,7 @@ describe Rapns::Daemon::Logger do
|
|
110
127
|
|
111
128
|
it "should not notify Airbrake if explicitly disabled in the call to error" do
|
112
129
|
e = RuntimeError.new("hi mom")
|
130
|
+
e.stub(:backtrace => [])
|
113
131
|
logger = Rapns::Daemon::Logger.new(:foreground => false, :airbrake_notify => true)
|
114
132
|
Airbrake.should_not_receive(:notify_or_ignore).with(e)
|
115
133
|
logger.error(e, :airbrake_notify => false)
|