mongo 1.6.1 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/README.md +17 -16
  2. data/Rakefile +30 -24
  3. data/docs/HISTORY.md +10 -0
  4. data/docs/RELEASES.md +7 -0
  5. data/docs/REPLICA_SETS.md +2 -2
  6. data/docs/TUTORIAL.md +181 -84
  7. data/lib/mongo.rb +0 -3
  8. data/lib/mongo/collection.rb +1 -1
  9. data/lib/mongo/connection.rb +28 -20
  10. data/lib/mongo/db.rb +5 -3
  11. data/lib/mongo/exceptions.rb +1 -1
  12. data/lib/mongo/gridfs/grid_file_system.rb +1 -1
  13. data/lib/mongo/networking.rb +18 -18
  14. data/lib/mongo/repl_set_connection.rb +24 -3
  15. data/lib/mongo/util/node.rb +6 -16
  16. data/lib/mongo/util/pool.rb +8 -11
  17. data/lib/mongo/util/ssl_socket.rb +34 -12
  18. data/lib/mongo/util/tcp_socket.rb +92 -3
  19. data/lib/mongo/util/uri_parser.rb +2 -2
  20. data/lib/mongo/version.rb +1 -1
  21. data/test/auxillary/repl_set_auth_test.rb +19 -5
  22. data/test/bson/bson_test.rb +23 -21
  23. data/test/bson/json_test.rb +1 -1
  24. data/test/collection_test.rb +14 -4
  25. data/test/connection_test.rb +14 -11
  26. data/test/cursor_test.rb +4 -4
  27. data/test/grid_file_system_test.rb +3 -1
  28. data/test/grid_io_test.rb +2 -2
  29. data/test/grid_test.rb +13 -6
  30. data/test/pool_test.rb +0 -2
  31. data/test/replica_sets/basic_test.rb +1 -1
  32. data/test/replica_sets/complex_connect_test.rb +5 -4
  33. data/test/replica_sets/connect_test.rb +14 -6
  34. data/test/replica_sets/pooled_insert_test.rb +1 -1
  35. data/test/replica_sets/query_test.rb +2 -2
  36. data/test/replica_sets/read_preference_test.rb +1 -2
  37. data/test/replica_sets/refresh_test.rb +4 -2
  38. data/test/replica_sets/refresh_with_threads_test.rb +7 -13
  39. data/test/replica_sets/rs_test_helper.rb +1 -1
  40. data/test/test_helper.rb +6 -4
  41. data/test/threading/threading_with_large_pool_test.rb +1 -1
  42. data/test/threading_test.rb +2 -2
  43. data/test/timeout_test.rb +40 -0
  44. data/test/tools/repl_set_manager.rb +9 -8
  45. data/test/unit/connection_test.rb +6 -7
  46. data/test/unit/node_test.rb +1 -0
  47. data/test/unit/pool_manager_test.rb +2 -1
  48. data/test/uri_test.rb +1 -2
  49. metadata +13 -6
@@ -139,11 +139,11 @@ module Mongo
139
139
  if @connect == 'direct'
140
140
  opts[:slave_ok] = true
141
141
  else
142
- opts[:read_secondary] = true
142
+ opts[:read] = :secondary
143
143
  end
144
144
  end
145
145
 
146
- opts[:rs_name] = @replicaset if @replicaset
146
+ opts[:name] = @replicaset if @replicaset
147
147
 
148
148
  opts
149
149
  end
@@ -1,3 +1,3 @@
1
1
  module Mongo
2
- VERSION = "1.6.1"
2
+ VERSION = "1.6.2"
3
3
  end
@@ -1,21 +1,22 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require './test/test_helper'
3
3
  require './test/tools/auth_repl_set_manager'
4
+ require './test/replica_sets/rs_test_helper'
4
5
 
5
6
  class AuthTest < Test::Unit::TestCase
6
7
  include Mongo
7
8
 
8
9
  def setup
