rapns 3.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/CHANGELOG.md +6 -0
  2. data/README.md +26 -20
  3. data/config/database.yml +9 -0
  4. data/lib/generators/templates/add_gcm.rb +12 -12
  5. data/lib/rapns/apns/app.rb +2 -2
  6. data/lib/rapns/apns_feedback.rb +12 -0
  7. data/lib/rapns/daemon/apns/app_runner.rb +6 -17
  8. data/lib/rapns/daemon/apns/connection.rb +3 -3
  9. data/lib/rapns/daemon/apns/delivery.rb +2 -2
  10. data/lib/rapns/daemon/apns/delivery_handler.rb +19 -5
  11. data/lib/rapns/daemon/apns/feedback_receiver.rb +10 -6
  12. data/lib/rapns/daemon/app_runner.rb +14 -8
  13. data/lib/rapns/daemon/database_reconnectable.rb +6 -6
  14. data/lib/rapns/daemon/delivery_handler.rb +1 -1
  15. data/lib/rapns/daemon/feeder.rb +1 -1
  16. data/lib/rapns/daemon/gcm/delivery.rb +4 -4
  17. data/lib/rapns/daemon/interruptible_sleep.rb +2 -2
  18. data/lib/rapns/daemon/reflectable.rb +1 -1
  19. data/lib/rapns/daemon.rb +4 -40
  20. data/lib/rapns/logger.rb +66 -0
  21. data/lib/rapns/push.rb +6 -2
  22. data/lib/rapns/upgraded.rb +31 -0
  23. data/lib/rapns/version.rb +1 -1
  24. data/lib/rapns.rb +12 -0
  25. data/spec/acceptance_spec_helper.rb +2 -2
  26. data/spec/unit/apns/feedback_spec.rb +0 -3
  27. data/spec/unit/apns/notification_spec.rb +0 -3
  28. data/spec/unit/apns_feedback_spec.rb +16 -0
  29. data/spec/unit/app_spec.rb +1 -3
  30. data/spec/unit/daemon/apns/app_runner_spec.rb +9 -5
  31. data/spec/unit/daemon/apns/connection_spec.rb +2 -2
  32. data/spec/unit/daemon/apns/delivery_handler_spec.rb +14 -9
  33. data/spec/unit/daemon/apns/delivery_spec.rb +2 -3
  34. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +6 -6
  35. data/spec/unit/daemon/app_runner_spec.rb +26 -6
  36. data/spec/unit/daemon/database_reconnectable_spec.rb +9 -7
  37. data/spec/unit/daemon/delivery_handler_shared.rb +3 -3
  38. data/spec/unit/daemon/feeder_spec.rb +2 -1
  39. data/spec/unit/daemon/gcm/app_runner_spec.rb +1 -1
  40. data/spec/unit/daemon/gcm/delivery_spec.rb +7 -7
  41. data/spec/unit/daemon/reflectable_spec.rb +2 -2
  42. data/spec/unit/daemon_spec.rb +25 -75
  43. data/spec/unit/embed_spec.rb +6 -0
  44. data/spec/unit/gcm/app_spec.rb +1 -2
  45. data/spec/unit/gcm/notification_spec.rb +0 -2
  46. data/spec/unit/{daemon/logger_spec.rb → logger_spec.rb} +19 -20
  47. data/spec/unit/notification_spec.rb +1 -3
  48. data/spec/unit/push_spec.rb +20 -9
  49. data/spec/unit/rapns_spec.rb +9 -0
  50. data/spec/unit/upgraded_spec.rb +46 -0
  51. data/spec/unit_spec_helper.rb +5 -2
  52. metadata +20 -6
  53. data/lib/rapns/daemon/logger.rb +0 -68
@@ -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
- Rapns::Daemon.start
10
- Rapns::Daemon.shutdown(true)
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
@@ -1,3 +1,3 @@
1
1
  module Rapns
