mongo 1.8.4 → 1.8.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +6 -14
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +2 -0
  5. data/VERSION +1 -1
  6. data/lib/mongo.rb +11 -9
  7. data/lib/mongo/collection.rb +26 -19
  8. data/lib/mongo/cursor.rb +7 -2
  9. data/lib/mongo/db.rb +1 -1
  10. data/lib/mongo/mongo_client.rb +1 -1
  11. data/lib/mongo/mongo_replica_set_client.rb +2 -3
  12. data/lib/mongo/mongo_sharded_client.rb +1 -2
  13. data/lib/mongo/util/node.rb +12 -14
  14. data/lib/mongo/util/pool.rb +1 -1
  15. data/lib/mongo/util/pool_manager.rb +13 -15
  16. data/lib/mongo/util/sharding_pool_manager.rb +5 -2
  17. data/lib/mongo/util/support.rb +14 -0
  18. data/mongo.gemspec +7 -3
  19. data/test/functional/authentication_test.rb +21 -0
  20. data/test/functional/collection_test.rb +0 -1
  21. data/test/functional/connection_test.rb +1 -1
  22. data/test/functional/db_test.rb +1 -56
  23. data/test/functional/support_test.rb +30 -0
  24. data/test/replica_set/authentication_test.rb +23 -0
  25. data/test/replica_set/max_values_test.rb +61 -0
  26. data/test/sharded_cluster/basic_test.rb +18 -0
  27. data/test/shared/authentication.rb +49 -0
  28. data/test/tools/mongo_config.rb +21 -26
  29. data/test/unit/node_test.rb +3 -0
  30. data/test/unit/pool_manager_test.rb +3 -1
  31. data/test/unit/read_test.rb +4 -0
  32. data/test/unit/sharding_pool_manager_test.rb +88 -0
  33. metadata +38 -69
  34. metadata.gz.sig +0 -0
  35. data/test/auxillary/1.4_feature_test.rb +0 -165
  36. data/test/auxillary/authentication_test.rb +0 -74
  37. data/test/auxillary/autoreconnect_test.rb +0 -39
  38. data/test/auxillary/fork_test.rb +0 -28
  39. data/test/auxillary/pool_reuse_test.rb +0 -65
  40. data/test/auxillary/repl_set_auth_test.rb +0 -69
  41. data/test/auxillary/slave_connection_test.rb +0 -37
  42. data/test/auxillary/threaded_authentication_test.rb +0 -99
  43. data/test/bson/binary_test.rb +0 -13
  44. data/test/bson/bson_test.rb +0 -762
  45. data/test/bson/byte_buffer_test.rb +0 -215
  46. data/test/bson/hash_with_indifferent_access_test.rb +0 -48
  47. data/test/bson/json_test.rb +0 -16
  48. data/test/bson/object_id_test.rb +0 -153
  49. data/test/bson/ordered_hash_test.rb +0 -247
  50. data/test/bson/timestamp_test.rb +0 -51
  51. data/test/tools/auth_repl_set_manager.rb +0 -14
@@ -1272,7 +1272,6 @@ end
1272
1272
  should "create a geoHaystack index" do
1273
1273
  @geo.save({ "_id" => 100, "pos" => { "long" => 126.9, "lat" => 35.2 }, "type" => "restaurant"})
1274
1274
  @geo.create_index([['pos', Mongo::GEOHAYSTACK], ['type', Mongo::ASCENDING]], :bucket_size => 1)
1275
- puts @geo.index_information['loc_geoHaystack_type_1']
1276
1275
  end
1277
1276
 
1278
1277
  should "create a geo 2dsphere index" do
@@ -309,7 +309,7 @@ class TestConnection < Test::Unit::TestCase
309
309
  conn.expects(:[]).with('admin').returns(admin_db)
310
310
 
311
311
  conn.connect
312
- assert_equal Mongo::DEFAULT_MAX_MESSAGE_SIZE, conn.max_message_size
312
+ assert_equal Mongo::DEFAULT_MAX_BSON_SIZE * Mongo::MESSAGE_SIZE_FACTOR, conn.max_message_size
313
313
  end
