mongo 1.2.4 → 1.3.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/README.md +13 -25
  2. data/Rakefile +9 -1
  3. data/docs/HISTORY.md +19 -0
  4. data/docs/RELEASES.md +33 -0
  5. data/docs/REPLICA_SETS.md +4 -3
  6. data/lib/mongo.rb +20 -2
  7. data/lib/mongo/collection.rb +15 -2
  8. data/lib/mongo/connection.rb +75 -14
  9. data/lib/mongo/cursor.rb +12 -4
  10. data/lib/mongo/db.rb +3 -3
  11. data/lib/mongo/exceptions.rb +3 -0
  12. data/lib/mongo/gridfs/grid_io.rb +88 -7
  13. data/lib/mongo/repl_set_connection.rb +29 -11
  14. data/lib/mongo/util/pool.rb +15 -6
  15. data/lib/mongo/util/timeout.rb +42 -0
  16. data/lib/mongo/util/uri_parser.rb +5 -1
  17. data/test/auxillary/fork_test.rb +30 -0
  18. data/test/bson/bson_test.rb +68 -27
  19. data/test/bson/byte_buffer_test.rb +11 -0
  20. data/test/bson/object_id_test.rb +14 -1
  21. data/test/bson/ordered_hash_test.rb +7 -0
  22. data/test/bson/timestamp_test.rb +24 -0
  23. data/test/collection_test.rb +41 -24
  24. data/test/connection_test.rb +33 -2
  25. data/test/conversions_test.rb +10 -11
  26. data/test/cursor_fail_test.rb +1 -1
  27. data/test/cursor_message_test.rb +1 -1
  28. data/test/cursor_test.rb +33 -4
  29. data/test/db_api_test.rb +13 -2
  30. data/test/db_test.rb +3 -3
  31. data/test/grid_file_system_test.rb +0 -1
  32. data/test/grid_io_test.rb +72 -1
  33. data/test/grid_test.rb +16 -16
  34. data/test/replica_sets/connect_test.rb +8 -0
  35. data/test/replica_sets/query_test.rb +10 -0
  36. data/test/support/hash_with_indifferent_access.rb +0 -13
  37. data/test/support_test.rb +0 -1
  38. data/test/test_helper.rb +27 -8
  39. data/test/timeout_test.rb +14 -0
  40. data/test/unit/collection_test.rb +1 -1
  41. data/test/unit/connection_test.rb +0 -13
  42. data/test/unit/cursor_test.rb +16 -6
  43. data/test/unit/db_test.rb +9 -11
  44. data/test/unit/repl_set_connection_test.rb +0 -13
  45. data/test/unit/safe_test.rb +1 -1
  46. metadata +15 -23
@@ -186,5 +186,16 @@ class ByteBufferTest < Test::Unit::TestCase
186
186
  @buf.get_int
187
187
  assert !@buf.more?
188
188
  end
189
+
190
+ def test_equality
191
+ @buf = ByteBuffer.new("foo")
192
+ assert_equal @buf, @buf
193
+ assert_equal ByteBuffer.new(""), ByteBuffer.new("")
194
+ assert_equal ByteBuffer.new("123"), ByteBuffer.new("123")
195
+ assert_not_equal ByteBuffer.new("123"), ByteBuffer.new("1234")
196
+ assert_equal @buf, "foo"
197
+ assert_not_equal @buf, 123
198
+ assert_not_equal @buf, nil
199
+ end
189
200
 
190
201
  end
@@ -126,14 +126,27 @@ class ObjectIdTest < Test::Unit::TestCase
126
126
  time = Time.now.utc
127
127
  id = ObjectId.from_time(time)
128
128
 
129
+ assert id.to_a[4, 8].all? {|byte| byte == 0 }
129
130
  assert_equal time.to_i, id.generation_time.to_i
130
131
  end
131
132
 
133
+ def test_from_time_unique
134
+ time = Time.now.utc
135
+ id = ObjectId.from_time(time, :unique => true)
136
+
137
+ mac_id = Digest::MD5.digest(Socket.gethostname)[0, 3].unpack("C3")
138
+ assert_equal id.to_a[4, 3], mac_id
139
+ assert_equal time.to_i, id.generation_time.to_i
140
+
141
+ id2 = ObjectId.new(nil, time)
142
+ assert_equal time.to_i, id2.generation_time.to_i
143
+ end
144
+
132
145
  def test_json
