rpush 1.0.0-java → 2.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +37 -22
  4. data/bin/rpush +13 -4
  5. data/lib/generators/rpush_generator.rb +2 -0
  6. data/lib/generators/templates/add_adm.rb +5 -5
  7. data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +1 -1
  8. data/lib/generators/templates/add_app_to_rapns.rb +2 -2
  9. data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +1 -1
  10. data/lib/generators/templates/add_gcm.rb +32 -32
  11. data/lib/generators/templates/add_rpush.rb +67 -67
  12. data/lib/generators/templates/add_wpns.rb +2 -2
  13. data/lib/generators/templates/create_rapns_apps.rb +5 -5
  14. data/lib/generators/templates/create_rapns_feedback.rb +2 -2
  15. data/lib/generators/templates/create_rapns_notifications.rb +15 -15
  16. data/lib/generators/templates/rpush.rb +28 -7
  17. data/lib/generators/templates/rpush_2_0_0_updates.rb +42 -0
  18. data/lib/rpush/client/active_model/adm/app.rb +23 -0
  19. data/lib/rpush/client/active_model/adm/data_validator.rb +14 -0
  20. data/lib/rpush/client/active_model/adm/notification.rb +28 -0
  21. data/lib/rpush/client/active_model/apns/app.rb +37 -0
  22. data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +16 -0
  23. data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +14 -0
  24. data/lib/rpush/client/active_model/apns/notification.rb +90 -0
  25. data/lib/rpush/client/active_model/gcm/app.rb +19 -0
  26. data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +14 -0
  27. data/lib/rpush/client/active_model/gcm/notification.rb +31 -0
  28. data/lib/rpush/client/active_model/notification.rb +26 -0
  29. data/lib/rpush/client/active_model/payload_data_size_validator.rb +13 -0
  30. data/lib/rpush/client/active_model/registration_ids_count_validator.rb +13 -0
  31. data/lib/rpush/client/active_model/wpns/app.rb +13 -0
  32. data/lib/rpush/client/active_model/wpns/notification.rb +17 -0
  33. data/lib/rpush/client/active_model.rb +21 -0
  34. data/lib/rpush/client/active_record/adm/app.rb +11 -0
  35. data/lib/rpush/client/active_record/adm/notification.rb +11 -0
  36. data/lib/rpush/client/active_record/apns/app.rb +11 -0
  37. data/lib/rpush/client/active_record/apns/feedback.rb +22 -0
  38. data/lib/rpush/client/active_record/apns/notification.rb +46 -0
  39. data/lib/rpush/client/active_record/app.rb +17 -0
  40. data/lib/rpush/client/active_record/gcm/app.rb +11 -0
  41. data/lib/rpush/client/active_record/gcm/notification.rb +11 -0
  42. data/lib/rpush/client/active_record/notification.rb +38 -0
  43. data/lib/rpush/client/active_record/wpns/app.rb +11 -0
  44. data/lib/rpush/client/active_record/wpns/notification.rb +11 -0
  45. data/lib/rpush/client/active_record.rb +19 -0
  46. data/lib/rpush/client/redis/adm/app.rb +14 -0
  47. data/lib/rpush/client/redis/adm/notification.rb +11 -0
  48. data/lib/rpush/client/redis/apns/app.rb +11 -0
  49. data/lib/rpush/client/redis/apns/feedback.rb +20 -0
  50. data/lib/rpush/client/redis/apns/notification.rb +11 -0
  51. data/lib/rpush/client/redis/app.rb +24 -0
  52. data/lib/rpush/client/redis/gcm/app.rb +11 -0
  53. data/lib/rpush/client/redis/gcm/notification.rb +11 -0
  54. data/lib/rpush/client/redis/notification.rb +68 -0
  55. data/lib/rpush/client/redis/wpns/app.rb +11 -0
  56. data/lib/rpush/client/redis/wpns/notification.rb +11 -0
  57. data/lib/rpush/client/redis.rb +35 -0
  58. data/lib/rpush/configuration.rb +27 -6
  59. data/lib/rpush/daemon/adm/delivery.rb +56 -55
  60. data/lib/rpush/daemon/apns/delivery.rb +20 -44
  61. data/lib/rpush/daemon/apns/feedback_receiver.rb +11 -8
  62. data/lib/rpush/daemon/apns.rb +6 -5
  63. data/lib/rpush/daemon/app_runner.rb +103 -99
  64. data/lib/rpush/daemon/batch.rb +54 -40
  65. data/lib/rpush/daemon/delivery.rb +13 -3
  66. data/lib/rpush/daemon/delivery_error.rb +10 -2
  67. data/lib/rpush/daemon/dispatcher/apns_tcp.rb +114 -0
  68. data/lib/rpush/daemon/dispatcher/http.rb +3 -3
  69. data/lib/rpush/daemon/dispatcher/tcp.rb +3 -3
  70. data/lib/rpush/daemon/dispatcher_loop.rb +37 -23
  71. data/lib/rpush/daemon/errors.rb +18 -0
  72. data/lib/rpush/daemon/feeder.rb +28 -39
  73. data/lib/rpush/daemon/gcm/delivery.rb +19 -20
  74. data/lib/rpush/daemon/interruptible_sleep.rb +26 -45
  75. data/lib/rpush/daemon/loggable.rb +2 -4
  76. data/lib/rpush/daemon/proc_title.rb +16 -0
  77. data/lib/rpush/daemon/queue_payload.rb +12 -0
  78. data/lib/rpush/daemon/reflectable.rb +3 -5
  79. data/lib/rpush/daemon/retry_header_parser.rb +6 -6
  80. data/lib/rpush/daemon/retryable_error.rb +2 -0
  81. data/lib/rpush/daemon/ring_buffer.rb +16 -0
  82. data/lib/rpush/daemon/service_config_methods.rb +23 -7
  83. data/lib/rpush/daemon/signal_handler.rb +56 -0
  84. data/lib/rpush/daemon/store/active_record/reconnectable.rb +21 -17
  85. data/lib/rpush/daemon/store/active_record.rb +71 -38
  86. data/lib/rpush/daemon/store/interface.rb +19 -0
  87. data/lib/rpush/daemon/store/redis.rb +149 -0
  88. data/lib/rpush/daemon/string_helpers.rb +15 -0
  89. data/lib/rpush/daemon/synchronizer.rb +60 -0
  90. data/lib/rpush/daemon/tcp_connection.rb +6 -11
  91. data/lib/rpush/daemon/wpns/delivery.rb +21 -30
  92. data/lib/rpush/daemon.rb +40 -60
  93. data/lib/rpush/deprecatable.rb +4 -3
  94. data/lib/rpush/deprecation.rb +7 -10
  95. data/lib/rpush/embed.rb +8 -3
  96. data/lib/rpush/logger.rb +11 -15
  97. data/lib/rpush/push.rb +1 -2
  98. data/lib/rpush/reflection.rb +8 -12
  99. data/lib/rpush/version.rb +1 -1
  100. data/lib/rpush.rb +5 -29
  101. data/lib/tasks/quality.rake +35 -0
  102. data/lib/tasks/test.rake +1 -5
  103. data/spec/.rubocop.yml +4 -0
  104. data/spec/functional/adm_spec.rb +3 -6
  105. data/spec/functional/apns_spec.rb +117 -24
  106. data/spec/functional/embed_spec.rb +20 -20
  107. data/spec/functional/gcm_spec.rb +4 -7
  108. data/spec/functional/new_app_spec.rb +59 -0
  109. data/spec/functional/retry_spec.rb +46 -0
  110. data/spec/functional/synchronization_spec.rb +68 -0
  111. data/spec/functional/wpns_spec.rb +3 -6
  112. data/spec/functional_spec_helper.rb +26 -0
  113. data/spec/integration/rpush_spec.rb +13 -0
  114. data/spec/integration/support/gcm_success_response.json +1 -0
  115. data/spec/spec_helper.rb +60 -0
  116. data/spec/support/active_record_setup.rb +48 -0
  117. data/{config → spec/support/config}/database.yml +0 -0
  118. data/spec/support/install.sh +43 -7
  119. data/spec/support/simplecov_helper.rb +9 -5
  120. data/spec/support/simplecov_quality_formatter.rb +10 -6
  121. data/spec/unit/apns_feedback_spec.rb +3 -3
  122. data/spec/unit/{adm → client/active_record/adm}/app_spec.rb +3 -3
  123. data/spec/unit/{adm → client/active_record/adm}/notification_spec.rb +5 -7
  124. data/spec/unit/client/active_record/apns/app_spec.rb +29 -0
  125. data/spec/unit/client/active_record/apns/feedback_spec.rb +9 -0
  126. data/spec/unit/client/active_record/apns/notification_spec.rb +231 -0
  127. data/spec/unit/client/active_record/app_spec.rb +30 -0
  128. data/spec/unit/client/active_record/gcm/app_spec.rb +4 -0
  129. data/spec/unit/{gcm → client/active_record/gcm}/notification_spec.rb +5 -7
  130. data/spec/unit/client/active_record/notification_spec.rb +21 -0
  131. data/spec/unit/client/active_record/wpns/app_spec.rb +4 -0
  132. data/spec/unit/client/active_record/wpns/notification_spec.rb +21 -0
  133. data/spec/unit/configuration_spec.rb +12 -5
  134. data/spec/unit/daemon/adm/delivery_spec.rb +66 -55
  135. data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +3 -3
  136. data/spec/unit/daemon/apns/delivery_spec.rb +90 -83
  137. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +22 -17
  138. data/spec/unit/daemon/app_runner_spec.rb +78 -186
  139. data/spec/unit/daemon/batch_spec.rb +52 -115
  140. data/spec/unit/daemon/delivery_spec.rb +15 -1
  141. data/spec/unit/daemon/dispatcher/http_spec.rb +3 -2
  142. data/spec/unit/daemon/dispatcher/tcp_spec.rb +10 -9
  143. data/spec/unit/daemon/dispatcher_loop_spec.rb +6 -24
  144. data/spec/unit/daemon/feeder_spec.rb +38 -39
  145. data/spec/unit/daemon/gcm/delivery_spec.rb +122 -101
  146. data/spec/unit/daemon/reflectable_spec.rb +2 -2
  147. data/spec/unit/daemon/retryable_error_spec.rb +1 -1
  148. data/spec/unit/daemon/service_config_methods_spec.rb +6 -3
  149. data/spec/unit/daemon/signal_handler_spec.rb +95 -0
  150. data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +48 -27
  151. data/spec/unit/daemon/store/active_record_spec.rb +38 -47
  152. data/spec/unit/daemon/tcp_connection_spec.rb +22 -34
  153. data/spec/unit/daemon/wpns/delivery_spec.rb +58 -50
  154. data/spec/unit/daemon_spec.rb +48 -82
  155. data/spec/unit/embed_spec.rb +6 -4
  156. data/spec/unit/logger_spec.rb +35 -43
  157. data/spec/unit/notification_shared.rb +9 -79
  158. data/spec/unit/push_spec.rb +6 -10
  159. data/spec/unit/reflection_spec.rb +25 -25
  160. data/spec/unit/rpush_spec.rb +1 -2
  161. data/spec/unit_spec_helper.rb +33 -88
  162. metadata +126 -76
  163. data/lib/rpush/TODO +0 -3
  164. data/lib/rpush/adm/app.rb +0 -15
  165. data/lib/rpush/adm/data_validator.rb +0 -11
  166. data/lib/rpush/adm/notification.rb +0 -29
  167. data/lib/rpush/apns/app.rb +0 -29
  168. data/lib/rpush/apns/binary_notification_validator.rb +0 -12
  169. data/lib/rpush/apns/device_token_format_validator.rb +0 -12
  170. data/lib/rpush/apns/feedback.rb +0 -16
  171. data/lib/rpush/apns/notification.rb +0 -84
  172. data/lib/rpush/app.rb +0 -18
  173. data/lib/rpush/daemon/apns/certificate_expired_error.rb +0 -20
  174. data/lib/rpush/daemon/apns/disconnection_error.rb +0 -20
  175. data/lib/rpush/daemon/dispatcher_loop_collection.rb +0 -33
  176. data/lib/rpush/daemon/too_many_requests_error.rb +0 -20
  177. data/lib/rpush/gcm/app.rb +0 -11
  178. data/lib/rpush/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +0 -11
  179. data/lib/rpush/gcm/notification.rb +0 -30
  180. data/lib/rpush/notification.rb +0 -69
  181. data/lib/rpush/notifier.rb +0 -52
  182. data/lib/rpush/payload_data_size_validator.rb +0 -10
  183. data/lib/rpush/railtie.rb +0 -11
  184. data/lib/rpush/registration_ids_count_validator.rb +0 -10
  185. data/lib/rpush/wpns/app.rb +0 -9
  186. data/lib/rpush/wpns/notification.rb +0 -26
  187. data/lib/tasks/cane.rake +0 -18
  188. data/lib/tasks/rpush.rake +0 -16
  189. data/spec/unit/apns/app_spec.rb +0 -29
  190. data/spec/unit/apns/feedback_spec.rb +0 -9
  191. data/spec/unit/apns/notification_spec.rb +0 -208
  192. data/spec/unit/app_spec.rb +0 -30
  193. data/spec/unit/daemon/apns/disconnection_error_spec.rb +0 -18
  194. data/spec/unit/daemon/dispatcher_loop_collection_spec.rb +0 -37
  195. data/spec/unit/daemon/interruptible_sleep_spec.rb +0 -68
  196. data/spec/unit/daemon/too_many_requests_error_spec.rb +0 -14
  197. data/spec/unit/gcm/app_spec.rb +0 -4
  198. data/spec/unit/notification_spec.rb +0 -15
  199. data/spec/unit/notifier_spec.rb +0 -49
  200. data/spec/unit/wpns/app_spec.rb +0 -4
  201. data/spec/unit/wpns/notification_spec.rb +0 -30
