ably 1.1.1 → 1.1.2
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/.travis.yml +2 -2
- data/CHANGELOG.md +8 -2
- data/ably.gemspec +1 -1
- data/lib/ably/logger.rb +7 -1
- data/lib/ably/modules/state_machine.rb +1 -1
- data/lib/ably/realtime/connection.rb +2 -0
- data/lib/ably/realtime/connection/connection_manager.rb +19 -1
- data/lib/ably/rest/client.rb +4 -2
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/auth_spec.rb +2 -1
- data/spec/acceptance/realtime/channel_spec.rb +11 -8
- data/spec/acceptance/realtime/client_spec.rb +8 -4
- data/spec/acceptance/realtime/connection_failures_spec.rb +68 -2
- data/spec/acceptance/realtime/connection_spec.rb +11 -2
- data/spec/acceptance/realtime/message_spec.rb +2 -4
- data/spec/acceptance/realtime/push_admin_spec.rb +40 -2
- data/spec/acceptance/rest/message_spec.rb +1 -2
- data/spec/acceptance/rest/push_admin_spec.rb +64 -8
- data/spec/support/debug_failure_helper.rb +9 -5
- data/spec/unit/modules/enum_spec.rb +1 -1
- data/spec/unit/realtime/client_spec.rb +1 -1
- data/spec/unit/realtime/connection_spec.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 372821f0df3a03b36e29d0c2ce4141e08b7467c794aa28c542e38b10d658a0f5
|
4
|
+
data.tar.gz: 7015ce6030cf75b97474cab9dfb809d671d4178efd34aff777514502a3a74d83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d92e931347421a955f3a318fca505cbb9f2271417a804a4e5a2e310c155abf4f42d2d89beca434e372a4b5777d931d278019a10b77d4b151d4e154a8a06d8064
|
7
|
+
data.tar.gz: 7e1d96e9b49558bdd010fa63e155ca291921e910212cb38ec00eafe7a6e7b58038150a1e24308d109ac59814bc5f181d2d653734c12c901ce11d7757410a4b28
|
data/.travis.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
sudo: false
|
2
2
|
env:
|
3
|
-
- RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=
|
4
|
-
- RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=
|
3
|
+
- RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=2 PROTOCOL=json
|
4
|
+
- RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=2 PROTOCOL=msgpack
|
5
5
|
language: ruby
|
6
6
|
rvm:
|
7
7
|
- 1.9.3
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [v1.1.
|
3
|
+
## [v1.1.2](https://github.com/ably/ably-ruby/tree/v1.1.2)
|
4
4
|
|
5
|
+
[Full Changelog](https://github.com/ably/ably-ruby/compare/v1.1.1...v1.1.2)
|
6
|
+
|
7
|
+
**Merged pull requests:**
|
8
|
+
|
9
|
+
- Remove legacy skipped tests and upgrade MsgPack [\#184](https://github.com/ably/ably-ruby/pull/184) ([mattheworiordan](https://github.com/mattheworiordan))
|
10
|
+
|
11
|
+
## [v1.1.1](https://github.com/ably/ably-ruby/tree/v1.1.1) (2019-05-06)
|
5
12
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v1.1.0...v1.1.1)
|
6
13
|
|
7
14
|
**Implemented enhancements:**
|
@@ -67,7 +74,6 @@
|
|
67
74
|
**Closed issues:**
|
68
75
|
|
69
76
|
- Passing a frozen channel name or name gives an error on the REST client \[Reopen\] [\#145](https://github.com/ably/ably-ruby/issues/145)
|
70
|
-
- Passing a frozen channel name or name gives an error on the REST client [\#132](https://github.com/ably/ably-ruby/issues/132)
|
71
77
|
|
72
78
|
**Merged pull requests:**
|
73
79
|
|
data/ably.gemspec
CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_runtime_dependency 'json'
|
31
31
|
end
|
32
32
|
spec.add_runtime_dependency 'websocket-driver', '~> 0.7'
|
33
|
-
spec.add_runtime_dependency 'msgpack', '>=
|
33
|
+
spec.add_runtime_dependency 'msgpack', '>= 1.3.0'
|
34
34
|
spec.add_runtime_dependency 'addressable', '>= 2.0.0'
|
35
35
|
|
36
36
|
spec.add_development_dependency 'rake', '~> 11.3'
|
data/lib/ably/logger.rb
CHANGED
@@ -20,6 +20,8 @@ module Ably
|
|
20
20
|
ensure_logger_interface_is_valid
|
21
21
|
|
22
22
|
@logger.level = log_level
|
23
|
+
|
24
|
+
@log_mutex = Mutex.new
|
23
25
|
end
|
24
26
|
|
25
27
|
# The logger used by this class, defaults to {http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html Ruby Logger}
|
@@ -38,7 +40,9 @@ module Ably
|
|
38
40
|
%w(fatal error warn info debug).each do |method_name|
|
39
41
|
define_method(method_name) do |*args, &block|
|
40
42
|
begin
|
41
|
-
|
43
|
+
log_mutex.synchronize do
|
44
|
+
logger.public_send(method_name, *args, &block)
|
45
|
+
end
|
42
46
|
rescue StandardError => e
|
43
47
|
logger.error "Logger: Failed to log #{method_name} block - #{e.class}: #{e.message}\n#{e.backtrace.join("\n")}"
|
44
48
|
end
|
@@ -46,6 +50,8 @@ module Ably
|
|
46
50
|
end
|
47
51
|
|
48
52
|
private
|
53
|
+
attr_reader :log_mutex
|
54
|
+
|
49
55
|
def client
|
50
56
|
@client
|
51
57
|
end
|
@@ -23,7 +23,7 @@ module Ably::Modules
|
|
23
23
|
def transition_state(state, *args)
|
24
24
|
unless result = transition_to(state.to_sym, *args)
|
25
25
|
exception = exception_for_state_change_to(state)
|
26
|
-
logger.fatal { "#{self.class}: #{exception.message}" }
|
26
|
+
logger.fatal { "#{self.class}: #{exception.message}\n#{caller[0..20].join("\n")}" }
|
27
27
|
end
|
28
28
|
result
|
29
29
|
end
|
@@ -161,6 +161,8 @@ module Ably
|
|
161
161
|
@state_machine = ConnectionStateMachine.new(self)
|
162
162
|
@state = STATE(state_machine.current_state)
|
163
163
|
@manager = ConnectionManager.new(self)
|
164
|
+
|
165
|
+
@current_host = client.endpoint.host
|
164
166
|
end
|
165
167
|
|
166
168
|
# Causes the connection to close, entering the closed state, from any state except
|
@@ -49,18 +49,31 @@ module Ably::Realtime
|
|
49
49
|
|
50
50
|
logger.debug { 'ConnectionManager: Opening a websocket transport connection' }
|
51
51
|
|
52
|
+
# The socket attempt can fail at the same time as a timer firing so ensure
|
53
|
+
# only one outcome is processed from this setup attempt
|
54
|
+
setup_attempt_status = {}
|
55
|
+
setup_failed = lambda do
|
56
|
+
return true if setup_attempt_status[:failed]
|
57
|
+
setup_attempt_status[:failed] = true
|
58
|
+
false
|
59
|
+
end
|
60
|
+
|
52
61
|
connection.create_websocket_transport.tap do |socket_deferrable|
|
53
62
|
socket_deferrable.callback do |websocket_transport|
|
54
63
|
subscribe_to_transport_events websocket_transport
|
55
64
|
yield websocket_transport if block_given?
|
56
65
|
end
|
57
66
|
socket_deferrable.errback do |error|
|
67
|
+
next if setup_failed.call
|
58
68
|
connection_opening_failed error
|
59
69
|
end
|
60
70
|
end
|
61
71
|
|
72
|
+
# The connection request timeout must be marginally higher than the REST request timeout to ensure
|
73
|
+
# any HTTP auth request failure due to timeout triggers before the connection timer kicks in
|
62
74
|
logger.debug { "ConnectionManager: Setting up automatic connection timeout timer for #{realtime_request_timeout}s" }
|
63
75
|
create_timeout_timer_whilst_in_state(:connecting, realtime_request_timeout) do
|
76
|
+
next if setup_failed.call
|
64
77
|
connection_opening_failed Ably::Exceptions::ConnectionTimeout.new("Connection to Ably timed out after #{realtime_request_timeout}s", nil, Ably::Exceptions::Codes::CONNECTION_TIMED_OUT)
|
65
78
|
end
|
66
79
|
end
|
@@ -80,7 +93,12 @@ module Ably::Realtime
|
|
80
93
|
|
81
94
|
logger.warn { "ConnectionManager: Connection to #{connection.current_host}:#{connection.port} failed; #{error.message}" }
|
82
95
|
next_state = get_next_retry_state_info
|
83
|
-
|
96
|
+
|
97
|
+
if connection.state == next_state.fetch(:state)
|
98
|
+
logger.error { "ConnectionManager: Skipping next retry state after connection opening failed as already in state #{next_state}\n#{caller[0..20].join("\n")}" }
|
99
|
+
else
|
100
|
+
connection.transition_state_machine next_state.fetch(:state), retry_in: next_state.fetch(:pause), reason: Ably::Exceptions::ConnectionError.new("Connection failed: #{error.message}", nil, Ably::Exceptions::Codes::CONNECTION_FAILED, error)
|
101
|
+
end
|
84
102
|
end
|
85
103
|
|
86
104
|
# Called whenever a new connection is made
|
data/lib/ably/rest/client.rb
CHANGED
@@ -471,11 +471,13 @@ module Ably
|
|
471
471
|
|
472
472
|
# Allowable duration for an external auth request
|
473
473
|
# For REST client this defaults to request_timeout
|
474
|
-
# For Realtime clients this defaults to realtime_request_timeout
|
474
|
+
# For Realtime clients this defaults to 250ms less than the realtime_request_timeout
|
475
|
+
# ensuring an auth failure will be triggered before the realtime request timeout fires
|
476
|
+
# which would lead to a misleading error message (connection timeout as opposed to auth request timeout)
|
475
477
|
# @api private
|
476
478
|
def auth_request_timeout
|
477
479
|
if @realtime_client
|
478
|
-
@realtime_client.connection.defaults.fetch(:realtime_request_timeout)
|
480
|
+
@realtime_client.connection.defaults.fetch(:realtime_request_timeout) - 0.25
|
479
481
|
else
|
480
482
|
http_defaults.fetch(:request_timeout)
|
481
483
|
end
|
data/lib/ably/version.rb
CHANGED
@@ -1139,6 +1139,7 @@ describe Ably::Realtime::Auth, :event_machine do
|
|
1139
1139
|
context 'when credentials are invalid' do
|
1140
1140
|
let(:key_secret) { 'invalid' }
|
1141
1141
|
let(:token) { Faraday.get("#{auth_url}?keyName=#{key_name}&keySecret=#{key_secret}").body }
|
1142
|
+
let(:client_options) { { token: token, environment: environment, protocol: protocol, log_level: :none } }
|
1142
1143
|
|
1143
1144
|
it 'fails with an invalid signature error' do
|
1144
1145
|
client.connection.once(:disconnected) do |state_change|
|
@@ -1239,7 +1240,7 @@ describe Ably::Realtime::Auth, :event_machine do
|
|
1239
1240
|
Faraday.get("#{auth_url}?keyName=#{key_name}&keySecret=#{key_secret}&capability=#{URI.escape(basic_capability)}").body
|
1240
1241
|
end
|
1241
1242
|
end
|
1242
|
-
let(:client_options) { default_options.merge(auth_callback: auth_callback) }
|
1243
|
+
let(:client_options) { default_options.merge(auth_callback: auth_callback, log_level: :error) }
|
1243
1244
|
|
1244
1245
|
it 'client fails to publish to a channel with subscribe-only capability and publishes successfully on a channel with permissions' do
|
1245
1246
|
client.connection.once(:connected) do
|
@@ -279,8 +279,7 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
279
279
|
key: restricted_api_key,
|
280
280
|
log_level: :fatal,
|
281
281
|
use_token_auth: true,
|
282
|
-
|
283
|
-
default_token_params: { capability: { "canpublish:foo" => ["publish"] } }
|
282
|
+
default_token_params: { capability: { "canpublish:foo" => ["*"] } }
|
284
283
|
)
|
285
284
|
end
|
286
285
|
let(:restricted_client) do
|
@@ -1009,9 +1008,6 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1009
1008
|
|
1010
1009
|
it 'publishes the message without a name attribute in the payload' do
|
1011
1010
|
published = false
|
1012
|
-
channel.publish(nil, data) do
|
1013
|
-
published = true
|
1014
|
-
end
|
1015
1011
|
|
1016
1012
|
channel.subscribe do |message|
|
1017
1013
|
expect(message.name).to be_nil
|
@@ -1024,6 +1020,10 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1024
1020
|
end
|
1025
1021
|
end
|
1026
1022
|
end
|
1023
|
+
|
1024
|
+
channel.publish(nil, data) do
|
1025
|
+
published = true
|
1026
|
+
end
|
1027
1027
|
end
|
1028
1028
|
end
|
1029
1029
|
|
@@ -1032,9 +1032,6 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1032
1032
|
|
1033
1033
|
it 'publishes the message without a data attribute in the payload' do
|
1034
1034
|
published = false
|
1035
|
-
channel.publish(name, nil) do
|
1036
|
-
published = true
|
1037
|
-
end
|
1038
1035
|
|
1039
1036
|
channel.subscribe do |message|
|
1040
1037
|
expect(message.data).to be_nil
|
@@ -1047,6 +1044,10 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1047
1044
|
end
|
1048
1045
|
end
|
1049
1046
|
end
|
1047
|
+
|
1048
|
+
channel.publish(name, nil) do
|
1049
|
+
published = true
|
1050
|
+
end
|
1050
1051
|
end
|
1051
1052
|
end
|
1052
1053
|
|
@@ -1997,6 +1998,8 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1997
1998
|
end
|
1998
1999
|
|
1999
2000
|
context '#resume (#RTL2f)' do
|
2001
|
+
let(:client_options) { default_options.merge(log_level: :fatal) }
|
2002
|
+
|
2000
2003
|
it 'is false when a channel first attaches' do
|
2001
2004
|
channel.attach
|
2002
2005
|
channel.on(:attached) do |channel_state_change|
|
@@ -315,8 +315,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
315
315
|
expect(msg.data).to eql(data)
|
316
316
|
stop_reactor
|
317
317
|
end
|
318
|
+
|
319
|
+
subject.publish channel_name, event_name, data
|
318
320
|
end
|
319
|
-
subject.publish channel_name, event_name, data
|
320
321
|
end
|
321
322
|
|
322
323
|
specify 'publishing does not result in a channel being created' do
|
@@ -341,8 +342,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
341
342
|
expect(msg.extras).to eql(extras)
|
342
343
|
stop_reactor
|
343
344
|
end
|
345
|
+
|
346
|
+
subject.publish channel_name, event_name, {}, extras: extras
|
344
347
|
end
|
345
|
-
subject.publish channel_name, event_name, {}, extras: extras
|
346
348
|
end
|
347
349
|
end
|
348
350
|
|
@@ -353,8 +355,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
353
355
|
expect(msg.data).to eql(data)
|
354
356
|
stop_reactor
|
355
357
|
end
|
358
|
+
|
359
|
+
subject.publish channel_name, [message]
|
356
360
|
end
|
357
|
-
subject.publish channel_name, [message]
|
358
361
|
end
|
359
362
|
|
360
363
|
specify 'publishing supports an array of Hash objects' do
|
@@ -364,8 +367,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
364
367
|
expect(msg.data).to eql(data)
|
365
368
|
stop_reactor
|
366
369
|
end
|
370
|
+
|
371
|
+
subject.publish channel_name, [name: event_name, data: data]
|
367
372
|
end
|
368
|
-
subject.publish channel_name, [name: event_name, data: data]
|
369
373
|
end
|
370
374
|
|
371
375
|
specify 'publishing on a closed connection fails' do
|
@@ -45,7 +45,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
45
45
|
connection.on(:failed) do |connection_state_change|
|
46
46
|
error = connection_state_change.reason
|
47
47
|
expect(connection.state).to eq(:failed)
|
48
|
-
# TODO: Check error type is a
|
48
|
+
# TODO: Check error type is a TokenNotFound exception
|
49
49
|
expect(error.status).to eq(401)
|
50
50
|
expect(error.code).to eq(40400) # not found
|
51
51
|
stop_reactor
|
@@ -110,6 +110,72 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
113
|
+
|
114
|
+
context 'request fails due to slow response and subsequent timeout', :webmock, em_timeout: (Ably::Rest::Client::HTTP_DEFAULTS.fetch(:request_timeout) + 5) * 2 do
|
115
|
+
let(:auth_url) { "http://#{random_str}.domain.will.be.stubbed/path" }
|
116
|
+
let(:client_options) { default_options.reject { |k, v| k == :key }.merge(auth_url: auth_url, log_level: :fatal) }
|
117
|
+
|
118
|
+
# Timeout +5 seconds, beyond default allowed timeout
|
119
|
+
before do
|
120
|
+
stub_request(:get, auth_url).
|
121
|
+
to_return do |request|
|
122
|
+
sleep Ably::Rest::Client::HTTP_DEFAULTS.fetch(:request_timeout) + 5
|
123
|
+
{ status: [500, "Internal Server Error"] }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
specify 'the connection moves to the disconnected state and tries again, returning again to the disconnected state (#RSA4c, #RSA4c1, #RSA4c2)' do
|
128
|
+
states = Hash.new { |hash, key| hash[key] = [] }
|
129
|
+
|
130
|
+
connection.once(:connected) { raise "Connection can never move to connected because of auth failures" }
|
131
|
+
|
132
|
+
connection.on do |connection_state|
|
133
|
+
states[connection_state.current.to_sym] << Time.now
|
134
|
+
if states[:disconnected].count == 2 && connection_state.current == :disconnected
|
135
|
+
expect(connection.error_reason).to be_a(Ably::Exceptions::ConnectionError)
|
136
|
+
expect(connection.error_reason.message).to match(/auth_url/)
|
137
|
+
EventMachine.add_timer(2) do
|
138
|
+
expect(states.keys).to include(:connecting, :disconnected)
|
139
|
+
expect(states[:connecting].count).to eql(2)
|
140
|
+
expect(states[:connected].count).to eql(0)
|
141
|
+
stop_reactor
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'request fails once due to slow response but succeeds the second time' do
|
149
|
+
let(:auth_url) { "http://#{random_str}.domain.will.be.stubbed/path" }
|
150
|
+
let(:client_options) { default_options.reject { |k, v| k == :key }.merge(auth_url: auth_url, log_level: :fatal) }
|
151
|
+
|
152
|
+
# Timeout +5 seconds, beyond default allowed timeout
|
153
|
+
before do
|
154
|
+
token_response = Ably::Rest::Client.new(default_options).auth.request_token
|
155
|
+
WebMock.enable!
|
156
|
+
|
157
|
+
stub_request(:get, auth_url).
|
158
|
+
to_return do |request|
|
159
|
+
sleep Ably::Rest::Client::HTTP_DEFAULTS.fetch(:request_timeout)
|
160
|
+
{ status: [500, "Internal Server Error"] }
|
161
|
+
end.then.
|
162
|
+
to_return(:status => 201, :body => token_response.to_json, :headers => { 'Content-Type' => 'application/json' })
|
163
|
+
end
|
164
|
+
|
165
|
+
specify 'the connection moves to the disconnected state and tries again, returning again to the disconnected state (#RSA4c, #RSA4c1, #RSA4c2)' do
|
166
|
+
states = Hash.new { |hash, key| hash[key] = [] }
|
167
|
+
|
168
|
+
connection.once(:connected) do
|
169
|
+
expect(states[:disconnected].count).to eql(1)
|
170
|
+
expect(states[:connecting].count).to eql(2)
|
171
|
+
stop_reactor
|
172
|
+
end
|
173
|
+
|
174
|
+
connection.on do |connection_state|
|
175
|
+
states[connection_state.current.to_sym] << Time.now
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
113
179
|
end
|
114
180
|
|
115
181
|
context 'existing CONNECTED connection' do
|
@@ -425,7 +491,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
425
491
|
let(:client_options) do
|
426
492
|
default_options.merge(
|
427
493
|
log_level: :none,
|
428
|
-
realtime_request_timeout: timeout
|
494
|
+
realtime_request_timeout: timeout,
|
429
495
|
)
|
430
496
|
end
|
431
497
|
|
@@ -27,6 +27,13 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
context 'current_host' do
|
31
|
+
it 'is available immediately after the client is instanced' do
|
32
|
+
expect(connection.current_host.to_s).to match(/\.ably\.io$/)
|
33
|
+
stop_reactor
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
30
37
|
context 'with :auto_connect option set to false' do
|
31
38
|
let(:client) do
|
32
39
|
auto_close Ably::Realtime::Client.new(default_options.merge(auto_connect: false))
|
@@ -1307,12 +1314,14 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1307
1314
|
expect(connection.send(:client_msg_serial)).to eql(-1) # no messages published yet
|
1308
1315
|
connection_id = client.connection.id
|
1309
1316
|
connection.transport.__incoming_protocol_msgbus__
|
1310
|
-
channel.
|
1317
|
+
channel.subscribe('event') do |message|
|
1318
|
+
expect(message.data).to eql('message-1')
|
1311
1319
|
msg_serial = connection.send(:client_msg_serial)
|
1312
1320
|
expect(msg_serial).to eql(0)
|
1313
1321
|
recovery_key = client.connection.recovery_key
|
1314
1322
|
connection.transition_state_machine! :failed
|
1315
1323
|
end
|
1324
|
+
channel.publish('event', 'message-1')
|
1316
1325
|
end
|
1317
1326
|
|
1318
1327
|
connection.on(:failed) do
|
@@ -1329,7 +1338,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1329
1338
|
expect(recover_client.connection.id).to eql(connection_id)
|
1330
1339
|
|
1331
1340
|
recover_client_channel.subscribe do |message|
|
1332
|
-
|
1341
|
+
expect(message.data).to eql('message-2')
|
1333
1342
|
EventMachine.add_timer(2) do
|
1334
1343
|
stop_reactor
|
1335
1344
|
end
|
@@ -96,8 +96,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
96
96
|
end
|
97
97
|
|
98
98
|
context 'JSON Array' do
|
99
|
-
|
100
|
-
let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55, 'string', { 'Hash' => true }, ['array'] ] } } } }
|
99
|
+
let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55, nil, 'string', { 'Hash' => true }, ['array'] ] } } } }
|
101
100
|
|
102
101
|
it 'is encoded and decoded to the same Array' do
|
103
102
|
publish_and_check_extras data
|
@@ -658,8 +657,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
658
657
|
expect(message_state).to be_empty
|
659
658
|
EventMachine.add_timer(2) do
|
660
659
|
expect(message_state).to contain_exactly(:delivered)
|
661
|
-
|
662
|
-
# expect(msgs_received.length).to eql(1)
|
660
|
+
expect(msgs_received.length).to eql(1)
|
663
661
|
stop_reactor
|
664
662
|
end
|
665
663
|
end
|
@@ -217,6 +217,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
|
|
217
217
|
let(:client_id) { random_str }
|
218
218
|
let(:fixture_count) { 6 }
|
219
219
|
|
220
|
+
before(:all) do
|
221
|
+
# As push tests often use the global scope (devices),
|
222
|
+
# we need to ensure tests cannot conflict
|
223
|
+
reload_test_app
|
224
|
+
end
|
225
|
+
|
220
226
|
before do
|
221
227
|
fixture_count.times.map do |index|
|
222
228
|
Thread.new do # Parallelise the setup
|
@@ -274,6 +280,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
|
|
274
280
|
let(:fixture_count) { 2 }
|
275
281
|
let(:client_id) { random_str }
|
276
282
|
|
283
|
+
before(:all) do
|
284
|
+
# As push tests often use the global scope (devices),
|
285
|
+
# we need to ensure tests cannot conflict
|
286
|
+
reload_test_app
|
287
|
+
end
|
288
|
+
|
277
289
|
before do
|
278
290
|
fixture_count.times.map do |index|
|
279
291
|
Thread.new do # Parallelise the setup
|
@@ -353,6 +365,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
|
|
353
365
|
}
|
354
366
|
end
|
355
367
|
|
368
|
+
before(:all) do
|
369
|
+
# As push tests often use the global scope (devices),
|
370
|
+
# we need to ensure tests cannot conflict
|
371
|
+
reload_test_app
|
372
|
+
end
|
373
|
+
|
356
374
|
after do
|
357
375
|
rest_device_registrations.remove_where client_id: client_id
|
358
376
|
end
|
@@ -388,6 +406,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
|
|
388
406
|
let(:device_id) { random_str }
|
389
407
|
let(:client_id) { random_str }
|
390
408
|
|
409
|
+
before(:all) do
|
410
|
+
# As push tests often use the global scope (devices),
|
411
|
+
# we need to ensure tests cannot conflict
|
412
|
+
reload_test_app
|
413
|
+
end
|
414
|
+
|
391
415
|
before do
|
392
416
|
rest_device_registrations.save({
|
393
417
|
id: "device-#{client_id}-0",
|
@@ -421,6 +445,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
|
|
421
445
|
let(:device_id) { random_str }
|
422
446
|
let(:client_id) { random_str }
|
423
447
|
|
448
|
+
before(:all) do
|
449
|
+
# As push tests often use the global scope (devices),
|
450
|
+
# we need to ensure tests cannot conflict
|
451
|
+
reload_test_app
|
452
|
+
end
|
453
|
+
|
424
454
|
before do
|
425
455
|
rest_device_registrations.save({
|
426
456
|
id: "device-#{client_id}-0",
|
@@ -481,6 +511,12 @@ describe Ably::Realtime::Push::Admin, :event_machine do
|
|
481
511
|
client.push.admin.channel_subscriptions
|
482
512
|
}
|
483
513
|
|
514
|
+
before(:all) do
|
515
|
+
# As push tests often use the global scope (devices),
|
516
|
+
# we need to ensure tests cannot conflict
|
517
|
+
reload_test_app
|
518
|
+
end
|
519
|
+
|
484
520
|
# Set up 2 devices with the same client_id
|
485
521
|
# and two device with the unique device_id and no client_id
|
486
522
|
before do
|
@@ -543,8 +579,10 @@ describe Ably::Realtime::Push::Admin, :event_machine do
|
|
543
579
|
describe '#list_channels' do
|
544
580
|
let(:fixture_count) { 6 }
|
545
581
|
|
546
|
-
before(:
|
547
|
-
|
582
|
+
before(:all) do
|
583
|
+
# As push tests often use the global scope (devices),
|
584
|
+
# we need to ensure tests cannot conflict
|
585
|
+
reload_test_app
|
548
586
|
end
|
549
587
|
|
550
588
|
before do
|
@@ -75,8 +75,7 @@ describe Ably::Rest::Channel, 'messages' do
|
|
75
75
|
end
|
76
76
|
|
77
77
|
context 'JSON Array' do
|
78
|
-
|
79
|
-
let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55, 'string', { 'Hash' => true }, ['array'] ] } } } }
|
78
|
+
let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55, nil, 'string', { 'Hash' => true }, ['array'] ] } } } }
|
80
79
|
|
81
80
|
it 'is encoded and decoded to the same deep multi-type object' do
|
82
81
|
channel.publish 'event', {}, extras: data
|
@@ -181,6 +181,12 @@ describe Ably::Rest::Push::Admin do
|
|
181
181
|
let(:client_id) { random_str }
|
182
182
|
let(:fixture_count) { 6 }
|
183
183
|
|
184
|
+
before(:all) do
|
185
|
+
# As push tests often use the global scope (devices),
|
186
|
+
# we need to ensure tests cannot conflict
|
187
|
+
reload_test_app
|
188
|
+
end
|
189
|
+
|
184
190
|
before do
|
185
191
|
fixture_count.times.map do |index|
|
186
192
|
Thread.new do
|
@@ -244,6 +250,12 @@ describe Ably::Rest::Push::Admin do
|
|
244
250
|
let(:fixture_count) { 2 }
|
245
251
|
let(:client_id) { random_str }
|
246
252
|
|
253
|
+
before(:all) do
|
254
|
+
# As push tests often use the global scope (devices),
|
255
|
+
# we need to ensure tests cannot conflict
|
256
|
+
reload_test_app
|
257
|
+
end
|
258
|
+
|
247
259
|
before do
|
248
260
|
fixture_count.times.map do |index|
|
249
261
|
Thread.new do
|
@@ -318,6 +330,12 @@ describe Ably::Rest::Push::Admin do
|
|
318
330
|
}
|
319
331
|
end
|
320
332
|
|
333
|
+
before(:all) do
|
334
|
+
# As push tests often use the global scope (devices),
|
335
|
+
# we need to ensure tests cannot conflict
|
336
|
+
reload_test_app
|
337
|
+
end
|
338
|
+
|
321
339
|
after do
|
322
340
|
subject.remove_where client_id: client_id, full_wait: true
|
323
341
|
end
|
@@ -444,6 +462,12 @@ describe Ably::Rest::Push::Admin do
|
|
444
462
|
let(:device_id) { random_str }
|
445
463
|
let(:client_id) { random_str }
|
446
464
|
|
465
|
+
before(:all) do
|
466
|
+
# As push tests often use the global scope (devices),
|
467
|
+
# we need to ensure tests cannot conflict
|
468
|
+
reload_test_app
|
469
|
+
end
|
470
|
+
|
447
471
|
before do
|
448
472
|
[
|
449
473
|
Thread.new do
|
@@ -501,6 +525,12 @@ describe Ably::Rest::Push::Admin do
|
|
501
525
|
let(:device_id) { random_str }
|
502
526
|
let(:client_id) { random_str }
|
503
527
|
|
528
|
+
before(:all) do
|
529
|
+
# As push tests often use the global scope (devices),
|
530
|
+
# we need to ensure tests cannot conflict
|
531
|
+
reload_test_app
|
532
|
+
end
|
533
|
+
|
504
534
|
before do
|
505
535
|
[
|
506
536
|
Thread.new do
|
@@ -585,8 +615,8 @@ describe Ably::Rest::Push::Admin do
|
|
585
615
|
# and two device with the unique device_id and no client_id
|
586
616
|
before do
|
587
617
|
[
|
588
|
-
lambda { device_registrations.save(default_device_attr.merge(id: device_id)) },
|
589
|
-
lambda { device_registrations.save(default_device_attr.merge(id: device_id_2)) },
|
618
|
+
lambda { device_registrations.save(default_device_attr.merge(id: device_id, client_id: nil)) },
|
619
|
+
lambda { device_registrations.save(default_device_attr.merge(id: device_id_2, client_id: nil)) },
|
590
620
|
lambda { device_registrations.save(default_device_attr.merge(client_id: client_id, id: random_str)) },
|
591
621
|
lambda { device_registrations.save(default_device_attr.merge(client_id: client_id, id: random_str)) }
|
592
622
|
].map do |proc|
|
@@ -602,6 +632,12 @@ describe Ably::Rest::Push::Admin do
|
|
602
632
|
describe '#list (#RSH1c1)' do
|
603
633
|
let(:fixture_count) { 6 }
|
604
634
|
|
635
|
+
before(:all) do
|
636
|
+
# As push tests often use the global scope (devices),
|
637
|
+
# we need to ensure tests cannot conflict
|
638
|
+
reload_test_app
|
639
|
+
end
|
640
|
+
|
605
641
|
before do
|
606
642
|
fixture_count.times.map do |index|
|
607
643
|
Thread.new { subject.save(channel: "pushenabled:#{random_str}", client_id: client_id) }
|
@@ -670,11 +706,14 @@ describe Ably::Rest::Push::Admin do
|
|
670
706
|
describe '#list_channels (#RSH1c2)' do
|
671
707
|
let(:fixture_count) { 6 }
|
672
708
|
|
673
|
-
before(:
|
674
|
-
|
709
|
+
before(:all) do
|
710
|
+
# As push tests often use the global scope (devices),
|
711
|
+
# we need to ensure tests cannot conflict
|
712
|
+
reload_test_app
|
675
713
|
end
|
676
714
|
|
677
715
|
before do
|
716
|
+
# Create 6 channel subscriptions to the client ID for this test
|
678
717
|
fixture_count.times.map do |index|
|
679
718
|
Thread.new do
|
680
719
|
subject.save(channel: "pushenabled:#{index}:#{random_str}", client_id: client_id)
|
@@ -694,9 +733,6 @@ describe Ably::Rest::Push::Admin do
|
|
694
733
|
end
|
695
734
|
|
696
735
|
it 'supports paging' do
|
697
|
-
skip 'Channel lists with limits is not reliable immediately after fixture creation'
|
698
|
-
# TODO: Remove this once list channels with limits is reliable immediately after fixtures created
|
699
|
-
# See https://github.com/ably/realtime/issues/1882
|
700
736
|
subject.list_channels
|
701
737
|
page = subject.list_channels(limit: 3)
|
702
738
|
expect(page).to be_a(Ably::Models::PaginatedResult)
|
@@ -730,6 +766,12 @@ describe Ably::Rest::Push::Admin do
|
|
730
766
|
let(:client_id) { random_str }
|
731
767
|
let(:device_id) { random_str }
|
732
768
|
|
769
|
+
before(:all) do
|
770
|
+
# As push tests often use the global scope (devices),
|
771
|
+
# we need to ensure tests cannot conflict
|
772
|
+
reload_test_app
|
773
|
+
end
|
774
|
+
|
733
775
|
it 'saves the new client_id PushChannelSubscription Hash object' do
|
734
776
|
subject.save(channel: channel, client_id: client_id)
|
735
777
|
|
@@ -802,6 +844,12 @@ describe Ably::Rest::Push::Admin do
|
|
802
844
|
|
803
845
|
let(:fixture_count) { 6 }
|
804
846
|
|
847
|
+
before(:all) do
|
848
|
+
# As push tests often use the global scope (devices),
|
849
|
+
# we need to ensure tests cannot conflict
|
850
|
+
reload_test_app
|
851
|
+
end
|
852
|
+
|
805
853
|
before do
|
806
854
|
fixture_count.times.map do |index|
|
807
855
|
[
|
@@ -814,8 +862,10 @@ describe Ably::Rest::Push::Admin do
|
|
814
862
|
end.each(&:join) # Wait for all threads to complete
|
815
863
|
end
|
816
864
|
|
865
|
+
# TODO: Reinstate once delete subscriptions by channel is possible
|
866
|
+
# See https://github.com/ably/realtime/issues/1359
|
817
867
|
it 'removes matching channels' do
|
818
|
-
skip '
|
868
|
+
skip 'deleting subscriptions is not yet supported realtime#1359'
|
819
869
|
subject.remove_where channel: fixed_channel, full_wait: true
|
820
870
|
expect(subject.list(channel: fixed_channel).items.count).to eql(0)
|
821
871
|
expect(subject.list(client_id: client_id).items.count).to eql(0)
|
@@ -852,6 +902,12 @@ describe Ably::Rest::Push::Admin do
|
|
852
902
|
let(:client_id) { random_str }
|
853
903
|
let(:device_id) { random_str }
|
854
904
|
|
905
|
+
before(:all) do
|
906
|
+
# As push tests often use the global scope (devices),
|
907
|
+
# we need to ensure tests cannot conflict
|
908
|
+
reload_test_app
|
909
|
+
end
|
910
|
+
|
855
911
|
before do
|
856
912
|
[
|
857
913
|
lambda { subject.save(channel: channel, client_id: client_id) },
|
@@ -2,6 +2,8 @@ RSpec.configure do |config|
|
|
2
2
|
config.before(:example) do |example|
|
3
3
|
next if example.metadata[:prevent_log_stubbing]
|
4
4
|
|
5
|
+
log_mutex = Mutex.new
|
6
|
+
|
5
7
|
@log_output = []
|
6
8
|
%w(fatal error warn info debug).each do |method_name|
|
7
9
|
allow_any_instance_of(Ably::Logger).to receive(method_name.to_sym).and_wrap_original do |method, *args, &block|
|
@@ -10,11 +12,13 @@ RSpec.configure do |config|
|
|
10
12
|
|
11
13
|
prefix = "#{Time.now.strftime('%H:%M:%S.%L')} [\e[33m#{method_name}\e[0m] "
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
log_mutex.synchronize do
|
16
|
+
begin
|
17
|
+
args << block.call unless block.nil?
|
18
|
+
@log_output << "#{prefix}#{args.compact.join(' ')}"
|
19
|
+
rescue StandardError => e
|
20
|
+
@log_output << "#{prefix}Failed to log block - #{e.class}: #{e.message}\n#{e.backtrace.join("\n")}}"
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
# Call original
|
@@ -53,7 +53,7 @@ describe Ably::Modules::Enum, :api_private do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'allows different type comparison 2' do
|
56
|
-
skip 'Unless we
|
56
|
+
skip 'Unless we monkeypatch Symbols, the == operator is never invoked'
|
57
57
|
expect([:value_zero].include?(subject.ValueZero)).to eql(true)
|
58
58
|
end
|
59
59
|
|
@@ -13,7 +13,7 @@ describe Ably::Realtime::Client do
|
|
13
13
|
let(:client_options) { { key: 'appid.keyuid:keysecret', auto_connect: false } }
|
14
14
|
|
15
15
|
it 'passes on the options to the initializer' do
|
16
|
-
rest_client = instance_double('Ably::Rest::Client', auth: instance_double('Ably::Auth'), options: client_options)
|
16
|
+
rest_client = instance_double('Ably::Rest::Client', auth: instance_double('Ably::Auth'), options: client_options, environment: 'production', use_tls?: true, custom_tls_port: nil)
|
17
17
|
expect(Ably::Rest::Client).to receive(:new).with(hash_including(client_options)).and_return(rest_client)
|
18
18
|
subject
|
19
19
|
end
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require 'shared/protocol_msgbus_behaviour'
|
3
3
|
|
4
4
|
describe Ably::Realtime::Connection do
|
5
|
-
let(:client) { instance_double('Ably::Realtime::Client', logger: double('logger').as_null_object, recover: nil) }
|
5
|
+
let(:client) { instance_double('Ably::Realtime::Client', logger: double('logger').as_null_object, recover: nil, endpoint: double('endpoint', host: 'realtime.ably.io')) }
|
6
6
|
|
7
7
|
subject do
|
8
8
|
Ably::Realtime::Connection.new(client, {}).tap do |connection|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ably
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lewis Marshall
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-08-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
@@ -115,14 +115,14 @@ dependencies:
|
|
115
115
|
requirements:
|
116
116
|
- - ">="
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version:
|
118
|
+
version: 1.3.0
|
119
119
|
type: :runtime
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
123
|
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version:
|
125
|
+
version: 1.3.0
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: addressable
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|