mongo 2.0.5 → 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo/auth/cr/conversation.rb +0 -1
  5. data/lib/mongo/client.rb +19 -5
  6. data/lib/mongo/cluster.rb +84 -16
  7. data/lib/mongo/cluster/topology.rb +3 -4
  8. data/lib/mongo/cluster/topology/replica_set.rb +75 -0
  9. data/lib/mongo/cluster/topology/sharded.rb +60 -0
  10. data/lib/mongo/cluster/topology/single.rb +51 -0
  11. data/lib/mongo/cluster/topology/unknown.rb +62 -0
  12. data/lib/mongo/error/invalid_bulk_operation.rb +2 -1
  13. data/lib/mongo/event.rb +9 -9
  14. data/lib/mongo/event/{server_added.rb → description_changed.rb} +6 -5
  15. data/lib/mongo/event/{server_removed.rb → standalone_discovered.rb} +15 -15
  16. data/lib/mongo/operation/aggregate.rb +6 -5
  17. data/lib/mongo/operation/command.rb +5 -6
  18. data/lib/mongo/operation/kill_cursors.rb +3 -2
  19. data/lib/mongo/operation/map_reduce.rb +6 -5
  20. data/lib/mongo/operation/read/collections_info.rb +5 -4
  21. data/lib/mongo/operation/read/get_more.rb +8 -7
  22. data/lib/mongo/operation/read/indexes.rb +4 -3
  23. data/lib/mongo/operation/read/list_collections.rb +5 -4
  24. data/lib/mongo/operation/read/list_indexes.rb +7 -6
  25. data/lib/mongo/operation/read/query.rb +8 -7
  26. data/lib/mongo/operation/read_preferrable.rb +6 -2
  27. data/lib/mongo/operation/write/bulk/bulk_delete.rb +13 -12
  28. data/lib/mongo/operation/write/bulk/bulk_insert.rb +10 -9
  29. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +2 -2
  30. data/lib/mongo/operation/write/bulk/bulk_update.rb +12 -11
  31. data/lib/mongo/operation/write/create_index.rb +8 -7
  32. data/lib/mongo/operation/write/create_user.rb +4 -3
  33. data/lib/mongo/operation/write/delete.rb +13 -12
  34. data/lib/mongo/operation/write/drop_index.rb +6 -5
  35. data/lib/mongo/operation/write/insert.rb +8 -7
  36. data/lib/mongo/operation/write/insert/result.rb +1 -1
  37. data/lib/mongo/operation/write/remove_user.rb +4 -3
  38. data/lib/mongo/operation/write/update.rb +10 -9
  39. data/lib/mongo/operation/write/update_user.rb +4 -3
  40. data/lib/mongo/server.rb +8 -15
  41. data/lib/mongo/server/context.rb +2 -2
  42. data/lib/mongo/server/description.rb +65 -3
  43. data/lib/mongo/server/description/features.rb +2 -1
  44. data/lib/mongo/server/description/inspector.rb +5 -5
  45. data/lib/mongo/server/description/inspector/{server_added.rb → description_changed.rb} +3 -5
  46. data/lib/mongo/server/description/inspector/{server_removed.rb → standalone_discovered.rb} +12 -15
  47. data/lib/mongo/version.rb +1 -1
  48. data/spec/mongo/auth/cr_spec.rb +1 -1
  49. data/spec/mongo/auth/ldap_spec.rb +1 -1
  50. data/spec/mongo/auth/scram_spec.rb +1 -1
  51. data/spec/mongo/auth/x509_spec.rb +1 -1
  52. data/spec/mongo/client_spec.rb +4 -0
  53. data/spec/mongo/cluster/topology/replica_set_spec.rb +254 -4
  54. data/spec/mongo/cluster/topology/sharded_spec.rb +70 -19
  55. data/spec/mongo/cluster/topology/single_spec.rb +25 -4
  56. data/spec/mongo/cluster/topology/unknown_spec.rb +167 -0
  57. data/spec/mongo/cluster/topology_spec.rb +6 -6
  58. data/spec/mongo/cluster_spec.rb +179 -1
  59. data/spec/mongo/operation/read_preferrable_spec.rb +81 -28
  60. data/spec/mongo/operation/write/bulk/bulk_delete_spec.rb +1 -0
  61. data/spec/mongo/server/connection_pool_spec.rb +10 -10
  62. data/spec/mongo/server/connection_spec.rb +1 -1
  63. data/spec/mongo/server/description/features_spec.rb +23 -3
  64. data/spec/mongo/server/description/inspector/description_changed_spec.rb +78 -0
  65. data/spec/mongo/server/description_spec.rb +238 -0
  66. data/spec/mongo/server/monitor_spec.rb +1 -1
  67. data/spec/mongo/server_discovery_and_monitoring_spec.rb +20 -4
  68. data/spec/mongo/server_selection_spec.rb +2 -2
  69. data/spec/mongo/server_spec.rb +12 -8
  70. data/spec/support/authorization.rb +8 -8
  71. data/spec/support/sdam/rs/discover_passives.yml +36 -0
  72. data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +2 -2
  73. data/spec/support/sdam/rs/primary_becomes_standalone.yml +1 -1
  74. data/spec/support/sdam/rs/primary_changes_set_name.yml +2 -2
  75. data/spec/support/sdam/rs/primary_disconnect.yml +1 -1
  76. data/spec/support/sdam/rs/primary_wrong_set_name.yml +1 -1
  77. data/spec/support/sdam/rs/secondary_wrong_set_name.yml +1 -1
  78. data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +2 -2
  79. data/spec/support/sdam/sharded/single_mongos.yml +33 -0
  80. data/spec/support/shared/operation.rb +12 -4
  81. data/spec/support/shared/server_selector.rb +1 -1
  82. metadata +12 -10
  83. metadata.gz.sig +0 -0
  84. data/spec/mongo/server/description/inspector/server_added_spec.rb +0 -92
  85. data/spec/mongo/server/description/inspector/server_removed_spec.rb +0 -95