@@ -1,4 +1,5 @@
1
- require "unit_spec_helper"
1
+ require 'unit_spec_helper'
2
+ require 'rpush/daemon/store/active_record'
2
3
 
3
4
  describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
4
5
 
@@ -7,35 +8,39 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
7
8
  let(:poll) { 60 }
8
9
  let(:certificate) { double }
9
10
  let(:password) { double }
10
- let(:app) { double(:name => 'my_app', :password => password, :certificate => certificate, :environment => 'production') }
11
- let(:connection) { double(:connect => nil, :read => nil, :close => nil) }
12
- let(:logger) { double(:error => nil, :info => nil) }
11
+ let(:app) { double(name: 'my_app', password: password, certificate: certificate, environment: 'production') }
12
+ let(:connection) { double(connect: nil, read: nil, close: nil) }
13
+ let(:logger) { double(error: nil, info: nil) }
13
14
  let(:receiver) { Rpush::Daemon::Apns::FeedbackReceiver.new(app) }
14
15
  let(:feedback) { double }
15
- let(:sleeper) { double(Rpush::Daemon::InterruptibleSleep, :sleep => nil, :interrupt_sleep => nil) }
16
- let(:store) { double(Rpush::Daemon::Store::ActiveRecord,
17
- create_apns_feedback: feedback, release_connection: nil) }
16
+ let(:sleeper) { double(Rpush::Daemon::InterruptibleSleep, sleep: nil, start: nil, stop: nil) }
17
+ let(:store) { double(Rpush::Daemon::Store::ActiveRecord, create_apns_feedback: feedback, release_connection: nil) }
18
18
 
