rpush 1.0.0 → 2.0.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +12 -14
- data/bin/rpush +11 -2
- data/lib/generators/rpush_generator.rb +2 -0
- data/lib/generators/templates/add_adm.rb +5 -5
- data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +1 -1
- data/lib/generators/templates/add_app_to_rapns.rb +2 -2
- data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +1 -1
- data/lib/generators/templates/add_gcm.rb +32 -32
- data/lib/generators/templates/add_rpush.rb +67 -67
- data/lib/generators/templates/add_wpns.rb +2 -2
- data/lib/generators/templates/create_rapns_apps.rb +5 -5
- data/lib/generators/templates/create_rapns_feedback.rb +2 -2
- data/lib/generators/templates/create_rapns_notifications.rb +15 -15
- data/lib/generators/templates/rpush.rb +10 -7
- data/lib/generators/templates/rpush_2_0_0_updates.rb +23 -0
- data/lib/rpush.rb +4 -28
- data/lib/rpush/client/active_model.rb +21 -0
- data/lib/rpush/client/active_model/adm/app.rb +23 -0
- data/lib/rpush/client/active_model/adm/data_validator.rb +14 -0
- data/lib/rpush/client/active_model/adm/notification.rb +28 -0
- data/lib/rpush/client/active_model/apns/app.rb +37 -0
- data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +16 -0
- data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +14 -0
- data/lib/rpush/client/active_model/apns/notification.rb +90 -0
- data/lib/rpush/client/active_model/gcm/app.rb +19 -0
- data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +14 -0
- data/lib/rpush/client/active_model/gcm/notification.rb +31 -0
- data/lib/rpush/client/active_model/notification.rb +26 -0
- data/lib/rpush/client/active_model/payload_data_size_validator.rb +13 -0
- data/lib/rpush/client/active_model/registration_ids_count_validator.rb +13 -0
- data/lib/rpush/client/active_model/wpns/app.rb +13 -0
- data/lib/rpush/client/active_model/wpns/notification.rb +17 -0
- data/lib/rpush/client/active_record.rb +19 -0
- data/lib/rpush/client/active_record/adm/app.rb +11 -0
- data/lib/rpush/client/active_record/adm/notification.rb +11 -0
- data/lib/rpush/client/active_record/apns/app.rb +11 -0
- data/lib/rpush/client/active_record/apns/feedback.rb +20 -0
- data/lib/rpush/client/active_record/apns/notification.rb +46 -0
- data/lib/rpush/client/active_record/app.rb +17 -0
- data/lib/rpush/client/active_record/gcm/app.rb +11 -0
- data/lib/rpush/client/active_record/gcm/notification.rb +11 -0
- data/lib/rpush/client/active_record/notification.rb +38 -0
- data/lib/rpush/client/active_record/wpns/app.rb +11 -0
- data/lib/rpush/client/active_record/wpns/notification.rb +11 -0
- data/lib/rpush/client/redis.rb +35 -0
- data/lib/rpush/client/redis/adm/app.rb +14 -0
- data/lib/rpush/client/redis/adm/notification.rb +11 -0
- data/lib/rpush/client/redis/apns/app.rb +11 -0
- data/lib/rpush/client/redis/apns/feedback.rb +20 -0
- data/lib/rpush/client/redis/apns/notification.rb +11 -0
- data/lib/rpush/client/redis/app.rb +22 -0
- data/lib/rpush/client/redis/gcm/app.rb +11 -0
- data/lib/rpush/client/redis/gcm/notification.rb +11 -0
- data/lib/rpush/client/redis/notification.rb +68 -0
- data/lib/rpush/client/redis/wpns/app.rb +11 -0
- data/lib/rpush/client/redis/wpns/notification.rb +11 -0
- data/lib/rpush/configuration.rb +27 -6
- data/lib/rpush/daemon.rb +36 -56
- data/lib/rpush/daemon/adm/delivery.rb +50 -52
- data/lib/rpush/daemon/apns.rb +6 -5
- data/lib/rpush/daemon/apns/delivery.rb +20 -44
- data/lib/rpush/daemon/apns/feedback_receiver.rb +11 -8
- data/lib/rpush/daemon/app_runner.rb +67 -60
- data/lib/rpush/daemon/batch.rb +54 -40
- data/lib/rpush/daemon/delivery.rb +13 -3
- data/lib/rpush/daemon/delivery_error.rb +10 -2
- data/lib/rpush/daemon/dispatcher/apns_tcp.rb +106 -0
- data/lib/rpush/daemon/dispatcher/http.rb +3 -3
- data/lib/rpush/daemon/dispatcher/tcp.rb +3 -3
- data/lib/rpush/daemon/dispatcher_loop.rb +15 -6
- data/lib/rpush/daemon/errors.rb +18 -0
- data/lib/rpush/daemon/feeder.rb +28 -39
- data/lib/rpush/daemon/gcm/delivery.rb +19 -20
- data/lib/rpush/daemon/interruptible_sleep.rb +26 -45
- data/lib/rpush/daemon/loggable.rb +2 -4
- data/lib/rpush/daemon/proc_title.rb +16 -0
- data/lib/rpush/daemon/queue_payload.rb +12 -0
- data/lib/rpush/daemon/reflectable.rb +3 -5
- data/lib/rpush/daemon/retry_header_parser.rb +6 -6
- data/lib/rpush/daemon/ring_buffer.rb +16 -0
- data/lib/rpush/daemon/service_config_methods.rb +23 -7
- data/lib/rpush/daemon/signal_handler.rb +51 -0
- data/lib/rpush/daemon/store/active_record.rb +71 -38
- data/lib/rpush/daemon/store/active_record/reconnectable.rb +15 -15
- data/lib/rpush/daemon/store/interface.rb +19 -0
- data/lib/rpush/daemon/store/redis.rb +149 -0
- data/lib/rpush/daemon/tcp_connection.rb +6 -11
- data/lib/rpush/daemon/wpns/delivery.rb +21 -30
- data/lib/rpush/deprecatable.rb +4 -3
- data/lib/rpush/deprecation.rb +7 -10
- data/lib/rpush/embed.rb +7 -2
- data/lib/rpush/logger.rb +11 -15
- data/lib/rpush/push.rb +0 -1
- data/lib/rpush/reflection.rb +6 -12
- data/lib/rpush/version.rb +1 -1
- data/lib/tasks/quality.rake +34 -0
- data/spec/.rubocop.yml +4 -0
- data/spec/functional/adm_spec.rb +3 -6
- data/spec/functional/apns_spec.rb +118 -24
- data/spec/functional/embed_spec.rb +22 -20
- data/spec/functional/gcm_spec.rb +4 -7
- data/spec/functional/new_app_spec.rb +61 -0
- data/spec/functional/retry_spec.rb +46 -0
- data/spec/functional/wpns_spec.rb +3 -6
- data/spec/functional_spec_helper.rb +26 -0
- data/spec/integration/rpush_spec.rb +13 -0
- data/spec/integration/support/gcm_success_response.json +1 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/support/active_record_setup.rb +48 -0
- data/{config → spec/support/config}/database.yml +0 -0
- data/spec/support/install.sh +43 -7
- data/spec/support/simplecov_helper.rb +9 -5
- data/spec/support/simplecov_quality_formatter.rb +10 -6
- data/spec/unit/apns_feedback_spec.rb +3 -3
- data/spec/unit/{adm → client/active_record/adm}/app_spec.rb +3 -3
- data/spec/unit/{adm → client/active_record/adm}/notification_spec.rb +5 -7
- data/spec/unit/client/active_record/apns/app_spec.rb +29 -0
- data/spec/unit/client/active_record/apns/feedback_spec.rb +9 -0
- data/spec/unit/client/active_record/apns/notification_spec.rb +231 -0
- data/spec/unit/client/active_record/app_spec.rb +30 -0
- data/spec/unit/client/active_record/gcm/app_spec.rb +4 -0
- data/spec/unit/{gcm → client/active_record/gcm}/notification_spec.rb +5 -7
- data/spec/unit/client/active_record/notification_spec.rb +15 -0
- data/spec/unit/client/active_record/wpns/app_spec.rb +4 -0
- data/spec/unit/client/active_record/wpns/notification_spec.rb +21 -0
- data/spec/unit/configuration_spec.rb +12 -5
- data/spec/unit/daemon/adm/delivery_spec.rb +57 -54
- data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +3 -3
- data/spec/unit/daemon/apns/delivery_spec.rb +90 -83
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +24 -17
- data/spec/unit/daemon/app_runner_spec.rb +66 -123
- data/spec/unit/daemon/batch_spec.rb +52 -115
- data/spec/unit/daemon/delivery_spec.rb +15 -1
- data/spec/unit/daemon/dispatcher/http_spec.rb +3 -2
- data/spec/unit/daemon/dispatcher/tcp_spec.rb +10 -9
- data/spec/unit/daemon/dispatcher_loop_spec.rb +7 -12
- data/spec/unit/daemon/feeder_spec.rb +40 -39
- data/spec/unit/daemon/gcm/delivery_spec.rb +108 -89
- data/spec/unit/daemon/reflectable_spec.rb +2 -2
- data/spec/unit/daemon/retryable_error_spec.rb +1 -1
- data/spec/unit/daemon/service_config_methods_spec.rb +6 -3
- data/spec/unit/daemon/signal_handler_spec.rb +72 -0
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +9 -9
- data/spec/unit/daemon/store/active_record_spec.rb +38 -47
- data/spec/unit/daemon/tcp_connection_spec.rb +22 -34
- data/spec/unit/daemon/too_many_requests_error_spec.rb +1 -1
- data/spec/unit/daemon/wpns/delivery_spec.rb +61 -50
- data/spec/unit/daemon_spec.rb +46 -81
- data/spec/unit/embed_spec.rb +4 -2
- data/spec/unit/logger_spec.rb +30 -40
- data/spec/unit/notification_shared.rb +9 -79
- data/spec/unit/push_spec.rb +3 -8
- data/spec/unit/reflection_spec.rb +25 -25
- data/spec/unit/rpush_spec.rb +1 -2
- data/spec/unit_spec_helper.rb +33 -88
- metadata +119 -67
- data/lib/rpush/TODO +0 -3
- data/lib/rpush/adm/app.rb +0 -15
- data/lib/rpush/adm/data_validator.rb +0 -11
- data/lib/rpush/adm/notification.rb +0 -29
- data/lib/rpush/apns/app.rb +0 -29
- data/lib/rpush/apns/binary_notification_validator.rb +0 -12
- data/lib/rpush/apns/device_token_format_validator.rb +0 -12
- data/lib/rpush/apns/feedback.rb +0 -16
- data/lib/rpush/apns/notification.rb +0 -84
- data/lib/rpush/app.rb +0 -18
- data/lib/rpush/daemon/apns/certificate_expired_error.rb +0 -20
- data/lib/rpush/daemon/apns/disconnection_error.rb +0 -20
- data/lib/rpush/gcm/app.rb +0 -11
- data/lib/rpush/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +0 -11
- data/lib/rpush/gcm/notification.rb +0 -30
- data/lib/rpush/notification.rb +0 -69
- data/lib/rpush/notifier.rb +0 -52
- data/lib/rpush/payload_data_size_validator.rb +0 -10
- data/lib/rpush/railtie.rb +0 -11
- data/lib/rpush/registration_ids_count_validator.rb +0 -10
- data/lib/rpush/wpns/app.rb +0 -9
- data/lib/rpush/wpns/notification.rb +0 -26
- data/lib/tasks/cane.rake +0 -18
- data/lib/tasks/rpush.rake +0 -16
- data/spec/unit/apns/app_spec.rb +0 -29
- data/spec/unit/apns/feedback_spec.rb +0 -9
- data/spec/unit/apns/notification_spec.rb +0 -208
- data/spec/unit/app_spec.rb +0 -30
- data/spec/unit/daemon/apns/disconnection_error_spec.rb +0 -18
- data/spec/unit/daemon/interruptible_sleep_spec.rb +0 -68
- data/spec/unit/gcm/app_spec.rb +0 -4
- data/spec/unit/notification_spec.rb +0 -15
- data/spec/unit/notifier_spec.rb +0 -49
- data/spec/unit/wpns/app_spec.rb +0 -4
- data/spec/unit/wpns/notification_spec.rb +0 -30
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
require
|
|
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,41 @@ 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(:
|
|
11
|
-
let(:connection) { double(:
|
|
12
|
-
let(:logger) { double(:
|
|
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, :
|
|
16
|
-
let(:store)
|
|
17
|
-
|
|
16
|
+
let(:sleeper) { double(Rpush::Daemon::InterruptibleSleep, sleep: nil, start: nil, stop: nil) }
|
|
17
|
+
let(:store) do double(Rpush::Daemon::Store::ActiveRecord,
|
|
18
|
+
create_apns_feedback: feedback, release_connection: nil)
|
|
19
|
+
end
|
|
18
20
|
|
|
19
21
|
before do
|
|
20
22
|
Rpush.config.feedback_poll = poll
|
|
21
|
-
Rpush::Daemon::InterruptibleSleep.stub(:
|
|
22
|
-
Rpush.stub(:
|
|
23
|
-
Rpush::Daemon::TcpConnection.stub(:
|
|
23
|
+
Rpush::Daemon::InterruptibleSleep.stub(new: sleeper)
|
|
24
|
+
Rpush.stub(logger: logger)
|
|
25
|
+
Rpush::Daemon::TcpConnection.stub(new: connection)
|
|
24
26
|
receiver.instance_variable_set("@stop", false)
|
|
25
|
-
Rpush::Daemon.stub(:
|
|
27
|
+
Rpush::Daemon.stub(store: store)
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def double_connection_read_with_tuple
|
|
29
31
|
connection.unstub(:read)
|
|
30
32
|
|
|
31
|
-
def connection.read(
|
|
32
|
-
|
|
33
|
+
def connection.read(*)
|
|
34
|
+
unless @called
|
|
33
35
|
@called = true
|
|
34
36
|
"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
37
|
end
|
|
36
38
|
end
|
|
37
39
|
end
|
|
38
40
|
|
|
41
|
+
it 'initializes the sleeper with the feedback polling duration' do
|
|
42
|
+
Rpush::Daemon::InterruptibleSleep.should_receive(:new).with(poll).and_return(sleeper)
|
|
43
|
+
Rpush::Daemon::Apns::FeedbackReceiver.new(app)
|
|
44
|
+
end
|
|
45
|
+
|
|
39
46
|
it 'instantiates a new connection' do
|
|
40
47
|
Rpush::Daemon::TcpConnection.should_receive(:new).with(app, host, port)
|
|
41
48
|
receiver.check_for_feedback
|
|
@@ -63,7 +70,7 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
|
|
|
63
70
|
end
|
|
64
71
|
|
|
65
72
|
it 'creates the feedback' do
|
|
66
|
-
Rpush::Daemon.store.should_receive(:create_apns_feedback).with(Time.at(
|
|
73
|
+
Rpush::Daemon.store.should_receive(:create_apns_feedback).with(Time.at(1_323_533_325), '834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17', app)
|
|
67
74
|
double_connection_read_with_tuple
|
|
68
75
|
receiver.check_for_feedback
|
|
69
76
|
end
|
|
@@ -81,9 +88,9 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
|
|
|
81
88
|
receiver.stub(:loop).and_yield
|
|
82
89
|
end
|
|
83
90
|
|
|
84
|
-
it 'sleeps
|
|
91
|
+
it 'sleeps' do
|
|
85
92
|
receiver.stub(:check_for_feedback)
|
|
86
|
-
sleeper.should_receive(:sleep).
|
|
93
|
+
sleeper.should_receive(:sleep).at_least(:once)
|
|
87
94
|
receiver.start
|
|
88
95
|
end
|
|
89
96
|
|
|
@@ -96,7 +103,7 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
|
|
|
96
103
|
describe 'stop' do
|
|
97
104
|
it 'interrupts sleep when stopped' do
|
|
98
105
|
receiver.stub(:check_for_feedback)
|
|
99
|
-
sleeper.should_receive(:
|
|
106
|
+
sleeper.should_receive(:stop)
|
|
100
107
|
receiver.stop
|
|
101
108
|
end
|
|
102
109
|
|
|
@@ -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(
|
|
15
|
+
def initialize(*)
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def start
|
|
@@ -42,69 +43,63 @@ describe Rpush::Daemon::AppRunner, 'stop' do
|
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
describe Rpush::Daemon::AppRunner, 'enqueue' do
|
|
45
|
-
let(:runner) { double(:
|
|
46
|
-
let(:notification1) { double(:
|
|
47
|
-
let(:notification2) { double(:
|
|
48
|
-
let(:logger) { double(Rpush::Logger, :
|
|
46
|
+
let(:runner) { double(enqueue: nil) }
|
|
47
|
+
let(:notification1) { double(app_id: 1) }
|
|
48
|
+
let(:notification2) { double(app_id: 2) }
|
|
49
|
+
let(:logger) { double(Rpush::Logger, error: nil, info: nil) }
|
|
49
50
|
|
|
50
51
|
before do
|
|
51
|
-
Rpush.stub(:
|
|
52
|
+
Rpush.stub(logger: logger)
|
|
53
|
+
Rpush::Daemon::ProcTitle.stub(:update)
|
|
52
54
|
Rpush::Daemon::AppRunner.runners[1] = runner
|
|
55
|
+
Rpush::Daemon::AppRunner.runners[2] = runner
|
|
53
56
|
end
|
|
54
57
|
|
|
55
58
|
after { Rpush::Daemon::AppRunner.runners.clear }
|
|
56
59
|
|
|
57
|
-
it '
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Rpush::Daemon::Batch.should_receive(:new).with([notification1])
|
|
61
|
-
Rpush::Daemon::Batch.should_receive(:new).with([notification2])
|
|
60
|
+
it 'enqueues notifications on each runner' do
|
|
61
|
+
runner.should_receive(:enqueue).with([notification1])
|
|
62
|
+
runner.should_receive(:enqueue).with([notification2])
|
|
62
63
|
Rpush::Daemon::AppRunner.enqueue([notification1, notification2])
|
|
63
64
|
end
|
|
64
65
|
|
|
65
|
-
it '
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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])
|
|
66
|
+
it 'syncs the app if a runner does not exist' do
|
|
67
|
+
Rpush::Daemon::AppRunner.runners[3].should be_nil
|
|
68
|
+
notification = double(app_id: 3)
|
|
69
|
+
app = double(Rpush::App, id: 3, connections: 1, service_name: 'app_runner_spec_service', environment: 'sandbox', certificate: TEST_CERT, password: nil, name: 'test')
|
|
70
|
+
Rpush::Daemon.store = double(app: app)
|
|
71
|
+
Rpush::Daemon::AppRunner.enqueue([notification])
|
|
72
|
+
Rpush::Daemon::AppRunner.runners[3].should_not be_nil
|
|
75
73
|
end
|
|
76
74
|
end
|
|
77
75
|
|
|
78
76
|
describe Rpush::Daemon::AppRunner, 'sync' do
|
|
79
|
-
let(:app) { double(Rpush::AppRunnerSpecService::App, :
|
|
80
|
-
let(:new_app) { double(Rpush::AppRunnerSpecService::App, :
|
|
81
|
-
let(:runner) { double(:
|
|
82
|
-
let(:logger) { double(Rpush::Logger, :
|
|
77
|
+
let(:app) { double(Rpush::AppRunnerSpecService::App, name: 'test') }
|
|
78
|
+
let(:new_app) { double(Rpush::AppRunnerSpecService::App, name: 'new_test') }
|
|
79
|
+
let(:runner) { double(sync: nil, stop: nil, start: nil) }
|
|
80
|
+
let(:logger) { double(Rpush::Logger, error: nil, warn: nil) }
|
|
83
81
|
let(:queue) { Queue.new }
|
|
82
|
+
let(:store) { double(all_apps: [app]) }
|
|
84
83
|
|
|
85
84
|
before do
|
|
86
|
-
app.stub(:
|
|
87
|
-
new_app.stub(:
|
|
88
|
-
Queue.stub(:
|
|
85
|
+
app.stub(id: 1)
|
|
86
|
+
new_app.stub(id: 2)
|
|
87
|
+
Queue.stub(new: queue)
|
|
89
88
|
Rpush::Daemon::AppRunner.runners[app.id] = runner
|
|
90
|
-
Rpush
|
|
91
|
-
Rpush.stub(:
|
|
89
|
+
Rpush.stub(logger: logger)
|
|
90
|
+
Rpush::Daemon.stub(store: store)
|
|
91
|
+
Rpush::Daemon::ProcTitle.stub(:update)
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
after { Rpush::Daemon::AppRunner.runners.clear }
|
|
95
95
|
|
|
96
|
-
it 'loads all apps' do
|
|
97
|
-
Rpush::App.should_receive(:all)
|
|
98
|
-
Rpush::Daemon::AppRunner.sync
|
|
99
|
-
end
|
|
100
|
-
|
|
101
96
|
it 'instructs existing runners to sync' do
|
|
102
97
|
runner.should_receive(:sync).with(app)
|
|
103
98
|
Rpush::Daemon::AppRunner.sync
|
|
104
99
|
end
|
|
105
100
|
|
|
106
101
|
it 'starts a runner for a new app' do
|
|
107
|
-
|
|
102
|
+
store.stub(all_apps: [app, new_app])
|
|
108
103
|
new_runner = double
|
|
109
104
|
Rpush::Daemon::AppRunner.should_receive(:new).with(new_app).and_return(new_runner)
|
|
110
105
|
new_runner.should_receive(:start)
|
|
@@ -112,13 +107,13 @@ describe Rpush::Daemon::AppRunner, 'sync' do
|
|
|
112
107
|
end
|
|
113
108
|
|
|
114
109
|
it 'deletes old runners' do
|
|
115
|
-
|
|
110
|
+
store.stub(all_apps: [])
|
|
116
111
|
runner.should_receive(:stop)
|
|
117
112
|
Rpush::Daemon::AppRunner.sync
|
|
118
113
|
end
|
|
119
114
|
|
|
120
115
|
it 'logs an error if the runner could not be started' do
|
|
121
|
-
|
|
116
|
+
store.stub(all_apps: [app, new_app])
|
|
122
117
|
new_runner = double
|
|
123
118
|
Rpush::Daemon::AppRunner.should_receive(:new).with(new_app).and_return(new_runner)
|
|
124
119
|
new_runner.stub(:start).and_raise(StandardError)
|
|
@@ -127,7 +122,7 @@ describe Rpush::Daemon::AppRunner, 'sync' do
|
|
|
127
122
|
end
|
|
128
123
|
|
|
129
124
|
it 'reflects errors if the runner could not be started' do
|
|
130
|
-
|
|
125
|
+
store.stub(all_apps: [app, new_app])
|
|
131
126
|
new_runner = double
|
|
132
127
|
Rpush::Daemon::AppRunner.should_receive(:new).with(new_app).and_return(new_runner)
|
|
133
128
|
e = StandardError.new
|
|
@@ -138,90 +133,53 @@ describe Rpush::Daemon::AppRunner, 'sync' do
|
|
|
138
133
|
end
|
|
139
134
|
|
|
140
135
|
describe Rpush::Daemon::AppRunner, 'debug' do
|
|
141
|
-
let(:app)
|
|
142
|
-
|
|
143
|
-
|
|
136
|
+
let(:app) do double(Rpush::AppRunnerSpecService::App, id: 1, name: 'test', connections: 1,
|
|
137
|
+
environment: 'development', certificate: TEST_CERT, service_name: 'app_runner_spec_service')
|
|
138
|
+
end
|
|
139
|
+
let(:logger) { double(Rpush::Logger, info: nil) }
|
|
140
|
+
let(:store) { double(all_apps: [app]) }
|
|
144
141
|
|
|
145
142
|
before do
|
|
146
|
-
Rpush::
|
|
147
|
-
Rpush
|
|
148
|
-
Rpush.stub(:logger => logger)
|
|
143
|
+
Rpush::Daemon.stub(config: {}, store: store)
|
|
144
|
+
Rpush.stub(logger: logger)
|
|
149
145
|
Rpush::Daemon::AppRunner.sync
|
|
150
146
|
end
|
|
151
147
|
|
|
152
148
|
after { Rpush::Daemon::AppRunner.runners.clear }
|
|
153
149
|
|
|
154
150
|
it 'prints debug app states to the log' do
|
|
155
|
-
Rpush.logger.should_receive(:info).with(
|
|
151
|
+
Rpush.logger.should_receive(:info).with(kind_of(String))
|
|
156
152
|
Rpush::Daemon::AppRunner.debug
|
|
157
153
|
end
|
|
158
154
|
end
|
|
159
155
|
|
|
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
156
|
describe Rpush::Daemon::AppRunner do
|
|
201
|
-
let(:app)
|
|
202
|
-
|
|
203
|
-
|
|
157
|
+
let(:app) do double(Rpush::AppRunnerSpecService::App, environment: :sandbox,
|
|
158
|
+
connections: 1, service_name: 'app_runner_spec_service',
|
|
159
|
+
name: 'test')
|
|
160
|
+
end
|
|
204
161
|
let(:runner) { Rpush::Daemon::AppRunner.new(app) }
|
|
205
|
-
let(:logger) { double(Rpush::Logger, :
|
|
162
|
+
let(:logger) { double(Rpush::Logger, info: nil) }
|
|
206
163
|
let(:queue) { Queue.new }
|
|
207
164
|
let(:dispatcher_loop_collection) { Rpush::Daemon::DispatcherLoopCollection.new }
|
|
208
|
-
let(:service_loop)
|
|
209
|
-
|
|
165
|
+
let(:service_loop) do double(Rpush::Daemon::AppRunnerSpecService::ServiceLoop,
|
|
166
|
+
start: nil, stop: nil)
|
|
167
|
+
end
|
|
210
168
|
let(:store) { double(Rpush::Daemon::Store::ActiveRecord, release_connection: nil) }
|
|
211
169
|
|
|
212
170
|
before do
|
|
213
171
|
Rpush::Daemon.stub(store: store)
|
|
214
|
-
Rpush::Daemon::AppRunnerSpecService::ServiceLoop.stub(:
|
|
215
|
-
Queue.stub(:
|
|
216
|
-
Rpush.stub(:
|
|
217
|
-
Rpush::Daemon::DispatcherLoopCollection.stub(:
|
|
172
|
+
Rpush::Daemon::AppRunnerSpecService::ServiceLoop.stub(new: service_loop)
|
|
173
|
+
Queue.stub(new: queue)
|
|
174
|
+
Rpush.stub(logger: logger)
|
|
175
|
+
Rpush::Daemon::DispatcherLoopCollection.stub(new: dispatcher_loop_collection)
|
|
218
176
|
end
|
|
219
177
|
|
|
220
178
|
describe 'start' do
|
|
221
179
|
it 'starts a delivery dispatcher for each connection' do
|
|
222
|
-
app.stub(:
|
|
180
|
+
app.stub(connections: 2)
|
|
223
181
|
runner.start
|
|
224
|
-
runner.
|
|
182
|
+
runner.num_dispatcher_loops.should eq 2
|
|
225
183
|
end
|
|
226
184
|
|
|
227
185
|
it 'starts the loops' do
|
|
@@ -232,16 +190,18 @@ describe Rpush::Daemon::AppRunner do
|
|
|
232
190
|
|
|
233
191
|
describe 'enqueue' do
|
|
234
192
|
let(:notification) { double }
|
|
235
|
-
let(:batch) { double(:notifications => [notification]) }
|
|
236
193
|
|
|
237
194
|
it 'enqueues the batch' do
|
|
238
|
-
queue.should_receive(:push)
|
|
239
|
-
|
|
195
|
+
queue.should_receive(:push) do |queue_payload|
|
|
196
|
+
queue_payload.notification.should eq notification
|
|
197
|
+
queue_payload.batch.should_not be_nil
|
|
198
|
+
end
|
|
199
|
+
runner.enqueue([notification])
|
|
240
200
|
end
|
|
241
201
|
|
|
242
202
|
it 'reflects the notification has been enqueued' do
|
|
243
203
|
runner.should_receive(:reflect).with(:notification_enqueued, notification)
|
|
244
|
-
runner.enqueue(
|
|
204
|
+
runner.enqueue([notification])
|
|
245
205
|
end
|
|
246
206
|
end
|
|
247
207
|
|
|
@@ -259,34 +219,17 @@ describe Rpush::Daemon::AppRunner do
|
|
|
259
219
|
end
|
|
260
220
|
end
|
|
261
221
|
|
|
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
222
|
describe 'sync' do
|
|
280
223
|
before { runner.start }
|
|
281
224
|
|
|
282
225
|
it 'reduces the number of dispatchers if needed' do
|
|
283
|
-
app.stub(:
|
|
284
|
-
expect { runner.sync(app) }.to change(runner, :
|
|
226
|
+
app.stub(connections: 0)
|
|
227
|
+
expect { runner.sync(app) }.to change(runner, :num_dispatcher_loops).to(0)
|
|
285
228
|
end
|
|
286
229
|
|
|
287
230
|
it 'increases the number of dispatchers if needed' do
|
|
288
|
-
app.stub(:
|
|
289
|
-
expect { runner.sync(app) }.to change(runner, :
|
|
231
|
+
app.stub(connections: 2)
|
|
232
|
+
expect { runner.sync(app) }.to change(runner, :num_dispatcher_loops).to(2)
|
|
290
233
|
end
|
|
291
234
|
end
|
|
292
235
|
end
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
require 'unit_spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Rpush::Daemon::Batch do
|
|
4
|
-
let(:notification1) { double(:notification1, :
|
|
5
|
-
let(:notification2) { double(:notification2, :
|
|
4
|
+
let(:notification1) { double(:notification1, id: 1) }
|
|
5
|
+
let(:notification2) { double(:notification2, id: 2) }
|
|
6
6
|
let(:batch) { Rpush::Daemon::Batch.new([notification1, notification2]) }
|
|
7
7
|
let(:store) { double.as_null_object }
|
|
8
8
|
let(:time) { Time.now }
|
|
9
9
|
|
|
10
10
|
before do
|
|
11
|
-
Time.stub(:
|
|
12
|
-
Rpush::Daemon.stub(:
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it 'exposes the notifications' do
|
|
16
|
-
batch.notifications.should eq [notification1, notification2]
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it 'exposes the number notifications' do
|
|
20
|
-
batch.num_notifications.should eq 2
|
|
11
|
+
Time.stub(now: time)
|
|
12
|
+
Rpush::Daemon.stub(store: store)
|
|
21
13
|
end
|
|
22
14
|
|
|
23
15
|
it 'exposes the number notifications processed' do
|
|
@@ -25,125 +17,85 @@ describe Rpush::Daemon::Batch do
|
|
|
25
17
|
end
|
|
26
18
|
|
|
27
19
|
it 'increments the processed notifications count' do
|
|
28
|
-
expect { batch.
|
|
20
|
+
expect { batch.notification_processed }.to change(batch, :num_processed).to(1)
|
|
29
21
|
end
|
|
30
22
|
|
|
31
23
|
it 'completes the batch when all notifications have been processed' do
|
|
32
24
|
batch.should_receive(:complete)
|
|
33
|
-
2.times { batch.
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it 'can be described' do
|
|
37
|
-
batch.describe.should eq '1, 2'
|
|
25
|
+
2.times { batch.notification_processed }
|
|
38
26
|
end
|
|
39
27
|
|
|
40
28
|
describe 'mark_delivered' do
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
it 'marks the notification as delivered immediately' do
|
|
45
|
-
store.should_receive(:mark_delivered).with(notification1, time)
|
|
46
|
-
batch.mark_delivered(notification1)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it 'reflects the notification was delivered' do
|
|
50
|
-
batch.should_receive(:reflect).with(:notification_delivered, notification1)
|
|
51
|
-
batch.mark_delivered(notification1)
|
|
52
|
-
end
|
|
29
|
+
it 'marks the notification as delivered immediately without persisting' do
|
|
30
|
+
store.should_receive(:mark_delivered).with(notification1, time, persist: false)
|
|
31
|
+
batch.mark_delivered(notification1)
|
|
53
32
|
end
|
|
54
33
|
|
|
55
|
-
|
|
56
|
-
|
|
34
|
+
it 'defers persisting' do
|
|
35
|
+
batch.mark_delivered(notification1)
|
|
36
|
+
batch.delivered.should eq [notification1]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
57
39
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
40
|
+
describe 'mark_all_delivered' do
|
|
41
|
+
it 'marks the notifications as delivered immediately without persisting' do
|
|
42
|
+
store.should_receive(:mark_delivered).with(notification1, time, persist: false)
|
|
43
|
+
store.should_receive(:mark_delivered).with(notification2, time, persist: false)
|
|
44
|
+
batch.mark_all_delivered
|
|
45
|
+
end
|
|
62
46
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
end
|
|
47
|
+
it 'defers persisting' do
|
|
48
|
+
batch.mark_all_delivered
|
|
49
|
+
batch.delivered.should eq [notification1, notification2]
|
|
67
50
|
end
|
|
68
51
|
end
|
|
69
52
|
|
|
70
53
|
describe 'mark_failed' do
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
it 'marks the notification as failed' do
|
|
75
|
-
store.should_receive(:mark_failed).with(notification1, 1, 'an error', time)
|
|
76
|
-
batch.mark_failed(notification1, 1, 'an error')
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
it 'reflects the notification failed' do
|
|
80
|
-
batch.should_receive(:reflect).with(:notification_delivered, notification1)
|
|
81
|
-
batch.mark_delivered(notification1)
|
|
82
|
-
end
|
|
54
|
+
it 'marks the notification as failed without persisting' do
|
|
55
|
+
store.should_receive(:mark_failed).with(notification1, 1, 'an error', time, persist: false)
|
|
56
|
+
batch.mark_failed(notification1, 1, 'an error')
|
|
83
57
|
end
|
|
84
58
|
|
|
85
|
-
|
|
86
|
-
|
|
59
|
+
it 'defers persisting' do
|
|
60
|
+
batch.mark_failed(notification1, 1, 'an error')
|
|
61
|
+
batch.failed.should eq([1, 'an error'] => [notification1])
|
|
62
|
+
end
|
|
63
|
+
end
|
|
87
64
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
65
|
+
describe 'mark_failed' do
|
|
66
|
+
it 'marks the notification as failed without persisting' do
|
|
67
|
+
store.should_receive(:mark_failed).with(notification1, 1, 'an error', time, persist: false)
|
|
68
|
+
store.should_receive(:mark_failed).with(notification2, 1, 'an error', time, persist: false)
|
|
69
|
+
batch.mark_all_failed(1, 'an error')
|
|
70
|
+
end
|
|
92
71
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
batch.failed.should eq({[1, 'an error'] => [notification1]})
|
|
97
|
-
end
|
|
72
|
+
it 'defers persisting' do
|
|
73
|
+
batch.mark_all_failed(1, 'an error')
|
|
74
|
+
batch.failed.should eq([1, 'an error'] => [notification1, notification2])
|
|
98
75
|
end
|
|
99
76
|
end
|
|
100
77
|
|
|
101
78
|
describe 'mark_retryable' do
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
it 'marks the notification as retryable' do
|
|
106
|
-
store.should_receive(:mark_retryable).with(notification1, time)
|
|
107
|
-
batch.mark_retryable(notification1, time)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
it 'reflects the notification will be retried' do
|
|
111
|
-
batch.should_receive(:reflect).with(:notification_will_retry, notification1)
|
|
112
|
-
batch.mark_retryable(notification1, time)
|
|
113
|
-
end
|
|
79
|
+
it 'marks the notification as retryable without persisting' do
|
|
80
|
+
store.should_receive(:mark_retryable).with(notification1, time, persist: false)
|
|
81
|
+
batch.mark_retryable(notification1, time)
|
|
114
82
|
end
|
|
115
83
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
it 'marks the notification as retryable without persisting' do
|
|
120
|
-
store.should_receive(:mark_retryable).with(notification1, time, :persist => false)
|
|
121
|
-
batch.mark_retryable(notification1, time)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
it 'defers persisting' do
|
|
125
|
-
batch.mark_retryable(notification1, time)
|
|
126
|
-
batch.retryable.should eq({time => [notification1]})
|
|
127
|
-
end
|
|
84
|
+
it 'defers persisting' do
|
|
85
|
+
batch.mark_retryable(notification1, time)
|
|
86
|
+
batch.retryable.should eq(time => [notification1])
|
|
128
87
|
end
|
|
129
88
|
end
|
|
130
89
|
|
|
131
90
|
describe 'complete' do
|
|
132
91
|
before do
|
|
133
|
-
Rpush.
|
|
134
|
-
Rpush.stub(:logger => double.as_null_object)
|
|
92
|
+
Rpush.stub(logger: double.as_null_object)
|
|
135
93
|
batch.stub(:reflect)
|
|
136
94
|
end
|
|
137
95
|
|
|
138
|
-
it 'clears the notifications' do
|
|
139
|
-
expect do
|
|
140
|
-
2.times { batch.notification_dispatched }
|
|
141
|
-
end.to change(batch, :notifications).to([])
|
|
142
|
-
end
|
|
143
|
-
|
|
144
96
|
it 'identifies as complete' do
|
|
145
97
|
expect do
|
|
146
|
-
2.times { batch.
|
|
98
|
+
2.times { batch.notification_processed }
|
|
147
99
|
end.to change(batch, :complete?).to(be_true)
|
|
148
100
|
end
|
|
149
101
|
|
|
@@ -151,14 +103,14 @@ describe Rpush::Daemon::Batch do
|
|
|
151
103
|
e = StandardError.new
|
|
152
104
|
batch.stub(:complete_delivered).and_raise(e)
|
|
153
105
|
batch.should_receive(:reflect).with(:error, e)
|
|
154
|
-
2.times { batch.
|
|
106
|
+
2.times { batch.notification_processed }
|
|
155
107
|
end
|
|
156
108
|
|
|
157
109
|
describe 'delivered' do
|
|
158
110
|
def complete
|
|
159
111
|
[notification1, notification2].each do |n|
|
|
160
112
|
batch.mark_delivered(n)
|
|
161
|
-
batch.
|
|
113
|
+
batch.notification_processed
|
|
162
114
|
end
|
|
163
115
|
end
|
|
164
116
|
|
|
@@ -172,18 +124,13 @@ describe Rpush::Daemon::Batch do
|
|
|
172
124
|
batch.should_receive(:reflect).with(:notification_delivered, notification2)
|
|
173
125
|
complete
|
|
174
126
|
end
|
|
175
|
-
|
|
176
|
-
it 'clears the delivered notifications' do
|
|
177
|
-
complete
|
|
178
|
-
batch.delivered.should eq([])
|
|
179
|
-
end
|
|
180
127
|
end
|
|
181
128
|
|
|
182
129
|
describe 'failed' do
|
|
183
130
|
def complete
|
|
184
131
|
[notification1, notification2].each do |n|
|
|
185
132
|
batch.mark_failed(n, 1, 'an error')
|
|
186
|
-
batch.
|
|
133
|
+
batch.notification_processed
|
|
187
134
|
end
|
|
188
135
|
end
|
|
189
136
|
|
|
@@ -197,18 +144,13 @@ describe Rpush::Daemon::Batch do
|
|
|
197
144
|
batch.should_receive(:reflect).with(:notification_failed, notification2)
|
|
198
145
|
complete
|
|
199
146
|
end
|
|
200
|
-
|
|
201
|
-
it 'clears the failed notifications' do
|
|
202
|
-
complete
|
|
203
|
-
batch.failed.should eq({})
|
|
204
|
-
end
|
|
205
147
|
end
|
|
206
148
|
|
|
207
149
|
describe 'retryable' do
|
|
208
150
|
def complete
|
|
209
151
|
[notification1, notification2].each do |n|
|
|
210
152
|
batch.mark_retryable(n, time)
|
|
211
|
-
batch.
|
|
153
|
+
batch.notification_processed
|
|
212
154
|
end
|
|
213
155
|
end
|
|
214
156
|
|
|
@@ -222,11 +164,6 @@ describe Rpush::Daemon::Batch do
|
|
|
222
164
|
batch.should_receive(:reflect).with(:notification_will_retry, notification2)
|
|
223
165
|
complete
|
|
224
166
|
end
|
|
225
|
-
|
|
226
|
-
it 'clears the retryable notifications' do
|
|
227
|
-
complete
|
|
228
|
-
batch.retryable.should eq({})
|
|
229
|
-
end
|
|
230
167
|
end
|
|
231
168
|
end
|
|
232
169
|
end
|