rapns 1.0.7 → 2.0.0rc1
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/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)
|