19
19
  before do
20
20
  Rpush.config.feedback_poll = poll
21
- Rpush::Daemon::InterruptibleSleep.stub(:new => sleeper)
22
- Rpush.stub(:logger => logger)
23
- Rpush::Daemon::TcpConnection.stub(:new => connection)
21
+ Rpush::Daemon::InterruptibleSleep.stub(new: sleeper)
22
+ Rpush.stub(logger: logger)
23
+ Rpush::Daemon::TcpConnection.stub(new: connection)
24
24
  receiver.instance_variable_set("@stop", false)
25
- Rpush::Daemon.stub(:store => store)
25
+ Rpush::Daemon.stub(store: store)
26
26
  end
27
27
 
28
28
  def double_connection_read_with_tuple
29
29
  connection.unstub(:read)
30
30
 
31
- def connection.read(bytes)
32
- if !@called
31
+ def connection.read(*)
32
+ unless @called
33
33
  @called = true
34
34
  "N\xE3\x84\r\x00 \x83OxfU\xEB\x9F\x84aJ\x05\xAD}\x00\xAF1\xE5\xCF\xE9:\xC3\xEA\a\x8F\x1D\xA4M*N\xB0\xCE\x17"
35
35
  end
36
36
  end
37
37
  end
38
38
 
39
+ it 'initializes the sleeper with the feedback polling duration' do
40
+ Rpush::Daemon::InterruptibleSleep.should_receive(:new).with(poll).and_return(sleeper)
41
+ Rpush::Daemon::Apns::FeedbackReceiver.new(app)
42
+ end
43
+
39
44
  it 'instantiates a new connection' do
