rpush 1.0.0-java → 2.0.0-java

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