mongo 0.18.1 → 0.18.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -25,7 +25,7 @@ module Mongo
25
25
  # Implements comparable.
26
26
  def <=>(new)
27
27
  local, new = self.to_a, to_array(new)
28
- for n in 0...local.size do
28
+ for n in 0...local.size do
29
29
  break if elements_include_mods?(local[n], new[n])
30
30
  if local[n] < new[n].to_i
31
31
  result = -1
@@ -52,10 +52,10 @@ module Mongo
52
52
 
53
53
  # Returns true if any elements include mod symbols (-, +)
54
54
  def elements_include_mods?(*elements)
55
- elements.any? { |n| n =~ /[\-\+]/ }
55
+ elements.any? { |n| n =~ /[\-\+]/ }
56
56
  end
57
57
 
58
- # Converts argument to an array of integers,
58
+ # Converts argument to an array of integers,
59
59
  # appending any mods as the final element.
60
60
  def to_array(version)
61
61
  array = version.split(".").map {|n| (n =~ /^\d+$/) ? n.to_i : n }
@@ -6,8 +6,8 @@ require 'test/test_helper'
6
6
  # NOTE: this test should be run only if a replica pair is running.
7
7
  class ReplicaPairCountTest < Test::Unit::TestCase
8
8
  include Mongo
9
-
10
- def setup
9
+
10
+ def setup
11
11
  @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil)
12
12
  @db = @conn.db('mongo-ruby-test')
13
13
  @db.drop_collection("test-pairs")
@@ -24,7 +24,7 @@ class ReplicaPairCountTest < Test::Unit::TestCase
24
24
  puts "Please disconnect the current master."
25
25
  gets
26
26
 
27
- rescue_connection_failure do
27
+ rescue_connection_failure do
28
28
  @coll.insert({:a => 30}, :safe => true)
29
29
  end
30
30
  @coll.insert({:a => 40}, :safe => true)
@@ -6,8 +6,8 @@ require 'test/test_helper'
6
6
  # NOTE: this test should be run only if a replica pair is running.
7
7
  class ReplicaPairInsertTest < Test::Unit::TestCase
8
8
  include Mongo
9
-
10
- def setup
9
+
10
+ def setup
11
11
  @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil)
12
12
  @db = @conn.db('mongo-ruby-test')
13
13
  @db.drop_collection("test-pairs")
@@ -19,7 +19,7 @@ class ReplicaPairInsertTest < Test::Unit::TestCase
19
19
  puts "Please disconnect the current master."
20
20
  gets
21
21
 
22
- rescue_connection_failure do
22
+ rescue_connection_failure do
23
23
  @coll.save({:a => 30}, :safe => true)
24
24
  end
25
25
 
@@ -28,12 +28,12 @@ class ReplicaPairInsertTest < Test::Unit::TestCase
28
28
  @coll.save({:a => 60}, :safe => true)
29
29
  @coll.save({:a => 70}, :safe => true)
30
30
 
31
- puts "Please reconnect the old master to make sure that the new master " +
31
+ puts "Please reconnect the old master to make sure that the new master " +
32
32
  "has synced with the previous master. Note: this may have happened already."
33
33
  gets
34
34
  results = []
35
-
36
- rescue_connection_failure do
35
+
36
+ rescue_connection_failure do
37
37
  @coll.find.each {|r| results << r}
38
38
  [20, 30, 40, 50, 60, 70].each do |a|
39
39
  assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
@@ -6,8 +6,8 @@ require 'test/test_helper'
6
6
  # NOTE: this test should be run only if a replica pair is running.
7
7
  class ReplicaPairPooledInsertTest < Test::Unit::TestCase
8
8
  include Mongo
9
-
10
- def setup
9
+
10
+ def setup
11
11
  @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil, :pool_size => 10, :timeout => 5)
12
12
  @db = @conn.db('mongo-ruby-test')
13
13
  @db.drop_collection("test-pairs")
@@ -22,22 +22,22 @@ class ReplicaPairPooledInsertTest < Test::Unit::TestCase
22
22
 
23
23
  threads = []