40
45
  Rpush::Daemon::TcpConnection.should_receive(:new).with(app, host, port)
41
46
  receiver.check_for_feedback
@@ -63,7 +68,7 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
63
68
  end
64
69
 
65
70
  it 'creates the feedback' do
66
- Rpush::Daemon.store.should_receive(:create_apns_feedback).with(Time.at(1323533325), '834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17', app)
71
+ Rpush::Daemon.store.should_receive(:create_apns_feedback).with(Time.at(1_323_533_325), '834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17', app)
67
72
  double_connection_read_with_tuple
68
73
  receiver.check_for_feedback
69
74
  end
@@ -81,9 +86,9 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
81
86
  receiver.stub(:loop).and_yield
82
87
  end
83
88
 
84
- it 'sleeps for the feedback poll period' do
89
+ it 'sleeps' do
85
90
  receiver.stub(:check_for_feedback)
86
- sleeper.should_receive(:sleep).with(60).at_least(:once)
91
+ sleeper.should_receive(:sleep).at_least(:once)
87
92
  receiver.start
88
93
  end
89
94
 
@@ -96,7 +101,7 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
96
101
  describe 'stop' do
97
102
  it 'interrupts sleep when stopped' do
98
103
  receiver.stub(:check_for_feedback)
99
- sleeper.should_receive(:interrupt_sleep)
104
+ sleeper.should_receive(:stop)
100
105
  receiver.stop