314
314
 
315
315
  def test_connection_activity
@@ -131,47 +131,6 @@ class DBTest < Test::Unit::TestCase
131
131
  end
132
132
  end
133
133
 
134
- def test_authenticate
135
- @@db.add_user('spongebob', 'squarepants')
136
- assert_raise Mongo::AuthenticationError do
137
- assert !@@db.authenticate('nobody', 'nopassword')
138
- end
139
- assert_raise Mongo::AuthenticationError do
140
- assert !@@db.authenticate('spongebob' , 'squareliederhosen')
141
- end
142
- assert @@db.authenticate('spongebob', 'squarepants')
143
- @@db.logout
144
- @@db.remove_user('spongebob')
145
- end
146
-
147
- def test_authenticate_with_special_characters
148
- assert @@db.add_user('foo:bar', '@foo')
149
- assert @@db.authenticate('foo:bar', '@foo')
150
- @@db.logout
151
- @@db.remove_user('foo:bar')
152
- end
153
-
154
- def test_authenticate_read_only
155
- @@db.add_user('joebob', 'user', true) # read-only user
156
- assert @@db.authenticate('joebob', 'user')
157
- @@db.logout
158
- @@db.remove_user('joebob')
159
- end
160
-
161
- def test_authenticate_with_connection_uri
162
- @@db.add_user('spongebob', 'squarepants')
163
- assert Mongo::MongoClient.from_uri("mongodb://spongebob:squarepants@#{host_port}/#{@@db.name}")
164
-
165
- assert_raise Mongo::AuthenticationError do
166
- client = Mongo::MongoClient.from_uri("mongodb://wrong:info@#{host_port}/#{@@db.name}")
167
- client['test']['foo'].find_one
168
- end
169
- end
170
-
171
- def test_logout
172
- assert @@db.logout
173
- end
174
-
175
134
  def test_command
176
135
  assert_raise OperationFailure do
177
136
  @@db.command({:non_command => 1}, :check_response => true)
@@ -249,25 +208,11 @@ class DBTest < Test::Unit::TestCase
249
208
  db.collection('users').remove
250
209
  end
251
210
 
252
- def test_user_management
253
- @@db.add_user("bob", "secret")
254
- assert @@db.authenticate("bob", "secret")
255
- @@db.logout
256
- assert @@db.remove_user("bob")
257
- assert_raise Mongo::AuthenticationError do
258
- @@db.authenticate("bob", "secret")
259
- end
260
- end
261
-
262
- def test_remove_non_existant_user
263
- assert !@@db.remove_user("joe")
264
- end
265
-
266
211
  def test_stored_function_management
267
212
  @@db.add_stored_function("sum", "function (x, y) { return x + y; }")
268
213
  assert_equal @@db.eval("return sum(2,3);"), 5
269
214
  assert @@db.remove_stored_function("sum")
270
- assert_raise OperationFailure do
215
+ assert_raise OperationFailure do
271
216
  @@db.eval("return sum(2,3);")
272
217
  end
273
218
  end
@@ -15,4 +15,34 @@ class SupportTest < Test::Unit::TestCase
15
15
  assert !Support.ok?('ok' => 'str')
16
16
  assert !Support.ok?('ok' => false)
17
17
  end
