jmongo 1.0.3 → 1.1.0

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 (96) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +43 -0
  3. data/Rakefile +72 -0
  4. data/jmongo.gemspec +84 -6
  5. data/lib/jmongo.rb +6 -14
  6. data/lib/jmongo/collection.rb +196 -114
  7. data/lib/jmongo/connection.rb +39 -13
  8. data/lib/jmongo/cursor.rb +161 -63
  9. data/lib/jmongo/db.rb +119 -30
  10. data/lib/jmongo/exceptions.rb +39 -0
  11. data/lib/jmongo/mongo-2.6.5.gb1.jar +0 -0
  12. data/lib/jmongo/mongo/bson.rb +130 -0
  13. data/lib/jmongo/mongo/collection.rb +185 -0
  14. data/lib/jmongo/mongo/connection.rb +45 -0
  15. data/lib/jmongo/mongo/db.rb +31 -0
  16. data/lib/jmongo/mongo/jmongo.rb +44 -0
  17. data/lib/jmongo/mongo/mongo.rb +98 -0
  18. data/lib/jmongo/mongo/ruby_ext.rb +38 -0
  19. data/lib/jmongo/mongo/utils.rb +136 -0
  20. data/lib/jmongo/version.rb +1 -1
  21. data/test-results.txt +98 -0
  22. data/test/auxillary/1.4_features.rb +166 -0
  23. data/test/auxillary/authentication_test.rb +68 -0
  24. data/test/auxillary/autoreconnect_test.rb +41 -0
  25. data/test/auxillary/fork_test.rb +30 -0
  26. data/test/auxillary/repl_set_auth_test.rb +58 -0
  27. data/test/auxillary/slave_connection_test.rb +36 -0
  28. data/test/auxillary/threaded_authentication_test.rb +101 -0
  29. data/test/bson/binary_test.rb +15 -0
  30. data/test/bson/bson_test.rb +657 -0
  31. data/test/bson/byte_buffer_test.rb +208 -0
  32. data/test/bson/hash_with_indifferent_access_test.rb +38 -0
  33. data/test/bson/json_test.rb +17 -0
  34. data/test/bson/object_id_test.rb +138 -0
  35. data/test/bson/ordered_hash_test.rb +245 -0
  36. data/test/bson/test_helper.rb +46 -0
  37. data/test/bson/timestamp_test.rb +46 -0
  38. data/test/collection_test.rb +933 -0
  39. data/test/connection_test.rb +325 -0
  40. data/test/conversions_test.rb +121 -0
  41. data/test/cursor_fail_test.rb +75 -0
  42. data/test/cursor_message_test.rb +43 -0
  43. data/test/cursor_test.rb +547 -0
  44. data/test/data/empty_data +0 -0
  45. data/test/data/sample_data +0 -0
  46. data/test/data/sample_file.pdf +0 -0
  47. data/test/data/small_data.txt +1 -0
  48. data/test/db_api_test.rb +739 -0
  49. data/test/db_connection_test.rb +15 -0
  50. data/test/db_test.rb +325 -0
  51. data/test/grid_file_system_test.rb +260 -0
  52. data/test/grid_io_test.rb +210 -0
  53. data/test/grid_test.rb +259 -0
  54. data/test/load/thin/config.ru +6 -0
  55. data/test/load/thin/config.yml.template +6 -0
  56. data/test/load/thin/load.rb +24 -0
  57. data/test/load/unicorn/config.ru +6 -0
  58. data/test/load/unicorn/load.rb +23 -0
  59. data/test/load/unicorn/unicorn.rb.template +29 -0
  60. data/test/replica_sets/connect_test.rb +111 -0
  61. data/test/replica_sets/connection_string_test.rb +29 -0
  62. data/test/replica_sets/count_test.rb +36 -0
  63. data/test/replica_sets/insert_test.rb +54 -0
  64. data/test/replica_sets/pooled_insert_test.rb +58 -0
  65. data/test/replica_sets/query_secondaries.rb +109 -0
  66. data/test/replica_sets/query_test.rb +52 -0
  67. data/test/replica_sets/read_preference_test.rb +43 -0
  68. data/test/replica_sets/refresh_test.rb +123 -0
  69. data/test/replica_sets/replication_ack_test.rb +71 -0
  70. data/test/replica_sets/rs_test_helper.rb +27 -0
  71. data/test/safe_test.rb +68 -0
  72. data/test/support/hash_with_indifferent_access.rb +186 -0
  73. data/test/support/keys.rb +45 -0
  74. data/test/support_test.rb +19 -0
  75. data/test/test_helper.rb +111 -0
  76. data/test/threading/threading_with_large_pool_test.rb +90 -0
  77. data/test/threading_test.rb +88 -0
  78. data/test/tools/auth_repl_set_manager.rb +14 -0
  79. data/test/tools/keyfile.txt +1 -0
  80. data/test/tools/repl_set_manager.rb +377 -0
  81. data/test/unit/collection_test.rb +128 -0
  82. data/test/unit/connection_test.rb +85 -0
  83. data/test/unit/cursor_test.rb +127 -0
  84. data/test/unit/db_test.rb +96 -0
  85. data/test/unit/grid_test.rb +51 -0
  86. data/test/unit/node_test.rb +73 -0
  87. data/test/unit/pool_manager_test.rb +47 -0
  88. data/test/unit/pool_test.rb +9 -0
  89. data/test/unit/read_test.rb +101 -0
  90. data/test/unit/safe_test.rb +125 -0
  91. data/test/uri_test.rb +92 -0
  92. metadata +170 -99
  93. data/lib/jmongo/ajrb.rb +0 -189
  94. data/lib/jmongo/jmongo_jext.rb +0 -302
  95. data/lib/jmongo/mongo-2.6.3.jar +0 -0
  96. data/lib/jmongo/utils.rb +0 -61