101
106
  end
102
107
 
@@ -1,4 +1,5 @@
1
1
  require 'unit_spec_helper'
2
+ require 'rpush/daemon/store/active_record'
2
3
 
3
4
  module Rpush
4
5
  module AppRunnerSpecService
@@ -11,7 +12,7 @@ module Rpush
11
12
  extend ServiceConfigMethods
12
13
 
13
14
  class ServiceLoop
14
- def initialize(app)
15
+ def initialize(*)
15
16
  end
16
17
 
17
18
  def start
@@ -30,198 +31,104 @@ module Rpush
30
31
  end
31
32
  end
32
33
 
33
- describe Rpush::Daemon::AppRunner, 'stop' do
34
- let(:runner) { double }
35
- before { Rpush::Daemon::AppRunner.runners['app'] = runner }
36
- after { Rpush::Daemon::AppRunner.runners.clear }
37
-
38
- it 'stops all runners' do
39
- runner.should_receive(:stop)
40
- Rpush::Daemon::AppRunner.stop
41
- end
42
- end
43
-
44
34
  describe Rpush::Daemon::AppRunner, 'enqueue' do
45
- let(:runner) { double(:enqueue => nil) }
46
- let(:notification1) { double(:app_id => 1) }
47
- let(:notification2) { double(:app_id => 2) }
48
- let(:logger) { double(Rpush::Logger, :error => nil) }
35
+ let(:app) { double(id: 1, name: 'Test', connections: 1) }
36
+ let(:notification) { double(app_id: 1) }
37
+ let(:runner) { double(Rpush::Daemon::AppRunner, enqueue: nil, start: nil, stop: nil) }
38
+ let(:logger) { double(Rpush::Logger, error: nil, info: nil) }
49
39
 
50
40
  before do
51
- Rpush.stub(:logger => logger)
52
- Rpush::Daemon::AppRunner.runners[1] = runner
41
+ Rpush.stub(logger: logger)
42
+ Rpush::Daemon::ProcTitle.stub(:update)
43
+ Rpush::Daemon::AppRunner.stub(new: runner)
44
+ Rpush::Daemon::AppRunner.start_app(app)
53
45
  end
54
46
 
55
- after { Rpush::Daemon::AppRunner.runners.clear }
47
+ after { Rpush::Daemon::AppRunner.stop }
56
48
 
57
- it 'batches notifications by app' do
58
- batch = double.as_null_object
59
- Rpush::Daemon::Batch.stub(:new => batch)
60
- Rpush::Daemon::Batch.should_receive(:new).with([notification1])
61
- Rpush::Daemon::Batch.should_receive(:new).with([notification2])
62
- Rpush::Daemon::AppRunner.enqueue([notification1, notification2])
49
+ it 'enqueues notifications on the runner' do
50
+ runner.should_receive(:enqueue).with([notification])
51
+ Rpush::Daemon::AppRunner.enqueue([notification])
63
52
  end
64
53
 