18
+
19
+ def test_array_of_pairs
20
+ hps = [["localhost", 27017], ["localhost", 27018], ["localhost", 27019]]
21
+ assert_equal [["localhost", 27017], ["localhost", 27018], ["localhost", 27019]], Support.normalize_seeds(hps)
22
+ end
23
+
24
+ def test_array_of_strings
25
+ hps = ["localhost:27017", "localhost:27018", "localhost:27019"]
26
+ assert_equal [["localhost", 27017], ["localhost", 27018], ["localhost", 27019]], Support.normalize_seeds(hps)
27
+ end
28
+
29
+ def test_single_string_with_host_port
30
+ hps = "localhost:27017"
31
+ assert_equal ["localhost", 27017], Support.normalize_seeds(hps)
32
+ end
33
+
34
+ def test_single_string_missing_port
35
+ hps = "localhost"
36
+ assert_equal ["localhost", 27017], Support.normalize_seeds(hps)
37
+ end
38
+
39
+ def test_single_element_array_missing_port
40
+ hps = ["localhost"]
41
+ assert_equal ["localhost", 27017], Support.normalize_seeds(hps)
42
+ end
43
+
44
+ def test_pair_doesnt_get_converted
45
+ hps = ["localhost", 27017]
46
+ assert_equal ["localhost", 27017], Support.normalize_seeds(hps)
47
+ end
18
48
  end
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+ require 'shared/authentication'
3
+
4
+ class ReplicaSetAuthenticationTest < Test::Unit::TestCase
5
+ include Mongo
6
+ include AuthenticationTests
7
+
8
+ def setup
9
+ ensure_cluster(:rs)
10
+ @client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :name => @rs.repl_set_name, :connect_timeout => 60)
11
+ @db = @client[MONGO_TEST_DB]
12
+ end
13
+
14
+ def teardown
15
+ @db['system.users'].remove
16
+ end
17
+
18
+ def test_authenticate_with_connection_uri
19
+ @db.add_user('eunice', 'uritest')
20
+ assert MongoReplicaSetClient.from_uri(
21
+ "mongodb://eunice:uritest@#{@rs.repl_set_seeds.join(',')}/#{@db.name}?replicaSet=#{@rs.repl_set_name}")
22
+ end
23
+ end
@@ -0,0 +1,61 @@
1
+ require 'test_helper'
2
+
3
+ class MaxValuesTest < Test::Unit::TestCase
4
+
5
+ include Mongo
6
+
7
+ def setup
8
+ ensure_cluster(:rs)
9
+ @client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :name => @rs.repl_set_name)
10
+ end
11
+
12
+ def test_initial_max_sizes
13
+ assert @client.max_message_size
14
+ assert @client.max_bson_size
15
+ end
16
+
17
+ def test_updated_max_sizes_after_node_config_change
18
+ # stub max sizes for one member
19
+ @client.local_manager.members.each_with_index do |m, i|
20
+ if i % 2 == 0
21
+ m.stubs(:config).returns({'maxMessageSizeBytes' => 1024 * MESSAGE_SIZE_FACTOR, 'maxBsonObjectSize' => 1024})
22
+ m.set_config
23
+ end
24
+ end
25
+
26
+ assert_equal 1024, @client.max_bson_size
27
+ assert_equal 1024 * MESSAGE_SIZE_FACTOR, @client.max_message_size
28
+ end
29
+
30
+ def test_neither_max_sizes_in_config
31
+ @client.local_manager.members.each do |m|
32
+ m.stubs(:config).returns({})
33
+ m.set_config
34
+ end
35
+
36
+ assert_equal DEFAULT_MAX_BSON_SIZE, @client.max_bson_size
37
+ assert_equal DEFAULT_MAX_BSON_SIZE * MESSAGE_SIZE_FACTOR, @client.max_message_size
38
+ end
39
+
40
+ def test_only_bson_size_in_config
41
+ @client.local_manager.members.each do |m|
42
+ m.stubs(:config).returns({'maxBsonObjectSize' => 1024})
43
+ m.set_config
44
+ end
45
+ assert_equal 1024, @client.max_bson_size
46
+ assert_equal 1024 * MESSAGE_SIZE_FACTOR, @client.max_message_size
47
+ end
48
+
49
+ def test_both_sizes_in_config
50
+ @client.local_manager.members.each do |m|
51
+ m.stubs(:config).returns({'maxMessageSizeBytes' => 1024 * 2 * MESSAGE_SIZE_FACTOR,
52
+ 'maxBsonObjectSize' => 1024})
53
+ m.set_config
54
+ end
55
+
56
+ assert_equal 1024, @client.max_bson_size
57
+ assert_equal 1024 * 2 * MESSAGE_SIZE_FACTOR, @client.max_message_size
58
+ end
59
+
60
+ end
61
+
@@ -89,6 +89,24 @@ class BasicTest < Test::Unit::TestCase
89
89
  @client.close
90
90
  end
91
91
 