2
- VERSION = '3.1.0'
2
+ VERSION = '3.2.0'
3
3
  end
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 = 'gcm'
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
@@ -1,8 +1,6 @@
1
- require "unit_spec_helper"
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) { {:feedback_poll => 60 } }
13
+ let(:config) { stub(:feedback_poll => 60, :push => false) }
14
14
  let(:logger) { stub(:info => nil) }
15
15
 
16
16
  before do
17
- Rapns::Daemon.stub(:logger => logger)
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, 'feedback.sandbox.push.apple.com',
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::Daemon.stub(:logger => logger)
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::Daemon.logger.should_receive(:info).with('[Connection 0] Idle period exceeded, reconnecting...')
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) { 'localhost' }
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, host, port) }
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
- Rapns::Daemon::Apns::DeliveryHandler.new(app, host, port)
27
+ delivery_handler.start
28
+ delivery_handler.stop
28
29
  end
29
30
 
30
- it 'performs delivery of an notification' do
31
- Rapns::Daemon::Apns::Delivery.should_receive(:perform).with(app, connection, notification)
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 "connects the socket when instantiated" do
37
- connection.should_receive(:connect)
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::Daemon.logger.should_receive(:error).with("[MyApp] Error received, reconnecting...")
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, host, port, poll) }
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::Daemon.logger = logger
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::Daemon.logger.should_receive(:info).with("[my_app] [FeedbackReceiver] Delivery failed at 2011-12-10 16:08:45 UTC for 834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17.")
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::Daemon.logger.should_receive(:error).with(error)
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::Daemon.logger.should_receive(:error).with(error)
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::Daemon.stub(:logger => logger)
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::Daemon.logger.should_receive(:error).any_number_of_times
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::Daemon.stub(:logger => logger)
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::Daemon.logger.should_receive(:info).with("\ntest:\n handlers: 1\n queued: 0\n idle: true\n")
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::Daemon.stub(:config => {})
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::Daemon.stub(:logger).and_return(@logger)
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::Daemon.logger.should_receive(:error).with(error)
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::Daemon.logger.should_receive(:warn).with("Lost connection to database, reconnecting...")
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::Daemon.logger.should_receive(:warn).with("Attempt 1")
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::Daemon.logger.should_receive(:warn).with("Attempt 2")
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::Daemon.logger.should_receive(:error).with(error, :airbrake_notify => false)
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::Daemon.stub(:logger => logger)
4
+ Rapns.stub(:logger => logger)
5
5
  error = StandardError.new
6
6
  delivery_handler.stub(:deliver).and_raise(error)
7
- Rapns::Daemon.logger.should_receive(:error).with(error)
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::Daemon.stub(:logger => stub(:error => nil))
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::Daemon.logger.should_receive(:error).with(e)
106
+ Rapns.logger.should_receive(:error).with(e)
106
107
  start
107
108
  end
108
109
 
@@ -11,7 +11,7 @@ describe Rapns::Daemon::Gcm::AppRunner do
11
11
  let(:logger) { stub(:info => nil) }
12
12
 
13
13
  before do
14
- Rapns::Daemon.stub(:logger => logger)
14
+ Rapns.stub(:logger => logger)
15
15
  Rapns::Daemon::Gcm::DeliveryHandler.stub(:new => handler)
16
16
  end
17
17
  end
@@ -15,7 +15,7 @@ describe Rapns::Daemon::Gcm::Delivery do
15
15
 
16
16
  before do
17
17
  Time.stub(:now => now)
18
- Rapns::Daemon.stub(:logger => logger)
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] 1 sent to xyz")
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::Daemon.logger.should_receive(:warn).with("All recipients unavailable. Notification #{notification.id} will be retired after 2012-10-14 00:00:02 (retry 1).")
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 2." }
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 2." }
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 1 will be retired after 2012-10-14 00:00:02 (retry 1).")
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::Daemon.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).")
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::Daemon.stub(:logger => logger)
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::Daemon.logger.should_receive(:error).with(error)
24
+ Rapns.logger.should_receive(:error).with(error)
25
25
  test_reflectable.reflect(:error)
26
26
  end
27
27
  end