mongo 1.10.0.rc0 → 1.10.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/VERSION +1 -1
  5. data/lib/mongo/bulk_write_collection_view.rb +31 -3
  6. data/lib/mongo/collection.rb +69 -25
  7. data/lib/mongo/collection_writer.rb +3 -2
  8. data/lib/mongo/connection/node.rb +5 -0
  9. data/lib/mongo/cursor.rb +4 -1
  10. data/lib/mongo/db.rb +23 -41
  11. data/lib/mongo/functional.rb +2 -0
  12. data/lib/mongo/functional/authentication.rb +18 -3
  13. data/lib/mongo/functional/sasl_java.rb +48 -0
  14. data/lib/mongo/functional/uri_parser.rb +62 -50
  15. data/lib/mongo/mongo_client.rb +24 -9
  16. data/lib/mongo/mongo_replica_set_client.rb +16 -5
  17. data/lib/mongo/networking.rb +3 -3
  18. data/lib/mongo/utils/conversions.rb +2 -1
  19. data/test/functional/authentication_test.rb +6 -1
  20. data/test/functional/bulk_api_stress_test.rb +133 -0
  21. data/test/functional/bulk_write_collection_view_test.rb +573 -226
  22. data/test/functional/client_test.rb +3 -1
  23. data/test/functional/collection_test.rb +336 -17
  24. data/test/functional/conversions_test.rb +32 -0
  25. data/test/functional/cursor_test.rb +3 -3
  26. data/test/functional/db_api_test.rb +2 -2
  27. data/test/functional/db_test.rb +24 -0
  28. data/test/functional/uri_test.rb +49 -32
  29. data/test/helpers/test_unit.rb +8 -0
  30. data/test/replica_set/authentication_test.rb +5 -1
  31. data/test/replica_set/client_test.rb +5 -4
  32. data/test/replica_set/max_values_test.rb +6 -0
  33. data/test/shared/authentication/basic_auth_shared.rb +101 -30
  34. data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
  35. data/test/shared/authentication/gssapi_shared.rb +164 -0
  36. data/test/shared/ssl_shared.rb +49 -27
  37. data/test/unit/client_test.rb +4 -2
  38. data/test/unit/connection_test.rb +4 -2
  39. data/test/unit/cursor_test.rb +12 -0
  40. data/test/unit/db_test.rb +6 -0
  41. metadata +27 -20
  42. metadata.gz.sig +0 -0
@@ -334,12 +334,13 @@ class ClientTest < Test::Unit::TestCase
334
334
  conn = standard_connection(:connect => false)
335
335
 
336
336
  admin_db = Object.new
337
- admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'maxWireVersion' => 1, 'minWireVersion' => 1})
337
+ admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'maxWireVersion' => 1, 'minWireVersion' => 1, 'maxWriteBatchSize' => 999})
338
338
  conn.expects(:[]).with('admin').returns(admin_db)
339
339
  conn.connect
340
340
 
341
341
  assert_equal 1, conn.max_wire_version
342
342
  assert_equal 1, conn.min_wire_version
343
+ assert_equal 999, conn.max_write_batch_size
343
344
  end
344
345
 
345
346
  def test_max_wire_version_and_min_wire_version_values_with_no_reported_values
@@ -352,6 +353,7 @@ class ClientTest < Test::Unit::TestCase
352
353
 
353
354
  assert_equal 0, conn.max_wire_version
354
355
  assert_equal 0, conn.min_wire_version
356
+ assert_equal Mongo::MongoClient::DEFAULT_MAX_WRITE_BATCH_SIZE, conn.max_write_batch_size
355
357
  end
356
358
 
357
359
  def test_wire_version_feature
@@ -96,7 +96,265 @@ class CollectionTest < Test::Unit::TestCase
96
96
  end
97
97
  end
98
98
 