92
+ def test_mongos_failover
93
+ @client = MongoShardedClient.new(@seeds, :refresh_interval => 5, :refresh_mode => :sync)
94
+ assert @client.connected?
95
+ # do a find to pin a pool
96
+ @client['MONGO_TEST_DB']['test'].find_one
97
+ original_primary = @client.manager.primary
98
+ # stop the pinned member
99
+ @sc.member_by_name("#{original_primary[0]}:#{original_primary[1]}").stop
100
+ # assert that the client fails over to the next available mongos
101
+ assert_nothing_raised do
102
+ @client['MONGO_TEST_DB']['test'].find_one
103
+ end
104
+
105
+ assert_not_equal original_primary, @client.manager.primary
106
+ assert @client.connected?
107
+ @client.close
108
+ end
109
+
92
110
  def test_all_down
93
111
  @client = MongoShardedClient.new(@seeds)
94
112
  assert @client.connected?
@@ -0,0 +1,49 @@
1
+ module AuthenticationTests
2
+ def test_add_user
3
+ @db.add_user('bob','user')
4
+ assert @db['system.users'].find_one({:user => 'bob'})
5
+ end
6
+
7
+ def test_remove_user
8
+ @db.remove_user('bob')
9
+ assert_nil @db['system.users'].find_one({:user => 'bob'})
10
+ end
11
+
12
+ def test_remove_non_existent_user
13
+ assert_equal @db.remove_user('joe'), false
14
+ end
15
+
16
+ def test_authenticate
17
+ @db.add_user('peggy', 'user')
18
+ assert @db.authenticate('peggy', 'user')
19
+ @db.remove_user('peggy')
20
+ @db.logout
21
+ end
22
+
23
+ def test_authenticate_non_existent_user
24
+ assert_raise Mongo::AuthenticationError do
25
+ @db.authenticate('frank', 'thetank')
26
+ end
27
+ end
28
+
29
+ def test_logout
30
+ @db.add_user('peggy', 'user')
31
+ assert @db.authenticate('peggy', 'user')
32
+ assert @db.logout
33
+ @db.remove_user('peggy')
34
+ end
35
+
36
+ def test_authenticate_with_special_characters
37
+ assert @db.add_user('foo:bar','@foo')
38
+ assert @db.authenticate('foo:bar','@foo')
39
+ @db.remove_user('foo:bar')
40
+ @db.logout
41
+ end
42
+
43
+ def test_authenticate_read_only
44
+ @db.add_user('randy', 'readonly', true)
45
+ assert @db.authenticate('randy', 'readonly')
46
+ @db.remove_user('randy')
47
+ @db.logout
48
+ end
49
+ end
@@ -24,7 +24,7 @@ end
24
24
  #
25
25
  module Mongo
26
26
  class Config
27
- DEFAULT_BASE_OPTS = { :host => 'localhost', :dbpath => 'data', :logpath => 'data/log'}
27
+ DEFAULT_BASE_OPTS = { :host => 'localhost', :dbpath => 'data', :logpath => 'data/log' }
28
28
  DEFAULT_REPLICA_SET = DEFAULT_BASE_OPTS.merge( :replicas => 3, :arbiters => 0 )
29
29
  DEFAULT_SHARDED_SIMPLE = DEFAULT_BASE_OPTS.merge( :shards => 2, :configs => 1, :routers => 4 )
30
30
  DEFAULT_SHARDED_REPLICA = DEFAULT_SHARDED_SIMPLE.merge( :replicas => 3, :arbiters => 0)
@@ -80,51 +80,46 @@ module Mongo
80
80
  end
81
81
 
82
82
  def self.make_mongo(kind, opts)
83
- dbpath = opts[:dbpath]
84
- port = self.get_available_port
85
- path = "#{dbpath}/#{kind}-#{port}"
83
+ dbpath = opts[:dbpath]
84
+ port = self.get_available_port
85
+ path = "#{dbpath}/#{kind}-#{port}"
86
86
  logpath = "#{path}/#{kind}.log"
87
87
 