@@ -13,8 +13,8 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require 'mongo/server/description/inspector/primary_elected'
16
- require 'mongo/server/description/inspector/server_added'
17
- require 'mongo/server/description/inspector/server_removed'
16
+ require 'mongo/server/description/inspector/description_changed'
17
+ require 'mongo/server/description/inspector/standalone_discovered'
18
18
 
19
19
  module Mongo
20
20
  class Server
@@ -32,9 +32,9 @@ module Mongo
32
32
  #
33
33
  # @since 2.0.0
34
34
  INSPECTORS = [
35
- Inspector::PrimaryElected,
36
- Inspector::ServerAdded,
37
- Inspector::ServerRemoved
35
+ Inspector::StandaloneDiscovered,
36
+ Inspector::DescriptionChanged,
37
+ Inspector::PrimaryElected
38
38
  ].freeze
39
39
 
40
40
  # @return [ Array ] inspectors The description inspectors.
@@ -21,7 +21,7 @@ module Mongo
21
21
  # added to the cluster.
22
22
  #
23
23
  # @since 2.0.0
24
- class ServerAdded
24
+ class DescriptionChanged
25
25
  include Event::Publisher
26
26
 
27
27
  # Instantiate the server added inspection.
@@ -46,10 +46,8 @@ module Mongo
46
46
  #
47
47
  # @since 2.0.0
48
48
  def run(description, updated)
49
- updated.servers.each do |host|
50
- unless description.servers.include?(host)
51
- publish(Event::SERVER_ADDED, host)
52
- end
49
+ unless description == updated
50
+ publish(Event::DESCRIPTION_CHANGED, updated)
53
51
  end
54
52
  end
55
53
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2015 MongoDB, Inc.
1
+ # Copyright (C) 2015 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the 'License');
4
4
  # you may not use this file except in compliance with the License.
@@ -17,39 +17,36 @@ module Mongo
17
17
  class Description
18
18
  class Inspector