9
- @manager = AuthReplSetManager.new(:start_port => 40000)
10
- @manager.start_set
10
+ @rs = AuthReplSetManager.new(:start_port => 40000)
11
+ @rs.start_set
11
12
  end
12
13
 
13
14
  def teardown
14
- @manager.cleanup_set
15
+ #@rs.cleanup_set
15
16
  end
16
17
 
17
18
  def test_repl_set_auth
18
- @conn = ReplSetConnection.new(build_seeds(3), :name => @manager.name)
19
+ @conn = ReplSetConnection.new(build_seeds(3), :name => @rs.name)
19
20
 
20
21
  # Add an admin user
21
22
  @conn['admin'].add_user("me", "secret")
@@ -51,7 +52,20 @@ class AuthTest < Test::Unit::TestCase
51
52
  end
52
53
 
53
54
  # But not when authenticated
54
- @slave1['admin'].authenticate("me", "secret")
55
+ assert @slave1['admin'].authenticate("me", "secret")
55
56
  assert @slave1['foo']['stuff'].find_one
57
+
58
+ # Same should apply when using :secondary_only
59
+ @second_only = ReplSetConnection.new(build_seeds(3),
60
+ :require_primary => false, :read => :secondary_only)
61
+
62
+ # Find should fail
63
+ assert_raise_error Mongo::OperationFailure, "unauthorized" do
64
+ @second_only['foo']['stuff'].find_one
65
+ end
66
+
67
+ # But not when authenticated
68
+ assert @second_only['admin'].authenticate("me", "secret")
69
+ assert @second_only['foo']['stuff'].find_one
56
70
  end
57
71
  end
@@ -3,19 +3,21 @@ require './test/bson/test_helper'
3
3
  require 'set'
4
4
 
5
5
  if RUBY_VERSION < '1.9'
6
- require 'complex'
7
- require 'rational'
6
+ silently do
7
+ require 'complex'
8
+ require 'rational'
9
+ end
8
10
  end
9
11
  require 'bigdecimal'
10
12
 
11
13
  begin
12
14
  require 'date'
13
15
  require 'tzinfo'
14
- require 'active_support/core_ext'
16
+ require 'active_support/timezone'
15
17
  Time.zone = "Pacific Time (US & Canada)"
16
18
  Zone = Time.zone.now
17
19
  rescue LoadError
18
- warn 'Mocking time with zone'
20
+ #warn 'Mocking time with zone'
19
21
  module ActiveSupport
20
22
  class TimeWithZone
21
23
  def initialize(utc_time, zone)
@@ -74,23 +76,21 @@ class BSONTest < Test::Unit::TestCase
74
76
  end
75
77
 
76
78
  def test_limit_max_bson_size
77
- doc = {'name' => 'a' * BSON_CODER.max_bson_size}
79
+ doc = {'name' => 'a' * BSON::DEFAULT_MAX_BSON_SIZE}
78
80
  assert_raise InvalidDocument do
79
81
  assert @encoder.serialize(doc)
80
82
  end
81
83
  end
82
84
 
83
- def test_max_bson_size
84
- assert BSON_CODER.max_bson_size >= BSON::DEFAULT_MAX_BSON_SIZE
85
- end
86
-
87
85
  def test_update_max_bson_size
88
86
  require 'ostruct'
89
87
  mock_conn = OpenStruct.new
90
88
  size = 7 * 1024 * 1024
91
89
  mock_conn.max_bson_size = size
92
- assert_equal size, BSON_CODER.update_max_bson_size(mock_conn)
93
- assert_equal size, BSON_CODER.max_bson_size
90
+ silently do
91
+ assert_equal size, BSON_CODER.update_max_bson_size(mock_conn)
92
+ assert_equal size, BSON_CODER.max_bson_size
93
+ end
94
94
  end
95
95
 
96
96
  def test_round_trip
@@ -217,10 +217,10 @@ class BSONTest < Test::Unit::TestCase
217
217
  doc = {'doc' => {'age' => 42, 'date' => Time.now.utc, 'shoe_size' => 9.5}}
218
218
  bson = @encoder.serialize(doc)
