Skip to content

Commit dafae82

Browse files
authored
RUBY-1954 Integration test for exceptions referencing second attempt's server for retryable operations (#1551)
* RUBY-1954 Integration test for exceptions referencing second attempt's server for retryable operations * Also verify servers are reset to unknown * Require 4.0+
2 parents 81a2f0a + 1c652fc commit dafae82

File tree

4 files changed

+119
-12
lines changed

4 files changed

+119
-12
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
require 'spec_helper'
2+
3+
describe 'Retryable writes tests' do
4+
# Requirement for fail point
5+
min_server_fcv '4.0'
6+
7+
let(:client) do
8+
subscribed_client
9+
end
10+
11+
let(:collection) do
12+
client['retryable-writes-error-spec']
13+
end
14+
15+
context 'when retry fails' do
16+
require_topology :replica_set
17+
18+
let(:fail_point_command) do
19+
{
20+
configureFailPoint: 'failCommand',
21+
mode: {times: 1},
22+
data: {
23+
failCommands: ['find'],
24+
errorCode: 11600,
25+
},
26+
}
27+
end
28+
29+
let(:clear_fail_point_command) do
30+
{
31+
configureFailPoint: 'failCommand',
32+
mode: 'off',
33+
}
34+
end
35+
36+
after do
37+
ClusterTools.instance.direct_client_for_each_server do |client|
38+
client.use(:admin).database.command(clear_fail_point_command)
39+
end
40+
end
41+
42+
let(:collection) do
43+
client['retryable-writes-error-spec', read: {mode: :secondary_preferred}]
44+
end
45+
46+
let(:events) do
47+
events = EventSubscriber.command_started_events('find')
48+
end
49+
50+
let(:first_server) do
51+
client.cluster.servers_list.detect do |server|
52+
server.address.seed == events.first.address.seed
53+
end
54+
end
55+
56+
let(:second_server) do
57+
client.cluster.servers_list.detect do |server|
58+
server.address.seed == events.last.address.seed
59+
end
60+
end
61+
62+
let(:perform_read) do
63+
client.cluster.servers_list.each do |server|
64+
server.monitor.stop!
65+
end
66+
67+
ClusterTools.instance.direct_client_for_each_server do |client|
68+
client.use(:admin).database.command(fail_point_command)
69+
end
70+
71+
begin
72+
collection.find(a: 1).to_a
73+
rescue Mongo::Error::OperationFailure => @exception
74+
else
75+
fail('Expected operation to fail')
76+
end
77+
78+
puts @exception.message
79+
80+
expect(events.length).to eq(2)
81+
expect(events.first.address.seed).not_to eq(events.last.address.seed)
82+
end
83+
84+
it 'is reported on the server of the second attempt' do
85+
perform_read
86+
87+
expect(@exception.message).not_to include(first_server.address.seed)
88+
expect(@exception.message).to include(second_server.address.seed)
89+
end
90+
91+
it 'marks servers used in both attempts unknown' do
92+
perform_read
93+
94+
expect(first_server).to be_unknown
95+
96+
expect(second_server).to be_unknown
97+
end
98+
end
99+
end
Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
require 'spec_helper'
22

33
describe 'Retryable writes errors tests' do
4-
describe 'when the storage engine does not support retryable writes but the server does' do
4+
5+
let(:client) do
6+
authorized_client.with(retry_writes: true)
7+
end
8+
9+
let(:collection) do
10+
client['retryable-writes-error-spec']
11+
end
12+
13+
context 'when the storage engine does not support retryable writes but the server does' do
514
require_mmapv1
615
min_server_fcv '3.6'
716
require_topology :replica_set, :sharded
@@ -10,14 +19,6 @@
1019
collection.delete_many
1120
end
1221

13-
let(:collection) do
14-
client[authorized_collection.name]
15-
end
16-
17-
let(:client) do
18-
authorized_client.with(retry_writes: true)
19-
end
20-
2122
context 'when a retryable write is attempted' do
2223
it 'raises an actionable error message' do
2324
expect {
@@ -27,4 +28,4 @@
2728
end
2829
end
2930
end
30-
end
31+
end

spec/support/cluster_tools.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,6 @@ def close_clients
349349
end
350350
end
351351

352-
private
353-
354352
def each_server(&block)
355353
admin_client.cluster.servers_list.each(&block)
356354
end
@@ -361,6 +359,8 @@ def direct_client_for_each_server(&block)
361359
end
362360
end
363361

362+
private
363+
364364
def reset_server_states
365365
each_server do |server|
366366
server.unknown!

spec/support/event_subscriber.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ def started(event)
4444
end
4545
end
4646

47+
# Filters command started events for the specified command name.
48+
def command_started_events(command_name)
49+
started_events.select do |event|
50+
event.command[command_name]
51+
end
52+
end
53+
4754
# Locates command stated events for the specified command name,
4855
# asserts that there is exactly one such event, and returns it.
4956
def single_command_started_event(command_name)

0 commit comments

Comments
 (0)