mongo 2.12.0.rc0 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +2 -1
  5. data/lib/mongo/client.rb +23 -9
  6. data/lib/mongo/client_encryption.rb +1 -1
  7. data/lib/mongo/cluster.rb +6 -2
  8. data/lib/mongo/crypt/auto_decryption_context.rb +3 -5
  9. data/lib/mongo/crypt/auto_encrypter.rb +17 -7
  10. data/lib/mongo/crypt/binding.rb +446 -379
  11. data/lib/mongo/crypt/context.rb +4 -4
  12. data/lib/mongo/crypt/encryption_io.rb +16 -10
  13. data/lib/mongo/crypt/explicit_encrypter.rb +3 -3
  14. data/lib/mongo/crypt/explicit_encryption_context.rb +1 -1
  15. data/lib/mongo/crypt/handle.rb +26 -4
  16. data/lib/mongo/crypt/hooks.rb +1 -1
  17. data/lib/mongo/database.rb +11 -1
  18. data/lib/mongo/error/bulk_write_error.rb +16 -14
  19. data/lib/mongo/error/notable.rb +0 -15
  20. data/lib/mongo/error/parser.rb +1 -1
  21. data/lib/mongo/grid/file/info.rb +1 -1
  22. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -1
  23. data/lib/mongo/operation/insert/command.rb +3 -2
  24. data/lib/mongo/operation/insert/legacy.rb +2 -1
  25. data/lib/mongo/operation/insert/op_msg.rb +1 -1
  26. data/lib/mongo/operation/shared/executable.rb +9 -9
  27. data/lib/mongo/operation/shared/op_msg_or_command.rb +2 -2
  28. data/lib/mongo/operation/shared/read_preference_supported.rb +68 -19
  29. data/lib/mongo/operation/shared/response_handling.rb +1 -1
  30. data/lib/mongo/operation/shared/sessions_supported.rb +44 -3
  31. data/lib/mongo/protocol/bit_vector.rb +2 -1
  32. data/lib/mongo/protocol/message.rb +22 -7
  33. data/lib/mongo/protocol/msg.rb +2 -5
  34. data/lib/mongo/protocol/serializers.rb +32 -11
  35. data/lib/mongo/retryable.rb +1 -1
  36. data/lib/mongo/server/connection.rb +1 -1
  37. data/lib/mongo/server/connection_base.rb +9 -4
  38. data/lib/mongo/server/connection_pool/populator.rb +1 -1
  39. data/lib/mongo/session.rb +1 -1
  40. data/lib/mongo/srv/monitor.rb +73 -42
  41. data/lib/mongo/srv/result.rb +0 -1
  42. data/lib/mongo/uri.rb +1 -1
  43. data/lib/mongo/uri/srv_protocol.rb +1 -1
  44. data/lib/mongo/version.rb +1 -1
  45. data/mongo.gemspec +0 -2
  46. data/spec/README.md +106 -12
  47. data/spec/integration/client_construction_spec.rb +29 -5
  48. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +6 -4
  49. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +19 -17
  50. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +5 -4
  51. data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +11 -8
  52. data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +14 -9
  53. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +46 -45
  54. data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +11 -7
  55. data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +13 -9
  56. data/spec/integration/client_side_encryption/client_close_spec.rb +10 -6
  57. data/spec/integration/client_side_encryption/corpus_spec.rb +19 -14
  58. data/spec/integration/client_side_encryption/data_key_spec.rb +10 -8
  59. data/spec/integration/client_side_encryption/external_key_vault_spec.rb +12 -8
  60. data/spec/integration/client_side_encryption/views_spec.rb +6 -4
  61. data/spec/integration/client_update_spec.rb +36 -2
  62. data/spec/integration/crud_spec.rb +89 -0
  63. data/spec/integration/read_preference_spec.rb +26 -0
  64. data/spec/integration/srv_monitoring_spec.rb +2 -2
  65. data/spec/kerberos/kerberos_spec.rb +87 -0
  66. data/spec/lite_spec_helper.rb +4 -8
  67. data/spec/mongo/bulk_write/result_spec.rb +11 -7
  68. data/spec/mongo/client_encryption_spec.rb +3 -6
  69. data/spec/mongo/crypt/auto_encrypter_spec.rb +8 -3
  70. data/spec/mongo/crypt/handle_spec.rb +38 -4
  71. data/spec/mongo/error/bulk_write_error_spec.rb +49 -0
  72. data/spec/mongo/error/notable_spec.rb +59 -0
  73. data/spec/mongo/operation/find/legacy_spec.rb +1 -0
  74. data/spec/mongo/operation/read_preference_legacy_spec.rb +351 -0
  75. data/spec/mongo/operation/read_preference_op_msg_spec.rb +194 -0
  76. data/spec/mongo/srv/monitor_spec.rb +88 -69
  77. data/spec/runners/transactions.rb +5 -7
  78. data/spec/spec_tests/client_side_encryption_spec.rb +0 -5
  79. data/spec/spec_tests/data/client_side_encryption/bulk.yml +3 -0
  80. data/spec/spec_tests/data/client_side_encryption/replaceOne.yml +4 -1
  81. data/spec/spec_tests/data/client_side_encryption/updateOne.yml +3 -0
  82. data/spec/support/cluster_tools.rb +6 -1
  83. data/spec/support/crypt.rb +14 -0
  84. data/spec/support/lite_constraints.rb +3 -1
  85. data/spec/support/spec_config.rb +10 -0
  86. data/spec/support/utils.rb +9 -1
  87. metadata +15 -14
  88. metadata.gz.sig +0 -0
  89. data/lib/mongo/cluster/srv_monitor.rb +0 -127
  90. data/lib/mongo/srv/warning_result.rb +0 -35
  91. data/spec/enterprise_auth/kerberos_spec.rb +0 -58
  92. data/spec/mongo/cluster/srv_monitor_spec.rb +0 -214
  93. data/spec/mongo/operation/read_preference_spec.rb +0 -245