24
24
  10.times do |i|
25
- threads[i] = Thread.new do
26
- rescue_connection_failure do
25
+ threads[i] = Thread.new do
26
+ rescue_connection_failure do
27
27
  @coll.save({:a => i}, :safe => true)
28
28
  end
29
29
  end
30
30
  end
31
31
 
32
- puts "Please reconnect the old master to make sure that the new master " +
33
- "has synced with the previous master. Note: this may have happened already." +
32
+ puts "Please reconnect the old master to make sure that the new master " +
33
+ "has synced with the previous master. Note: this may have happened already." +
34
34
  "Note also that when connection with multiple threads, you may need to wait a few seconds" +
35
35
  "after restarting the old master so that all the data has had a chance to sync." +
36
36
  "This is a case of eventual consistency."
37
37
  gets
38
38
  results = []
39
-
40
- rescue_connection_failure do
39
+
40
+ rescue_connection_failure do
41
41
  @coll.find.each {|r| results << r}
42
42
  expected_results.each do |a|
43
43
  assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
@@ -6,8 +6,8 @@ require 'test/test_helper'
6
6
  # NOTE: this test should be run only if a replica pair is running.
7
7
  class ReplicaPairQueryTest < Test::Unit::TestCase
8
8
  include Mongo
9
-
10
- def setup
9
+
10
+ def setup
11
11
  @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil)
12
12
  @db = @conn.db('mongo-ruby-test')
13
13
  @db.drop_collection("test-pairs")
@@ -28,7 +28,7 @@ class ReplicaPairQueryTest < Test::Unit::TestCase
28
28
  gets
29
29
 
30
30
  results = []
31
- rescue_connection_failure do
31
+ rescue_connection_failure do
32
32
  @coll.find.each {|r| results << r}
33
33
  [20, 30, 40].each do |a|
34
34
  assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
data/test/test_bson.rb CHANGED
@@ -23,6 +23,13 @@ class BSONTest < Test::Unit::TestCase
23
23
  assert_equal doc, BSON.deserialize(bson)
24
24
  end
25
25
 
26
+ def test_document_length
27
+ doc = {'name' => 'a' * 5 * 1024 * 1024}
28
+ assert_raise InvalidDocument do
29
+ assert BSON.serialize(doc)
30
+ end
31
+ end
32
+
26
33
  # In 1.8 we test that other string encodings raise an exception.
27
34
  # In 1.9 we test that they get auto-converted.
28
35
  if RUBY_VERSION < '1.9'
@@ -314,4 +321,29 @@ class BSONTest < Test::Unit::TestCase
314
321
  assert_equal BSON.serialize(one).to_a, BSON.serialize(dup).to_a
315
322
  end
316
323
 
324
+ def test_null_character
325
+ doc = {"a" => "\x00"}
326
+
327
+ assert_equal doc, BSON.deserialize(BSON.serialize(doc).to_a)
328
+
329
+ assert_raise InvalidDocument do
330
+ BSON.serialize({"\x00" => "a"})
331
+ end
332
+
333
+ assert_raise InvalidDocument do
334
+ BSON.serialize({"a" => (Regexp.compile "ab\x00c")})
335
+ end
336
+ end
337
+
338
+ def test_invalid_object
339
+ o = Object.new
340
+ assert_raise InvalidDocument do
341
+ BSON.serialize({:foo => o})
342
+ end
343
+
344
+ assert_raise InvalidDocument do
345
+ BSON.serialize({:foo => Date.today})
346
+ end
347
+ end
348
+
317
349
  end
@@ -53,18 +53,55 @@ class TestCollection < Test::Unit::TestCase
53
53
  assert_equal 5, @@db.collection("test.foo").find_one()["x"]
54
54
  end
55
55
 