19
19
 
20
- # Handles inspecting the result of an ismaster command for servers
21
- # that were removed from the cluster.
20
+ # Handles notifying the cluster that a standalone was discovered.
22
21
  #
23
- # @since 2.0.0
24
- class ServerRemoved
22
+ # @since 2.0.6
23
+ class StandaloneDiscovered
25
24
  include Event::Publisher
26
25
 
27
- # Instantiate the server removed inspection.
26
+ # Instantiate the standalone discovered inspection.
28
27
  #
29
28
  # @example Instantiate the inspection.
30
- # ServerRemoved.new(listeners)
29
+ # StandaloneDiscovered.new(listeners)
31
30
  #
32
31
  # @param [ Event::Listeners ] event_listeners The event listeners.
33
32
  #
34
- # @since 2.0.0
33
+ # @since 2.0.6
35
34
  def initialize(event_listeners)
36
35
  @event_listeners = event_listeners
37
36
  end
38
37
 
39
- # Run the server added inspection.
38
+ # Run the standalone discovered inspection.
40
39
  #
41
40
  # @example Run the inspection.
42
- # ServerAdded.run(description, {})
41
+ # StandaloneDiscovered.run(description, {})
43
42
  #
44
43
  # @param [ Description ] description The server description.
45
44
  # @param [ Description ] updated The updated description.
46
45
  #
47
- # @since 2.0.0
46
+ # @since 2.0.6
48
47
  def run(description, updated)
49
- description.hosts.each do |host|
50
- if updated.primary? && !updated.hosts.include?(host)
51
- publish(Event::SERVER_REMOVED, host)
52
- end
48
+ if !description.standalone? && updated.standalone?
49
+ publish(Event::STANDALONE_DISCOVERED, updated)
53
50
  end
54
51
  end
55
52
  end
@@ -17,5 +17,5 @@ module Mongo
17
17
  # The current version of the driver.
18
18
  #
19
19
  # @since 2.0.0
20
- VERSION = '2.0.5'.freeze
20
+ VERSION = '2.0.6'.freeze
21
21
  end
@@ -7,7 +7,7 @@ describe Mongo::Auth::CR do
7
7
  end
8
8
 
9
9
  let(:server) do
10
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
10
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
11
11
  end
12
12
 
13
13
  let(:connection) do
@@ -7,7 +7,7 @@ describe Mongo::Auth::LDAP do
7
7
  end
8
8
 
9
9
  let(:server) do
10
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
10
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
11
11
  end
12
12
 
13
13
  let(:connection) do
@@ -7,7 +7,7 @@ describe Mongo::Auth::SCRAM do
7
7
  end
8
8
 
9
9
  let(:server) do
10
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
10
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
11
11
  end
12
12
 
13
13
  let(:connection) do
@@ -7,7 +7,7 @@ describe Mongo::Auth::X509 do
7
7
  end
8
8
 
9
9
  let(:server) do
10
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
10
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
11
11
  end
12
12
 
13
13
  let(:connection) do
@@ -412,6 +412,10 @@ describe Mongo::Client do
412
412
  it 'returns the new client' do
413
413
  expect(client.send(:database).name).to eq('ruby-driver')
414
414
  end
415
+
416
+ it 'keeps the same cluster' do
417
+ expect(database.cluster).to equal(client.cluster)
418
+ end
415
419
  end
416
420
 
417
421
  context 'when provided a string' do
@@ -9,19 +9,19 @@ describe Mongo::Cluster::Topology::ReplicaSet do
9
9
  describe '#servers' do
10
10
 
11
11
  let(:mongos) do
12
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
12
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
13
13
  end
14
14
 
15
15
  let(:standalone) do
16
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
16
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
17
17
  end
18
18
 
19
19
  let(:replica_set) do
20
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
20
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
21
21
  end
22
22
 
23
23
  let(:replica_set_two) do
24
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
24
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
25
25
  end
26
26
 
27
27
  let(:mongos_description) do