133
146
  id = ObjectId.new
134
147
  assert_equal "{\"$oid\": \"#{id}\"}", id.to_json
135
148
  end
136
-
149
+
137
150
  def test_as_json
138
151
  id = ObjectId.new
139
152
  assert_equal({"$oid" => id.to_s}, id.as_json)
@@ -194,4 +194,11 @@ class OrderedHashTest < Test::Unit::TestCase
194
194
  copy[:foo] = 1
195
195
  assert copy.keys != @oh.keys
196
196
  end
197
+
198
+ def test_dup
199
+ oh2 = @oh.dup
200
+ oh2['f'] = 9
201
+ assert_nil @oh['f']
202
+ assert_equal ['c', 'a', 'z'], @oh.keys
203
+ end
197
204
  end
@@ -0,0 +1,24 @@
1
+ require './test/test_helper'
2
+
3
+ class TiumestampTest < Test::Unit::TestCase
4
+ include Mongo
5
+
6
+ def test_timestamp_equality
7
+ t1 = Timestamp.new(5000, 200)
8
+ t2 = Timestamp.new(5000, 200)
9
+ assert_equal t2, t1
10
+ end
11
+
12
+ def test_implements_array_for_backward_compatibility
13
+ ts = Timestamp.new(5000, 200)
14
+ assert_equal 200, ts[0]
15
+ assert_equal 5000, ts[1]
16
+
17
+ array = ts.map {|t| t }
18
+ assert_equal 2, array.length
19
+
20
+ assert_equal 200, array[0]
21
+ assert_equal 5000, array[1]
22
+ end
23
+
24
+ end
@@ -1,7 +1,7 @@
1
1
  require './test/test_helper'
2
2
 
3
3
  class TestCollection < Test::Unit::TestCase
4
- @@connection ||= standard_connection
4
+ @@connection ||= standard_connection(:op_timeout => 2)
5
5
  @@db = @@connection.db(MONGO_TEST_DB)
6
6
  @@test = @@db.collection("test")
7
7
  @@version = @@connection.server_version
@@ -373,8 +373,8 @@ class TestCollection < Test::Unit::TestCase
373
373
 
374
374
  docs = [{"hello" => "world"}, {"hello" => "world"}]
375
375
  @@test.insert(docs)
376
- docs.each do |doc|
377
- assert(doc.include?(:_id))
376
+ docs.each do |d|
377
+ assert(d.include?(:_id))
378
378
  end
379
379
  end
380
380
 
@@ -466,31 +466,34 @@ class TestCollection < Test::Unit::TestCase
466
466
  assert res["timeMillis"]
467
467
  end
468
468
 
469
- def test_map_reduce_with_collection_merge
470
- @@test << {:user_id => 1}
471
- @@test << {:user_id => 2}
472
- output_collection = "test-map-coll"
473
- m = Code.new("function() { emit(this.user_id, {count: 1}); }")
474
- r = Code.new("function(k,vals) { var sum = 0;" +
475
- " vals.forEach(function(v) { sum += v.count;} ); return {count: sum}; }")
476
- res = @@test.map_reduce(m, r, :out => output_collection)
477
469
 
478
- @@test.remove
479
- @@test << {:user_id => 3}
480
- res = @@test.map_reduce(m, r, :out => {:merge => output_collection})
481
- assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 1}
470
+ if @@version >= "1.8.0"
471
+ def test_map_reduce_with_collection_merge
472
+ @@test << {:user_id => 1}
473
+ @@test << {:user_id => 2}
474
+ output_collection = "test-map-coll"
475
+ m = Code.new("function() { emit(this.user_id, {count: 1}); }")
476
+ r = Code.new("function(k,vals) { var sum = 0;" +
477
+ " vals.forEach(function(v) { sum += v.count;} ); return {count: sum}; }")
478
+ res = @@test.map_reduce(m, r, :out => output_collection)
482
479
 
483
- @@test.remove
484
- @@test << {:user_id => 3}
485
- res = @@test.map_reduce(m, r, :out => {:reduce => output_collection})
486
- assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 2}
480
+ @@test.remove
481
+ @@test << {:user_id => 3}
482
+ res = @@test.map_reduce(m, r, :out => {:merge => output_collection})
483
+ assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 1}
487
484
 