56
+ def test_nil_id
57
+ assert_equal 5, @@test.insert({"_id" => 5, "foo" => "bar"}, {:safe => true})
58
+ assert_equal 5, @@test.save({"_id" => 5, "foo" => "baz"}, {:safe => true})
59
+ assert_equal nil, @@test.find_one("foo" => "bar")
60
+ assert_equal "baz", @@test.find_one(:_id => 5)["foo"]
61
+ assert_raise OperationFailure do
62
+ @@test.insert({"_id" => 5, "foo" => "bar"}, {:safe => true})
63
+ end
64
+
65
+ assert_equal nil, @@test.insert({"_id" => nil, "foo" => "bar"}, {:safe => true})
66
+ assert_equal nil, @@test.save({"_id" => nil, "foo" => "baz"}, {:safe => true})
67
+ assert_equal nil, @@test.find_one("foo" => "bar")
68
+ assert_equal "baz", @@test.find_one(:_id => nil)["foo"]
69
+ assert_raise OperationFailure do
70
+ @@test.insert({"_id" => nil, "foo" => "bar"}, {:safe => true})
71
+ end
72
+ assert_raise OperationFailure do
73
+ @@test.insert({:_id => nil, "foo" => "bar"}, {:safe => true})
74
+ end
75
+ end
76
+
56
77
  if @@version > "1.1"
57
- def test_distinct
58
- @@test.remove
59
- @@test.insert([{:a => 0, :b => {:c => "a"}},
60
- {:a => 1, :b => {:c => "b"}},
61
- {:a => 1, :b => {:c => "c"}},
62
- {:a => 2, :b => {:c => "a"}},
63
- {:a => 3},
64
- {:a => 3}])
78
+ context "distinct queries" do
79
+ setup do
80
+ @@test.remove
81
+ @@test.insert([{:a => 0, :b => {:c => "a"}},
82
+ {:a => 1, :b => {:c => "b"}},
83
+ {:a => 1, :b => {:c => "c"}},
84
+ {:a => 2, :b => {:c => "a"}},
85
+ {:a => 3},
86
+ {:a => 3}])
87
+ end
88
+
89
+ should "return distinct values" do
90
+ assert_equal [0, 1, 2, 3], @@test.distinct(:a).sort
91
+ assert_equal ["a", "b", "c"], @@test.distinct("b.c").sort
92
+ end
93
+
94
+ if @@version >= "1.2"
95
+
96
+ should "filter collection with query" do
97
+ assert_equal [2, 3], @@test.distinct(:a, {:a => {"$gt" => 1}}).sort
98
+ end
65
99
 
66
- assert_equal [0, 1, 2, 3], @@test.distinct(:a).sort
67
- assert_equal ["a", "b", "c"], @@test.distinct("b.c").sort
100
+ should "filter nested objects" do
101
+ assert_equal ["a", "b"], @@test.distinct("b.c", {"b.c" => {"$ne" => "c"}}).sort
102
+ end
103
+
104
+ end
68
105
  end
69
106
  end
70
107
 
@@ -259,26 +296,42 @@ class TestCollection < Test::Unit::TestCase
259
296
  assert c.closed?
260
297
  end
261
298
 
262
- def test_mapreduce
263
- @@test << { "user_id" => 1 }
264
- @@test << { "user_id" => 2 }
299
+ if @@version < "1.1.1"
300
+ def test_map_reduce
301
+ @@test << { "user_id" => 1 }
302
+ @@test << { "user_id" => 2 }
265
303
 
266
- m = "function() { emit(this.user_id, 1); }"
267
- r = "function(k,vals) { return 1; }"
268
- res = @@test.map_reduce(m, r);
269
- assert res.find_one({"_id" => 1})
270
- assert res.find_one({"_id" => 2})
271
- end
304
+ m = "function() { emit(this.user_id, 1); }"
305
+ r = "function(k,vals) { return 1; }"
306
+ res = @@test.map_reduce(m, r);
307
+ assert res.find_one({"_id" => 1})
308
+ assert res.find_one({"_id" => 2})
309
+ end
272
310
 
273
- def test_mapreduce_with_code_objects
274
- @@test << { "user_id" => 1 }
275
- @@test << { "user_id" => 2 }
311
+ def test_map_reduce_with_code_objects
312
+ @@test << { "user_id" => 1 }
313
+ @@test << { "user_id" => 2 }
276
314
 