@@ -98,4 +98,254 @@ describe Mongo::Cluster::Topology::ReplicaSet do
98
98
  expect(described_class.new({})).to_not be_single
99
99
  end
100
100
  end
101
+
102
+ describe '#add_hosts?' do
103
+
104
+ let(:primary) do
105
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
106
+ end
107
+
108
+ let(:secondary) do
109
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
110
+ end
111
+
112
+ let(:primary_description) do
113
+ Mongo::Server::Description.new(address, { 'ismaster' => true, 'setName' => 'testing' })
114
+ end
115
+
116
+ let(:secondary_description) do
117
+ Mongo::Server::Description.new(address, { 'ismaster' => false, 'secondary' => true,
118
+ 'setName' => 'testing' })
119
+ end
120
+
121
+ let(:topology) do
122
+ described_class.new(:replica_set => 'testing')
123
+ end
124
+
125
+ before do
126
+ primary.monitor.instance_variable_set(:@description, primary_description)
127
+ secondary.monitor.instance_variable_set(:@description, secondary_description)
128
+ end
129
+
130
+ context 'when the list of servers does not include a primary' do
131
+
132
+ let(:servers) do
133
+ [ secondary ]
134
+ end
135
+
136
+ context 'when the description is a member of the replica set' do
137
+
138
+ let(:description) do
139
+ double('description').tap do |d|
140
+ allow(d).to receive(:replica_set_member?).and_return(true)
141
+ allow(d).to receive(:replica_set_name).and_return('testing')
142
+ end
143
+ end
144
+
145
+ it 'returns true' do
146
+ expect(topology.add_hosts?(description, servers)).to eq(true)
147
+ end
148
+ end
149
+
150
+ context 'when the description is not a member of the replica set' do
151
+
152
+ let(:description) do
153
+ double('description').tap do |d|
154
+ allow(d).to receive(:replica_set_member?).and_return(false)
155
+ end
156
+ end
157
+
158
+ it 'returns false' do
159
+ expect(topology.add_hosts?(description, servers)).to eq(false)
160
+ end
161
+ end
162
+ end
163
+
164
+ context 'when the list of servers has a primary' do
165
+
166
+ let(:servers) do
167
+ [ primary, secondary ]
168
+ end
169
+
170
+ let(:description) do
171
+ double('description').tap do |d|
172
+ allow(d).to receive(:replica_set_member?).and_return(true)
173
+ allow(d).to receive(:replica_set_name).and_return('testing')
174
+ end
175
+ end
176
+
177
+ it 'returns false' do
178
+ expect(topology.add_hosts?(description, servers)).to eq(false)
179
+ end
180
+ end
181
+ end
182
+
183
+ describe '#remove_hosts?' do
184
+
185
+ let(:primary) do
186
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
187
+ end
188
+
189
+ let(:primary_description) do
190
+ Mongo::Server::Description.new(address, { 'ismaster' => true, 'setName' => 'testing' })
191
+ end
192
+
193
+ let(:topology) do
194
+ described_class.new(:replica_set => 'testing')
195
+ end
196
+
197
+ before do
198
+ primary.monitor.instance_variable_set(:@description, primary_description)
199
+ end
200
+
201
+ context 'when the description has an empty config' do
202
+
203
+ let(:description) do
204
+ double('description').tap do |d|
205
+ allow(d).to receive(:config).and_return({})
206
+ end
207
+ end
208
+
209
+ it 'returns false' do
210
+ expect(topology.remove_hosts?(description)).to eq(false)
211
+ end
212
+ end
213
+
214
+ context 'when the description is from a primary' do
215
+
216
+ let(:description) do
217
+ double('description').tap do |d|
218
+ allow(d).to receive(:config).and_return({ 'ismaster' => true })
219
+ allow(d).to receive(:primary?).and_return(true)
220
+ end
221
+ end
222
+
223
+ it 'returns true' do
224
+ expect(topology.remove_hosts?(description)).to eq(true)
225
+ end
226
+ end
227
+
228
+ context 'when the description has an empty hosts list' do
229
+
230
+ let(:description) do
231
+ double('description').tap do |d|
232
+ allow(d).to receive(:config).and_return({ 'ismaster' => true })
233
+ allow(d).to receive(:primary?).and_return(false)
234
+ allow(d).to receive(:hosts).and_return([])
235
+ end
236
+ end
237
+
238
+ it 'returns true' do
239
+ expect(topology.remove_hosts?(description)).to eq(true)
240
+ end
241
+ end
242
+
243
+ context 'when the description is not from the replica set' do
244
+
245
+ let(:description) do
246
+ double('description').tap do |d|
247
+ allow(d).to receive(:config).and_return({ 'ismaster' => true })
248
+ allow(d).to receive(:primary?).and_return(false)
249
+ allow(d).to receive(:hosts).and_return([ primary ])
250
+ allow(d).to receive(:replica_set_name).and_return('test')
251
+ allow(d).to receive(:replica_set_member?).and_return(true)
252
+ end
253
+ end
254
+
255
+ it 'returns true' do
256
+ expect(topology.remove_hosts?(description)).to eq(true)
257
+ end
258
+ end
259
+
260
+ end
261
+
262
+ describe '#remove_server?' do
263
+
264
+ let(:secondary) do
265
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
266
+ end
267
+
268
+ let(:secondary_description) do
269
+ Mongo::Server::Description.new(address, { 'ismaster' => false, 'secondary' => true,
270
+ 'setName' => 'test' })
271
+ end
272
+
273
+ let(:topology) do
274
+ described_class.new(:replica_set => 'testing')
275
+ end
276
+
277
+ before do
278
+ secondary.monitor.instance_variable_set(:@description, secondary_description)
279
+ end
280
+
281
+ context 'when the description is from a server that should itself be removed' do
282
+
283
+ let(:description) do
284
+ double('description').tap do |d|
285
+ allow(d).to receive(:config).and_return({ 'setName' => 'test' })
286
+ allow(d).to receive(:replica_set_member?).and_return(true)
287
+ allow(d).to receive(:replica_set_name).and_return('test')
288
+ allow(d).to receive(:is_server?).and_return(true)
289
+ allow(d).to receive(:ghost?).and_return(false)
290
+ end
291
+ end
292
+
293
+ it 'returns true' do
294
+ expect(topology.remove_server?(description, secondary)).to eq(true)
295
+ end
296
+ end
297
+
298
+ context 'when the description is a member of the replica set' do
299
+
300
+ context 'when the description includes the server in question' do
301
+
302
+ let(:description) do
303
+ double('description').tap do |d|
304
+ allow(d).to receive(:config).and_return({ 'setName' => 'testing' })
305
+ allow(d).to receive(:replica_set_member?).and_return(true)
306
+ allow(d).to receive(:replica_set_name).and_return('testing')
307
+ allow(d).to receive(:lists_server?).and_return(true)
308
+ end
309
+ end
310
+
311
+ it 'returns false' do
312
+ expect(topology.remove_server?(description, secondary)).to eq(false)
313
+ end
314
+ end
315
+
316
+ context 'when the description does not include the server in question' do
317
+
318
+ let(:description) do
319
+ double('description').tap do |d|
320
+ allow(d).to receive(:config).and_return({ 'setName' => 'testing' })
321
+ allow(d).to receive(:replica_set_member?).and_return(true)
322
+ allow(d).to receive(:replica_set_name).and_return('testing')
323
+ allow(d).to receive(:is_server?).and_return(false)
324
+ allow(d).to receive(:lists_server?).and_return(false)
325
+ end
326
+ end
327
+
328
+ it 'returns true' do
329
+ expect(topology.remove_server?(description, secondary)).to eq(true)
330
+ end
331
+ end
332
+ end
333
+
334
+ context 'when the description is not a member of the replica set' do
335
+
336
+ let(:description) do
337
+ double('description').tap do |d|
338
+ allow(d).to receive(:config).and_return({ 'setName' => 'test' })
339
+ allow(d).to receive(:replica_set_member?).and_return(true)
340
+ allow(d).to receive(:replica_set_name).and_return('test')
341
+ allow(d).to receive(:is_server?).and_return(false)
342
+ end
343
+ end
344
+
345
+ it 'returns false' do
346
+ expect(topology.remove_server?(description, secondary)).to eq(false)
347
+ end
348
+ end
349
+
350
+ end
101
351
  end
