Skip to content

Commit bfe7a35

Browse files
RUBY-2706 Test find related options (#2789)
* 2706 * Add unified test for all find options * Add missing options * Clarify collation on collection * Add tests for read_concern option * Add tests for read_preference option
1 parent 7fd9ad4 commit bfe7a35

File tree

5 files changed

+551
-1
lines changed

5 files changed

+551
-1
lines changed

Diff for: lib/mongo/collection.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,9 @@ def capped?
339339
# inserted or updated documents where the clustered index key value
340340
# matches an existing value in the index.
341341
# - *:name* -- Optional. A name that uniquely identifies the clustered index.
342-
# @option opts [ Hash ] :collation The collation to use.
342+
# @option opts [ Hash ] :collation The collation to use when creating the
343+
# collection. This option will not be sent to the server when calling
344+
# collection methods.
343345
# @option opts [ Hash ] :encrypted_fields Hash describing encrypted fields
344346
# for queryable encryption.
345347
# @option opts [ Integer ] :expire_after Number indicating

Diff for: lib/mongo/collection/view/iterable.rb

+1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ def initial_query_op(session)
162162
let: options[:let],
163163
limit: limit,
164164
allow_disk_use: options[:allow_disk_use],
165+
allow_partial_results: options[:allow_partial_results],
165166
read: read,
166167
read_concern: options[:read_concern] || read_concern,
167168
batch_size: batch_size,

Diff for: spec/integration/find_options_spec.rb

+190
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe 'Find operation options' do
6+
require_mri
7+
require_no_auth
8+
min_server_fcv '4.4'
9+
10+
let(:subscriber) { Mrss::EventSubscriber.new }
11+
12+
let(:seeds) do
13+
[ SpecConfig.instance.addresses.first ]
14+
end
15+
16+
let(:client) do
17+
ClientRegistry.instance.new_local_client(
18+
seeds,
19+
SpecConfig.instance.test_options.merge(client_options)
20+
).tap do |client|
21+
client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
22+
end
23+
end
24+
25+
let(:collection) do
26+
client['find_options', collection_options]
27+
end
28+
29+
let(:find_command) do
30+
subscriber.started_events.find { |cmd| cmd.command_name == 'find' }
31+
end
32+
33+
before do
34+
ClientRegistry.instance.global_client('authorized')['find_options'].drop
35+
collection.insert_many([ { a: 1 }, { a: 2 }, { a: 3 } ])
36+
end
37+
38+
describe 'collation' do
39+
let(:client_options) do
40+
{}
41+
end
42+
43+
let(:collation) do
44+
{ 'locale' => 'en_US' }
45+
end
46+
47+
context 'when defined on the collection' do
48+
let(:collection_options) do
49+
{ collation: collation }
50+
end
51+
52+
it 'uses the collation defined on the collection' do
53+
collection.find.to_a
54+
expect(find_command.command['collation']).to be_nil
55+
end
56+
end
57+
58+
context 'when defined on the operation' do
59+
let(:collection_options) do
60+
{}
61+
end
62+
63+
it 'uses the collation defined on the collection' do
64+
collection.find({}, collation: collation).to_a
65+
expect(find_command.command['collation']).to eq(collation)
66+
end
67+
end
68+
69+
context 'when defined on both collection and operation' do
70+
let(:collection_options) do
71+
{ 'locale' => 'de_AT' }
72+
end
73+
74+
it 'uses the collation defined on the collection' do
75+
collection.find({}, collation: collation).to_a
76+
expect(find_command.command['collation']).to eq(collation)
77+
end
78+
end
79+
end
80+
81+
describe 'read concern' do
82+
context 'when defined on the client' do
83+
let(:client_options) do
84+
{ read_concern: { level: :local } }
85+
end
86+
87+
let(:collection_options) do
88+
{}
89+
end
90+
91+
it 'uses the read concern defined on the client' do
92+
collection.find.to_a
93+
expect(find_command.command['readConcern']).to eq('level' => 'local')
94+
end
95+
96+
context 'when defined on the collection' do
97+
let(:collection_options) do
98+
{ read_concern: { level: :majority } }
99+
end
100+
101+
it 'uses the read concern defined on the collection' do
102+
collection.find.to_a
103+
expect(find_command.command['readConcern']).to eq('level' => 'majority')
104+
end
105+
106+
context 'when defined on the operation' do
107+
let(:operation_read_concern) do
108+
{ level: :available }
109+
end
110+
111+
it 'uses the read concern defined on the operation' do
112+
collection.find({}, read_concern: operation_read_concern).to_a
113+
expect(find_command.command['readConcern']).to eq('level' => 'available')
114+
end
115+
end
116+
end
117+
118+
context 'when defined on the operation' do
119+
let(:collection_options) do
120+
{}
121+
end
122+
123+
let(:operation_read_concern) do
124+
{ level: :available }
125+
end
126+
127+
it 'uses the read concern defined on the operation' do
128+
collection.find({}, read_concern: operation_read_concern).to_a
129+
expect(find_command.command['readConcern']).to eq('level' => 'available')
130+
end
131+
end
132+
end
133+
134+
context 'when defined on the collection' do
135+
let(:client_options) do
136+
{}
137+
end
138+
139+
let(:collection_options) do
140+
{ read_concern: { level: :majority } }
141+
end
142+
143+
it 'uses the read concern defined on the collection' do
144+
collection.find.to_a
145+
expect(find_command.command['readConcern']).to eq('level' => 'majority')
146+
end
147+
148+
context 'when defined on the operation' do
149+
let(:operation_read_concern) do
150+
{ level: :available }
151+
end
152+
153+
it 'uses the read concern defined on the operation' do
154+
collection.find({}, read_concern: operation_read_concern).to_a
155+
expect(find_command.command['readConcern']).to eq('level' => 'available')
156+
end
157+
end
158+
end
159+
end
160+
161+
describe 'read preference' do
162+
require_topology :replica_set
163+
164+
context 'when defined on the client' do
165+
let(:client_options) do
166+
{ read: { mode: :secondary } }
167+
end
168+
169+
let(:collection_options) do
170+
{}
171+
end
172+
173+
it 'uses the read preference defined on the client' do
174+
collection.find.to_a
175+
expect(find_command.command['$readPreference']).to eq('mode' => 'secondary')
176+
end
177+
178+
context 'when defined on the collection' do
179+
let(:collection_options) do
180+
{ read: { mode: :secondary_preferred } }
181+
end
182+
183+
it 'uses the read concern defined on the collection' do
184+
collection.find.to_a
185+
expect(find_command.command['$readPreference']).to eq('mode' => 'secondaryPreferred')
186+
end
187+
end
188+
end
189+
end
190+
end

Diff for: spec/runners/unified/crud_operations.rb

+12
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ def get_find_view(op)
3232
if session = args.use('session')
3333
opts[:session] = entities.get(:session, session)
3434
end
35+
if collation = args.use('collation')
36+
opts[:collation] = collation
37+
end
38+
if args.key?('noCursorTimeout')
39+
opts[:no_cursor_timeout] = args.use('noCursorTimeout')
40+
end
41+
if args.key?('oplogReplay')
42+
opts[:oplog_replay] = args.use('oplogReplay')
43+
end
44+
if args.key?('allowPartialResults')
45+
opts[:allow_partial_results] = args.use('allowPartialResults')
46+
end
3547
req = collection.find(args.use!('filter'), **opts)
3648
if batch_size = args.use('batchSize')
3749
req = req.batch_size(batch_size)

0 commit comments

Comments
 (0)