65
- it 'enqueues each batch' do
66
- runner.should_receive(:enqueue).with(kind_of(Rpush::Daemon::Batch))
67
- Rpush::Daemon::AppRunner.enqueue([notification1])
68
- end
69
-
70
- it 'logs an error if there is no runner to deliver the notification' do
71
- notification1.stub(:app_id => 2, :id => 123)
72
- notification2.stub(:app_id => 2, :id => 456)
73
- logger.should_receive(:error).with("No such app '#{notification1.app_id}' for notifications 123, 456.")
74
- Rpush::Daemon::AppRunner.enqueue([notification1, notification2])
54
+ it 'starts the app if a runner does not exist' do
55
+ notification = double(app_id: 3)
56
+ new_app = double(Rpush::App, id: 3, name: 'NewApp', connections: 1)
57
+ Rpush::Daemon.store = double(app: new_app)
58
+ Rpush::Daemon::AppRunner.enqueue([notification])
59
+ Rpush::Daemon::AppRunner.app_running?(new_app).should be_true
75
60
  end
76
61
  end
77
62
 
78
- describe Rpush::Daemon::AppRunner, 'sync' do
79
- let(:app) { double(Rpush::AppRunnerSpecService::App, :name => 'test') }
80
- let(:new_app) { double(Rpush::AppRunnerSpecService::App, :name => 'new_test') }
81
- let(:runner) { double(:sync => nil, :stop => nil, :start => nil) }
82
- let(:logger) { double(Rpush::Logger, :error => nil, :warn => nil) }
83
- let(:queue) { Queue.new }
63
+ describe Rpush::Daemon::AppRunner, 'start_app' do
64
+ let(:app) { double(id: 1, name: 'test') }
65
+ let(:runner) { double(Rpush::Daemon::AppRunner, enqueue: nil, start: nil, stop: nil) }
66
+ let(:logger) { double(Rpush::Logger, error: nil, info: nil) }
84
67
 
85
68
  before do
86
- app.stub(:id => 1)
87
- new_app.stub(:id => 2)
88
- Queue.stub(:new => queue)
89
- Rpush::Daemon::AppRunner.runners[app.id] = runner
90
- Rpush::App.stub(:all => [app])
91
- Rpush.stub(:logger => logger)
92
- end
93
-
94
- after { Rpush::Daemon::AppRunner.runners.clear }
95
-
96
- it 'loads all apps' do
97
- Rpush::App.should_receive(:all)
98
- Rpush::Daemon::AppRunner.sync
99
- end
100
-
101
- it 'instructs existing runners to sync' do
102
- runner.should_receive(:sync).with(app)
103
- Rpush::Daemon::AppRunner.sync
104
- end
105
-
106
- it 'starts a runner for a new app' do
107
- Rpush::App.stub(:all => [app, new_app])
108
- new_runner = double
109
- Rpush::Daemon::AppRunner.should_receive(:new).with(new_app).and_return(new_runner)
110
- new_runner.should_receive(:start)
111
- Rpush::Daemon::AppRunner.sync
112
- end
113
-
114
- it 'deletes old runners' do
115
- Rpush::App.stub(:all => [])
116
- runner.should_receive(:stop)
117
- Rpush::Daemon::AppRunner.sync
69
+ Rpush.stub(logger: logger)
118
70
  end
119
71
 
120
72
  it 'logs an error if the runner could not be started' do
121
- Rpush::App.stub(:all => [app, new_app])
122
- new_runner = double
123
- Rpush::Daemon::AppRunner.should_receive(:new).with(new_app).and_return(new_runner)
124
- new_runner.stub(:start).and_raise(StandardError)
73
+ Rpush::Daemon::AppRunner.should_receive(:new).with(app).and_return(runner)
74
+ runner.stub(:start).and_raise(StandardError)
125
75
  Rpush.logger.should_receive(:error)
126
- Rpush::Daemon::AppRunner.sync
127
- end
128
-
129
- it 'reflects errors if the runner could not be started' do
130
- Rpush::App.stub(:all => [app, new_app])
131
- new_runner = double
132
- Rpush::Daemon::AppRunner.should_receive(:new).with(new_app).and_return(new_runner)
133
- e = StandardError.new
134
- new_runner.stub(:start).and_raise(e)
135
- Rpush::Daemon::AppRunner.should_receive(:reflect).with(:error, e)
136
- Rpush::Daemon::AppRunner.sync
76
+ Rpush::Daemon::AppRunner.start_app(app)
137
77
  end
138
78
  end
139
79
 
140
80
  describe Rpush::Daemon::AppRunner, 'debug' do
