rapns 3.1.0 → 3.2.0

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.
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