@@ -0,0 +1,59 @@
1
+ require 'lite_spec_helper'
2
+
3
+ describe Mongo::Error::Notable do
4
+ let(:exception_cls) do
5
+ # Since Notable is a module, we need a class that includes it for testing
6
+ Mongo::Error
7
+ end
8
+
9
+ context 'when there are no notes' do
10
+ let(:exception) do
11
+ exception_cls.new('hello world')
12
+ end
13
+
14
+ describe '#message' do
15
+ it 'is correct' do
16
+ exception.message.should == 'hello world'
17
+ end
18
+ end
19
+
20
+ describe '#to_s' do
21
+ it 'is correct' do
22
+ exception.to_s.should == 'hello world'
23
+ end
24
+ end
25
+
26
+ describe '#inspect' do
27
+ it 'is correct' do
28
+ exception.inspect.should == '#<Mongo::Error: hello world>'
29
+ end
30
+ end
31
+ end
32
+
33
+ context 'when there are notes' do
34
+ let(:exception) do
35
+ exception_cls.new('hello world').tap do |exception|
36
+ exception.add_note('brilliant')
37
+ exception.add_note('weird')
38
+ end
39
+ end
40
+
41
+ describe '#message' do
42
+ it 'is correct' do
43
+ exception.message.should == 'hello world (brilliant, weird)'
44
+ end
45
+ end
46
+
47
+ describe '#to_s' do
48
+ it 'is correct' do
49
+ exception.to_s.should == 'hello world (brilliant, weird)'
50
+ end
51
+ end
52
+
53
+ describe '#inspect' do
54
+ it 'is correct' do
55
+ exception.inspect.should == '#<Mongo::Error: hello world (brilliant, weird)>'
56
+ end
57
+ end
58
+ end
59
+ end
@@ -71,6 +71,7 @@ describe Mongo::Operation::Find::Legacy do
71
71
  let(:secondary_server_single) do
72
72
  double('secondary_server').tap do |server|
73
73
  allow(server).to receive(:mongos?) { false }
74
+ allow(server).to receive(:standalone?) { false }
74
75
  allow(server).to receive(:cluster) { cluster_single }
75
76
  allow(server).to receive(:features) { authorized_primary.features }
76
77
  end