88
- {
89
- :host => opts[:host],
90
- :port => port,
91
- :logpath => logpath,
92
- :logappend => true
93
- }
88
+ { :host => opts[:host],
89
+ :port => port,
90
+ :logpath => logpath,
91
+ :logappend => true }
94
92
  end
95
93
 
96
94
  def self.make_mongod(kind, opts)
97
95
  params = make_mongo('mongods', opts)
98
96
 
99
97
  mongod = ENV['MONGOD'] || 'mongod'
100
- path = File.dirname(params[:logpath])
98
+ path = File.dirname(params[:logpath])
101
99
 
102
100
  noprealloc = opts[:noprealloc] || true
103
101
  smallfiles = opts[:smallfiles] || true
104
102
  quiet = opts[:quiet] || true
105
103
  fast_sync = opts[:fastsync] || false
106
-
107
- params.merge(
108
- :command => mongod,
109
- :dbpath => path,
110
- :smallfiles => smallfiles,
111
- :noprealloc => noprealloc,
112
- :quiet => quiet,
113
- :fastsync => fast_sync
114
- )
104
+ auth = opts[:auth] || true
105
+
106
+ params.merge(:command => mongod,
107
+ :dbpath => path,
108
+ :smallfiles => smallfiles,
109
+ :noprealloc => noprealloc,
110
+ :quiet => quiet,
111
+ :fastsync => fast_sync)
115
112
  end
116
113
 
117
114
  def self.make_replica(opts, count)
118
- params = make_mongod('replicas', opts)
115
+ params = make_mongod('replicas', opts)
119
116
 
120
117
  replSet = opts[:replSet] || 'ruby-driver-test'
121
118
  oplog_size = opts[:oplog_size] || 5
122
119
 
123
- params.merge(
124
- :_id => count,
125
- :replSet => replSet,
126
- :oplogSize => oplog_size
127
- )
120
+ params.merge(:_id => count,
121
+ :replSet => replSet,
122
+ :oplogSize => oplog_size)
128
123
  end
129
124
 
130
125
  def self.make_config(opts)
@@ -4,6 +4,9 @@ class NodeTest < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
6
  @client = stub()
7
+ manager = mock('pool_manager')
8
+ manager.stubs(:update_max_sizes)
9
+ @client.stubs(:local_manager).returns(manager)
7
10
  end
8
11
 
9
12
  should "refuse to connect to node without 'hosts' key" do
@@ -52,6 +52,7 @@ class PoolManagerTest < Test::Unit::TestCase
52
52
 
53
53
  seeds = [['localhost', 27017]]
54
54
  manager = Mongo::PoolManager.new(@client, seeds)
55
+ @client.stubs(:local_manager).returns(manager)
55
56
  manager.connect
56
57
 
57
58
  assert_equal ['localhost', 27017], manager.primary
@@ -77,7 +78,8 @@ class PoolManagerTest < Test::Unit::TestCase
77
78
  )
78
79
 
79
80
  seeds = [['localhost', 27017]]
80
- manager = Mongo::PoolManager.new(@client, seeds)
81
+ manager = PoolManager.new(@client, seeds)
82
+ @client.stubs(:local_manager).returns(manager)
81
83
  manager.connect
82
84
 
83
85
  assert_equal ['localhost', 27018], manager.primary
@@ -106,6 +106,8 @@ class ReadTest < Test::Unit::TestCase
106
106
  sock = new_mock_socket
107
107
  read_pool = stub(:checkin => true)
108
108
  @client.stubs(:read_pool).returns(read_pool)
109
+ local_manager = PoolManager.new(@client, @client.seeds)
110
+ @client.stubs(:local_manager).returns(local_manager)
109
111
  primary_pool = stub(:checkin => true)
110
112
  sock.stubs(:pool).returns(primary_pool)
111
113
  @client.stubs(:primary_pool).returns(primary_pool)
@@ -120,6 +122,8 @@ class ReadTest < Test::Unit::TestCase
120
122
  should "allow override default value on query" do
121
123
  @cursor = @col.find({:a => 1}, :read => :primary)
122
124
  sock = new_mock_socket