141
- let(:app) { double(Rpush::AppRunnerSpecService::App, :id => 1, :name => 'test', :connections => 1,
142
- :environment => 'development', :certificate => TEST_CERT, :service_name => 'app_runner_spec_service') }
143
- let(:logger) { double(Rpush::Logger, :info => nil) }
81
+ let(:app) do
82
+ double(Rpush::AppRunnerSpecService::App, id: 1, name: 'test', connections: 1,
83
+ environment: 'development', certificate: TEST_CERT, service_name: 'app_runner_spec_service')
84
+ end
85
+ let(:logger) { double(Rpush::Logger, info: nil) }
86
+ let(:store) { double(all_apps: [app], release_connection: nil) }
144
87
 
145
88
  before do
146
- Rpush::App.stub(:all => [app])
147
- Rpush::Daemon.stub(:config => {})
148
- Rpush.stub(:logger => logger)
149
- Rpush::Daemon::AppRunner.sync
89
+ Rpush::Daemon.stub(config: {}, store: store)
90
+ Rpush.stub(logger: logger)
91
+ Rpush::Daemon::AppRunner.start_app(app)
150
92
  end
151
93
 
152
- after { Rpush::Daemon::AppRunner.runners.clear }
94
+ after { Rpush::Daemon::AppRunner.stop_app(app.id) }
153
95
 
154
96
  it 'prints debug app states to the log' do
155
- Rpush.logger.should_receive(:info).with("\ntest:\n dispatchers: 1\n queued: 0\n batch size: 0\n batch processed: 0\n idle: true\n")
97
+ Rpush.logger.should_receive(:info).with(kind_of(String))
156
98
  Rpush::Daemon::AppRunner.debug
157
99
  end
158
100
  end
159
101
 
160
- describe Rpush::Daemon::AppRunner, 'idle' do
161
- let(:app) { double(Rpush::AppRunnerSpecService::App, :name => 'test', :connections => 1,
162
- :environment => 'development', :certificate => TEST_CERT, :id => 1,
163
- :service_name => 'app_runner_spec_service') }
164
- let(:logger) { double(Rpush::Logger, :info => nil) }
165
-
166
- before do
167
- Rpush::App.stub(:all => [app])
168
- Rpush.stub(:logger => logger)
169
- Rpush::Daemon::AppRunner.sync
170
- end
171
-
172
- after { Rpush::Daemon::AppRunner.runners.clear }
173
-
174
- it 'returns idle runners' do
175
- runner = Rpush::Daemon::AppRunner.runners[app.id]
176
- Rpush::Daemon::AppRunner.idle.should eq [runner]
177
- end
178
- end
179
-
180
- describe Rpush::Daemon::AppRunner, 'wait' do
181
- let(:app) { double(Rpush::AppRunnerSpecService::App, :id => 1, :name => 'test',
182
- :connections => 1, :environment => 'development', :certificate => TEST_CERT,
183
- :service_name => 'app_runner_spec_service') }
184
- let(:logger) { double(Rpush::Logger, :info => nil) }
185
-
186
- before do
187
- Rpush::App.stub(:all => [app])
188
- Rpush.stub(:logger => logger)
189
- Rpush::Daemon::AppRunner.sync
190
- end
191
-
192
- after { Rpush::Daemon::AppRunner.runners.clear }
193
-
194
- it 'waits until all runners are idle' do
195
- Rpush::Daemon::AppRunner.runners.count.should eq 1
196
- Timeout.timeout(5) { Rpush::Daemon::AppRunner.wait }
197
- end
198
- end
199
-
200
102
  describe Rpush::Daemon::AppRunner do
201
- let(:app) { double(Rpush::AppRunnerSpecService::App, :environment => :sandbox,
202
- :connections => 1, :service_name => 'app_runner_spec_service',
203
- :name => 'test') }
103
+ let(:app) do
104
+ double(Rpush::AppRunnerSpecService::App, environment: :sandbox,
105
+ connections: 1, service_name: 'app_runner_spec_service', name: 'test')
106
+ end
204
107
  let(:runner) { Rpush::Daemon::AppRunner.new(app) }
205
- let(:logger) { double(Rpush::Logger, :info => nil) }
108
+ let(:logger) { double(Rpush::Logger, info: nil) }
206
109
  let(:queue) { Queue.new }
207
- let(:dispatcher_loop_collection) { Rpush::Daemon::DispatcherLoopCollection.new }
208
- let(:service_loop) { double(Rpush::Daemon::AppRunnerSpecService::ServiceLoop,
209
- :start => nil, :stop => nil) }
110
+ let(:service_loop) { double(Rpush::Daemon::AppRunnerSpecService::ServiceLoop, start: nil, stop: nil) }
111
+ let(:dispatcher_loop) { double(Rpush::Daemon::DispatcherLoop, stop: nil, start: nil) }
210
112
  let(:store) { double(Rpush::Daemon::Store::ActiveRecord, release_connection: nil) }