219
219
  doc2 = @encoder.deserialize(bson)
220
- assert doc['doc']
221
- assert_equal 42, doc['doc']['age']
222
- assert_equal 9.5, doc['doc']['shoe_size']
223
- assert_in_delta Time.now, doc['doc']['date'], 1
220
+ assert doc2['doc']
221
+ assert_equal 42, doc2['doc']['age']
222
+ assert_equal 9.5, doc2['doc']['shoe_size']
223
+ assert_in_delta Time.now, doc2['doc']['date'], 1
224
224
  end
225
225
 
226
226
  def test_oid
@@ -269,6 +269,7 @@ class BSONTest < Test::Unit::TestCase
269
269
  doc = {'date' => [Time.now.utc]}
270
270
  bson = @encoder.serialize(doc)
271
271
  doc2 = @encoder.deserialize(bson)
272
+ assert doc2
272
273
  end
273
274
 
274
275
  def test_date_returns_as_utc
@@ -279,6 +280,7 @@ class BSONTest < Test::Unit::TestCase
279
280
  end
280
281
 
281
282
  def test_date_before_epoch
283
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ then return true end
282
284
  begin
283
285
  doc = {'date' => Time.utc(1600)}
284
286
  bson = @encoder.serialize(doc)
@@ -297,7 +299,7 @@ class BSONTest < Test::Unit::TestCase
297
299
  [DateTime.now, Date.today, Zone].each do |invalid_date|
298
300
  doc = {:date => invalid_date}
299
301
  begin
300
- bson = BSON::BSON_CODER.serialize(doc)
302
+ BSON::BSON_CODER.serialize(doc)
301
303
  rescue => e
302
304
  ensure
303
305
  if !invalid_date.is_a? Time
@@ -431,7 +433,7 @@ class BSONTest < Test::Unit::TestCase
431
433
 
432
434
  if !(RUBY_PLATFORM =~ /java/)
433
435
  def test_timestamp
