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
@@ -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