mongo 1.10.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +190 -0
  5. data/README.md +149 -0
  6. data/Rakefile +31 -0
  7. data/VERSION +1 -0
  8. data/bin/mongo_console +43 -0
  9. data/ext/jsasl/target/jsasl.jar +0 -0
  10. data/lib/mongo.rb +90 -0
  11. data/lib/mongo/bulk_write_collection_view.rb +380 -0
  12. data/lib/mongo/collection.rb +1164 -0
  13. data/lib/mongo/collection_writer.rb +364 -0
  14. data/lib/mongo/connection.rb +19 -0
  15. data/lib/mongo/connection/node.rb +239 -0
  16. data/lib/mongo/connection/pool.rb +347 -0
  17. data/lib/mongo/connection/pool_manager.rb +325 -0
  18. data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
  19. data/lib/mongo/connection/socket.rb +18 -0
  20. data/lib/mongo/connection/socket/socket_util.rb +37 -0
  21. data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
  22. data/lib/mongo/connection/socket/tcp_socket.rb +86 -0
  23. data/lib/mongo/connection/socket/unix_socket.rb +39 -0
  24. data/lib/mongo/cursor.rb +719 -0
  25. data/lib/mongo/db.rb +735 -0
  26. data/lib/mongo/exception.rb +88 -0
  27. data/lib/mongo/functional.rb +21 -0
  28. data/lib/mongo/functional/authentication.rb +318 -0
  29. data/lib/mongo/functional/logging.rb +85 -0
  30. data/lib/mongo/functional/read_preference.rb +174 -0
  31. data/lib/mongo/functional/sasl_java.rb +48 -0
  32. data/lib/mongo/functional/uri_parser.rb +374 -0
  33. data/lib/mongo/functional/write_concern.rb +66 -0
  34. data/lib/mongo/gridfs.rb +18 -0
  35. data/lib/mongo/gridfs/grid.rb +112 -0
  36. data/lib/mongo/gridfs/grid_ext.rb +53 -0
  37. data/lib/mongo/gridfs/grid_file_system.rb +163 -0
  38. data/lib/mongo/gridfs/grid_io.rb +484 -0
  39. data/lib/mongo/legacy.rb +140 -0
  40. data/lib/mongo/mongo_client.rb +702 -0
  41. data/lib/mongo/mongo_replica_set_client.rb +523 -0
  42. data/lib/mongo/mongo_sharded_client.rb +159 -0
  43. data/lib/mongo/networking.rb +370 -0
  44. data/lib/mongo/utils.rb +19 -0
  45. data/lib/mongo/utils/conversions.rb +110 -0
  46. data/lib/mongo/utils/core_ext.rb +70 -0
  47. data/lib/mongo/utils/server_version.rb +69 -0
  48. data/lib/mongo/utils/support.rb +80 -0
  49. data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
  50. data/mongo.gemspec +36 -0
  51. data/test/functional/authentication_test.rb +35 -0
  52. data/test/functional/bulk_api_stress_test.rb +133 -0
  53. data/test/functional/bulk_write_collection_view_test.rb +1129 -0
  54. data/test/functional/client_test.rb +565 -0
  55. data/test/functional/collection_test.rb +2073 -0
  56. data/test/functional/collection_writer_test.rb +83 -0
  57. data/test/functional/conversions_test.rb +163 -0
  58. data/test/functional/cursor_fail_test.rb +63 -0
  59. data/test/functional/cursor_message_test.rb +57 -0
  60. data/test/functional/cursor_test.rb +625 -0
  61. data/test/functional/db_api_test.rb +819 -0
  62. data/test/functional/db_connection_test.rb +27 -0
  63. data/test/functional/db_test.rb +344 -0
  64. data/test/functional/grid_file_system_test.rb +285 -0
  65. data/test/functional/grid_io_test.rb +252 -0
  66. data/test/functional/grid_test.rb +273 -0
  67. data/test/functional/pool_test.rb +62 -0
  68. data/test/functional/safe_test.rb +98 -0
  69. data/test/functional/ssl_test.rb +29 -0
  70. data/test/functional/support_test.rb +62 -0
  71. data/test/functional/timeout_test.rb +58 -0
  72. data/test/functional/uri_test.rb +330 -0
  73. data/test/functional/write_concern_test.rb +118 -0
  74. data/test/helpers/general.rb +50 -0
  75. data/test/helpers/test_unit.rb +317 -0
  76. data/test/replica_set/authentication_test.rb +35 -0
  77. data/test/replica_set/basic_test.rb +174 -0
  78. data/test/replica_set/client_test.rb +341 -0
  79. data/test/replica_set/complex_connect_test.rb +77 -0
  80. data/test/replica_set/connection_test.rb +138 -0
  81. data/test/replica_set/count_test.rb +64 -0
  82. data/test/replica_set/cursor_test.rb +212 -0
  83. data/test/replica_set/insert_test.rb +140 -0
  84. data/test/replica_set/max_values_test.rb +145 -0
  85. data/test/replica_set/pinning_test.rb +55 -0
  86. data/test/replica_set/query_test.rb +73 -0
  87. data/test/replica_set/read_preference_test.rb +214 -0
  88. data/test/replica_set/refresh_test.rb +175 -0
  89. data/test/replica_set/replication_ack_test.rb +94 -0
  90. data/test/replica_set/ssl_test.rb +32 -0
  91. data/test/sharded_cluster/basic_test.rb +197 -0
  92. data/test/shared/authentication/basic_auth_shared.rb +286 -0
  93. data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
  94. data/test/shared/authentication/gssapi_shared.rb +164 -0
  95. data/test/shared/authentication/sasl_plain_shared.rb +96 -0
  96. data/test/shared/ssl_shared.rb +235 -0
  97. data/test/test_helper.rb +56 -0
  98. data/test/threading/basic_test.rb +120 -0
  99. data/test/tools/mongo_config.rb +608 -0
  100. data/test/tools/mongo_config_test.rb +160 -0
  101. data/test/unit/client_test.rb +347 -0
  102. data/test/unit/collection_test.rb +166 -0
  103. data/test/unit/connection_test.rb +325 -0
  104. data/test/unit/cursor_test.rb +299 -0
  105. data/test/unit/db_test.rb +136 -0
  106. data/test/unit/grid_test.rb +76 -0
  107. data/test/unit/mongo_sharded_client_test.rb +48 -0
  108. data/test/unit/node_test.rb +93 -0
  109. data/test/unit/pool_manager_test.rb +142 -0
  110. data/test/unit/read_pref_test.rb +115 -0
  111. data/test/unit/read_test.rb +159 -0
  112. data/test/unit/safe_test.rb +158 -0
  113. data/test/unit/sharding_pool_manager_test.rb +84 -0
  114. data/test/unit/write_concern_test.rb +175 -0
  115. metadata +260 -0
  116. metadata.gz.sig +0 -0