434
- val = {"test" => [4, 20]}
436
+ # val = {"test" => [4, 20]}
435
437
  result = @encoder.deserialize([0x13, 0x00, 0x00, 0x00,
436
438
  0x11, 0x74, 0x65, 0x73,
437
439
  0x74, 0x00, 0x04, 0x00,
@@ -455,7 +457,7 @@ class BSONTest < Test::Unit::TestCase
455
457
  def test_overflow
456
458
  doc = {"x" => 2**75}
457
459
  assert_raise RangeError do
458
- bson = @encoder.serialize(doc)
460
+ @encoder.serialize(doc)
459
461
  end
460
462
 
461
463
  doc = {"x" => 9223372036854775}
@@ -466,7 +468,7 @@ class BSONTest < Test::Unit::TestCase
466
468
 
467
469
  doc["x"] = doc["x"] + 1
468
470
  assert_raise RangeError do
469
- bson = @encoder.serialize(doc)
471
+ @encoder.serialize(doc)
470
472
  end
471
473
 
472
474
  doc = {"x" => -9223372036854775}
@@ -477,7 +479,7 @@ class BSONTest < Test::Unit::TestCase
477
479
 
478
480
  doc["x"] = doc["x"] - 1
479
481
  assert_raise RangeError do
480
- bson = BSON::BSON_CODER.serialize(doc)
482
+ BSON::BSON_CODER.serialize(doc)
481
483
  end
482
484
  end
483
485
 
@@ -529,7 +531,7 @@ class BSONTest < Test::Unit::TestCase
529
531
  #one = {"_foo" => "foo"}
530
532
 
531
533
  #assert_equal @encoder.serialize(one).to_a, @encoder.serialize(dup).to_a
532
- warn "Pending test for duplicate keys"
534
+ #warn "Pending test for duplicate keys"
533
535
  end
534
536
 
535
537
  def test_no_duplicate_id_when_moving_id
@@ -7,7 +7,7 @@ class JSONTest < Test::Unit::TestCase
7
7
  # This test passes when run by itself but fails
8
8
  # when run as part of the whole test suite.
9
9
  def test_object_id_as_json
10
- warn "Pending test object id as json"
10
+ #warn "Pending test object id as json"
11
11
  #id = BSON::ObjectId.new
12
12
 
13
13
  #obj = {'_id' => id}
@@ -1,4 +1,5 @@
1
1
  require './test/test_helper'
2
+ require 'rbconfig'
2
3
 
3
4
  class TestCollection < Test::Unit::TestCase
4
5
  @@connection ||= standard_connection(:op_timeout => 10)
@@ -42,8 +43,10 @@ class TestCollection < Test::Unit::TestCase
42
43
  end
43
44
 
44
45
  def test_pk_factory_on_collection
45
- @coll = Collection.new('foo', @@db, TestPK)
46
- assert_equal TestPK, @coll.pk_factory
46
+ silently do
47
+ @coll = Collection.new('foo', @@db, TestPK)
48
+ assert_equal TestPK, @coll.pk_factory
49
+ end
47
50
 
48
51
 
49
52
  @coll2 = Collection.new('foo', @@db, :pk => TestPK)
@@ -197,6 +200,7 @@ class TestCollection < Test::Unit::TestCase
197
200
  docs << {:bar => 1}
198
201
  doc_ids, error_docs = @@test.insert(docs, :collect_on_error => true)
199
202
  assert_equal 2, @@test.count
203
+ assert_equal 2, doc_ids.count
200
204
  assert_equal error_docs, []
201
205
  end
202
206
 
@@ -215,16 +219,20 @@ class TestCollection < Test::Unit::TestCase
215
219
 
216
220
  doc_ids, error_docs = @@test.insert(docs, :collect_on_error => true)
217
221
  assert_equal 2, @@test.count
222
+ assert_equal 2, doc_ids.count
218
223
  assert_equal error_docs, invalid_docs
219
224
  end
220
225
 
221
226
  def test_bson_invalid_encoding_serialize_error_with_collect_on_error
227
+ # Broken for current JRuby
228
+ if RUBY_PLATFORM == 'java' then return end
222
229
  docs = []
223
230
  docs << {:foo => 1}
224
231
  docs << {:bar => 1}
225
232
  invalid_docs = []
226
- invalid_docs << {"\223\372\226{" => 1} # non utf8 encoding
227
- docs += invalid_docs
233
+ invalid_docs << {"\223\372\226}" => 1} # non utf8 encoding
234
+ docs += invalid_docs
235
+
228
236
  assert_raise BSON::InvalidStringEncoding do
229
237
  @@test.insert(docs, :collect_on_error => false)
230
238
  end
@@ -232,6 +240,7 @@ class TestCollection < Test::Unit::TestCase
232
240
 
233
241
  doc_ids, error_docs = @@test.insert(docs, :collect_on_error => true)
234
242
  assert_equal 2, @@test.count
243
+ assert_equal 2, doc_ids.count
235
244
  assert_equal error_docs, invalid_docs
236
245
  end
237
246
 
@@ -652,6 +661,7 @@ class TestCollection < Test::Unit::TestCase
652
661
  end
653
662
 
654
663
  def test_saving_dates_pre_epoch
664
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ then return true end
655
665
  begin
656
666
  @@test.save({'date' => Time.utc(1600)})
657
667
  assert_in_delta Time.utc(1600), @@test.find_one()["date"], 2
@@ -133,7 +133,7 @@ class TestConnection < Test::Unit::TestCase
133
133
  output = StringIO.new
134
134
  logger = Logger.new(output)
135
135
  logger.level = Logger::DEBUG
136
- connection = standard_connection(:logger => logger).db(MONGO_TEST_DB)
136
+ standard_connection(:logger => logger).db(MONGO_TEST_DB)
137
137
  assert output.string.include?("admin['$cmd'].find")
138
138
  end
139
139
 
@@ -141,8 +141,8 @@ class TestConnection < Test::Unit::TestCase
141
141
  output = StringIO.new
142
142
  logger = Logger.new(output)
143
143
  logger.level = Logger::DEBUG
144
- connection = standard_connection(:logger => logger).db(MONGO_TEST_DB)
145
- assert_match /\(\d+ms\)/, output.string
144
+ standard_connection(:logger => logger).db(MONGO_TEST_DB)
145
+ assert_match(/\(\d+ms\)/, output.string)
146
146
  assert output.string.include?("admin['$cmd'].find")
147
147
  end
148
148
 
@@ -170,11 +170,13 @@ class TestConnection < Test::Unit::TestCase
170
170
  end
171
171
 
172
172
  def test_nodes
173
- conn = Connection.multi([['foo', 27017], ['bar', 27018]], :connect => false)
174
- nodes = conn.nodes
175
- assert_equal 2, nodes.length
176
- assert_equal ['foo', 27017], nodes[0]
177
- assert_equal ['bar', 27018], nodes[1]
173
+ silently do
174
+ @conn = Connection.multi([['foo', 27017], ['bar', 27018]], :connect => false)
175
+ end
176
+ seeds = @conn.seeds
177
+ assert_equal 2, seeds.length
178
+ assert_equal ['foo', 27017], seeds[0]
179
+ assert_equal ['bar', 27018], seeds[1]
178
180
  end
179
181
 
180
182
  def test_fsync_lock
@@ -227,7 +229,7 @@ class TestConnection < Test::Unit::TestCase
227
229
  conn.expects(:[]).with('admin').returns(admin_db)
228
230
 
229
231
  conn.connect
230
- assert_equal Mongo::DEFAULT_MAX_BSON_SIZE, BSON::BSON_CODER.max_bson_size
232
+ assert_equal Mongo::DEFAULT_MAX_BSON_SIZE, conn.max_bson_size
231
233
  end
232
234
 
233
235
  def test_connection_activity
@@ -290,7 +292,7 @@ class TestConnection < Test::Unit::TestCase
290
292
  context "Socket pools" do
291
293
  context "checking out writers" do
292
294
  setup do
293
- @con = standard_connection(:pool_size => 10, :timeout => 10)
295
+ @con = standard_connection(:pool_size => 10, :pool_timeout => 10)
294
296
  @coll = @con[MONGO_TEST_DB]['test-connection-exceptions']
295
297
  end
296
298
 
@@ -325,7 +327,7 @@ class TestConnection < Test::Unit::TestCase
325
327
 
326
328
  context "Connection exceptions" do
327
329
  setup do
328
- @con = standard_connection(:pool_size => 10, :timeout => 10)
330
+ @con = standard_connection(:pool_size => 10, :pool_timeout => 10)
329
331
  @coll = @con[MONGO_TEST_DB]['test-connection-exceptions']
330
332
  end
331
333
 
@@ -363,6 +365,7 @@ class TestConnection < Test::Unit::TestCase
363
365
  TCPSocket.stubs(:new).returns(fake_socket)
364
366
 
365
367
  @con.primary_pool.checkout_new_socket
368
+ @con.primary_pool.expects(:warn)
366
369
  assert @con.primary_pool.close
367
370
  end
368
371
  end
@@ -238,17 +238,17 @@ class CursorTest < Test::Unit::TestCase
238
238
  end
239
239
 
240
240
  def test_timeout
241
- opts = Cursor.new(@@coll).query_opts
241
+ opts = Cursor.new(@@coll).options
242
242
  assert_equal 0, opts & Mongo::Constants::OP_QUERY_NO_CURSOR_TIMEOUT
243
243
 
244
- opts = Cursor.new(@@coll, :timeout => false).query_opts
244
+ opts = Cursor.new(@@coll, :timeout => false).options
245
245
  assert_equal Mongo::Constants::OP_QUERY_NO_CURSOR_TIMEOUT,
246
246
  opts & Mongo::Constants::OP_QUERY_NO_CURSOR_TIMEOUT
247
247
  end
248
248
 
249
249
  def test_limit_exceptions
250
250
  cursor = @@coll.find()
251
- firstResult = cursor.next_document
251
+ cursor.next_document
252
252
  assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
253
253
  cursor.limit(1)
254
254
  end
@@ -278,7 +278,7 @@ class CursorTest < Test::Unit::TestCase
278
278
 
279
279
  def test_skip_exceptions
280
280
  cursor = @@coll.find()
281
- firstResult = cursor.next_document
281
+ cursor.next_document
282
282
  assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
283
283
  cursor.skip(1)
284
284
  end
@@ -263,7 +263,9 @@ class GridFileSystemTest < Test::Unit::TestCase
263
263
 
264
264
  should "seek only in read mode" do
265
265
  assert_raise GridError do
266
- @grid.open('hello', 'w') {|f| f.seek(0) }
266
+ silently do
267
+ @grid.open('hello', 'w') { |f| f.seek(0) }
268
+ end
267
269
  end
268
270
  end
269
271
  end
@@ -45,7 +45,7 @@ class GridIOTest < Test::Unit::TestCase
45
45
  should "read data character by character using" do
46
46
  bytes = 0
47
47
  file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
48
- while char = file.getc
48
+ while file.getc
49
49
  bytes += 1
50
50
  end
51
51
  assert_equal bytes, 1_000_000
@@ -111,7 +111,7 @@ class GridIOTest < Test::Unit::TestCase
111
111
 
112
112
  should "tell position, eof, and rewind" do
113
113
  file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
114
- string = file.read(1000)
114
+ file.read(1000)
115
115
  assert_equal 1000, file.pos
116
116
  assert !file.eof?
117
117
  file.read
@@ -2,7 +2,7 @@ require './test/test_helper'
2
2
  include Mongo
3
3
 
4
4
  def read_and_write_stream(filename, read_length, opts={})
5
- io = File.open(File.join(File.dirname(__FILE__), 'data', filename), 'r')
5
+ io = File.open(File.join(File.dirname(__FILE__), 'data', filename), 'r+b')
6
6
  id = @grid.put(io, opts.merge!(:filename => filename + read_length.to_s))
7
7
  file = @grid.get(id)
8
8
  io.rewind
@@ -142,7 +142,9 @@ class GridTest < Test::Unit::TestCase
142
142
  end
143
143
 
144
144
  should "ignore special keys" do
145
- id = @grid.put(@data, :file_length => 100, :phrase => "blimey")
145
+ id = silently do
146
+ @grid.put(@data, :file_length => 100, :phrase => "blimey")
147
+ end
146
148
  file = @grid.get(id)
147
149
 
148
150
  assert_equal "blimey", file['phrase']
@@ -153,8 +155,9 @@ class GridTest < Test::Unit::TestCase
153
155
  context "Storing data with a length of zero" do
154
156
  setup do
155
157
  @grid = Grid.new(@db, 'test-fs')
156
- @id = @grid.put('', :filename => 'sample',
157
- :metadata => {'app' => 'photos'})
158
+ @id = silently do
159
+ @grid.put('', :filename => 'sample', :metadata => {'app' => 'photos'})
160
+ end
158
161
  end
159
162
 
160
163
  should "return the zero length" do
@@ -201,7 +204,9 @@ class GridTest < Test::Unit::TestCase
201
204
  @grid = Grid.new(@db, 'test-fs')
202
205
  filename = 'empty_data'
203
206
  @io = File.open(File.join(File.dirname(__FILE__), 'data', filename), 'r')
204
- id = @grid.put(@io, :filename => filename)
207
+ id = silently do
208
+ @grid.put(@io, :filename => filename)
209
+ end
205
210
  @file = @grid.get(id)
206
211
  @io.rewind
207
212
  @data = @io.read
@@ -239,7 +244,9 @@ class GridTest < Test::Unit::TestCase
239
244
  end
240
245
 
241
246
  should "put and get an empty io object" do
242
- read_and_write_stream('empty_data', 1)
247
+ silently do
248
+ read_and_write_stream('empty_data', 1)
249
+ end
243
250
  end
244
251
 
245
252
  should "put and get a small io object" do