211
113
 
212
114
  before do
115
+ Rpush::Daemon::DispatcherLoop.stub(new: dispatcher_loop)
213
116
  Rpush::Daemon.stub(store: store)
214
- Rpush::Daemon::AppRunnerSpecService::ServiceLoop.stub(:new => service_loop)
215
- Queue.stub(:new => queue)
216
- Rpush.stub(:logger => logger)
217
- Rpush::Daemon::DispatcherLoopCollection.stub(:new => dispatcher_loop_collection)
117
+ Rpush::Daemon::AppRunnerSpecService::ServiceLoop.stub(new: service_loop)
118
+ Queue.stub(new: queue)
119
+ Rpush.stub(logger: logger)
218
120
  end
219
121
 
220
122
  describe 'start' do
221
123
  it 'starts a delivery dispatcher for each connection' do
222
- app.stub(:connections => 2)
124
+ app.stub(connections: 2)
125
+ runner.start
126
+ runner.num_dispatcher_loops.should eq 2
127
+ end
128
+
129
+ it 'starts the dispatcher loop' do
130
+ dispatcher_loop.should_receive(:start)
223
131
  runner.start
224
- runner.num_dispatchers.should eq 2
225
132
  end
226
133
 
227
134
  it 'starts the loops' do
@@ -232,16 +139,32 @@ describe Rpush::Daemon::AppRunner do
232
139
 
233
140
  describe 'enqueue' do
234
141
  let(:notification) { double }
235
- let(:batch) { double(:notifications => [notification]) }
236
142
 
237
143
  it 'enqueues the batch' do
238
- queue.should_receive(:push).with([notification, batch])
239
- runner.enqueue(batch)
144
+ queue.should_receive(:push) do |queue_payload|
145
+ queue_payload.notification.should eq notification
146
+ queue_payload.batch.should_not be_nil
147
+ end
148
+ runner.enqueue([notification])
240
149
  end
241
150
 
242
151
  it 'reflects the notification has been enqueued' do
243
152
  runner.should_receive(:reflect).with(:notification_enqueued, notification)
244
- runner.enqueue(batch)
153
+ runner.enqueue([notification])
154
+ end
155
+
156
+ describe 'a service that batches deliveries' do
157
+ before do
158
+ runner.send(:service).stub(batch_deliveries?: true)
159
+ end
160
+
161
+ describe '1 notification with more than one dispatcher loop' do
162
+ it 'does not raise ArgumentError: invalid slice size' do
163
+ # https://github.com/rpush/rpush/issues/57
164
+ runner.stub(:num_dispatcher_loops).and_return(2)
165
+ runner.enqueue([notification])
166
+ end
167
+ end
245
168
  end
246
169
  end
247
170
 
@@ -249,7 +172,7 @@ describe Rpush::Daemon::AppRunner do
249
172
  before { runner.start }
250
173
 
251
174
  it 'stops the delivery dispatchers' do
252
- dispatcher_loop_collection.should_receive(:stop)
175
+ dispatcher_loop.should_receive(:stop)
253
176
  runner.stop
254
177
  end
255
178
 
@@ -258,35 +181,4 @@ describe Rpush::Daemon::AppRunner do
258
181
  runner.stop
259
182
  end
260
183
  end
261
-
262
- describe 'idle?' do
263
- it 'is idle if all notifications have been processed' do
264
- runner.batch = double(:complete? => true)
265
- runner.idle?.should be_true
266
- end
267
-
268
- it 'is idle if the runner has no associated batch' do
269
- runner.batch = nil
270
- runner.idle?.should be_true
271
- end
272
-
273
- it 'is not idle if not all notifications have been processed' do
274
- runner.batch = double(:complete? => false)
275
- runner.idle?.should be_false
276
- end
277
- end
278
-
279
- describe 'sync' do
280
- before { runner.start }
281
-
282
- it 'reduces the number of dispatchers if needed' do
283
- app.stub(:connections => 0)
284
- expect { runner.sync(app) }.to change(runner, :num_dispatchers).to(0)
285
- end
286
-
287
- it 'increases the number of dispatchers if needed' do
288
- app.stub(:connections => 2)
289
- expect { runner.sync(app) }.to change(runner, :num_dispatchers).to(2)
290
- end
291
- end
292
184
  end