488
- assert_raise ArgumentError do
489
- @@test.map_reduce(m, r, :out => {:inline => 1})
490
- end
485
+ @@test.remove
486
+ @@test << {:user_id => 3}
487
+ res = @@test.map_reduce(m, r, :out => {:reduce => output_collection})
488
+ assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 2}
491
489
 
492
- @@test.map_reduce(m, r, :raw => true, :out => {:inline => 1})
493
- assert res["results"]
490
+ assert_raise ArgumentError do
491
+ @@test.map_reduce(m, r, :out => {:inline => 1})
492
+ end
493
+
494
+ @@test.map_reduce(m, r, :raw => true, :out => {:inline => 1})
495
+ assert res["results"]
496
+ end
494
497
  end
495
498
  end
496
499
 
@@ -592,6 +595,20 @@ class TestCollection < Test::Unit::TestCase
592
595
  assert_equal 1, x
593
596
  end
594
597
 
598
+ def test_find_with_transformer
599
+ klass = Struct.new(:id, :a)
600
+ transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
601
+ cursor = @@test.find({}, :transformer => transformer)
602
+ assert_equal(transformer, cursor.transformer)
603
+ end
604
+
605
+ def test_find_one_with_transformer
606
+ klass = Struct.new(:id, :a)
607
+ transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
608
+ id = @@test.insert('a' => 1)
609
+ doc = @@test.find_one(id, :transformer => transformer)
610
+ assert_instance_of(klass, doc)
611
+ end
595
612
 
596
613
  def test_ensure_index
597
614
  @@test.drop_indexes
@@ -22,12 +22,22 @@ class TestConnection < Test::Unit::TestCase
22
22
  end
23
23
  end
24
24
 
25
+ def test_host_port_accessors
26
+ assert_equal @conn.host, TEST_HOST
27
+ assert_equal @conn.port, TEST_PORT
28
+ end
29
+
25
30
  def test_server_info
26
31
  server_info = @conn.server_info
27
32
  assert server_info.keys.include?("version")
28
33
  assert Mongo::Support.ok?(server_info)
29
34
  end
30
35
 
36
+ def test_ping
37
+ ping = @conn.ping
38
+ assert ping['ok']
39
+ end
40
+
31
41
  def test_connection_uri
32
42
  con = Connection.from_uri("mongodb://#{host_port}")
33
43
  assert_equal mongo_host, con.primary_pool.host
@@ -35,7 +45,7 @@ class TestConnection < Test::Unit::TestCase
35
45
  end
36
46
 
37
47
  def test_server_version
38
- assert_match /\d\.\d+(\.\d+)?/, @conn.server_version.to_s
48
+ assert_match(/\d\.\d+(\.\d+)?/, @conn.server_version.to_s)
39
49
  end
40
50
 
41
51
  def test_invalid_database_names
@@ -149,7 +159,7 @@ class TestConnection < Test::Unit::TestCase
149
159
  @conn.lock!
150
160
  assert @conn.locked?
151
161
  assert_equal 1, @conn['admin']['$cmd.sys.inprog'].find_one['fsyncLock'], "Not fsync-locked"
152
- assert_equal "unlock requested", @conn.unlock!['info']
162
+ assert_match(/unlock/, @conn.unlock!['info'])
153
163
  unlocked = false
154
164
  counter = 0
155
165
  while counter < 5
@@ -200,6 +210,27 @@ class TestConnection < Test::Unit::TestCase
200
210
  assert_equal Mongo::DEFAULT_MAX_BSON_SIZE, BSON::BSON_CODER.max_bson_size
201
211
  end
202
212
 
213
+ def test_connection_activity
214
+ conn = standard_connection
215
+ assert conn.active?
216
+
217
+ conn.primary_pool.close
218
+ assert !conn.active?
219
+
220
+ # Simulate a dropped connection.
221
+ dropped_socket = Mocha::Mock.new
222
+ dropped_socket.stubs(:read).raises(Errno::ECONNRESET)
223
+ dropped_socket.stubs(:send).raises(Errno::ECONNRESET)
224
+ dropped_socket.stub_everything
225
+
226
+ conn.primary_pool.host = 'localhost'
227
+ conn.primary_pool.port = Mongo::Connection::DEFAULT_PORT
228
+ conn.primary_pool.instance_variable_set("@pids", {dropped_socket => Process.pid})
229
+ conn.primary_pool.instance_variable_set("@sockets", [dropped_socket])
230
+
231
+ assert !conn.active?
232
+ end
233
+
203
234
  context "Saved authentications" do