99
+ if @@version >= '2.5.4'
100
+
101
+ def test_single_delete_write_command
102
+ @@test.drop
103
+ @@test.insert([{ :a => 1 }, { :a => 1 }])
104
+
105
+ command = {
106
+ 'delete' => @@test.name,
107
+ :deletes => [{ :q => { :a => 1 }, :limit => 1 }],
108
+ :writeConcern => { :w => 1 },
109
+ :ordered => false
110
+ }
111
+
112
+ result = @@db.command(command)
113
+ assert_equal 1, result['n']
114
+ assert_equal 1, result['ok']
115
+ assert_equal 1, @@test.count
116
+ end
117
+
118
+ def test_multi_ordered_delete_write_command
119
+ @@test.drop
120
+ @@test.insert([{ :a => 1 }, { :a => 1 }])
121
+
122
+ command = {
123
+ 'delete' => @@test.name,
124
+ :deletes => [{ :q => { :a => 1 }, :limit => 0 }],
125
+ :writeConcern => { :w => 1 },
126
+ :ordered => true
127
+ }
128
+
129
+ result = @@db.command(command)
130
+ assert_equal 2, result['n']
131
+ assert_equal 1, result['ok']
132
+ assert_equal 0, @@test.count
133
+ end
134
+
135
+ def test_multi_unordered_delete_write_command
136
+ @@test.drop
137
+ @@test.insert([{ :a => 1 }, { :a => 1 }])
138
+
139
+ command = {
140
+ 'delete' => @@test.name,
141
+ :deletes => [{ :q => { :a => 1 }, :limit => 0 }],
142
+ :writeConcern => { :w => 1 },
143
+ :ordered => false
144
+ }
145
+
146
+ result = @@db.command(command)
147
+ assert_equal 2, result['n']
148
+ assert_equal 1, result['ok']
149
+ assert_equal 0, @@test.count
150
+ end
151
+
152
+ def test_delete_write_command_with_no_concern
153
+ @@test.drop
154
+ @@test.insert([{ :a => 1 }, { :a => 1 }])
155
+
156
+ command = {
157
+ 'delete' => @@test.name,
158
+ :deletes => [{ :q => { :a => 1 }, :limit => 0 }],
159
+ :ordered => false
160
+ }
161
+
162
+ result = @@db.command(command)
163
+ assert_equal 2, result['n']
164
+ assert_equal 1, result['ok']
165
+ assert_equal 0, @@test.count
166
+ end
167
+
168
+ def test_delete_write_command_with_error
169
+ @@test.drop
170
+ @@test.insert([{ :a => 1 }, { :a => 1 }])
171
+
172
+ command = {
173
+ 'delete' => @@test.name,
174
+ :deletes => [{ :q => { '$set' => { :a => 1 }}, :limit => 0 }],
175
+ :writeConcern => { :w => 1 },
176
+ :ordered => false
177
+ }
178
+
179
+ assert_raise Mongo::OperationFailure do
180
+ @@db.command(command)
181
+ end
182
+ end
183
+
184
+ def test_single_insert_write_command
185
+ @@test.drop
186
+
187
+ command = {
188
+ 'insert' => @@test.name,
189
+ :documents => [{ :a => 1 }],
190
+ :writeConcern => { :w => 1 },
191
+ :ordered => false
192
+ }
193
+
194
+ result = @@db.command(command)
195
+ assert_equal 1, result['ok']
196
+ assert_equal 1, @@test.count
197
+ end
198
+
199
+ def test_multi_ordered_insert_write_command
200
+ @@test.drop
201
+
202
+ command = {
203
+ 'insert' => @@test.name,
204
+ :documents => [{ :a => 1 }, { :a => 2 }],
205
+ :writeConcern => { :w => 1 },
206
+ :ordered => true
207
+ }
208
+
209
+ result = @@db.command(command)
210
+ assert_equal 1, result['ok']
211
+ assert_equal 2, @@test.count
212
+ end
213
+
214
+ def test_multi_unordered_insert_write_command
215
+ @@test.drop
216
+
217
+ command = {
218
+ 'insert' => @@test.name,
219
+ :documents => [{ :a => 1 }, { :a => 2 }],
220
+ :writeConcern => { :w => 1 },
221
+ :ordered => false
222
+ }
223
+
224
+ result = @@db.command(command)
225
+ assert_equal 1, result['ok']
226
+ assert_equal 2, @@test.count
227
+ end
228
+
229
+ def test_insert_write_command_with_no_concern
230
+ @@test.drop
231
+
232
+ command = {
233
+ 'insert' => @@test.name,
234
+ :documents => [{ :a => 1 }, { :a => 2 }],
235
+ :ordered => false
236
+ }
237
+
238
+ result = @@db.command(command)
239
+ assert_equal 1, result['ok']
240
+ assert_equal 2, @@test.count
241
+ end
242
+
243
+ def test_insert_write_command_with_error
244
+ @@test.drop
245
+ @@test.ensure_index({ :a => 1 }, { :unique => true })
246
+
247
+ command = {
248
+ 'insert' => @@test.name,
249
+ :documents => [{ :a => 1 }, { :a => 1 }],
250
+ :writeConcern => { :w => 1 },
251
+ :ordered => false
252
+ }
253
+
254
+ assert_raise Mongo::OperationFailure do
255
+ @@db.command(command)
256
+ end
257
+ end
258
+
259
+ def test_single_update_write_command
260
+ @@test.drop
261
+ @@test.insert([{ :a => 1 }, { :a => 2 }])
262
+
263
+ command = {
264
+ 'update' => @@test.name,
265
+ :updates => [{ :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}}],
266
+ :writeConcern => { :w => 1 }
267
+ }
268
+
269
+ result = @@db.command(command)
270
+ assert_equal 1, result['ok']
271
+ assert_equal 1, result['n']
272
+ assert_equal 2, @@test.find({ :a => 2 }).count
273
+ end
274
+
275
+ def test_multi_ordered_update_write_command
276
+ @@test.drop
277
+ @@test.insert([{ :a => 1 }, { :a => 3 }])
278
+
279
+ command = {
280
+ 'update' => @@test.name,
281
+ :updates => [
282
+ { :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
283
+ { :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
284
+ ],
285
+ :writeConcern => { :w => 1 },
286
+ :ordered => true
287
+ }
288
+
289
+ result = @@db.command(command)
290
+ assert_equal 1, result['ok']
291
+ assert_equal 2, result['n']
292
+ assert_equal 1, @@test.find({ :a => 2 }).count
293
+ assert_equal 1, @@test.find({ :a => 4 }).count
294
+ end
295
+
296
+ def test_multi_unordered_update_write_command
297
+ @@test.drop
298
+ @@test.insert([{ :a => 1 }, { :a => 3 }])
299
+
300
+ command = {
301
+ 'update' => @@test.name,
302
+ :updates => [
303
+ { :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
304
+ { :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
305
+ ],
306
+ :writeConcern => { :w => 1 },
307
+ :ordered => false
308
+ }
309
+
310
+ result = @@db.command(command)
311
+ assert_equal 1, result['ok']
312
+ assert_equal 2, result['n']
313
+ assert_equal 1, @@test.find({ :a => 2 }).count
314
+ assert_equal 1, @@test.find({ :a => 4 }).count
315
+ end
316
+
317
+ def test_update_write_command_with_no_concern
318
+ @@test.drop
319
+ @@test.insert([{ :a => 1 }, { :a => 3 }])
320
+
321
+ command = {
322
+ 'update' => @@test.name,
323
+ :updates => [
324
+ { :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
325
+ { :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
326
+ ],
327
+ :ordered => false
328
+ }
329
+
330
+ result = @@db.command(command)
331
+ assert_equal 1, result['ok']
332
+ assert_equal 2, result['n']
333
+ assert_equal 1, @@test.find({ :a => 2 }).count
334
+ assert_equal 1, @@test.find({ :a => 4 }).count
335
+ end
336
+
337
+ def test_update_write_command_with_error
338
+ @@test.drop
339
+ @@test.ensure_index({ :a => 1 }, { :unique => true })
340
+ @@test.insert([{ :a => 1 }, { :a => 2 }])
341
+
342
+ command = {
343
+ 'update' => @@test.name,
344
+ :updates => [
345
+ { :q => { :a => 2 }, :u => { '$set' => { :a => 1 }}}
346
+ ],
347
+ :ordered => false
348
+ }
349
+
350
+ assert_raise Mongo::OperationFailure do
351
+ @@db.command(command)
352
+ end
353
+ end
354
+ end
355
+
99
356
  if @@version >= '2.5.1'
357
+
100
358
  def test_aggregation_cursor
101
359
  [10, 1000].each do |size|
102
360
  @@test.drop
@@ -119,6 +377,16 @@ class CollectionTest < Test::Unit::TestCase
119
377
  @@test.drop
120
378
  end
121
379
 
380
+ def test_aggregation_array
381
+ @@test.drop
382
+ 100.times {|i| @@test.insert({ :_id => i }) }
383
+ agg = @@test.aggregate([{ :$project => {:_id => '$_id'}} ])
384
+
385
+ assert agg.kind_of?(Array)
386
+
387
+ @@test.drop
388
+ end
389
+
122
390
  def test_aggregation_cursor_invalid_ops
123
391
  cursor = @@test.aggregate([], :cursor => {})
124
392
  assert_raise(Mongo::InvalidOperation) { cursor.rewind! }
@@ -134,13 +402,6 @@ class CollectionTest < Test::Unit::TestCase
134
402
  end
135
403
 
136
404
  if @@version >= '2.5.3'
137
- def test_aggregation_allow_disk_usage
138
- @@db.expects(:command).with do |selector, opts|
139
- opts[:allowDiskUsage] == true
140
- end.returns({ 'ok' => 1 })
141
- @@test.aggregate([], :allowDiskUsage => true)
142
- end
143
-
144
405
  def test_aggregation_supports_explain
145
406
  @@db.expects(:command).with do |selector, opts|
146
407
  opts[:explain] == true
@@ -613,6 +874,26 @@ class CollectionTest < Test::Unit::TestCase
613
874
  end
614
875
  end
615
876
 
877
+ if @@version < "2.5.3"
878
+ def test_jnote_raises_exception
879
+ with_no_journaling(@@client) do
880
+ ex = assert_raise Mongo::OperationFailure do
881
+ @@test.insert({:foo => 1}, :j => true)
882
+ end
883
+ result = ex.result
884
+ assert_true result.has_key?("jnote")
885
+ end
886
+ end
887
+
888
+ def test_wnote_raises_exception
889
+ ex = assert_raise Mongo::OperationFailure do
890
+ @@test.insert({:foo => 1}, :w => 2)
891
+ end
892
+ result = ex.result
893
+ assert_true result.has_key?("wnote")
894
+ end
895
+ end
896
+
616
897
  def test_update
617
898
  id1 = @@test.save("x" => 5)
618
899
  @@test.update({}, {"$inc" => {"x" => 1}})
@@ -780,7 +1061,7 @@ class CollectionTest < Test::Unit::TestCase
780
1061
  end
781
1062
  end
782
1063
 
783
- def test_defualt_timeout
1064
+ def test_default_timeout
784
1065
  cursor = @@test.find
785
1066
  assert_equal true, cursor.timeout
786
1067
  end
@@ -804,6 +1085,28 @@ class CollectionTest < Test::Unit::TestCase
804
1085
  end
805
1086
  end
806
1087
 
1088
+ if @@version >= '2.5.5'
1089
+ def test_meta_field_projection
1090
+ @@test.save({ :t => 'spam eggs and spam'})
1091
+ @@test.save({ :t => 'spam'})
1092
+ @@test.save({ :t => 'egg sausage and bacon'})
1093
+
1094
+ @@test.ensure_index([[:t, 'text']])
1095
+ assert @@test.find_one({ :$text => { :$search => 'spam' }},
1096
+ { :fields => [:t, { :score => { :$meta => 'textScore' } }] })
1097
+ end
1098
+
1099
+ def test_sort_by_meta
1100
+ @@test.save({ :t => 'spam eggs and spam'})
1101
+ @@test.save({ :t => 'spam'})
1102
+ @@test.save({ :t => 'egg sausage and bacon'})
1103
+
1104
+ @@test.ensure_index([[:t, 'text']])
1105
+ assert @@test.find({ :$text => { :$search => 'spam' }}).sort([:score, { '$meta' => 'textScore' }])
1106
+ assert @@test.find({ :$text => { :$search => 'spam' }}).sort(:score => { '$meta' =>'textScore' })
1107
+ end
1108
+ end
1109
+
807
1110
  if @@version >= "1.5.1"
808
1111
  def test_fields_with_slice
809
1112
  @@test.save({:foo => [1, 2, 3, 4, 5, 6], :test => 'slice'})
@@ -1181,19 +1484,32 @@ class CollectionTest < Test::Unit::TestCase
1181
1484
  end
1182
1485
 
1183
1486
  if @@version >= '2.5.5'
1487
+ def test_aggregation_allow_disk_use
1488
+ @@db.expects(:command).with do |selector, opts|
1489
+ opts[:allowDiskUse] == true
1490
+ end.returns({ 'ok' => 1 })
1491
+ @@test.aggregate([], :allowDiskUse => true)
1492
+ end
1493
+
1184
1494
  def test_parallel_scan
1185
1495
  8000.times { |i| @@test.insert({ :_id => i }) }
1186
1496
 
1187
- n_docs = {}
1497
+ lock = Mutex.new
1498
+ doc_ids = Set.new
1188
1499
  threads = []
1189
1500
  cursors = @@test.parallel_scan(3)
1190
1501
  cursors.each_with_index do |cursor, i|
1191
1502
  threads << Thread.new do
1192
- n_docs[i] = cursor.to_a.size
1503
+ docs = cursor.to_a
1504
+ lock.synchronize do
1505
+ docs.each do |doc|
1506
+ doc_ids << doc['_id']
1507
+ end
1508
+ end
1193
1509
  end
1194
1510
  end
1195
1511
  threads.each(&:join)
1196
- assert_equal @@test.count, n_docs.values.inject(0) { |sum, n| sum + n }
1512
+ assert_equal 8000, doc_ids.count
1197
1513
  end
1198
1514
  end
1199
1515
 
@@ -1718,16 +2034,19 @@ end
1718
2034
  end
1719
2035
 
1720
2036
  should "generate indexes in the proper order" do
1721
- @collection.expects(:send_write) do |type, selector, documents, check_keys, opts, collection_name|
1722
- assert_equal 'b_1_a_1', selector[:name]
2037
+ key = BSON::OrderedHash['b', 1, 'a', 1]
2038
+ if @@version < '2.5.5'
2039
+ @collection.expects(:send_write) do |type, selector, documents, check_keys, opts, collection_name|
2040
+ assert_equal key, selector[:key]
2041
+ end
2042
+ else
2043
+ @collection.db.expects(:command) do |selector|
2044
+ assert_equal key, selector[:indexes].first[:key]
2045
+ end
1723
2046
  end
1724
2047
  @collection.create_index([['b', 1], ['a', 1]])
1725
2048
  end
1726
2049
 
1727
- should "allow multiple calls to create_index" do
1728
-
1729
- end
1730
-
1731
2050
  should "allow creation of multiple indexes" do
1732
2051
  assert @collection.create_index([['a', 1]])
1733
2052
  assert @collection.create_index([['a', 1]])
@@ -27,6 +27,34 @@ class ConversionsTest < Test::Unit::TestCase
27
27
  assert_equal({ "field1" => 1, "field2" => -1 }, params)
28
28
  end
29
29
 
30
+ def test_array_as_sort_parameters_with_array_of_key_and_hash
31
+ params = array_as_sort_parameters(["score", {"$meta" => "textScore"}])
32
+ assert_equal({"score" => {"$meta" => "textScore"}}, params)
33
+ end
34
+
35
+ def test_array_as_sort_parameters_with_array_of_key_and_hashes
36
+ params = array_as_sort_parameters([["field1", :asc],["score", {"$meta" => "textScore"}]])
37
+ assert_equal({"field1" => 1, "score" => {"$meta" => "textScore"}}, params)
38
+ end
39
+
40
+ def test_hash_as_sort_parameters_with_string
41
+ sort = BSON::OrderedHash["field", "asc"]
42
+ params = hash_as_sort_parameters(sort)
43
+ assert_equal({"field" => 1}, params)
44
+ end
45
+
46
+ def test_hash_as_sort_parameters_with_hash
47
+ sort = BSON::OrderedHash["score", {"$meta" => "textScore"}]
48
+ params = hash_as_sort_parameters(sort)
49
+ assert_equal({"score" => {"$meta" => "textScore"}}, params)
50
+ end
51
+
52
+ def test_hash_as_sort_parameters_with_hash_and_string
53
+ sort = BSON::OrderedHash["score", {"$meta" => "textScore"}, "field", "asc"]
54
+ params = hash_as_sort_parameters(sort)
55
+ assert_equal({ "score" => {"$meta" => "textScore"}, "field" => 1 }, params)
56
+ end
57
+
30
58
  def test_string_as_sort_parameters_with_string
31
59
  params = string_as_sort_parameters("field")
32
60
  assert_equal({ "field" => 1 }, params)
@@ -122,6 +150,10 @@ class ConversionsTest < Test::Unit::TestCase
122
150
  assert_equal(-1, sort_value(:DESC))
123
151
  end
124
152
 
153
+ def test_sort_value_when_value_is_hash
154
+ assert_equal({"$meta" => "textScore"}, sort_value("$meta" => "textScore"))
155
+ end
156
+
125
157
  def test_sort_value_when_value_is_invalid
126
158
  assert_raise Mongo::InvalidSortValueError do
127
159
  sort_value(2)