@@ -0,0 +1,351 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Operation::ReadPreferenceSupported do
4
+
5
+ let(:selector) do
6
+ { name: 'test' }
7
+ end
8
+
9
+ let(:options) do
10
+ {}
11
+ end
12
+
13
+ let(:cluster) do
14
+ double('cluster').tap do |cluster|
15
+ allow(cluster).to receive(:single?).and_return(single?)
16
+ end
17
+ end
18
+
19
+ let(:operation) do
20
+ Class.new do
21
+ include Mongo::Operation::ReadPreferenceSupported
22
+ end.new.tap do |op|
23
+ allow(op).to receive(:read).and_return(read_pref)
24
+ allow(op).to receive(:selector).and_return(selector)
25
+ allow(op).to receive(:options).and_return(options)
26
+ end
27
+ end
28
+
29
+ let(:server) do
30
+ double('server').tap do |server|
31
+ allow(server).to receive(:cluster).and_return(cluster)
32
+ allow(server).to receive(:mongos?).and_return(mongos?)
33
+ allow(server).to receive(:standalone?).and_return(standalone?)
34
+ end
35
+ end
36
+
37
+ describe '#add_slave_ok_flag_maybe' do
38
+
39
+ let(:actual) do
40
+ operation.send(:add_slave_ok_flag_maybe, operation.send(:options), server)
41
+ end
42
+
43
+ shared_examples_for 'sets the slave_ok flag as expected' do
44
+ it 'sets the slave_ok flag as expected' do
45
+ expect(actual).to eq(expected)
46
+ end
47
+ end
48
+
49
+ shared_examples_for 'never sets slave_ok' do
50
+
51
+ let(:expected) do
52
+ { }
53
+ end
54
+
55
+ context 'when no read preference is specified' do
56
+ let(:read_pref) { Mongo::ServerSelector.get }
57
+
58
+ it_behaves_like 'sets the slave_ok flag as expected'
59
+ end
60
+
61
+ context 'when primary read preference is specified' do
62
+ let(:read_pref) { Mongo::ServerSelector.get(:mode => :primary) }
63
+
64
+ it_behaves_like 'sets the slave_ok flag as expected'
65
+ end
66
+
67
+ context 'when secondary read preference is specified' do
68
+ let(:read_pref) { Mongo::ServerSelector.get(:mode => :secondary) }
69
+
70
+ it_behaves_like 'sets the slave_ok flag as expected'
71
+ end
72
+ end
73
+
74
+ shared_examples_for 'always sets slave_ok' do
75
+
76
+ let(:expected) do
77
+ { :flags => [ :slave_ok ] }
78
+ end
79
+
80
+ context 'when no read preference is specified' do
81
+ let(:read_pref) { Mongo::ServerSelector.get }
82
+
83
+ it_behaves_like 'sets the slave_ok flag as expected'
84
+ end
85
+
86
+ context 'when primary read preference is specified' do
87
+ let(:read_pref) { Mongo::ServerSelector.get(:mode => :primary) }
88
+
89
+ it_behaves_like 'sets the slave_ok flag as expected'
90
+ end
91
+
92
+ context 'when secondary read preference is specified' do
93
+ let(:read_pref) { Mongo::ServerSelector.get(:mode => :secondary) }
94
+
95
+ it_behaves_like 'sets the slave_ok flag as expected'
96
+ end
97
+ end
98
+
99
+ shared_examples_for 'sets slave_ok if read preference is specified and is not primary' do
100
+
101
+ context 'when there is no read preference set' do
102
+
103
+ let(:read_pref) { Mongo::ServerSelector.get }
104
+
105
+ let(:expected) do
106
+ { }
107
+ end
108
+
109
+ it_behaves_like 'sets the slave_ok flag as expected'
110
+ end
111
+
112
+ context 'when there is a read preference' do
113
+
114
+ context 'when the read preference requires the slave_ok flag' do
115
+
116
+ let(:read_pref) { Mongo::ServerSelector.get(:mode => :secondary) }
117
+
118
+ let(:expected) do
119
+ { :flags => [ :slave_ok ] }
120
+ end
121
+
122
+ it_behaves_like 'sets the slave_ok flag as expected'
123
+ end
124
+
125
+ context 'when the read preference does not require the slave_ok flag' do
126
+
127
+ let(:read_pref) { Mongo::ServerSelector.get(:mode => :primary) }
128
+
129
+ let(:expected) do
130
+ { }
131
+ end
132
+
133
+ it_behaves_like 'sets the slave_ok flag as expected'
134
+ end
135
+ end
136
+ end
137
+
138
+ context 'when the topology is Single' do
139
+
140
+ let(:single?) { true }
141
+ let(:mongos?) { false }
142
+
143
+ context 'when the server is a standalone' do
144
+
145
+ let(:standalone?) { true }
146
+
147
+ it_behaves_like 'never sets slave_ok'
148
+ end
149
+
150
+ context 'when the server is a mongos' do
151
+
152
+ let(:standalone?) { false }
153
+ let(:mongos?) { true }
154
+
155
+ it_behaves_like 'always sets slave_ok'
156
+ end
157
+
158
+ context 'when the server is a replica set member' do
159
+
160
+ let(:standalone?) { false }
161
+ let(:mongos?) { false }
162
+
163
+ it_behaves_like 'always sets slave_ok'
164
+ end
165
+ end
166
+
167
+ context 'when the topology is not Single' do
168
+
169
+ let(:single?) { false }
170
+ let(:mongos?) { false }
171
+
172
+ context 'when the server is a standalone' do
173
+
174
+ let(:standalone?) { true }
175
+
176
+ it_behaves_like 'never sets slave_ok'
177
+ end
178
+
179
+ context 'when the server is a mongos' do
180
+
181
+ let(:standalone?) { false }
182
+ let(:mongos?) { true }
183
+
184
+ it_behaves_like 'sets slave_ok if read preference is specified and is not primary'
185
+ end
186
+
187
+ context 'when the server is a replica set member' do
188
+
189
+ let(:standalone?) { false }
190
+ let(:mongos?) { false }
191
+
192
+ it_behaves_like 'sets slave_ok if read preference is specified and is not primary'
193
+ end
194
+ end
195
+ end
196
+
197
+ describe '#update_selector_for_read_pref' do
198
+
199
+ let(:read_pref) do
200
+ Mongo::ServerSelector.get(:mode => mode)
201
+ end
202
+
203
+ # Behavior of sending $readPreference is the same regardless of topology.
204
+ shared_examples_for '$readPreference in the command' do
205
+ let(:actual) do
206
+ operation.send(:update_selector_for_read_pref, operation.send(:selector), server)
207
+ end
208
+
209
+ let(:expected_read_preference) do
210
+ {mode: mode.to_s.gsub(/_(.)/) { $1.upcase }}
211
+ end
212
+
213
+ shared_examples_for 'adds read preference moving existing contents to $query' do
214
+
215
+ let(:expected) do
216
+ { :$query => selector, :$readPreference => expected_read_preference }
217
+ end
218
+
219
+ it 'moves existing selector contents under $query and adds read preference' do
220
+ expect(actual).to eq(expected)
221
+ end
222
+
223
+ context 'when the selector already has $query in it' do
224
+
225
+ let(:selector) do
226
+ { :$query => { :name => 'test' },
227
+ :$orderby => { :name => -1 } }
228
+ end
229
+
230
+ let(:expected) do
231
+ selector.merge(:$readPreference => expected_read_preference)
232
+ end
233
+
234
+ it 'keeps existing $query and adds read preference' do
235
+ expect(actual).to eq(expected)
236
+ end
237
+ end
238
+ end
239
+
240
+ shared_examples_for 'does not modify selector' do
241
+
242
+ it 'does not modify selector' do
243
+ expect(actual).to eq(selector)
244
+ end
245
+ end
246
+
247
+ shared_examples_for 'does not send read preference' do
248
+ ([nil] + %i(primary primary_preferred secondary secondary_preferred nearest)).each do |_mode|
249
+ active_mode = _mode
250
+
251
+ context "when read preference mode is #{active_mode}" do
252
+ let(:mode) { active_mode }
253
+
254
+ it_behaves_like 'does not modify selector'
255
+ end
256
+ end
257
+ end
258
+
259
+ context 'when the server is a standalone' do
260
+
261
+ let(:standalone?) { true }
262
+ let(:mongos?) { false }
263
+
264
+ it_behaves_like 'does not send read preference'
265
+ end
266
+
267
+ context 'when the server is a mongos' do
268
+
269
+ let(:standalone?) { false }
270
+ let(:mongos?) { true }
271
+
272
+ context 'when the read preference mode is nil' do
273
+
274
+ let(:mode) { nil }
275
+
276
+ it_behaves_like 'does not modify selector'
277
+ end
278
+
279
+ context 'when the read preference mode is primary' do
280
+
281
+ let(:mode) { :primary }
282
+
283
+ it_behaves_like 'does not modify selector'
284
+ end
285
+
286
+ context 'when the read preference mode is primary_preferred' do
287
+
288
+ let(:mode) { :primary_preferred }
289
+
290
+ it_behaves_like 'adds read preference moving existing contents to $query'
291
+ end
292
+
293
+ context 'when the read preference mode is secondary' do
294
+
295
+ let(:mode) { :secondary }
296
+
297
+ it_behaves_like 'adds read preference moving existing contents to $query'
298
+ end
299
+
300
+ context 'when the read preference mode is secondary_preferred' do
301
+
302
+ let(:mode) { :secondary_preferred }
303
+
304
+ it_behaves_like 'does not modify selector'
305
+
306
+ context 'when there are fields in the selector besides :mode' do
307
+ let(:read_pref) do
308
+ Mongo::ServerSelector.get(:mode => mode, tag_sets: ['dc' => 'nyc'])
309
+ end
310
+
311
+ let(:expected_read_preference) do
312
+ {mode: mode.to_s.gsub(/_(.)/) { $1.upcase }, tags: ['dc' => 'nyc']}
313
+ end
314
+
315
+ it_behaves_like 'adds read preference moving existing contents to $query'
316
+ end
317
+ end
318
+
319
+ context 'when the read preference mode is nearest' do
320
+
321
+ let(:mode) { :nearest }
322
+
323
+ it_behaves_like 'adds read preference moving existing contents to $query'
324
+ end
325
+ end
326
+
327
+ context 'when the server is a replica set member' do
328
+
329
+ let(:standalone?) { false }
330
+ let(:mongos?) { false }
331
+
332
+ # $readPreference is not sent to replica set nodes running legacy
333
+ # servers - the allowance of secondary reads is handled by slave_ok
334
+ # flag.
335
+ it_behaves_like 'does not send read preference'
336
+ end
337
+ end
338
+
339
+ context 'in single topology' do
340
+ let(:single?) { true }
341
+
342
+ it_behaves_like '$readPreference in the command'
343
+ end
344
+
345
+ context 'not in single topology' do
346
+ let(:single?) { false }
347
+
348
+ it_behaves_like '$readPreference in the command'
349
+ end
350
+ end
351
+ end
@@ -0,0 +1,194 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Operation::SessionsSupported do
4
+
5
+ let(:selector) do
6
+ BSON::Document.new(name: 'test')
7
+ end
8
+
9
+ let(:options) do
10
+ {}
11
+ end
12
+
13
+ let(:cluster) do
14
+ double('cluster').tap do |cluster|
15
+ allow(cluster).to receive(:single?).and_return(single?)
16
+ end
17
+ end
18
+
19
+ let(:operation) do
20
+ Class.new do
21
+ include Mongo::Operation::SessionsSupported
22
+ end.new.tap do |op|
23
+ allow(op).to receive(:read).and_return(read_pref)
24
+ allow(op).to receive(:selector).and_return(selector)
25
+ allow(op).to receive(:options).and_return(options)
26
+ end
27
+ end
28
+
29
+ let(:server) do
30
+ double('server').tap do |server|
31
+ allow(server).to receive(:cluster).and_return(cluster)
32
+ allow(server).to receive(:mongos?).and_return(mongos?)
33
+ allow(server).to receive(:standalone?).and_return(standalone?)
34
+ end
35
+ end
36
+
37
+ describe '#add_read_preference' do
38
+
39
+ let(:read_pref) do
40
+ Mongo::ServerSelector.get(:mode => mode)
41
+ end
42
+
43
+ let(:actual) do
44
+ sel = operation.send(:selector).dup
45
+ operation.send(:add_read_preference, sel, server)
46
+ sel
47
+ end
48
+
49
+ let(:expected_read_preference) do
50
+ {mode: mode.to_s.gsub(/_(.)/) { $1.upcase }}
51
+ end
52
+
53
+ shared_examples_for 'adds read preference' do
54
+
55
+ let(:expected) do
56
+ selector.merge(:$readPreference => expected_read_preference)
57
+ end
58
+
59
+ it 'adds read preference' do
60
+ expect(actual).to eq(expected)
61
+ end
62
+ end
63
+
64
+ shared_examples_for 'does not modify selector' do
65
+
66
+ it 'does not modify selector' do
67
+ expect(actual).to eq(selector)
68
+ end
69
+ end
70
+
71
+ shared_examples_for 'does not send read preference' do
72
+ ([nil] + %i(primary primary_preferred secondary secondary_preferred nearest)).each do |_mode|
73
+ active_mode = _mode
74
+
75
+ context "when read preference mode is #{active_mode}" do
76
+ let(:mode) { active_mode }
77
+
78
+ it_behaves_like 'does not modify selector'
79
+ end
80
+ end
81
+ end
82
+
83
+ shared_examples_for 'sends user-specified read preference' do
84
+ %i(primary primary_preferred secondary secondary_preferred nearest).each do |_mode|
85
+ active_mode = _mode
86
+
87
+ context "when read preference mode is #{active_mode}" do
88
+ let(:mode) { active_mode }
89
+
90
+ it_behaves_like 'adds read preference'
91
+ end
92
+ end
93
+
94
+ context "when read preference mode is nil" do
95
+ let(:mode) { nil }
96
+
97
+ let(:expected_read_preference) do
98
+ {mode: 'primary'}
99
+ end
100
+
101
+ it_behaves_like 'adds read preference'
102
+ end
103
+ end
104
+
105
+ shared_examples_for 'changes read preference to allow secondary reads' do
106
+
107
+ %i(primary_preferred secondary secondary_preferred nearest).each do |_mode|
108
+ active_mode = _mode
109
+
110
+ context "when read preference mode is #{active_mode}" do
111
+ let(:mode) { active_mode }
112
+
113
+ it_behaves_like 'adds read preference'
114
+ end
115
+ end
116
+
117
+ context "when read preference mode is primary" do
118
+ let(:mode) { :primary }
119
+
120
+ let(:expected_read_preference) do
121
+ {mode: 'primaryPreferred'}
122
+ end
123
+
124
+ it_behaves_like 'adds read preference'
125
+ end
126
+
127
+ context "when read preference mode is nil" do
128
+ let(:mode) { nil }
129
+
130
+ let(:expected_read_preference) do
131
+ {mode: 'primaryPreferred'}
132
+ end
133
+
134
+ it_behaves_like 'adds read preference'
135
+ end
136
+ end
137
+
138
+ context 'in single topology' do
139
+ let(:single?) { true }
140
+
141
+ context 'when the server is a standalone' do
142
+
143
+ let(:standalone?) { true }
144
+ let(:mongos?) { false }
145
+
146
+ it_behaves_like 'does not send read preference'
147
+ end
148
+
149
+ context 'when the server is a mongos' do
150
+
151
+ let(:standalone?) { false }
152
+ let(:mongos?) { true }
153
+
154
+ it_behaves_like 'changes read preference to allow secondary reads'
155
+ end
156
+
157
+ context 'when the server is a replica set member' do
158
+
159
+ let(:standalone?) { false }
160
+ let(:mongos?) { false }
161
+
162
+ it_behaves_like 'changes read preference to allow secondary reads'
163
+ end
164
+ end
165
+
166
+ context 'not in single topology' do
167
+ let(:single?) { false }
168
+
169
+ context 'when the server is a standalone' do
170
+
171
+ let(:standalone?) { true }
172
+ let(:mongos?) { false }
173
+
174
+ it_behaves_like 'does not send read preference'
175
+ end
176
+
177
+ context 'when the server is a mongos' do
178
+
179
+ let(:standalone?) { false }
180
+ let(:mongos?) { true }
181
+
182
+ it_behaves_like 'sends user-specified read preference'
183
+ end
184
+
185
+ context 'when the server is a replica set member' do
186
+
187
+ let(:standalone?) { false }
188
+ let(:mongos?) { false }
189
+
190
+ it_behaves_like 'sends user-specified read preference'
191
+ end
192
+ end
193
+ end
194
+ end