277
- m = Code.new("function() { emit(this.user_id, 1); }")
278
- r = Code.new("function(k,vals) { return 1; }")
279
- res = @@test.map_reduce(m, r);
280
- assert res.find_one({"_id" => 1})
281
- assert res.find_one({"_id" => 2})
315
+ m = Code.new("function() { emit(this.user_id, 1); }")
316
+ r = Code.new("function(k,vals) { return 1; }")
317
+ res = @@test.map_reduce(m, r);
318
+ assert res.find_one({"_id" => 1})
319
+ assert res.find_one({"_id" => 2})
320
+ end
321
+
322
+ def test_map_reduce_with_options
323
+ @@test.remove
324
+ @@test << { "user_id" => 1 }
325
+ @@test << { "user_id" => 2 }
326
+ @@test << { "user_id" => 3 }
327
+
328
+ m = Code.new("function() { emit(this.user_id, 1); }")
329
+ r = Code.new("function(k,vals) { return 1; }")
330
+ res = @@test.map_reduce(m, r, :query => {"user_id" => {"$gt" => 1}});
331
+ assert_equal 2, res.count
332
+ assert res.find_one({"_id" => 2})
333
+ assert res.find_one({"_id" => 3})
334
+ end
282
335
  end
283
336
 
284
337
  def test_saving_dates_pre_epoch
@@ -306,12 +359,12 @@ class TestCollection < Test::Unit::TestCase
306
359
  @@test.save(:foo => i)
307
360
  end
308
361
 
309
- assert_equal 5, @@test.find({}, :skip => 5).next_object()["foo"]
310
- assert_equal nil, @@test.find({}, :skip => 10).next_object()
362
+ assert_equal 5, @@test.find({}, :skip => 5).next_document()["foo"]
363
+ assert_equal nil, @@test.find({}, :skip => 10).next_document()
311
364
 
312
365
  assert_equal 5, @@test.find({}, :limit => 5).to_a.length
313
366
 
314
- assert_equal 3, @@test.find({}, :skip => 3, :limit => 5).next_object()["foo"]
367
+ assert_equal 3, @@test.find({}, :skip => 3, :limit => 5).next_document()["foo"]
315
368
  assert_equal 5, @@test.find({}, :skip => 3, :limit => 5).to_a.length
316
369
  end
317
370
 
@@ -348,82 +401,104 @@ class TestCollection < Test::Unit::TestCase
348
401
  assert_equal 1, x
349
402
  end
350
403
 
351
- def test_group_with_scope
352
- @@test.save("a" => 1)
353
- @@test.save("b" => 1)
404
+ context "Grouping" do
405
+ setup do
406
+ @@test.remove
407
+ @@test.save("a" => 1)
408
+ @@test.save("b" => 1)
409
+ @initial = {"count" => 0}
410
+ @reduce_function = "function (obj, prev) { prev.count += inc_value; }"
411
+ end
354
412
 
355
- reduce_function = "function (obj, prev) { prev.count += inc_value; }"
413
+ should "group results using eval form" do
414
+ assert_equal 1, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 0.5}))[0]["count"]
415
+ assert_equal 2, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}))[0]["count"]
416
+ assert_equal 4, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 2}))[0]["count"]
417
+ end
356
418
 
357
- assert_equal 2, @@test.group([], {}, {"count" => 0},
358
- Code.new(reduce_function,
359
- {"inc_value" => 1}))[0]["count"]
419
+ should "group results using command form" do
420
+ assert_equal 1, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 0.5}), true)[0]["count"]
421
+ assert_equal 2, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), true)[0]["count"]
422
+ assert_equal 4, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 2}), true)[0]["count"]
423
+ end
360
424
 
361
- # TODO enable these tests when SERVER-262 is fixed
425
+ should "finalize grouped results" do
426
+ @finalize = "function(doc) {doc.f = doc.count + 200; }"
427
+ assert_equal 202, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), true, @finalize)[0]["f"]
428
+ end
429
+ end
362
430
 
