rapns 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +6 -0
- data/README.md +26 -20
- data/config/database.yml +9 -0
- data/lib/generators/templates/add_gcm.rb +12 -12
- data/lib/rapns/apns/app.rb +2 -2
- data/lib/rapns/apns_feedback.rb +12 -0
- data/lib/rapns/daemon/apns/app_runner.rb +6 -17
- data/lib/rapns/daemon/apns/connection.rb +3 -3
- data/lib/rapns/daemon/apns/delivery.rb +2 -2
- data/lib/rapns/daemon/apns/delivery_handler.rb +19 -5
- data/lib/rapns/daemon/apns/feedback_receiver.rb +10 -6
- data/lib/rapns/daemon/app_runner.rb +14 -8
- data/lib/rapns/daemon/database_reconnectable.rb +6 -6
- data/lib/rapns/daemon/delivery_handler.rb +1 -1
- data/lib/rapns/daemon/feeder.rb +1 -1
- data/lib/rapns/daemon/gcm/delivery.rb +4 -4
- data/lib/rapns/daemon/interruptible_sleep.rb +2 -2
- data/lib/rapns/daemon/reflectable.rb +1 -1
- data/lib/rapns/daemon.rb +4 -40
- data/lib/rapns/logger.rb +66 -0
- data/lib/rapns/push.rb +6 -2
- data/lib/rapns/upgraded.rb +31 -0
- data/lib/rapns/version.rb +1 -1
- data/lib/rapns.rb +12 -0
- data/spec/acceptance_spec_helper.rb +2 -2
- data/spec/unit/apns/feedback_spec.rb +0 -3
- data/spec/unit/apns/notification_spec.rb +0 -3
- data/spec/unit/apns_feedback_spec.rb +16 -0
- data/spec/unit/app_spec.rb +1 -3
- data/spec/unit/daemon/apns/app_runner_spec.rb +9 -5
- data/spec/unit/daemon/apns/connection_spec.rb +2 -2
- data/spec/unit/daemon/apns/delivery_handler_spec.rb +14 -9
- data/spec/unit/daemon/apns/delivery_spec.rb +2 -3
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +6 -6
- data/spec/unit/daemon/app_runner_spec.rb +26 -6
- data/spec/unit/daemon/database_reconnectable_spec.rb +9 -7
- data/spec/unit/daemon/delivery_handler_shared.rb +3 -3
- data/spec/unit/daemon/feeder_spec.rb +2 -1
- data/spec/unit/daemon/gcm/app_runner_spec.rb +1 -1
- data/spec/unit/daemon/gcm/delivery_spec.rb +7 -7
- data/spec/unit/daemon/reflectable_spec.rb +2 -2
- data/spec/unit/daemon_spec.rb +25 -75
- data/spec/unit/embed_spec.rb +6 -0
- data/spec/unit/gcm/app_spec.rb +1 -2
- data/spec/unit/gcm/notification_spec.rb +0 -2
- data/spec/unit/{daemon/logger_spec.rb → logger_spec.rb} +19 -20
- data/spec/unit/notification_spec.rb +1 -3
- data/spec/unit/push_spec.rb +20 -9
- data/spec/unit/rapns_spec.rb +9 -0
- data/spec/unit/upgraded_spec.rb +46 -0
- data/spec/unit_spec_helper.rb +5 -2
- metadata +20 -6
- data/lib/rapns/daemon/logger.rb +0 -68
data/lib/rapns/logger.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
module Rapns
|
2
|
+
class Logger
|
3
|
+
def initialize(options)
|
4
|
+
@options = options
|
5
|
+
|
6
|
+
begin
|
7
|
+
log = File.open(File.join(Rails.root, 'log', 'rapns.log'), 'a')
|
8
|
+
log.sync = true
|
9
|
+
@logger = ActiveSupport::BufferedLogger.new(log, Rails.logger.level)
|
10
|
+
@logger.auto_flushing = Rails.logger.respond_to?(:auto_flushing) ? Rails.logger.auto_flushing : true
|
11
|
+
rescue Errno::ENOENT, Errno::EPERM => e
|
12
|
+
@logger = nil
|
13
|
+
error(e)
|
14
|
+
error('Logging disabled.')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def info(msg)
|
19
|
+
log(:info, msg)
|
20
|
+
end
|
21
|
+
|
22
|
+
def error(msg, options = {})
|
23
|
+
airbrake_notify(msg) if notify_via_airbrake?(msg, options)
|
24
|
+
log(:error, msg, 'ERROR', STDERR)
|
25
|
+
end
|
26
|
+
|
27
|
+
def warn(msg)
|
28
|
+
log(:warn, msg, 'WARNING', STDERR)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def log(where, msg, prefix = nil, io = STDOUT)
|
34
|
+
if msg.is_a?(Exception)
|
35
|
+
formatted_backtrace = msg.backtrace.join("\n")
|
36
|
+
msg = "#{msg.class.name}, #{msg.message}\n#{formatted_backtrace}"
|
37
|
+
end
|
38
|
+
|
39
|
+
formatted_msg = "[#{Time.now.to_s(:db)}] "
|
40
|
+
formatted_msg << "[#{prefix}] " if prefix
|
41
|
+
formatted_msg << msg
|
42
|
+
|
43
|
+
if io == STDERR
|
44
|
+
io.puts formatted_msg
|
45
|
+
elsif @options[:foreground]
|
46
|
+
io.puts formatted_msg
|
47
|
+
end
|
48
|
+
|
49
|
+
@logger.send(where, formatted_msg) if @logger
|
50
|
+
end
|
51
|
+
|
52
|
+
def airbrake_notify(e)
|
53
|
+
return unless @options[:airbrake_notify] == true
|
54
|
+
|
55
|
+
if defined?(Airbrake)
|
56
|
+
Airbrake.notify_or_ignore(e)
|
57
|
+
elsif defined?(HoptoadNotifier)
|
58
|
+
HoptoadNotifier.notify_or_ignore(e)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def notify_via_airbrake?(msg, options)
|
63
|
+
msg.is_a?(Exception) && options[:airbrake_notify] != false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/rapns/push.rb
CHANGED
@@ -6,7 +6,11 @@ module Rapns
|
|
6
6
|
options.each { |k, v| config.send("#{k}=", v) }
|
7
7
|
config.push = true
|
8
8
|
Rapns.config.update(config)
|
9
|
-
|
10
|
-
|
9
|
+
|
10
|
+
Upgraded.check(:exit => false)
|
11
|
+
Rapns::Daemon::AppRunner.sync
|
12
|
+
Rapns::Daemon::Feeder.start
|
13
|
+
Rapns::Daemon::AppRunner.wait
|
14
|
+
Rapns::Daemon::AppRunner.stop
|
11
15
|
end
|
12
16
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rapns
|
2
|
+
module Upgraded
|
3
|
+
def self.check(options = {})
|
4
|
+
count = 0
|
5
|
+
|
6
|
+
begin
|
7
|
+
count = Rapns::App.count
|
8
|
+
rescue ActiveRecord::StatementInvalid
|
9
|
+
puts "!!!! RAPNS NOT STARTED !!!!"
|
10
|
+
puts
|
11
|
+
puts "As of version v2.0.0 apps are configured in the database instead of rapns.yml."
|
12
|
+
puts "Please run 'rails g rapns' to generate the new migrations and create your app."
|
13
|
+
puts "See https://github.com/ileitch/rapns for further instructions."
|
14
|
+
puts
|
15
|
+
exit 1 if options[:exit]
|
16
|
+
end
|
17
|
+
|
18
|
+
if count == 0
|
19
|
+
Rapns.logger.warn("You have not created an app yet. See https://github.com/ileitch/rapns for instructions.")
|
20
|
+
end
|
21
|
+
|
22
|
+
if File.exists?(File.join(Rails.root, 'config', 'rapns', 'rapns.yml'))
|
23
|
+
Rapns.logger.warn(<<-EOS)
|
24
|
+
Since 2.0.0 rapns uses command-line options and a Ruby based configuration file.
|
25
|
+
Please run 'rails g rapns' to generate a new configuration file into config/initializers.
|
26
|
+
Remove config/rapns/rapns.yml to avoid this warning.
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/rapns/version.rb
CHANGED
data/lib/rapns.rb
CHANGED
@@ -4,6 +4,7 @@ require 'multi_json'
|
|
4
4
|
require 'rapns/version'
|
5
5
|
require 'rapns/deprecation'
|
6
6
|
require 'rapns/deprecatable'
|
7
|
+
require 'rapns/logger'
|
7
8
|
require 'rapns/multi_json_helper'
|
8
9
|
require 'rapns/notification'
|
9
10
|
require 'rapns/app'
|
@@ -11,6 +12,8 @@ require 'rapns/configuration'
|
|
11
12
|
require 'rapns/reflection'
|
12
13
|
require 'rapns/embed'
|
13
14
|
require 'rapns/push'
|
15
|
+
require 'rapns/apns_feedback'
|
16
|
+
require 'rapns/upgraded'
|
14
17
|
|
15
18
|
require 'rapns/apns/binary_notification_validator'
|
16
19
|
require 'rapns/apns/device_token_format_validator'
|
@@ -30,4 +33,13 @@ module Rapns
|
|
30
33
|
require 'rapns/daemon'
|
31
34
|
require 'rapns/patches'
|
32
35
|
end
|
36
|
+
|
37
|
+
def self.logger
|
38
|
+
@logger ||= Logger.new(:foreground => Rapns.config.foreground,
|
39
|
+
:airbrake_notify => Rapns.config.airbrake_notify)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.logger=(logger)
|
43
|
+
@logger = logger
|
44
|
+
end
|
33
45
|
end
|
@@ -8,7 +8,7 @@ Bundler.require(:default)
|
|
8
8
|
TMP_DIR = '/tmp'
|
9
9
|
RAILS_DIR = File.join(TMP_DIR, 'rapns_test')
|
10
10
|
if ENV['TRAVIS']
|
11
|
-
TRAVIS_BRANCH = '
|
11
|
+
TRAVIS_BRANCH = 'master'
|
12
12
|
RAPNS_ROOT = 'git://github.com/ileitch/rapns.git'
|
13
13
|
else
|
14
14
|
RAPNS_ROOT = File.expand_path(__FILE__ + '/../../')
|
@@ -48,7 +48,7 @@ end
|
|
48
48
|
def cmd(str, echo = true)
|
49
49
|
puts "* #{str.strip}" if echo
|
50
50
|
retval = Bundler.with_clean_env { `#{str}` }
|
51
|
-
puts retval.strip if echo
|
51
|
+
puts retval.strip if echo && retval.strip != ""
|
52
52
|
retval
|
53
53
|
end
|
54
54
|
|
@@ -1,9 +1,6 @@
|
|
1
1
|
require "unit_spec_helper"
|
2
2
|
|
3
3
|
describe Rapns::Apns::Feedback do
|
4
|
-
it { should validate_presence_of(:device_token) }
|
5
|
-
it { should validate_presence_of(:failed_at) }
|
6
|
-
|
7
4
|
it "should validate the format of the device_token" do
|
8
5
|
notification = Rapns::Apns::Feedback.new(:device_token => "{$%^&*()}")
|
9
6
|
notification.valid?.should be_false
|
@@ -4,9 +4,6 @@ require 'unit/notification_shared.rb'
|
|
4
4
|
describe Rapns::Apns::Notification do
|
5
5
|
it_should_behave_like 'an Notification subclass'
|
6
6
|
|
7
|
-
it { should validate_presence_of(:device_token) }
|
8
|
-
it { should validate_numericality_of(:badge) }
|
9
|
-
|
10
7
|
let(:notification_class) { Rapns::Apns::Notification }
|
11
8
|
let(:notification) { notification_class.new }
|
12
9
|
let(:data_setter) { 'attributes_for_device=' }
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe Rapns, 'apns_feedback' do
|
4
|
+
let!(:app) { Rapns::Apns::App.create!(:name => 'test', :environment => 'production', :certificate => TEST_CERT) }
|
5
|
+
let(:receiver) { stub(:check_for_feedback => nil) }
|
6
|
+
|
7
|
+
before do
|
8
|
+
Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => receiver)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'checks feedback for each app' do
|
12
|
+
Rapns::Daemon::Apns::FeedbackReceiver.should_receive(:new).with(app, 0).and_return(receiver)
|
13
|
+
receiver.should_receive(:check_for_feedback)
|
14
|
+
Rapns.apns_feedback
|
15
|
+
end
|
16
|
+
end
|
data/spec/unit/app_spec.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require 'unit_spec_helper'
|
2
2
|
|
3
3
|
describe Rapns::App do
|
4
|
-
it { should validate_numericality_of(:connections) }
|
5
|
-
|
6
4
|
it 'validates the uniqueness of name within type and environment' do
|
7
5
|
Rapns::Apns::App.create!(:name => 'test', :environment => 'production', :certificate => TEST_CERT)
|
8
6
|
app = Rapns::Apns::App.new(:name => 'test', :environment => 'production', :certificate => TEST_CERT)
|
@@ -10,19 +10,17 @@ describe Rapns::Daemon::Apns::AppRunner do
|
|
10
10
|
let(:runner) { Rapns::Daemon::Apns::AppRunner.new(app) }
|
11
11
|
let(:handler) { stub(:start => nil, :stop => nil, :queue= => nil) }
|
12
12
|
let(:receiver) { stub(:start => nil, :stop => nil) }
|
13
|
-
let(:config) {
|
13
|
+
let(:config) { stub(:feedback_poll => 60, :push => false) }
|
14
14
|
let(:logger) { stub(:info => nil) }
|
15
15
|
|
16
16
|
before do
|
17
|
-
Rapns
|
17
|
+
Rapns.stub(:logger => logger, :config => config)
|
18
18
|
Rapns::Daemon::Apns::DeliveryHandler.stub(:new => handler)
|
19
19
|
Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => receiver)
|
20
|
-
Rapns::Daemon.stub(:config => config)
|
21
20
|
end
|
22
21
|
|
23
22
|
it 'instantiates a new feedback receiver when started' do
|
24
|
-
Rapns::Daemon::Apns::FeedbackReceiver.should_receive(:new).with(app,
|
25
|
-
2196, 60)
|
23
|
+
Rapns::Daemon::Apns::FeedbackReceiver.should_receive(:new).with(app, 60)
|
26
24
|
runner.start
|
27
25
|
end
|
28
26
|
|
@@ -36,4 +34,10 @@ describe Rapns::Daemon::Apns::AppRunner do
|
|
36
34
|
receiver.should_receive(:stop)
|
37
35
|
runner.stop
|
38
36
|
end
|
37
|
+
|
38
|
+
it 'does not check for feedback when in push mode' do
|
39
|
+
config.stub(:push => true)
|
40
|
+
Rapns::Daemon::Apns::FeedbackReceiver.should_not_receive(:new)
|
41
|
+
runner.start
|
42
|
+
end
|
39
43
|
end
|
@@ -20,7 +20,7 @@ describe Rapns::Daemon::Apns::Connection do
|
|
20
20
|
OpenSSL::X509::Certificate.stub(:new => x509_certificate)
|
21
21
|
TCPSocket.stub(:new => tcp_socket)
|
22
22
|
OpenSSL::SSL::SSLSocket.stub(:new => ssl_socket)
|
23
|
-
Rapns
|
23
|
+
Rapns.stub(:logger => logger)
|
24
24
|
end
|
25
25
|
|
26
26
|
it "reads the number of bytes from the SSL socket" do
|
@@ -236,7 +236,7 @@ describe Rapns::Daemon::Apns::Connection do
|
|
236
236
|
it 'logs the the connection is idle' do
|
237
237
|
Rapns::Daemon::Apns::Connection.stub(:idle_period => 0.1)
|
238
238
|
sleep 0.2
|
239
|
-
Rapns
|
239
|
+
Rapns.logger.should_receive(:info).with('[Connection 0] Idle period exceeded, reconnecting...')
|
240
240
|
connection.write('blah')
|
241
241
|
end
|
242
242
|
end
|
@@ -4,12 +4,12 @@ require File.dirname(__FILE__) + '/../delivery_handler_shared.rb'
|
|
4
4
|
describe Rapns::Daemon::Apns::DeliveryHandler do
|
5
5
|
it_should_behave_like 'an DeliveryHandler subclass'
|
6
6
|
|
7
|
-
let(:host) { '
|
7
|
+
let(:host) { 'gateway.push.apple.com' }
|
8
8
|
let(:port) { 2195 }
|
9
9
|
let(:certificate) { stub }
|
10
10
|
let(:password) { stub }
|
11
|
-
let(:app) { stub(:password => password, :certificate => certificate, :name => 'MyApp')}
|
12
|
-
let(:delivery_handler) { Rapns::Daemon::Apns::DeliveryHandler.new(app
|
11
|
+
let(:app) { stub(:password => password, :certificate => certificate, :name => 'MyApp', :environment => 'production')}
|
12
|
+
let(:delivery_handler) { Rapns::Daemon::Apns::DeliveryHandler.new(app) }
|
13
13
|
let(:connection) { stub('Connection', :select => false, :write => nil, :reconnect => nil, :close => nil, :connect => nil) }
|
14
14
|
let(:notification) { stub }
|
15
15
|
let(:http) { stub(:shutdown => nil)}
|
@@ -24,18 +24,18 @@ describe Rapns::Daemon::Apns::DeliveryHandler do
|
|
24
24
|
|
25
25
|
it "instantiates a new connection" do
|
26
26
|
Rapns::Daemon::Apns::Connection.should_receive(:new).with(app, host, port)
|
27
|
-
|
27
|
+
delivery_handler.start
|
28
|
+
delivery_handler.stop
|
28
29
|
end
|
29
30
|
|
30
|
-
it
|
31
|
-
|
31
|
+
it "connects the socket" do
|
32
|
+
connection.should_receive(:connect)
|
32
33
|
delivery_handler.start
|
33
34
|
delivery_handler.stop
|
34
35
|
end
|
35
36
|
|
36
|
-
it
|
37
|
-
|
38
|
-
Rapns::Daemon::Apns::DeliveryHandler.new(app, host, port)
|
37
|
+
it 'performs delivery of an notification' do
|
38
|
+
Rapns::Daemon::Apns::Delivery.should_receive(:perform).with(app, connection, notification)
|
39
39
|
delivery_handler.start
|
40
40
|
delivery_handler.stop
|
41
41
|
end
|
@@ -45,4 +45,9 @@ describe Rapns::Daemon::Apns::DeliveryHandler do
|
|
45
45
|
delivery_handler.start
|
46
46
|
delivery_handler.stop
|
47
47
|
end
|
48
|
+
|
49
|
+
it 'does not attempt to close the connection if the connection was not established' do
|
50
|
+
connection.should_not_receive(:close)
|
51
|
+
delivery_handler.stop
|
52
|
+
end
|
48
53
|
end
|
@@ -16,8 +16,7 @@ describe Rapns::Daemon::Apns::Delivery do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
before do
|
19
|
-
Rapns.stub(:config => config)
|
20
|
-
Rapns::Daemon.stub(:logger => logger)
|
19
|
+
Rapns.stub(:config => config, :logger => logger)
|
21
20
|
end
|
22
21
|
|
23
22
|
it "sends the binary version of the notification" do
|
@@ -143,7 +142,7 @@ describe Rapns::Daemon::Apns::Delivery do
|
|
143
142
|
end
|
144
143
|
|
145
144
|
it "logs that the connection is being reconnected" do
|
146
|
-
Rapns
|
145
|
+
Rapns.logger.should_receive(:error).with("[MyApp] Error received, reconnecting...")
|
147
146
|
perform
|
148
147
|
end
|
149
148
|
|
@@ -6,15 +6,15 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
|
|
6
6
|
let(:poll) { 60 }
|
7
7
|
let(:certificate) { stub }
|
8
8
|
let(:password) { stub }
|
9
|
-
let(:app) { stub(:name => 'my_app', :password => password, :certificate => certificate) }
|
9
|
+
let(:app) { stub(:name => 'my_app', :password => password, :certificate => certificate, :environment => 'production') }
|
10
10
|
let(:connection) { stub(:connect => nil, :read => nil, :close => nil) }
|
11
11
|
let(:logger) { stub(:error => nil, :info => nil) }
|
12
|
-
let(:receiver) { Rapns::Daemon::Apns::FeedbackReceiver.new(app,
|
12
|
+
let(:receiver) { Rapns::Daemon::Apns::FeedbackReceiver.new(app, poll) }
|
13
13
|
let(:feedback) { stub }
|
14
14
|
|
15
15
|
before do
|
16
16
|
receiver.stub(:interruptible_sleep)
|
17
|
-
Rapns
|
17
|
+
Rapns.stub(:logger => logger)
|
18
18
|
Rapns::Daemon::Apns::Connection.stub(:new => connection)
|
19
19
|
Rapns::Apns::Feedback.stub(:create! => feedback)
|
20
20
|
receiver.instance_variable_set("@stop", false)
|
@@ -53,7 +53,7 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
|
|
53
53
|
|
54
54
|
it 'logs the feedback' do
|
55
55
|
stub_connection_read_with_tuple
|
56
|
-
Rapns
|
56
|
+
Rapns.logger.should_receive(:info).with("[my_app] [FeedbackReceiver] Delivery failed at 2011-12-10 16:08:45 UTC for 834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17.")
|
57
57
|
receiver.check_for_feedback
|
58
58
|
end
|
59
59
|
|
@@ -66,7 +66,7 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
|
|
66
66
|
it 'logs errors' do
|
67
67
|
error = StandardError.new('bork!')
|
68
68
|
connection.stub(:read).and_raise(error)
|
69
|
-
Rapns
|
69
|
+
Rapns.logger.should_receive(:error).with(error)
|
70
70
|
receiver.check_for_feedback
|
71
71
|
end
|
72
72
|
|
@@ -118,7 +118,7 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
|
|
118
118
|
error = StandardError.new('bork!')
|
119
119
|
stub_connection_read_with_tuple
|
120
120
|
callback = Proc.new { raise error }
|
121
|
-
Rapns
|
121
|
+
Rapns.logger.should_receive(:error).with(error)
|
122
122
|
Rapns::Deprecation.silenced do
|
123
123
|
Rapns.config.on_apns_feedback &callback
|
124
124
|
end
|
@@ -17,7 +17,7 @@ describe Rapns::Daemon::AppRunner, 'deliver' do
|
|
17
17
|
let(:logger) { stub(:error => nil) }
|
18
18
|
|
19
19
|
before do
|
20
|
-
Rapns
|
20
|
+
Rapns.stub(:logger => logger)
|
21
21
|
Rapns::Daemon::AppRunner.runners[1] = runner
|
22
22
|
end
|
23
23
|
|
@@ -48,6 +48,7 @@ describe Rapns::Daemon::AppRunner, 'sync' do
|
|
48
48
|
Rapns::Daemon::DeliveryQueue.stub(:new => queue)
|
49
49
|
Rapns::Daemon::AppRunner.runners[app.id] = runner
|
50
50
|
Rapns::App.stub(:all => [app])
|
51
|
+
Rapns.stub(:logger => logger)
|
51
52
|
end
|
52
53
|
|
53
54
|
after { Rapns::Daemon::AppRunner.runners.clear }
|
@@ -81,7 +82,7 @@ describe Rapns::Daemon::AppRunner, 'sync' do
|
|
81
82
|
new_runner = stub
|
82
83
|
Rapns::Daemon::Apns::AppRunner.should_receive(:new).with(new_app).and_return(new_runner)
|
83
84
|
new_runner.stub(:start).and_raise(StandardError)
|
84
|
-
Rapns
|
85
|
+
Rapns.logger.should_receive(:error).any_number_of_times
|
85
86
|
Rapns::Daemon::AppRunner.sync
|
86
87
|
end
|
87
88
|
end
|
@@ -95,14 +96,14 @@ describe Rapns::Daemon::AppRunner, 'debug' do
|
|
95
96
|
Rapns::Daemon.stub(:config => {})
|
96
97
|
Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => stub.as_null_object)
|
97
98
|
Rapns::Daemon::Apns::Connection.stub(:new => stub.as_null_object)
|
98
|
-
Rapns
|
99
|
+
Rapns.stub(:logger => logger)
|
99
100
|
Rapns::Daemon::AppRunner.sync
|
100
101
|
end
|
101
102
|
|
102
103
|
after { Rapns::Daemon::AppRunner.runners.clear }
|
103
104
|
|
104
105
|
it 'prints debug app states to the log' do
|
105
|
-
Rapns
|
106
|
+
Rapns.logger.should_receive(:info).with("\ntest:\n handlers: 1\n queued: 0\n idle: true\n")
|
106
107
|
Rapns::Daemon::AppRunner.debug
|
107
108
|
end
|
108
109
|
end
|
@@ -113,10 +114,9 @@ describe Rapns::Daemon::AppRunner, 'idle' do
|
|
113
114
|
let(:logger) { stub(:info => nil) }
|
114
115
|
|
115
116
|
before do
|
116
|
-
Rapns
|
117
|
+
Rapns.stub(:logger => logger)
|
117
118
|
Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => stub.as_null_object)
|
118
119
|
Rapns::Daemon::Apns::Connection.stub(:new => stub.as_null_object)
|
119
|
-
Rapns::Daemon.stub(:logger => logger)
|
120
120
|
Rapns::Daemon::AppRunner.sync
|
121
121
|
end
|
122
122
|
|
@@ -127,3 +127,23 @@ describe Rapns::Daemon::AppRunner, 'idle' do
|
|
127
127
|
Rapns::Daemon::AppRunner.idle.should == [runner]
|
128
128
|
end
|
129
129
|
end
|
130
|
+
|
131
|
+
describe Rapns::Daemon::AppRunner, 'wait' do
|
132
|
+
let!(:app) { Rapns::Apns::App.create!(:name => 'test', :connections => 1,
|
133
|
+
:environment => 'development', :certificate => TEST_CERT) }
|
134
|
+
let(:logger) { stub(:info => nil) }
|
135
|
+
|
136
|
+
before do
|
137
|
+
Rapns.stub(:logger => logger)
|
138
|
+
Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => stub.as_null_object)
|
139
|
+
Rapns::Daemon::Apns::Connection.stub(:new => stub.as_null_object)
|
140
|
+
Rapns::Daemon::AppRunner.sync
|
141
|
+
end
|
142
|
+
|
143
|
+
after { Rapns::Daemon::AppRunner.runners.clear }
|
144
|
+
|
145
|
+
it 'waits until all runners are idle' do
|
146
|
+
Rapns::Daemon::AppRunner.runners.count.should == 1
|
147
|
+
Timeout.timeout(5) { Rapns::Daemon::AppRunner.wait }
|
148
|
+
end
|
149
|
+
end
|
@@ -32,6 +32,8 @@ describe Rapns::Daemon::DatabaseReconnectable do
|
|
32
32
|
ActiveRecord::JDBCError
|
33
33
|
when 'jdbcmysql'
|
34
34
|
ActiveRecord::JDBCError
|
35
|
+
when 'jdbch2'
|
36
|
+
ActiveRecord::JDBCError
|
35
37
|
else
|
36
38
|
raise "Please update #{__FILE__} for adapter #{$adapter}"
|
37
39
|
end
|
@@ -41,7 +43,7 @@ describe Rapns::Daemon::DatabaseReconnectable do
|
|
41
43
|
|
42
44
|
before do
|
43
45
|
@logger = mock("Logger", :info => nil, :error => nil, :warn => nil)
|
44
|
-
Rapns
|
46
|
+
Rapns.stub(:logger).and_return(@logger)
|
45
47
|
|
46
48
|
ActiveRecord::Base.stub(:clear_all_connections!)
|
47
49
|
ActiveRecord::Base.stub(:establish_connection)
|
@@ -49,17 +51,17 @@ describe Rapns::Daemon::DatabaseReconnectable do
|
|
49
51
|
end
|
50
52
|
|
51
53
|
it "should log the error raised" do
|
52
|
-
Rapns
|
54
|
+
Rapns.logger.should_receive(:error).with(error)
|
53
55
|
test_double.perform
|
54
56
|
end
|
55
57
|
|
56
58
|
it "should log that the database is being reconnected" do
|
57
|
-
Rapns
|
59
|
+
Rapns.logger.should_receive(:warn).with("Lost connection to database, reconnecting...")
|
58
60
|
test_double.perform
|
59
61
|
end
|
60
62
|
|
61
63
|
it "should log the reconnection attempt" do
|
62
|
-
Rapns
|
64
|
+
Rapns.logger.should_receive(:warn).with("Attempt 1")
|
63
65
|
test_double.perform
|
64
66
|
end
|
65
67
|
|
@@ -92,12 +94,12 @@ describe Rapns::Daemon::DatabaseReconnectable do
|
|
92
94
|
end
|
93
95
|
|
94
96
|
it "should log the 2nd attempt" do
|
95
|
-
Rapns
|
97
|
+
Rapns.logger.should_receive(:warn).with("Attempt 2")
|
96
98
|
test_double.perform
|
97
99
|
end
|
98
100
|
|
99
101
|
it "should log errors raised when the reconnection is not successful without notifying airbrake" do
|
100
|
-
Rapns
|
102
|
+
Rapns.logger.should_receive(:error).with(error, :airbrake_notify => false)
|
101
103
|
test_double.perform
|
102
104
|
end
|
103
105
|
|
@@ -106,4 +108,4 @@ describe Rapns::Daemon::DatabaseReconnectable do
|
|
106
108
|
test_double.perform
|
107
109
|
end
|
108
110
|
end
|
109
|
-
end
|
111
|
+
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
shared_examples_for 'an DeliveryHandler subclass' do
|
2
2
|
it 'logs all delivery errors' do
|
3
3
|
logger = stub
|
4
|
-
Rapns
|
4
|
+
Rapns.stub(:logger => logger)
|
5
5
|
error = StandardError.new
|
6
6
|
delivery_handler.stub(:deliver).and_raise(error)
|
7
|
-
Rapns
|
7
|
+
Rapns.logger.should_receive(:error).with(error)
|
8
8
|
delivery_handler.send(:handle_next_notification)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'reflects an exception' do
|
12
|
-
Rapns
|
12
|
+
Rapns.stub(:logger => stub(:error => nil))
|
13
13
|
error = StandardError.new
|
14
14
|
delivery_handler.stub(:deliver).and_raise(error)
|
15
15
|
delivery_handler.should_receive(:reflect).with(:error, error)
|
@@ -11,6 +11,7 @@ describe Rapns::Daemon::Feeder do
|
|
11
11
|
Rapns.stub(:config => config)
|
12
12
|
Rapns::Daemon::Feeder.stub(:stop? => true)
|
13
13
|
Rapns::Daemon::AppRunner.stub(:idle => [stub(:app => app)])
|
14
|
+
Rapns.stub(:logger => logger)
|
14
15
|
end
|
15
16
|
|
16
17
|
def start
|
@@ -102,7 +103,7 @@ describe Rapns::Daemon::Feeder do
|
|
102
103
|
it "logs errors" do
|
103
104
|
e = StandardError.new("bork")
|
104
105
|
Rapns::Notification.stub(:ready_for_delivery).and_raise(e)
|
105
|
-
Rapns
|
106
|
+
Rapns.logger.should_receive(:error).with(e)
|
106
107
|
start
|
107
108
|
end
|
108
109
|
|
@@ -15,7 +15,7 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
15
15
|
|
16
16
|
before do
|
17
17
|
Time.stub(:now => now)
|
18
|
-
Rapns
|
18
|
+
Rapns.stub(:logger => logger)
|
19
19
|
end
|
20
20
|
|
21
21
|
describe 'an 200 response' do
|
@@ -38,7 +38,7 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
38
38
|
|
39
39
|
it 'logs that the notification was delivered' do
|
40
40
|
response.stub(:body => JSON.dump({ 'failure' => 0 }))
|
41
|
-
logger.should_receive(:info).with("[MyApp]
|
41
|
+
logger.should_receive(:info).with("[MyApp] #{notification.id} sent to xyz")
|
42
42
|
perform
|
43
43
|
end
|
44
44
|
|
@@ -93,7 +93,7 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
it 'logs that the notification will be retried' do
|
96
|
-
Rapns
|
96
|
+
Rapns.logger.should_receive(:warn).with("All recipients unavailable. Notification #{notification.id} will be retired after 2012-10-14 00:00:02 (retry 1).")
|
97
97
|
perform
|
98
98
|
end
|
99
99
|
end
|
@@ -146,7 +146,7 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
146
146
|
{ 'error' => 'NotRegistered' },
|
147
147
|
{ 'error' => 'Unavailable' }
|
148
148
|
]}}
|
149
|
-
let(:error_description) { "Failed to deliver to recipients 0, 1, 2. Errors: Unavailable, NotRegistered, Unavailable. 0, 2 will be retried as notification
|
149
|
+
let(:error_description) { "Failed to deliver to recipients 0, 1, 2. Errors: Unavailable, NotRegistered, Unavailable. 0, 2 will be retried as notification #{notification.id + 1}." }
|
150
150
|
it_should_behave_like 'an notification with some delivery failures'
|
151
151
|
end
|
152
152
|
end
|
@@ -160,7 +160,7 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
160
160
|
{ 'message_id' => '1:000' },
|
161
161
|
{ 'error' => 'InternalServerError' }
|
162
162
|
]}}
|
163
|
-
let(:error_description) { "Failed to deliver to recipients 0, 2. Errors: Unavailable, InternalServerError. 0, 2 will be retried as notification
|
163
|
+
let(:error_description) { "Failed to deliver to recipients 0, 2. Errors: Unavailable, InternalServerError. 0, 2 will be retried as notification #{notification.id + 1}." }
|
164
164
|
it_should_behave_like 'an notification with some delivery failures'
|
165
165
|
end
|
166
166
|
|
@@ -168,7 +168,7 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
168
168
|
before { response.stub(:code => 503) }
|
169
169
|
|
170
170
|
it 'logs a warning that the notification will be retried.' do
|
171
|
-
logger.should_receive(:warn).with("GCM responded with an Service Unavailable Error. Notification
|
171
|
+
logger.should_receive(:warn).with("GCM responded with an Service Unavailable Error. Notification #{notification.id} will be retired after 2012-10-14 00:00:02 (retry 1).")
|
172
172
|
perform
|
173
173
|
end
|
174
174
|
|
@@ -205,7 +205,7 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
205
205
|
end
|
206
206
|
|
207
207
|
it 'logs a warning that the notification has been re-queued.' do
|
208
|
-
Rapns
|
208
|
+
Rapns.logger.should_receive(:warn).with("GCM responded with an Internal Error. Notification #{notification.id} will be retired after #{(now + 2 ** 3).strftime("%Y-%m-%d %H:%M:%S")} (retry 3).")
|
209
209
|
perform
|
210
210
|
end
|
211
211
|
|
@@ -10,7 +10,7 @@ describe Rapns::Daemon::Reflectable do
|
|
10
10
|
|
11
11
|
before do
|
12
12
|
Rapns.reflections.stub(:__dispatch)
|
13
|
-
Rapns
|
13
|
+
Rapns.stub(:logger => logger)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'dispatches the given reflection' do
|
@@ -21,7 +21,7 @@ describe Rapns::Daemon::Reflectable do
|
|
21
21
|
it 'logs errors raise by the reflection' do
|
22
22
|
error = StandardError.new
|
23
23
|
Rapns.reflections.stub(:__dispatch).and_raise(error)
|
24
|
-
Rapns
|
24
|
+
Rapns.logger.should_receive(:error).with(error)
|
25
25
|
test_reflectable.reflect(:error)
|
26
26
|
end
|
27
27
|
end
|