@@ -10,31 +10,32 @@ describe Mongo::Cluster::Topology::Sharded do
10
10
  described_class.new({})
11
11
  end
12
12
 
13
- describe '.servers' do
14
13
 
15
- let(:mongos) do
16
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
17
- end
14
+ let(:mongos) do
15
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
16
+ end
18
17
 
19
- let(:standalone) do
20
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
21
- end
18
+ let(:standalone) do
19
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
20
+ end
22
21
 
23
- let(:replica_set) do
24
- Mongo::Server.new(address, Mongo::Event::Listeners.new, TEST_OPTIONS)
25
- end
22
+ let(:replica_set) do
23
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, TEST_OPTIONS)
24
+ end
26
25
 
27
- let(:mongos_description) do
28
- Mongo::Server::Description.new(address, { 'msg' => 'isdbgrid' })
29
- end
26
+ let(:mongos_description) do
27
+ Mongo::Server::Description.new(address, { 'msg' => 'isdbgrid' })
28
+ end
30
29
 
31
- let(:standalone_description) do
32
- Mongo::Server::Description.new(address, { 'ismaster' => true })
33
- end
30
+ let(:standalone_description) do
31
+ Mongo::Server::Description.new(address, { 'ismaster' => true })
32
+ end
34
33
 
35
- let(:replica_set_description) do
36
- Mongo::Server::Description.new(address, { 'ismaster' => true, 'setName' => 'testing' })
37
- end
34
+ let(:replica_set_description) do
35
+ Mongo::Server::Description.new(address, { 'ismaster' => true, 'setName' => 'testing', 'ok' => 1 })
36
+ end
37
+
38
+ describe '.servers' do
38
39
 