363
- # assert_equal 2, @@test.group([], {}, {"count" => 0},
364
- # Code.new(reduce_function,
365
- # {"inc_value" => 1}), true)[0]["count"]
431
+ context "Grouping with a key function" do
432
+ setup do
433
+ @@test.remove
434
+ @@test.save("a" => 1)
435
+ @@test.save("a" => 2)
436
+ @@test.save("a" => 3)
437
+ @@test.save("a" => 4)
438
+ @@test.save("a" => 5)
439
+ @initial = {"count" => 0}
440
+ @keyf = "function (doc) { if(doc.a % 2 == 0) { return {even: true}; } else {return {odd: true}} };"
441
+ @reduce = "function (obj, prev) { prev.count += 1; }"
442
+ end
366
443
 
367
- assert_equal 4, @@test.group([], {}, {"count" => 0},
368
- Code.new(reduce_function,
369
- {"inc_value" => 2}))[0]["count"]
370
- # assert_equal 4, @@test.group([], {}, {"count" => 0},
371
- # Code.new(reduce_function,
372
- # {"inc_value" => 2}), true)[0]["count"]
444
+ should "group results" do
445
+ results = @@test.group(@keyf, {}, @initial, @reduce, true).sort {|a, b| a['count'] <=> b['count']}
446
+ assert results[0]['even'] && results[0]['count'] == 2.0
447
+ assert results[1]['odd'] && results[1]['count'] == 3.0
448
+ end
373
449
 
374
- assert_equal 1, @@test.group([], {}, {"count" => 0},
375
- Code.new(reduce_function,
376
- {"inc_value" => 0.5}))[0]["count"]
377
- # assert_equal 1, @@test.group([], {}, {"count" => 0},
378
- # Code.new(reduce_function,
379
- # {"inc_value" => 0.5}), true)[0]["count"]
450
+ should "raise an error if trying to use keyf as a group eval" do
451
+ assert_raise OperationFailure do
452
+ @@test.group(@keyf, {}, @initial, @reduce)
453
+ end
380
454
  end
455
+ end
381
456
 
382
- context "A collection with two records" do
383
- setup do
457
+ context "A collection with two records" do
458
+ setup do
384
459
  @collection = @@db.collection('test-collection')
385
460
  @collection.insert({:name => "Jones"})
386
461
  @collection.insert({:name => "Smith"})
387
462
  end
388
463
 
389
- should "have two records" do
464
+ should "have two records" do
390
465
  assert_equal 2, @collection.size
391
466
  end
392
467
 
393
- should "remove the two records" do
468
+ should "remove the two records" do
394
469
  @collection.remove()
395
470
  assert_equal 0, @collection.size
396
471
  end
397
472
 
398
- should "remove all records if an empty document is specified" do
473
+ should "remove all records if an empty document is specified" do
399
474
  @collection.remove({})
400
475
  assert_equal 0, @collection.find.count
401
476
  end
402
477
 
403
- should "remove only matching records" do
478
+ should "remove only matching records" do
404
479
  @collection.remove({:name => "Jones"})
405
480
  assert_equal 1, @collection.size
406
481
  end
407
482
  end
408
483
 
409
- context "Creating indexes " do
410
- setup do
484
+ context "Creating indexes " do
485
+ setup do
411
486
  @collection = @@db.collection('test-collection')
412
487
  end
413
488
 
414
- should "generate indexes in the proper order" do
489
+ should "generate indexes in the proper order" do
415
490
  @collection.expects(:insert_documents) do |sel, coll, safe|
416
491
  assert_equal 'b_1_a_1', sel[:name]
417
492
  end
418
493
  @collection.create_index([['b', 1], ['a', 1]])
419
494
  end
420
495
 
421
- context "with an index created" do
422
- setup do
496
+ context "with an index created" do
497
+ setup do
423
498
  @collection.create_index([['b', 1], ['a', 1]])
424
499
  end
425
500
 
426
- should "return properly ordered index information" do
501
+ should "return properly ordered index information" do
427
502
  assert_equal [['b', 1], ['a', 1]], @collection.index_information["b_1_a_1"]
428
503
  end
429
504
  end