mongo 1.6.1 → 1.6.2

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 (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
@@ -12,12 +12,10 @@ class PoolTest < Test::Unit::TestCase
12
12
  @pool = Pool.new(@connection, TEST_HOST, TEST_PORT, :size => 5)
13
13
 
14
14
  @threads = []
15
- @sockets = []
16
15
 
17
16
  10.times do
18
17
  @threads << Thread.new do
19
18
  original_socket = @pool.checkout
20
- @sockets << original_socket
21
19
  @pool.checkin(original_socket)
22
20
  5000.times do
23
21
  socket = @pool.checkout
@@ -43,7 +43,7 @@ class BasicTest < Test::Unit::TestCase
43
43
  assert_equal @conn.port, @rs.primary[1]
44
44
  assert_equal @conn.host, @conn.primary_pool.host
45
45
  assert_equal @conn.port, @conn.primary_pool.port
46
- assert_equal @conn.nodes.sort, @conn.seeds.sort
46
+ #assert_equal @conn.nodes.sort, @conn.seeds.sort
47
47
  assert_equal 2, @conn.secondaries.length
48
48
  assert_equal 0, @conn.arbiters.length
49
49
  assert_equal 2, @conn.secondary_pools.length
@@ -1,5 +1,4 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- require 'logger'
3
2
  require './test/replica_sets/rs_test_helper'
4
3
 
5
4
  class ComplexConnectTest < Test::Unit::TestCase
@@ -14,11 +13,13 @@ class ComplexConnectTest < Test::Unit::TestCase
14
13
  end
15
14
 
16
15
  def test_complex_connect
17
- logger = Logger.new(STDOUT)
18
16
  primary = Connection.new(@rs.host, @rs.ports[0])
19
17
 
20
- @conn = ReplSetConnection.new([@rs.host, @rs.ports[2]], [@rs.host, @rs.ports[1]],
21
- [@rs.host, @rs.ports[0]], :logger => logger)
18
+ @conn = ReplSetConnection.new([
19
+ "#{@rs.host}:#{@rs.ports[2]}",
20
+ "#{@rs.host}:#{@rs.ports[1]}",
21
+ "#{@rs.host}:#{@rs.ports[0]}",
22
+ ])
22
23
 
23
24
  @conn['test']['foo'].insert({:a => 1})
24
25
  assert @conn['test']['foo'].find_one
@@ -14,7 +14,9 @@ class ConnectTest < Test::Unit::TestCase
14
14
  # TODO: test connect timeout.
15
15
 
16
16
  def test_connect_with_deprecated_multi
17
- @conn = Connection.multi([[@rs.host, @rs.ports[0]], [@rs.host, @rs.ports[1]]], :name => @rs.name)
17
+ silently do
18
+ @conn = Connection.multi([[@rs.host, @rs.ports[0]], [@rs.host, @rs.ports[1]]], :name => @rs.name)
19
+ end
18
20
  assert @conn.is_a?(ReplSetConnection)
19
21
  assert @conn.connected?
20
22
  end
@@ -26,7 +28,7 @@ class ConnectTest < Test::Unit::TestCase
26
28
  end
27
29
 
28
30
  def test_connect_with_primary_node_killed
29
- node = @rs.kill_primary
31
+ @rs.kill_primary
30
32
 
31
33
  # Becuase we're killing the primary and trying to connect right away,
32
34
  # this is going to fail right away.
@@ -41,7 +43,7 @@ class ConnectTest < Test::Unit::TestCase
41
43
  end
42
44
 
43
45
  def test_connect_with_secondary_node_killed
44
- node = @rs.kill_secondary
46
+ @rs.kill_secondary
45
47
 
46
48
  rescue_connection_failure do
47
49
  @conn = ReplSetConnection.new build_seeds(3)
@@ -97,7 +99,9 @@ class ConnectTest < Test::Unit::TestCase
97
99
  end
98
100
 
99
101
  def test_connect_with_connection_string
100
- @conn = Connection.from_uri("mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name}")
102
+ silently do
103
+ @conn = Connection.from_uri("mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name}")
104
+ end
101
105
  assert @conn.is_a?(ReplSetConnection)
102
106
  assert @conn.connected?
103
107
  end
@@ -108,12 +112,16 @@ class ConnectTest < Test::Unit::TestCase
108
112
  end
109
113
 
110
114
  def test_connect_with_old_seed_format
111
- @conn = ReplSetConnection.new([@rs.host, @rs.ports[0]], [@rs.host, @rs.ports[1]], [@rs.host, @rs.ports[2]])
115
+ silently do
116
+ @conn = ReplSetConnection.new([@rs.host, @rs.ports[0]], [@rs.host, @rs.ports[1]], [@rs.host, @rs.ports[2]])
117
+ end
112
118
  assert @conn.connected?
113
119
  end
114
120
 
115
121
  def test_connect_with_full_connection_string
116
- @conn = Connection.from_uri("mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name};safe=true;w=2;fsync=true;slaveok=true")
122
+ silently do
123
+ @conn = Connection.from_uri("mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name};safe=true;w=2;fsync=true;slaveok=true")
124
+ end
117
125
  assert @conn.is_a?(ReplSetConnection)
118
126
  assert @conn.connected?
119
127
  assert_equal 2, @conn.safe[:w]
@@ -7,7 +7,7 @@ class ReplicaSetPooledInsertTest < Test::Unit::TestCase
7
7
 
8
8
  def setup
9
9
  ensure_rs
10
- @conn = ReplSetConnection.new(build_seeds(3), :pool_size => 10, :timeout => 5, :refresh_mode => false)
10
+ @conn = ReplSetConnection.new(build_seeds(3), :pool_size => 10, :pool_timeout => 5, :refresh_mode => false)
11
11
  @db = @conn.db(MONGO_TEST_DB)
12
12
  @db.drop_collection("test-sets")
13
13
  @coll = @db.collection("test-sets")
@@ -26,7 +26,7 @@ class ReplicaSetQueryTest < Test::Unit::TestCase
26
26
  assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
27
27
  end
28
28
 
29
- puts "Benchmark before failover: #{benchmark_queries}"
29
+ #puts "Benchmark before failover: #{benchmark_queries}"
30
30
 
31
31
  @rs.kill_primary
32
32
 
@@ -37,7 +37,7 @@ class ReplicaSetQueryTest < Test::Unit::TestCase
37
37
  assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
38
38
  end
39
39
 
40
- puts "Benchmark after failover: #{benchmark_queries}"
40
+ #puts "Benchmark after failover: #{benchmark_queries}"
41
41
  end
42
42
  end
43
43
 
@@ -87,7 +87,7 @@ class ReadPreferenceTest < Test::Unit::TestCase
87
87
 
88
88
  results = []
89
89
  rescue_connection_failure do
90
- puts "@coll.find().each"
90
+ #puts "@coll.find().each"
91
91
  @coll.find.each {|r| results << r}
92
92
  [20, 30, 40].each do |a|
93
93
  assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
@@ -105,7 +105,6 @@ class ReadPreferenceTest < Test::Unit::TestCase
105
105
  @rs.kill_primary
106
106
  assert_equal 2, @coll.find.to_a.length
107
107
  rescue_connection_failure do
108
- puts "@coll.save()"
109
108
  @coll.save({:a => 50}, :safe => {:w => 2, :wtimeout => 10000})
110
109
  end
111
110
  @rs.restart_killed_nodes
@@ -10,9 +10,10 @@ class ReplicaSetRefreshTest < Test::Unit::TestCase
10
10
 
11
11
  def teardown
12
12
  @rs.restart_killed_nodes
13
- @conn.close if @conn
13
+ @conn.close if defined?(@conn)
14
14
  end
15
15
 
16
+ =begin
16
17
  def test_connect_speed
17
18
  Benchmark.bm do |x|
18
19
  x.report("Connect") do
@@ -31,6 +32,7 @@ class ReplicaSetRefreshTest < Test::Unit::TestCase
31
32
  end
32
33
  end
33
34
  end
35
+ =end
34
36
 
35
37
  def test_connect_and_manual_refresh_with_secondaries_down
36
38
  @rs.kill_all_secondaries
@@ -95,7 +97,7 @@ class ReplicaSetRefreshTest < Test::Unit::TestCase
95
97
  num_secondaries = @conn.secondary_pools.length
96
98
  old_refresh_version = @conn.refresh_version
97
99
 
98
- n = @rs.kill_secondary
100
+ @rs.kill_secondary
99
101
  sleep(4)
100
102
  @conn['foo']['bar'].find_one
101
103
 
@@ -10,11 +10,13 @@ class ReplicaSetRefreshWithThreadsTest < Test::Unit::TestCase
10
10
  end
11
11
 
12
12
  def teardown
13
- @rs.restart_killed_nodes
14
13
  @conn.close if @conn
15
14
  end
16
15
 
17
16
  def test_read_write_load_with_added_nodes
17
+ # MongoDB < 2.0 will disconnect clients on rs.reconfig()
18
+ return true if @rs.version.first < 2
19
+
18
20
  seeds = build_seeds(3)
19
21
  args = {
20
22
  :refresh_interval => 5,
@@ -45,18 +47,10 @@ class ReplicaSetRefreshWithThreadsTest < Test::Unit::TestCase
45
47
  end
46
48
  end
47
49
 
48
- # MongoDB < 2.0 will disconnect clients on rs.reconfig()
49
- if @rs.version.first < 2
50
- assert_raise Mongo::ConnectionFailure do
51
- @rs.add_node
52
- threads.each {|t| t.join }
53
- end
54
- else
55
- @rs.add_node
56
- threads.each {|t| t.join }
57
- end
58
-
59
- config = @conn['admin'].command({:ismaster => 1})
50
+ @rs.add_node
51
+ threads.each {|t| t.join }
52
+
53
+ @conn['admin'].command({:ismaster => 1})
60
54
 
61
55
  assert_equal 3, @conn.secondary_pools.length
62
56
  assert_equal 3, @conn.secondaries.length
@@ -21,7 +21,7 @@ class Test::Unit::TestCase
21
21
  begin
22
22
  yield
23
23
  rescue Mongo::ConnectionFailure => ex
24
- puts "Rescue attempt #{retries}: from #{ex}"
24
+ #puts "Rescue attempt #{retries}: from #{ex}"
25
25
  retries += 1
26
26
  raise ex if retries > max_retries
27
27
  sleep(2)
@@ -7,8 +7,11 @@ require 'test/unit'
7
7
  def silently
8
8
  warn_level = $VERBOSE
9
9
  $VERBOSE = nil
10
- result = yield
11
- $VERBOSE = warn_level
10
+ begin
11
+ result = yield
12
+ ensure
13
+ $VERBOSE = warn_level
14
+ end
12
15
  result
13
16
  end
14
17
 
@@ -25,7 +28,6 @@ You can install them as follows:
25
28
  gem install mocha
26
29
 
27
30
  MSG
28
-
29
31
  exit
30
32
  end
31
33
 
@@ -88,7 +90,7 @@ class Test::Unit::TestCase
88
90
  end
89
91
 
90
92
  def new_mock_db
91
- db = Object.new
93
+ Object.new
92
94
  end
93
95
 
94
96
  def assert_raise_error(klass, message)
@@ -6,7 +6,7 @@ class TestThreadingLargePool < Test::Unit::TestCase
6
6
 
7
7
  include Mongo
8
8
 
9
- @@db = standard_connection(:pool_size => 50, :timeout => 60).db(MONGO_TEST_DB)
9
+ @@db = standard_connection(:pool_size => 50, :pool_timeout => 60).db(MONGO_TEST_DB)
10
10
  @@coll = @@db.collection('thread-test-collection')
11
11
 
12
12
  def set_up_safe_data
@@ -4,7 +4,7 @@ class TestThreading < Test::Unit::TestCase
4
4
 
5
5
  include Mongo
6
6
 
7
- @@con = standard_connection(:pool_size => 10, :timeout => 30)
7
+ @@con = standard_connection(:pool_size => 10, :pool_timeout => 30)
8
8
  @@db = @@con[MONGO_TEST_DB]
9
9
  @@coll = @@db.collection('thread-test-collection')
10
10
 
@@ -73,7 +73,7 @@ class TestThreading < Test::Unit::TestCase
73
73
  @@coll = @@db.collection('thread-test-collection')
74
74
 
75
75
  1000.times do |i|
76
- @@coll.insert("x" => i)
76
+ @@coll.insert("x" => i, :safe => true)
77
77
  end
78
78
 
79
79
  threads = []
@@ -0,0 +1,40 @@
1
+ require './test/test_helper'
2
+
3
+ class TestTimeout < Test::Unit::TestCase
4
+ def test_op_timeout
5
+ connection = standard_connection(:op_timeout => 2)
6
+
7
+ admin = connection.db('admin')
8
+
9
+ command = BSON::OrderedHash.new
10
+ command[:sleep] = 1
11
+ command[:secs] = 1
12
+ # Should not timeout
13
+ assert admin.command(command)
14
+
15
+ # Should timeout
16
+ command[:secs] = 3
17
+ assert_raise Mongo::OperationTimeout do
18
+ admin.command(command)
19
+ end
20
+
21
+ end
22
+ =begin
23
+ def test_ssl_op_timeout
24
+ connection = standard_connection(:op_timeout => 1, :ssl => true)
25
+
26
+ coll = connection.db(MONGO_TEST_DB).collection("test")
27
+ coll.insert({:a => 1})
28
+
29
+ # Should not timeout
30
+ assert coll.find_one({"$where" => "sleep(100); return true;"})
31
+
32
+ # Should timeout
33
+ assert_raise Mongo::OperationTimeout do
34
+ coll.find_one({"$where" => "sleep(5 * 1000); return true;"})
35
+ end
36
+
37
+ coll.remove
38
+ end
39
+ =end
40
+ end
@@ -46,10 +46,10 @@ class ReplSetManager
46
46
  end
47
47
 
48
48
  def start_set
49
- system("killall mongod")
49
+ system("killall mongod > /dev/null 2> /dev/null")
50
50
  sleep(1)
51
51
  should_start = true
52
- puts "** Starting a replica set with #{@count} nodes"
52
+ #puts "** Starting a replica set with #{@count} nodes"
53
53
 
54
54
  n = 0
55
55
  (@primary_count + @secondary_count).times do
@@ -131,6 +131,7 @@ class ReplSetManager
131
131
  @mongods[n]['start'] += " --dur" if @durable
132
132
  @mongods[n]['start'] += " --smallfiles" if @smallfiles
133
133
  @mongods[n]['start'] += " --noprealloc" unless @prealloc
134
+ @mongods[n]['start'] += "> /dev/null 2>/dev/null"
134
135
  @mongods[n]['start']
135
136
  end
136
137
 
@@ -185,7 +186,7 @@ class ReplSetManager
185
186
  puts "waiting for mongod @ pid #{pid} to die..."
186
187
  sleep(1)
187
188
  else
188
- puts "mongod @ pid #{pid} was killed successfully"
189
+ #puts "mongod @ pid #{pid} was killed successfully"
189
190
  return true
190
191
  end
191
192
  end
@@ -195,7 +196,7 @@ class ReplSetManager
195
196
 
196
197
  def kill(node, signal=2)
197
198
  pid = @mongods[node]['pid']
198
- puts "** Killing node with pid #{pid} at port #{@mongods[node]['port']}"
199
+ #puts "** Killing node with pid #{pid} at port #{@mongods[node]['port']}"
199
200
  system("kill #{pid}")
200
201
  dead = wait_for_death(pid)
201
202
  @mongods[node]['up'] = false if dead
@@ -260,10 +261,10 @@ class ReplSetManager
260
261
  alias :restart :start
261
262
 
262
263
  def ensure_up(n=nil, connection=nil)
263
- print "** Ensuring members are up..."
264
+ #print "** Ensuring members are up..."
264
265
 
265
266
  attempt(n) do
266
- print "."
267
+ #print "."
267
268
  con = connection || get_connection
268
269
  begin
269
270
  status = con['admin'].command({:replSetGetStatus => 1})
@@ -293,7 +294,7 @@ class ReplSetManager
293
294
  end
294
295
 
295
296
  if states.any? {|s| s['ismaster']}
296
- print "all members up!\n\n"
297
+ #puts "all members up!"
297
298
  connections.each {|c| c.close }
298
299
  con.close
299
300
  return status
@@ -335,7 +336,7 @@ class ReplSetManager
335
336
  private
336
337
 
337
338
  def initiate
338
- puts "Initiating replica set..."
339
+ #puts "Initiating replica set..."
339
340
  con = get_connection
340
341
 
341
342
  attempt do
@@ -41,6 +41,12 @@ class ConnectionTest < Test::Unit::TestCase
41
41
  end
42
42
 
43
43
  context "given a replica set" do
44
+ #should "enforce a minimum refresh_interval" do
45
+ # @conn = ReplSetConnection.new(['localhost:27017'],
46
+ # :connect => false, :refresh_mode => :sync, :refresh_interval => 10)
47
+ # assert_equal 60, @conn.refresh_interval
48
+ #end
49
+
44
50
  should "warn if invalid options are specified" do
45
51
  conn = ReplSetConnection.allocate
46
52
  opts = {:connect => false}
@@ -81,13 +87,6 @@ class ConnectionTest < Test::Unit::TestCase
81
87
  assert_equal({:w => 2, :wtimeout => 1000, :fsync => true, :j => true}, @conn.safe)
82
88
  end
83
89
 
84
- should "have wtimeoutMS take precidence over the depricated wtimeout" do
85
- host_name = "localhost"
86
- opts = "safe=true&wtimeout=100&wtimeoutMS=500"
87
- @conn = Connection.from_uri("mongodb://#{host_name}/foo?#{opts}", :connect => false)
88
- assert_equal({:wtimeout => 500}, @conn.safe)
89
- end
90
-
91
90
  should "set timeout options on connection" do
92
91
  host_name = "localhost"
93
92
  opts = "connectTimeoutMS=1000&socketTimeoutMS=5000"
@@ -15,6 +15,7 @@ class NodeTest < Test::Unit::TestCase
15
15
  admin_db = new_mock_db
16
16
  admin_db.stubs(:command).returns({'ok' => 1, 'ismaster' => 1})
17
17
  @connection.stubs(:[]).with('admin').returns(admin_db)
18
+ @connection.stubs(:op_timeout).returns(nil)
18
19
  @connection.stubs(:connect_timeout).returns(nil)
19
20
  @connection.expects(:log)
20
21
 
@@ -10,7 +10,8 @@ class PoolManagerTest < Test::Unit::TestCase
10
10
  @db = new_mock_db
11
11
 
12
12
  @connection = stub("Connection")
13
- @connection.stubs(:connect_timeout).returns(5000)
13
+ @connection.stubs(:connect_timeout).returns(5)
14
+ @connection.stubs(:op_timeout).returns(5)
14
15
  @connection.stubs(:pool_size).returns(2)
15
16
  @connection.stubs(:pool_timeout).returns(100)
16
17
  @connection.stubs(:seeds).returns(['localhost:30000'])
@@ -78,10 +78,9 @@ class URITest < Test::Unit::TestCase
78
78
  end
79
79
 
80
80
  def test_opts_safe
81
- parser = Mongo::URIParser.new('mongodb://localhost:27018?safe=true;w=2;journal=true;wtimeout=200;fsync=true;wtimeoutMS=200')
81
+ parser = Mongo::URIParser.new('mongodb://localhost:27018?safe=true;w=2;journal=true;fsync=true;wtimeoutMS=200')
82
82
  assert parser.safe
83
83
  assert_equal 2, parser.w
84
- assert_equal 200, parser.wtimeout
85
84
  assert parser.fsync
86
85
  assert parser.journal
87
86
  assert_equal 200, parser.wtimeoutms