@@ -0,0 +1,118 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'test_helper'
16
+ include Mongo
17
+
18
+ class WriteConcernTest < Test::Unit::TestCase
19
+ context "Write concern propogation: " do
20
+ setup do
21
+ @con = standard_connection
22
+ @db = @con[TEST_DB]
23
+ @col = @db['test-safe']
24
+ @col.create_index([[:a, 1]], :unique => true)
25
+ @col.remove
26
+ end
27
+
28
+ #TODO: add write concern tests for remove
29
+
30
+ should "propogate write concern options on insert" do
31
+ @col.insert({:a => 1})
32
+
33
+ assert_raise_error(OperationFailure, "duplicate key") do
34
+ @col.insert({:a => 1})
35
+ end
36
+ end
37
+
38
+ should "allow write concern override on insert" do
39
+ @col.insert({:a => 1})
40
+ @col.insert({:a => 1}, :w => 0)
41
+ end
42
+
43
+ should "propogate write concern option on update" do
44
+ @col.insert({:a => 1})
45
+ @col.insert({:a => 2})
46
+
47
+ assert_raise_error(OperationFailure, "duplicate key") do
48
+ @col.update({:a => 2}, {:a => 1})
49
+ end
50
+ end
51
+
52
+ should "allow write concern override on update" do
53
+ @col.insert({:a => 1})
54
+ @col.insert({:a => 2})
55
+ @col.update({:a => 2}, {:a => 1}, :w => 0)
56
+ end
57
+ end
58
+
59
+ context "Write concern error objects" do
60
+ setup do
61
+ @con = standard_connection
62
+ @db = @con[TEST_DB]
63
+ @col = @db['test']
64
+ @col.remove
65
+ @col.insert({:a => 1})
66
+ @col.insert({:a => 1})
67
+ @col.insert({:a => 1})
68
+ end
69
+
70
+ should "return object on update" do
71
+ response = @col.update({:a => 1}, {"$set" => {:a => 2}},
72
+ :multi => true)
73
+
74
+ assert(response['updatedExisting'] || @db.connection.wire_version_feature?(Mongo::MongoClient::BATCH_COMMANDS)) # TODO - review new write command return values
75
+ assert(response['n'] == 3 || @db.connection.wire_version_feature?(Mongo::MongoClient::BATCH_COMMANDS)) # TODO - update command top pending
76
+ end
77
+
78
+ should "return object on remove" do
79
+ response = @col.remove({})
80
+ assert_equal 3, response['n']
81
+ end
82
+ end
83
+
84
+ context "Write concern in gridfs" do
85
+ setup do
86
+ @db = standard_connection.db(TEST_DB)
87
+ @grid = Mongo::GridFileSystem.new(@db)
88
+ @filename = 'sample'
89
+ end
90
+
91
+ teardown do
92
+ @grid.delete(@filename)
93
+ end
94
+
95
+ should "should acknowledge writes by default using md5" do
96
+ file = @grid.open(@filename, 'w')
97
+ file.write "Hello world!"
98
+ file.close
99
+ assert_equal file.client_md5, file.server_md5
100
+ end
101
+
102
+ should "should allow for unacknowledged writes" do
103
+ file = @grid.open(@filename, 'w', {:w => 0} )
104
+ file.write "Hello world!"
105
+ file.close
106
+ assert_nil file.client_md5, file.server_md5
107
+ end
108
+
109
+ should "should support legacy write concern api" do
110
+ file = @grid.open(@filename, 'w', {:safe => false} )
111
+ file.write "Hello world!"
112
+ file.close
113
+ assert_nil file.client_md5, file.server_md5
114
+ end
115
+
116
+ end
117
+
118
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # Redirects output while yielding a given block of code.
16
+ #
17
+ # @return [Object] The result of the block.
18
+ def silently
19
+ warn_level = $VERBOSE
20
+ $VERBOSE = nil
21
+ begin
22
+ result = yield
23
+ ensure
24
+ $VERBOSE = warn_level
25
+ end
26
+ result
27
+ end
28
+
29
+ class Hash
30
+ def stringify_keys
31
+ dup.stringify_keys!
32
+ end
33
+
34
+ def stringify_keys!
35
+ keys.each do |key|
36
+ self[key.to_s] = delete(key)
37
+ end
38
+ self
39
+ end
40
+
41
+ def except(*keys)
42
+ dup.except!(*keys)
43
+ end
44
+
45
+ # Replaces the hash without the given keys.
46
+ def except!(*keys)
47
+ keys.each { |key| delete(key) }
48
+ self
49
+ end
50
+ end
@@ -0,0 +1,317 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ TEST_DB = 'ruby_test' unless defined? TEST_DB
16
+ TEST_HOST = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost' unless defined? TEST_HOST
17
+ TEST_DATA = File.join(File.dirname(__FILE__), 'fixtures/data')
18
+ TEST_BASE = Test::Unit::TestCase
19
+
20
+ unless defined? TEST_PORT
21
+ TEST_PORT = if ENV['MONGO_RUBY_DRIVER_PORT']
22
+ ENV['MONGO_RUBY_DRIVER_PORT'].to_i
23
+ else
24
+ Mongo::MongoClient::DEFAULT_PORT
25
+ end
26
+ end
27
+
28
+ class Test::Unit::TestCase
29
+ include Mongo
30
+ include BSON
31
+
32
+ # Handles creating a pre-defined MongoDB cluster for integration testing.
33
+ #
34
+ # @param kind=nil [Symbol] Type of cluster (:rs or :sc).
35
+ # @param opts={} [Hash] Options to be passed through to the cluster manager.
36
+ #
37
+ # @return [ClusterManager] The cluster manager instance being used.
38
+ def ensure_cluster(kind=nil, opts={})
39
+ cluster_instance = nil
40
+ class_vars = TEST_BASE.class_eval { class_variables }
41
+ if class_vars.include?("@@cluster_#{kind}") || class_vars.include?("@@cluster_#{kind}".to_sym)
42
+ cluster_instance = TEST_BASE.class_eval { class_variable_get("@@cluster_#{kind}") }
43
+ end
44
+
45
+ unless cluster_instance
46
+ if kind == :rs
47
+ cluster_opts = Config::DEFAULT_REPLICA_SET.dup
48
+ else
49
+ cluster_opts = Config::DEFAULT_SHARDED_SIMPLE.dup
50
+ end
51
+
52
+ cluster_opts.merge!(opts)
53
+ cluster_opts.merge!(:dbpath => ENV['MONGO_DBPATH'] || 'data')
54
+ config = Config.cluster(cluster_opts)
55
+
56
+ cluster_instance = Config::ClusterManager.new(config)
57
+ TEST_BASE.class_eval { class_variable_set("@@cluster_#{kind}", cluster_instance) }
58
+ end
59
+
60
+ cluster_instance.start
61
+ instance_variable_set("@#{kind}", cluster_instance)
62
+ end
63
+
64
+ # Generic helper to rescue and retry from a connection failure.
65
+ #
66
+ # @param max_retries=30 [Integer] The number of times to attempt a retry.
67
+ #
68
+ # @return [Object] The block result.
69
+ def rescue_connection_failure(max_retries=30)
70
+ retries = 0
71
+ begin
72
+ yield
73
+ rescue Mongo::ConnectionFailure => ex
74
+ retries += 1
75
+ raise ex if retries > max_retries
76
+ sleep(2)
77
+ retry
78
+ end
79
+ end
80
+
81
+ # Creates and connects a standard, pre-defined MongoClient instance.
82
+ #
83
+ # @param options={} [Hash] Options to be passed to the client instance.
84
+ # @param legacy=false [Boolean] When true, uses deprecated Mongo::Connection.
85
+ #
86
+ # @return [MongoClient] The client instance.
87
+ def self.standard_connection(options={}, legacy=false)
88
+ if legacy
89
+ Connection.new(TEST_HOST, TEST_PORT, options)
90
+ else
91
+ MongoClient.new(TEST_HOST, TEST_PORT, options)
92
+ end
93
+ end
94
+
95
+ # Creates and connects a standard, pre-defined MongoClient instance.
96
+ #
97
+ # @param options={} [Hash] Options to be passed to the client instance.
98
+ # @param legacy=false [Boolean] When true, uses deprecated Mongo::Connection.
99
+ #
100
+ # @return [MongoClient] The client instance.
101
+ def standard_connection(options={}, legacy=false)
102
+ self.class.standard_connection(options, legacy)
103
+ end
104
+
105
+ def self.host_port
106
+ "#{mongo_host}:#{mongo_port}"
107
+ end
108
+
109
+ def self.mongo_host
110
+ TEST_HOST
111
+ end
112
+
113
+ def self.mongo_port
114
+ TEST_PORT
115
+ end
116
+
117
+ def host_port
118
+ self.class.host_port
119
+ end
120
+
121
+ def mongo_host
122
+ self.class.mongo_host
123
+ end
124
+
125
+ def mongo_port
126
+ self.class.mongo_port
127
+ end
128
+
129
+ def method_name
130
+ caller[0]=~/`(.*?)'/
131
+ $1
132
+ end
133
+
134
+ def perform_step_down(member)
135
+ start = Time.now
136
+ timeout = 20 # seconds
137
+ begin
138
+ step_down_command = BSON::OrderedHash.new
139
+ step_down_command[:replSetStepDown] = 30
140
+ member['admin'].command(step_down_command)
141
+ rescue Mongo::OperationFailure => e
142
+ retry unless (Time.now - start) > timeout
143
+ raise e
144
+ end
145
+ end
146
+
147
+ def new_mock_socket(host='localhost', port=27017)
148
+ socket = Object.new
149
+ socket.stubs(:setsockopt).with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
150
+ socket.stubs(:close)
151
+ socket.stubs(:closed?)
152
+ socket.stubs(:checkin)
153
+ socket.stubs(:pool)
154
+ socket
155
+ end
156
+
157
+ def new_mock_unix_socket(sockfile='/tmp/mongod.sock')
158
+ socket = Object.new
159
+ socket.stubs(:setsockopt).with(Socket::IPPROTO_TCP)
160
+ socket.stubs(:close)
161
+ socket.stubs(:closed?)
162
+ socket
163
+ end
164
+
165
+ def new_mock_db
166
+ Object.new
167
+ end
168
+
169
+ def assert_raise_error(klass, message=nil)
170
+ begin
171
+ yield
172
+ rescue => e
173
+ if klass.to_s != e.class.to_s
174
+ flunk "Expected exception class #{klass} but got #{e.class}.\n #{e.backtrace}"
175
+ end
176
+
177
+ if message && !e.message.include?(message)
178
+ p e.backtrace
179
+ flunk "#{e.message} does not include #{message}.\n#{e.backtrace}"
180
+ end
181
+ else
182
+ flunk "Expected assertion #{klass} but none was raised."
183
+ end
184
+ end
185
+
186
+ def match_document(key, expected, actual) # special cases for Regexp match, BSON::ObjectId, Range
187
+ if expected.is_a?(Hash) && actual.is_a?(Hash)
188
+ expected_keys = expected.keys.sort
189
+ actual_keys = actual.keys.sort
190
+ #currently allow extra fields in actual as the following check for equality of keys is commented out
191
+ #raise "field:#{key.inspect} - Hash keys expected:#{expected_keys.inspect} actual:#{actual_keys.inspect}" if expected_keys != actual_keys
192
+ expected_keys.each{|k| match_document(k, expected[k], actual[k])}
193
+ elsif expected.is_a?(Array) && actual.is_a?(Array)
194
+ raise "field:#{key.inspect} - Array size expected:#{expected.size} actual:#{actual.size}" if expected.size != actual.size
195
+ (0...expected.size).each{|i| match_document(i, expected[i], actual[i])}
196
+ elsif expected.is_a?(Regexp) && actual.is_a?(String)
197
+ raise "field:#{key.inspect} - Regexp expected:#{expected.inspect} actual:#{actual.inspect}" if expected !~ actual
198
+ elsif expected.is_a?(BSON::ObjectId) && actual.is_a?(BSON::ObjectId)
199
+ # match type but not value
200
+ elsif expected.is_a?(Range)
201
+ raise "field:#{key.inspect} - Range expected:#{expected.inspect} actual:#{actual.inspect}" if !expected.include?(actual)
202
+ elsif expected.is_a?(Set)
203
+ raise "field:#{key.inspect} - Set expected:#{expected.inspect} actual:#{actual.inspect}" if !expected.include?(actual)
204
+ else
205
+ raise "field:#{key.inspect} - expected:#{expected.inspect} actual:#{actual.inspect}" if expected != actual
206
+ end
207
+ true
208
+ end
209
+
210
+ def assert_match_document(expected, actual, message = '')
211
+ match = begin
212
+ match_document('', expected, actual)
213
+ rescue => ex
214
+ message = ex.message + ' - ' + message
215
+ false
216
+ end
217
+ assert(match, message)
218
+ end
219
+
220
+ def with_forced_timeout(client, &block)
221
+ cmd_line_args = client['admin'].command({ :getCmdLineOpts => 1 })['argv']
222
+ if cmd_line_args.include?('enableTestCommands=1') && client.server_version >= "2.5.3"
223
+ begin
224
+ #Force any query or command with valid non-zero max time to fail (SERVER-10650)
225
+ fail_point_cmd = OrderedHash.new
226
+ fail_point_cmd[:configureFailPoint] = 'maxTimeAlwaysTimeOut'
227
+ fail_point_cmd[:mode] = 'alwaysOn'
228
+ client['admin'].command(fail_point_cmd)
229
+ yield
230
+ fail_point_cmd[:mode] = 'off'
231
+ client['admin'].command(fail_point_cmd)
232
+ end
233
+ end
234
+ end
235
+
236
+ def with_auth(client, &block)
237
+ cmd_line_args = client['admin'].command({ :getCmdLineOpts => 1 })['parsed']
238
+ yield if cmd_line_args.include?('auth')
239
+ end
240
+
241
+ def with_default_journaling(client, &block)
242
+ cmd_line_args = client['admin'].command({ :getCmdLineOpts => 1 })['parsed']
243
+ unless client.server_version < "2.0" || cmd_line_args.include?('nojournal')
244
+ yield
245
+ end
246
+ end
247
+
248
+ def with_no_replication(client, &block)
249
+ if client.class == MongoClient
250
+ yield
251
+ end
252
+ end
253
+
254
+ def with_no_journaling(client, &block)
255
+ cmd_line_args = client['admin'].command({ :getCmdLineOpts => 1 })['parsed']
256
+ unless client.server_version < "2.0" || !cmd_line_args.include?('nojournal')
257
+ yield
258
+ end
259
+ end
260
+
261
+ def with_ipv6_enabled(client, &block)
262
+ cmd_line_args = client['admin'].command({ :getCmdLineOpts => 1 })['parsed']
263
+ if cmd_line_args.include?('ipv6')
264
+ yield
265
+ end
266
+ end
267
+
268
+ def with_write_commands(client, &block)
269
+ wire_version = Mongo::MongoClient::BATCH_COMMANDS
270
+ if client.primary_wire_version_feature?(wire_version)
271
+ yield wire_version
272
+ end
273
+ end
274
+
275
+ def with_preserved_env_uri(new_uri=nil, &block)
276
+ old_mongodb_uri = ENV['MONGODB_URI']
277
+ begin
278
+ ENV['MONGODB_URI'] = new_uri
279
+ yield
280
+ ensure
281
+ ENV['MONGODB_URI'] = old_mongodb_uri
282
+ end
283
+ end
284
+
285
+ def with_write_operations(client, &block)
286
+ wire_version = Mongo::MongoClient::RELEASE_2_4_AND_BEFORE
287
+ if client.primary_wire_version_feature?(wire_version)
288
+ client.class.class_eval(%Q{
289
+ alias :old_use_write_command? :use_write_command?
290
+ def use_write_command?(write_concern)
291
+ false
292
+ end
293
+ })
294
+ yield wire_version
295
+ client.class.class_eval(%Q{
296
+ alias :use_write_command? :old_use_write_command?
297
+ })
298
+ end
299
+ end
300
+
301
+ def with_write_commands_and_operations(client, &block)
302
+ with_write_commands(client, &block)
303
+ with_write_operations(client, &block)
304
+ end
305
+
306
+ def batch_commands?(wire_version)
307
+ wire_version >= Mongo::MongoClient::BATCH_COMMANDS
308
+ end
309
+ end
310
+
311
+ # Before and after hooks for the entire test run
312
+ # handles mop up after the cluster manager is done.
313
+ Test::Unit.at_exit do
314
+ TEST_BASE.class_eval { class_variables }.select { |v| v =~ /@@cluster_/ }.each do |cluster|
315
+ TEST_BASE.class_eval { class_variable_get(cluster) }.stop
316
+ end
317
+ end