39
40
  before do
40
41
  mongos.monitor.instance_variable_set(:@description, mongos_description)
@@ -71,4 +72,54 @@ describe Mongo::Cluster::Topology::Sharded do
71
72
  expect(topology).to_not be_single
72
73
  end
73
74
  end
75
+
76
+ describe '#add_hosts?' do
77
+
78
+ it 'returns false' do
79
+ expect(topology.add_hosts?(double('description'), [])).to eq(false)
80
+ end
81
+ end
82
+
83
+ describe '#remove_hosts?' do
84
+
85
+ it 'returns true' do
86
+ expect(topology.remove_hosts?(double('description'))).to eq(true)
87
+ end
88
+ end
89
+
90
+ describe '#remove_server?' do
91
+
92
+ before do
93
+ mongos.monitor.instance_variable_set(:@description, mongos_description)
94
+ replica_set.monitor.instance_variable_set(:@description, replica_set_description)
95
+ end
96
+
97
+ context 'when the server itself should be removed' do
98
+
99
+ let(:description) do
100
+ double('description').tap do |d|
101
+ allow(d).to receive(:mongos?).and_return(false)
102
+ allow(d).to receive(:is_server?).and_return(true)
103
+ end
104
+ end
105
+
106
+ it 'returns true' do
107
+ expect(topology.remove_server?(description, mongos)).to eq(true)
108
+ end
109
+ end
110
+
111
+ context 'when the server is neither a mongos nor an unknown' do
112
+
113
+ let(:description) do
114
+ double('description').tap do |d|
115
+ allow(d).to receive(:mongos?).and_return(true)
116
+ allow(d).to receive(:is_server?).and_return(false)
117
+ end
118
+ end
119
+
120
+ it 'returns true' do
121
+ expect(topology.remove_server?(description, replica_set)).to eq(true)
122
+ end
123
+ end
124
+ end
74
125
  end