125
+ local_manager = PoolManager.new(@client, @client.seeds)
126
+ @client.stubs(:local_manager).returns(local_manager)
123
127
  primary_pool = stub(:checkin => true)
124
128
  sock.stubs(:pool).returns(primary_pool)
125
129
  @client.stubs(:primary_pool).returns(primary_pool)
@@ -0,0 +1,88 @@
1
+ require 'test_helper'
2
+ include Mongo
3
+
4
+ class ShardingPoolManagerTest < Test::Unit::TestCase
5
+
6
+ context "Initialization: " do
7
+
8
+ setup do
9
+ TCPSocket.stubs(:new).returns(new_mock_socket)
10
+ @db = new_mock_db
11
+
12
+ @client = stub("MongoShardedClient")
13
+ @client.stubs(:connect_timeout).returns(5)
14
+ @client.stubs(:op_timeout).returns(5)
15
+ @client.stubs(:pool_size).returns(2)
16
+ @client.stubs(:pool_timeout).returns(100)
17
+ @client.stubs(:socket_class).returns(TCPSocket)
18
+ @client.stubs(:mongos?).returns(true)
19
+ @client.stubs(:[]).returns(@db)
20
+
21
+ @client.stubs(:replica_set_name).returns(nil)
22
+ @client.stubs(:log)
23
+ @arbiters = ['localhost:27020']
24
+ @hosts = [
25
+ 'localhost:27017',
26
+ 'localhost:27018',
27
+ 'localhost:27019'
28
+ ]
29
+
30
+ @ismaster = {
31
+ 'hosts' => @hosts,
32
+ 'arbiters' => @arbiters,
33
+ 'maxMessageSizeBytes' => 1024 * 2.5,
34
+ 'maxBsonObjectSize' => 1024
35
+ }
36
+ end
37
+
38
+ should "populate pools correctly" do
39
+
40
+ @db.stubs(:command).returns(
41
+ # First call to get a socket.
42
+ @ismaster.merge({'ismaster' => true}),
43
+
44
+ # Subsequent calls to configure pools.
45
+ @ismaster.merge({'ismaster' => true}),
46
+ @ismaster.merge({'secondary' => true, 'maxMessageSizeBytes' => 700}),
47
+ @ismaster.merge({'secondary' => true, 'maxBsonObjectSize' => 500}),
48
+ @ismaster.merge({'arbiterOnly' => true})
49
+ )
50
+
51
+ seed = ['localhost:27017']
52
+ manager = Mongo::ShardingPoolManager.new(@client, seed)
53
+ @client.stubs(:local_manager).returns(manager)
54
+ manager.connect
55
+
56
+ formatted_seed = ['localhost', 27017]
57
+
58
+ assert manager.seeds.include? formatted_seed
59
+ assert_equal 500, manager.max_bson_size
60
+ assert_equal 700 , manager.max_message_size
61
+ end
62
+
63
+ should "maintain seed format when checking connection health" do
64
+
65
+ @db.stubs(:command).returns(
66
+ # First call to get a socket.
67
+ @ismaster.merge({'ismaster' => true}),
68
+
69
+ # Subsequent calls to configure pools.
70
+ @ismaster.merge({'ismaster' => true}),
71
+ @ismaster.merge({'secondary' => true, 'maxMessageSizeBytes' => 700}),
72
+ @ismaster.merge({'secondary' => true, 'maxBsonObjectSize' => 500}),
73
+ @ismaster.merge({'arbiterOnly' => true})
74
+ )
75
+
76
+ config_db = new_mock_db
77
+ mongos_coll = mock('collection')
78
+ mongos_coll.stubs(:find).returns(@hosts.map{|h| {'_id' => h}})
79
+ config_db.stubs(:[]).with('mongos').returns(mongos_coll)
80
+ @client.stubs(:[]).with('config').returns(config_db)
81
+
82
+ manager = Mongo::ShardingPoolManager.new(@client, @hosts)
83
+ manager.check_connection_health
84
+
85
+ assert manager.seeds.all? {|s| s.is_a?(Array) && s[0].is_a?(String) && s[1].is_a?(Integer)}
86
+ end
87
+ end
88
+ end