@@ -0,0 +1,73 @@
1
+ require './test/test_helper'
2
+
3
+ class NodeTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @connection = stub()
7
+ end
8
+
9
+ should "refuse to connect to node without 'hosts' key" do
10
+ tcp = mock()
11
+ node = Node.new(@connection, ['localhost', 27017])
12
+ tcp.stubs(:new).returns(new_mock_socket)
13
+ @connection.stubs(:socket_class).returns(tcp)
14
+
15
+ admin_db = new_mock_db
16
+ admin_db.stubs(:command).returns({'ok' => 1, 'ismaster' => 1})
17
+ @connection.stubs(:[]).with('admin').returns(admin_db)
18
+ @connection.stubs(:connect_timeout).returns(nil)
19
+ @connection.expects(:log)
20
+
21
+ assert node.connect
22
+ node.set_config
23
+ end
24
+
25
+ should "load a node from an array" do
26
+ node = Node.new(@connection, ['power.level.com', 9001])
27
+ assert_equal 'power.level.com', node.host
28
+ assert_equal 9001, node.port
29
+ assert_equal 'power.level.com:9001', node.address
30
+ end
31
+
32
+ should "should default the port for an array" do
33
+ node = Node.new(@connection, ['power.level.com'])
34
+ assert_equal 'power.level.com', node.host
35
+ assert_equal Connection::DEFAULT_PORT, node.port
36
+ assert_equal "power.level.com:#{Connection::DEFAULT_PORT}", node.address
37
+ end
38
+
39
+ should "load a node from a string" do
40
+ node = Node.new(@connection, 'localhost:1234')
41
+ assert_equal 'localhost', node.host
42
+ assert_equal 1234, node.port
43
+ assert_equal 'localhost:1234', node.address
44
+ end
45
+
46
+ should "should default the port for a string" do
47
+ node = Node.new(@connection, '192.168.0.1')
48
+ assert_equal '192.168.0.1', node.host
49
+ assert_equal Connection::DEFAULT_PORT, node.port
50
+ assert_equal "192.168.0.1:#{Connection::DEFAULT_PORT}", node.address
51
+ end
52
+
53
+ should "two nodes with the same address should be equal" do
54
+ assert_equal Node.new(@connection, '192.168.0.1'),
55
+ Node.new(@connection, ['192.168.0.1', Connection::DEFAULT_PORT])
56
+ end
57
+
58
+ should "two nodes with the same address should have the same hash" do
59
+ assert_equal Node.new(@connection, '192.168.0.1').hash,
60
+ Node.new(@connection, ['192.168.0.1', Connection::DEFAULT_PORT]).hash
61
+ end
62
+
63
+ should "two nodes with different addresses should not be equal" do
64
+ assert_not_equal Node.new(@connection, '192.168.0.2'),
65
+ Node.new(@connection, ['192.168.0.1', Connection::DEFAULT_PORT])
66
+ end
67
+
68
+ should "two nodes with the same address should have the same hash negate" do
69
+ assert_not_equal Node.new(@connection, '192.168.0.1').hash,
70
+ Node.new(@connection, '1239.33.4.2393:29949').hash
71
+ end
72
+
73
+ end
@@ -0,0 +1,47 @@
1
+ require './test/test_helper'
2
+ include Mongo
3
+
4
+ class PoolManagerTest < Test::Unit::TestCase
5
+
6
+ context "Initialization: " do
7
+
8
+ should "populate pools correctly" do
9
+ TCPSocket.stubs(:new).returns(new_mock_socket)
10
+ @db = new_mock_db
11
+
12
+ @connection = stub("Connection")
13
+ @connection.stubs(:connect_timeout).returns(5000)
14
+ @connection.stubs(:pool_size).returns(2)
15
+ @connection.stubs(:socket_class).returns(TCPSocket)
16
+ @connection.stubs(:[]).returns(@db)
17
+
18
+ @connection.stubs(:replica_set_name).returns(nil)
19
+ @connection.stubs(:log)
20
+ @arbiters = ['localhost:27020']
21
+ @hosts = ['localhost:27017', 'localhost:27018', 'localhost:27019',
22
+ 'localhost:27020']
23
+
24
+ @db.stubs(:command).returns(
25
+ # First call to get a socket.
26
+ {'ismaster' => true, 'hosts' => @hosts, 'arbiters' => @arbiters},
27
+
28
+ # Subsequent calls to configure pools.
29
+ {'ismaster' => true, 'hosts' => @hosts, 'arbiters' => @arbiters},
30
+ {'secondary' => true, 'hosts' => @hosts, 'arbiters' => @arbiters},
31
+ {'secondary' => true, 'hosts' => @hosts, 'arbiters' => @arbiters},
32
+ {'arbiterOnly' => true, 'hosts' => @hosts, 'arbiters' => @arbiters})
33
+
34
+ seeds = [['localhost', 27017]]
35
+ manager = Mongo::PoolManager.new(@connection, seeds)
36
+ manager.connect
37
+
38
+ assert_equal ['localhost', 27017], manager.primary
39
+ assert_equal 27017, manager.primary_pool.port
40
+ assert_equal 2, manager.secondaries.length
41
+ assert_equal 27018, manager.secondary_pools[0].port
42
+ assert_equal [['localhost', 27020]], manager.arbiters
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,9 @@
1
+ require './test/test_helper'
2
+ include Mongo
3
+
4
+ class PoolTest < Test::Unit::TestCase
5
+ context "Initialization: " do
6
+ should "do" do
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,101 @@
1
+ require './test/test_helper'
2
+
3
+ class ReadTest < Test::Unit::TestCase
4
+
5
+ context "Read mode on standard connection: " do
6
+ setup do
7
+ @read_preference = :secondary
8
+ @con = Mongo::Connection.new('localhost', 27017, :read => @read_preference, :connect => false)
9
+ end
10
+
11
+ end
12
+
13
+ context "Read mode on connection: " do
14
+ setup do
15
+ @read_preference = :secondary
16
+ @con = Mongo::ReplSetConnection.new(['localhost', 27017], :read => @read_preference, :connect => false)
17
+ end
18
+
19
+ should "store read preference on Connection" do
20
+ assert_equal @read_preference, @con.read_preference
21
+ end
22
+
23
+ should "propogate to DB" do
24
+ db = @con['foo']
25
+ assert_equal @read_preference, db.read_preference
26
+
27
+ db = @con.db('foo')
28
+ assert_equal @read_preference, db.read_preference
29
+
30
+ db = DB.new('foo', @con)
31
+ assert_equal @read_preference, db.read_preference
32
+ end
33
+
34
+ should "allow db override" do
35
+ db = DB.new('foo', @con, :read => :primary)
36
+ assert_equal :primary, db.read_preference
37
+
38
+ db = @con.db('foo', :read => :primary)
39
+ assert_equal :primary, db.read_preference
40
+ end
41
+
42
+ context "on DB: " do
43
+ setup do
44
+ @db = @con['foo']
45
+ end
46
+
47
+ should "propogate to collection" do
48
+ col = @db.collection('bar')
49
+ assert_equal @read_preference, col.read_preference
50
+
51
+ col = @db['bar']
52
+ assert_equal @read_preference, col.read_preference
53
+
54
+ col = Collection.new('bar', @db)
55
+ assert_equal @read_preference, col.read_preference
56
+ end
57
+
58
+ should "allow override on collection" do
59
+ col = @db.collection('bar', :read => :primary)
60
+ assert_equal :primary, col.read_preference
61
+
62
+ col = Collection.new('bar', @db, :read => :primary)
63
+ assert_equal :primary, col.read_preference
64
+ end
65
+ end
66
+
67
+ context "on read mode ops" do
68
+ setup do
69
+ @col = @con['foo']['bar']
70
+ @mock_socket = stub()
71
+ end
72
+
73
+ should "use default value on query" do
74
+ @con.expects(:receive_message).with do |o, m, l, s, c, r|
75
+ r == :secondary
76
+ end.returns([[], 0, 0])
77
+
78
+ @col.find_one({:a => 1})
79
+ end
80
+
81
+ should "allow override default value on query" do
82
+ @con.expects(:receive_message).with do |o, m, l, s, c, r|
83
+ r == :primary
84
+ end.returns([[], 0, 0])
85
+
86
+ @col.find_one({:a => 1}, :read => :primary)
87
+ end
88
+
89
+ should "allow override alternate value on query" do
90
+ # TODO: enable this test once we enable reading from tags.
91
+ # @con.expects(:receive_message).with do |o, m, l, s, c, r|
92
+ # tags = {:dc => "ny"}
93
+ # end.returns([[], 0, 0])
94
+
95
+ assert_raise MongoArgumentError do
96
+ @col.find_one({:a => 1}, :read => {:dc => "ny"})
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,125 @@
1
+ require './test/test_helper'
2
+
3
+ class SafeTest < Test::Unit::TestCase
4
+
5
+ context "Safe mode on connection: " do
6
+ setup do
7
+ @safe_value = {:w => 7}
8
+ @con = Mongo::Connection.new('localhost', 27017, :safe => @safe_value, :connect => false)
9
+ end
10
+
11
+ should "propogate to DB" do
12
+ db = @con['foo']
13
+ assert_equal @safe_value, db.safe
14
+
15
+
16
+ db = @con.db('foo')
17
+ assert_equal @safe_value, db.safe
18
+
19
+ db = DB.new('foo', @con)
20
+ assert_equal @safe_value, db.safe
21
+ end
22
+
23
+ should "allow db override" do
24
+ db = DB.new('foo', @con, :safe => false)
25
+ assert_equal false, db.safe
26
+
27
+ db = @con.db('foo', :safe => false)
28
+ assert_equal false, db.safe
29
+ end
30
+
31
+ context "on DB: " do
32
+ setup do
33
+ @db = @con['foo']
34
+ end
35
+
36
+ should "propogate to collection" do
37
+ col = @db.collection('bar')
38
+ assert_equal @safe_value, col.safe
39
+
40
+ col = @db['bar']
41
+ assert_equal @safe_value, col.safe
42
+
43
+ col = Collection.new('bar', @db)
44
+ assert_equal @safe_value, col.safe
45
+ end
46
+
47
+ should "allow override on collection" do
48
+ col = @db.collection('bar', :safe => false)
49
+ assert_equal false, col.safe
50
+
51
+ col = Collection.new('bar', @db, :safe => false)
52
+ assert_equal false, col.safe
53
+ end
54
+ end
55
+
56
+ context "on operations supporting safe mode" do
57
+ setup do
58
+ @col = @con['foo']['bar']
59
+ end
60
+
61
+ should "use default value on insert" do
62
+ @con.expects(:send_message_with_safe_check).with do |op, msg, log, n, safe|
63
+ safe == @safe_value
64
+ end
65
+
66
+ @col.insert({:a => 1})
67
+ end
68
+
69
+ should "allow override alternate value on insert" do
70
+ @con.expects(:send_message_with_safe_check).with do |op, msg, log, n, safe|
71
+ safe == {:w => 100}
72
+ end
73
+
74
+ @col.insert({:a => 1}, :safe => {:w => 100})
75
+ end
76
+
77
+ should "allow override to disable on insert" do
78
+ @con.expects(:send_message)
79
+ @col.insert({:a => 1}, :safe => false)
80
+ end
81
+
82
+ should "use default value on update" do
83
+ @con.expects(:send_message_with_safe_check).with do |op, msg, log, n, safe|
84
+ safe == @safe_value
85
+ end
86
+
87
+ @col.update({:a => 1}, {:a => 2})
88
+ end
89
+
90
+ should "allow override alternate value on update" do
91
+ @con.expects(:send_message_with_safe_check).with do |op, msg, log, n, safe|
92
+ safe == {:w => 100}
93
+ end
94
+
95
+ @col.update({:a => 1}, {:a => 2}, :safe => {:w => 100})
96
+ end
97
+
98
+ should "allow override to disable on update" do
99
+ @con.expects(:send_message)
100
+ @col.update({:a => 1}, {:a => 2}, :safe => false)
101
+ end
102
+
103
+ should "use default value on remove" do
104
+ @con.expects(:send_message_with_safe_check).with do |op, msg, log, n, safe|
105
+ safe == @safe_value
106
+ end
107
+
108
+ @col.remove
109
+ end
110
+
111
+ should "allow override alternate value on remove" do
112
+ @con.expects(:send_message_with_safe_check).with do |op, msg, log, n, safe|
113
+ safe == {:w => 100}
114
+ end
115
+
116
+ @col.remove({}, :safe => {:w => 100})
117
+ end
118
+
119
+ should "allow override to disable on remove" do
120
+ @con.expects(:send_message)
121
+ @col.remove({}, :safe => false)
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,92 @@
1
+ __END__
2
+ require './test/test_helper'
3
+
4
+ class TestThreading < Test::Unit::TestCase
5
+ include Mongo
6
+
7
+ def test_uri_without_port
8
+ parser = Mongo::URIParser.new('mongodb://localhost')
9
+ assert_equal 1, parser.nodes.length
10
+ assert_equal 'localhost', parser.nodes[0][0]
11
+ assert_equal 27017, parser.nodes[0][1]
12
+ end
13
+
14
+ def test_basic_uri
15
+ parser = Mongo::URIParser.new('mongodb://localhost:27018')
16
+ assert_equal 1, parser.nodes.length
17
+ assert_equal 'localhost', parser.nodes[0][0]
18
+ assert_equal 27018, parser.nodes[0][1]
19
+ end
20
+
21
+ def test_multiple_uris
22
+ parser = Mongo::URIParser.new('mongodb://a.example.com:27018,b.example.com')
23
+ assert_equal 2, parser.nodes.length
24
+ assert_equal 'a.example.com', parser.nodes[0][0]
25
+ assert_equal 27018, parser.nodes[0][1]
26
+ assert_equal 'b.example.com', parser.nodes[1][0]
27
+ assert_equal 27017, parser.nodes[1][1]
28
+ end
29
+
30
+ def test_complex_passwords
31
+ parser = Mongo::URIParser.new('mongodb://bob:secret.word@a.example.com:27018/test')
32
+ assert_equal "bob", parser.auths[0]["username"]
33
+ assert_equal "secret.word", parser.auths[0]["password"]
34
+
35
+ parser = Mongo::URIParser.new('mongodb://bob:s-_3#%R.t@a.example.com:27018/test')
36
+ assert_equal "bob", parser.auths[0]["username"]
37
+ assert_equal "s-_3#%R.t", parser.auths[0]["password"]
38
+ end
39
+
40
+ def test_passwords_contain_no_commas
41
+ assert_raise MongoArgumentError do
42
+ Mongo::URIParser.new('mongodb://bob:a,b@a.example.com:27018/test')
43
+ end
44
+ end
45
+
46
+ def test_multiple_uris_with_auths
47
+ parser = Mongo::URIParser.new('mongodb://bob:secret@a.example.com:27018/test,joe:secret2@b.example.com/test2')
48
+ assert_equal 2, parser.nodes.length
49
+ assert_equal 'a.example.com', parser.nodes[0][0]
50
+ assert_equal 27018, parser.nodes[0][1]
51
+ assert_equal 'b.example.com', parser.nodes[1][0]
52
+ assert_equal 27017, parser.nodes[1][1]
53
+ assert_equal 2, parser.auths.length
54
+ assert_equal "bob", parser.auths[0]["username"]
55
+ assert_equal "secret", parser.auths[0]["password"]
56
+ assert_equal "test", parser.auths[0]["db_name"]
57
+ assert_equal "joe", parser.auths[1]["username"]
58
+ assert_equal "secret2", parser.auths[1]["password"]
59
+ assert_equal "test2", parser.auths[1]["db_name"]
60
+ end
61
+
62
+ def test_opts_basic
63
+ parser = Mongo::URIParser.new('mongodb://localhost:27018?connect=direct;slaveok=true;safe=true')
64
+ assert_equal 'direct', parser.connect
65
+ assert parser.slaveok
66
+ assert parser.safe
67
+ end
68
+
69
+ def test_opts_with_amp_separator
70
+ parser = Mongo::URIParser.new('mongodb://localhost:27018?connect=direct&slaveok=true&safe=true')
71
+ assert_equal 'direct', parser.connect
72
+ assert parser.slaveok
73
+ assert parser.safe
74
+ end
75
+
76
+ def test_opts_safe
77
+ parser = Mongo::URIParser.new('mongodb://localhost:27018?safe=true;w=2;wtimeout=200;fsync=true')
78
+ assert parser.safe
79
+ assert_equal 2, parser.w
80
+ assert_equal 200, parser.wtimeout
81
+ assert parser.fsync
82
+ end
83
+
84
+ def test_opts_replica_set
85
+ assert_raise_error MongoArgumentError, "specify that connect=replicaset" do
86
+ Mongo::URIParser.new('mongodb://localhost:27018?replicaset=foo')
87
+ end
88
+ parser = Mongo::URIParser.new('mongodb://localhost:27018?connect=replicaset;replicaset=foo')
89
+ assert_equal 'foo', parser.replicaset
90
+ assert_equal 'replicaset', parser.connect
91
+ end
92
+ end