Skip to content

Commit c1623c3

Browse files
committed
Fix EventMachine test pollution causing cascade failures
- Add after(:example) hook to clear stale realtime_clients and stop EM reactor between tests, preventing leaked state from crashed or timed-out tests poisoning subsequent EM-dependent tests - Switch paginated result specs from manual include + run_reactor to :event_machine metadata tag so they get proper before/around/after lifecycle hooks
1 parent 411d708 commit c1623c3

3 files changed

Lines changed: 37 additions & 38 deletions

File tree

spec/support/event_machine_helper.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,21 @@ def wait_until(condition_block, &block)
139139
# Ensure EventMachine shutdown hooks are deregistered for every test
140140
EventMachine.instance_variable_set '@tails', []
141141
end
142+
143+
# Catch-all cleanup for ANY test that used EventMachine, whether via
144+
# the :event_machine tag or by calling run_reactor directly. Without this,
145+
# a crashed/timed-out reactor and stale client references leak into
146+
# subsequent tests causing cascade failures.
147+
config.after(:example) do
148+
RSpec::EventMachine.realtime_clients.clear
149+
begin
150+
EventMachine.stop if EventMachine.reactor_running?
151+
rescue RuntimeError
152+
# EM can be in a corrupted state (e.g. signal_loopbreak failure)
153+
# where reactor_running? returns true but stop raises. Swallow
154+
# the error to prevent cascading failures across subsequent tests.
155+
end
156+
end
142157
end
143158

144159
module RSpec

spec/unit/models/http_paginated_result_spec.rb

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -128,40 +128,32 @@
128128
end
129129

130130
if defined?(Ably::Realtime)
131-
context 'with option async_blocking_operations: true' do
132-
include RSpec::EventMachine
133-
131+
context 'with option async_blocking_operations: true', :event_machine do
134132
subject do
135133
paginated_result_class.new(http_response, full_url, paged_client, async_blocking_operations: true)
136134
end
137135

138136
context '#next' do
139137
it 'returns a SafeDeferrable that catches exceptions in callbacks and logs them' do
140-
run_reactor do
141-
expect(subject.next).to be_a(Ably::Util::SafeDeferrable)
142-
stop_reactor
143-
end
138+
expect(subject.next).to be_a(Ably::Util::SafeDeferrable)
139+
stop_reactor
144140
end
145141

146142
it 'allows a success callback block to be added' do
147-
run_reactor do
148-
subject.next do |paginated_result|
149-
expect(paginated_result).to be_a(Ably::Models::HttpPaginatedResponse)
150-
stop_reactor
151-
end
143+
subject.next do |paginated_result|
144+
expect(paginated_result).to be_a(Ably::Models::HttpPaginatedResponse)
145+
stop_reactor
152146
end
153147
end
154148
end
155149

156150
context '#first' do
157151
it 'calls the errback callback when first page headers are missing' do
158-
run_reactor do
159-
subject.next do |paginated_result|
160-
deferrable = subject.first
161-
deferrable.errback do |error|
162-
expect(error).to be_a(Ably::Exceptions::PageMissing)
163-
stop_reactor
164-
end
152+
subject.next do |paginated_result|
153+
deferrable = subject.first
154+
deferrable.errback do |error|
155+
expect(error).to be_a(Ably::Exceptions::PageMissing)
156+
stop_reactor
165157
end
166158
end
167159
end

spec/unit/models/paginated_result_spec.rb

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -126,40 +126,32 @@
126126
end
127127

128128
if defined?(Ably::Realtime)
129-
context 'with option async_blocking_operations: true' do
130-
include RSpec::EventMachine
131-
129+
context 'with option async_blocking_operations: true', :event_machine do
132130
subject do
133131
paginated_result_class.new(http_response, full_url, paged_client, async_blocking_operations: true)
134132
end
135133

136134
context '#next' do
137135
it 'returns a SafeDeferrable that catches exceptions in callbacks and logs them' do
138-
run_reactor do
139-
expect(subject.next).to be_a(Ably::Util::SafeDeferrable)
140-
stop_reactor
141-
end
136+
expect(subject.next).to be_a(Ably::Util::SafeDeferrable)
137+
stop_reactor
142138
end
143139

144140
it 'allows a success callback block to be added' do
145-
run_reactor do
146-
subject.next do |paginated_result|
147-
expect(paginated_result).to be_a(Ably::Models::PaginatedResult)
148-
stop_reactor
149-
end
141+
subject.next do |paginated_result|
142+
expect(paginated_result).to be_a(Ably::Models::PaginatedResult)
143+
stop_reactor
150144
end
151145
end
152146
end
153147

154148
context '#first' do
155149
it 'calls the errback callback when first page headers are missing' do
156-
run_reactor do
157-
subject.next do |paginated_result|
158-
deferrable = subject.first
159-
deferrable.errback do |error|
160-
expect(error).to be_a(Ably::Exceptions::PageMissing)
161-
stop_reactor
162-
end
150+
subject.next do |paginated_result|
151+
deferrable = subject.first
152+
deferrable.errback do |error|
153+
expect(error).to be_a(Ably::Exceptions::PageMissing)
154+
stop_reactor
163155
end
164156
end
165157
end

0 commit comments

Comments
 (0)