204
235
  setup do
205
236
  @conn = standard_connection
@@ -1,7 +1,6 @@
1
1
  require './test/test_helper'
2
2
  require 'mongo/exceptions'
3
3
  require 'mongo/util/conversions'
4
- require 'bson/ordered_hash'
5
4
 
6
5
  class ConversionsTest < Test::Unit::TestCase
7
6
  include Mongo::Conversions
@@ -40,11 +39,11 @@ class ConversionsTest < Test::Unit::TestCase
40
39
  end
41
40
 
42
41
  def test_sort_value_when_value_is_negative_one
43
- assert_equal -1, sort_value(-1)
42
+ assert_equal(-1, sort_value(-1))
44
43
  end
45
44
 
46
45
  def test_sort_value_when_value_is_negative_one_as_a_string
47
- assert_equal -1, sort_value("-1")
46
+ assert_equal(-1, sort_value("-1"))
48
47
  end
49
48
 
50
49
  def test_sort_value_when_value_is_ascending
@@ -80,35 +79,35 @@ class ConversionsTest < Test::Unit::TestCase
80
79
  end
81
80
 
82
81
  def test_sort_value_when_value_is_descending
83
- assert_equal -1, sort_value("descending")
82
+ assert_equal(-1, sort_value("descending"))
84
83
  end
85
84
 
86
85
  def test_sort_value_when_value_is_desc
87
- assert_equal -1, sort_value("desc")
86
+ assert_equal(-1, sort_value("desc"))
88
87
  end
89
88
 
90
89
  def test_sort_value_when_value_is_uppercase_descending
91
- assert_equal -1, sort_value("DESCENDING")
90
+ assert_equal(-1, sort_value("DESCENDING"))
92
91
  end
93
92
 
94
93
  def test_sort_value_when_value_is_uppercase_desc
95
- assert_equal -1, sort_value("DESC")
94
+ assert_equal(-1, sort_value("DESC"))
96
95
  end
97
96
 
98
97
  def test_sort_value_when_value_is_symbol_descending
99
- assert_equal -1, sort_value(:descending)
98
+ assert_equal(-1, sort_value(:descending))
100
99
  end
101
100
 
102
101
  def test_sort_value_when_value_is_symbol_desc
103
- assert_equal -1, sort_value(:desc)
102
+ assert_equal(-1, sort_value(:desc))
104
103
  end
105
104
 
106
105
  def test_sort_value_when_value_is_uppercase_symbol_descending
107
- assert_equal -1, sort_value(:DESCENDING)
106
+ assert_equal(-1, sort_value(:DESCENDING))
108
107
  end
109
108
 
110
109
  def test_sort_value_when_value_is_uppercase_symbol_desc
111
- assert_equal -1, sort_value(:DESC)
110
+ assert_equal(-1, sort_value(:DESC))
112
111
  end
113
112
 
114
113
  def test_sort_value_when_value_is_invalid
@@ -1,7 +1,7 @@
1
1
  require './test/test_helper'
2
2
  require 'logger'
3
3
 
4
- class CursorTest < Test::Unit::TestCase
4
+ class CursorFailTest < Test::Unit::TestCase
5
5
 
6
6
  include Mongo
7
7
 
@@ -1,7 +1,7 @@
1
1
  require './test/test_helper'
2
2
  require 'logger'
3
3
 
4
- class CursorTest < Test::Unit::TestCase
4
+ class CursorMessageTest < Test::Unit::TestCase
5
5
 
6
6
  include Mongo
7
7
 
@@ -120,7 +120,7 @@ class CursorTest < Test::Unit::TestCase
120
120
  results = @@coll.find.sort([:n, :asc]).to_a
121
121
 
122
122
  assert_equal MinKey.new, results[0]['n']
123
- assert_equal -1000000, results[1]['n']
123
+ assert_equal(-1000000, results[1]['n'])
124
124
  assert_equal 1000000, results[2]['n']
125
125
  assert_equal MaxKey.new, results[3]['n']
126
126
  end
@@ -171,8 +171,8 @@ class CursorTest < Test::Unit::TestCase
171
171
  cursor = Cursor.new(@@coll, :timeout => false)
172
172
  assert_equal false, cursor.timeout
173
173
 
174
- @@coll.find({}, :timeout => false) do |cursor|
175
- assert_equal false, cursor.timeout
174
+ @@coll.find({}, :timeout => false) do |c|
175
+ assert_equal false, c.timeout
176
176
  end
177
177
  end
178
178
 
@@ -395,10 +395,13 @@ class CursorTest < Test::Unit::TestCase
395
395
  end
396
396
 
397
397
  cursor = @@coll.find
398
+ n = 0
398
399
  while cursor.has_next?
399
- assert cursor.next_document
400
+ assert cursor.next
401
+ n += 1
400
402
  end
401
403
 
404
+ assert_equal n, 200
402
405
  assert_equal false, cursor.has_next?
403
406
  end
404
407
 
@@ -451,4 +454,30 @@ class CursorTest < Test::Unit::TestCase
451
454
  assert_equal 100, cursor.map {|doc| doc }.length
452
455
  end
453
456
 
457
+ def test_transformer
458
+ transformer = Proc.new { |doc| doc }
459
+ cursor = Cursor.new(@@coll, :transformer => transformer)
460
+ assert_equal(transformer, cursor.transformer)
454
461
  end
462
+
463
+ def test_instance_transformation_with_next
464
+ klass = Struct.new(:id, :a)
465
+ transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
466
+ cursor = Cursor.new(@@coll, :transformer => transformer)
467
+ instance = cursor.next
468
+
469
+ assert_instance_of(klass, instance)
470
+ assert_instance_of(BSON::ObjectId, instance.id)
471
+ assert_equal(1, instance.a)
472
+ end
473
+
474
+ def test_instance_transformation_with_each
475
+ klass = Struct.new(:id, :a)
476
+ transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
477
+ cursor = Cursor.new(@@coll, :transformer => transformer)
478
+
479
+ cursor.each do |instance|
480
+ assert_instance_of(klass, instance)
481
+ end
482
+ end
483
+ end
@@ -239,7 +239,7 @@ class DBAPITest < Test::Unit::TestCase
239
239
  names = @@db.collection_names
240
240
  assert names.length >= 2
241
241
  assert names.include?(@@coll.name)
242
- assert names.include?('mongo-ruby-test.test2')
242
+ assert names.include?('test2')
243
243
  ensure
244
244
  @@db.drop_collection('test2')
245
245
  end
@@ -270,6 +270,17 @@ class DBAPITest < Test::Unit::TestCase
270
270
  end
271
271
  end
272
272
 
273
+ def test_collection_options_are_passed_to_the_existing_ones
274
+ @@db.drop_collection('foobar')
275
+
276
+ @@db.create_collection('foobar')
277
+
278
+ opts = {:safe => true}
279
+ coll = @@db.create_collection('foobar', opts)
280
+ assert_equal true, coll.safe
281
+ end
282
+
283
+
273
284
  def test_index_information
274
285
  assert_equal @@coll.index_information.length, 1
275
286
 
@@ -621,7 +632,7 @@ class DBAPITest < Test::Unit::TestCase
621
632
  assert_equal("mike", @@coll.find_one()["hello"])
622
633
  end
623
634
 
624
- def test_collection_names
635
+ def test_collection_names_errors
625
636
  assert_raise TypeError do
626
637
  @@db.collection(5)
627
638
  end
@@ -26,7 +26,7 @@ class DBTest < Test::Unit::TestCase
26
26
  @@db.collection('test').insert('a' => 1)
27
27
  fail "expected 'NilClass' exception"
28
28
  rescue => ex
29
- assert_match /NilClass/, ex.to_s
29
+ assert_match(/NilClass/, ex.to_s)
30
30
  ensure
31
31
  @@db = standard_connection.db(MONGO_TEST_DB)
32
32
  @@users = @@db.collection('system.users')
@@ -104,7 +104,7 @@ class DBTest < Test::Unit::TestCase
104
104
  db.pk_factory = Object.new
105
105
  fail "error: expected exception"
106
106
  rescue => ex
107
- assert_match /Cannot change/, ex.to_s
107
+ assert_match(/Cannot change/, ex.to_s)
108
108
  ensure
109
109
  conn.close
110
110
  end
@@ -280,7 +280,7 @@ class DBTest < Test::Unit::TestCase
280
280
  assert_not_nil doc
281
281
  result = doc['result']
282
282
  assert_not_nil result
283
- assert_match /firstExtent/, result
283
+ assert_match(/firstExtent/, result)
284
284
  end
285
285
 
286
286
  end