mongo-lyon 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/LICENSE.txt +190 -0
  2. data/README.md +344 -0
  3. data/Rakefile +202 -0
  4. data/bin/mongo_console +34 -0
  5. data/docs/1.0_UPGRADE.md +21 -0
  6. data/docs/CREDITS.md +123 -0
  7. data/docs/FAQ.md +116 -0
  8. data/docs/GridFS.md +158 -0
  9. data/docs/HISTORY.md +225 -0
  10. data/docs/REPLICA_SETS.md +72 -0
  11. data/docs/TUTORIAL.md +247 -0
  12. data/docs/WRITE_CONCERN.md +28 -0
  13. data/lib/mongo.rb +77 -0
  14. data/lib/mongo/collection.rb +872 -0
  15. data/lib/mongo/connection.rb +875 -0
  16. data/lib/mongo/cursor.rb +449 -0
  17. data/lib/mongo/db.rb +607 -0
  18. data/lib/mongo/exceptions.rb +68 -0
  19. data/lib/mongo/gridfs/grid.rb +106 -0
  20. data/lib/mongo/gridfs/grid_ext.rb +57 -0
  21. data/lib/mongo/gridfs/grid_file_system.rb +145 -0
  22. data/lib/mongo/gridfs/grid_io.rb +394 -0
  23. data/lib/mongo/gridfs/grid_io_fix.rb +38 -0
  24. data/lib/mongo/repl_set_connection.rb +342 -0
  25. data/lib/mongo/util/conversions.rb +89 -0
  26. data/lib/mongo/util/core_ext.rb +60 -0
  27. data/lib/mongo/util/pool.rb +185 -0
  28. data/lib/mongo/util/server_version.rb +71 -0
  29. data/lib/mongo/util/support.rb +82 -0
  30. data/lib/mongo/util/uri_parser.rb +181 -0
  31. data/lib/mongo/version.rb +3 -0
  32. data/mongo.gemspec +34 -0
  33. data/test/auxillary/1.4_features.rb +166 -0
  34. data/test/auxillary/authentication_test.rb +68 -0
  35. data/test/auxillary/autoreconnect_test.rb +41 -0
  36. data/test/auxillary/repl_set_auth_test.rb +58 -0
  37. data/test/auxillary/slave_connection_test.rb +36 -0
  38. data/test/auxillary/threaded_authentication_test.rb +101 -0
  39. data/test/bson/binary_test.rb +15 -0
  40. data/test/bson/bson_test.rb +614 -0
  41. data/test/bson/byte_buffer_test.rb +190 -0
  42. data/test/bson/hash_with_indifferent_access_test.rb +38 -0
  43. data/test/bson/json_test.rb +17 -0
  44. data/test/bson/object_id_test.rb +154 -0
  45. data/test/bson/ordered_hash_test.rb +197 -0
  46. data/test/collection_test.rb +893 -0
  47. data/test/connection_test.rb +303 -0
  48. data/test/conversions_test.rb +120 -0
  49. data/test/cursor_fail_test.rb +75 -0
  50. data/test/cursor_message_test.rb +43 -0
  51. data/test/cursor_test.rb +457 -0
  52. data/test/db_api_test.rb +715 -0
  53. data/test/db_connection_test.rb +15 -0
  54. data/test/db_test.rb +287 -0
  55. data/test/grid_file_system_test.rb +244 -0
  56. data/test/grid_io_test.rb +120 -0
  57. data/test/grid_test.rb +200 -0
  58. data/test/load/thin/load.rb +24 -0
  59. data/test/load/unicorn/load.rb +23 -0
  60. data/test/replica_sets/connect_test.rb +86 -0
  61. data/test/replica_sets/connection_string_test.rb +32 -0
  62. data/test/replica_sets/count_test.rb +35 -0
  63. data/test/replica_sets/insert_test.rb +53 -0
  64. data/test/replica_sets/pooled_insert_test.rb +55 -0
  65. data/test/replica_sets/query_secondaries.rb +96 -0
  66. data/test/replica_sets/query_test.rb +51 -0
  67. data/test/replica_sets/replication_ack_test.rb +66 -0
  68. data/test/replica_sets/rs_test_helper.rb +27 -0
  69. data/test/safe_test.rb +68 -0
  70. data/test/support/hash_with_indifferent_access.rb +199 -0
  71. data/test/support/keys.rb +45 -0
  72. data/test/support_test.rb +19 -0
  73. data/test/test_helper.rb +83 -0
  74. data/test/threading/threading_with_large_pool_test.rb +90 -0
  75. data/test/threading_test.rb +87 -0
  76. data/test/tools/auth_repl_set_manager.rb +14 -0
  77. data/test/tools/repl_set_manager.rb +266 -0
  78. data/test/unit/collection_test.rb +130 -0
  79. data/test/unit/connection_test.rb +98 -0
  80. data/test/unit/cursor_test.rb +99 -0
  81. data/test/unit/db_test.rb +96 -0
  82. data/test/unit/grid_test.rb +49 -0
  83. data/test/unit/pool_test.rb +9 -0
  84. data/test/unit/repl_set_connection_test.rb +72 -0
  85. data/test/unit/safe_test.rb +125 -0
  86. data/test/uri_test.rb +91 -0
  87. metadata +202 -0
@@ -0,0 +1,303 @@
1
+ require './test/test_helper'
2
+ require 'logger'
3
+ require 'stringio'
4
+ require 'thread'
5
+
6
+ class TestConnection < Test::Unit::TestCase
7
+
8
+ include Mongo
9
+ include BSON
10
+
11
+ def setup
12
+ @conn = standard_connection
13
+ end
14
+
15
+ def teardown
16
+ @conn[MONGO_TEST_DB].get_last_error
17
+ end
18
+
19
+ def test_connection_failure
20
+ assert_raise Mongo::ConnectionFailure do
21
+ Mongo::Connection.new('localhost', 27347)
22
+ end
23
+ end
24
+
25
+ def test_server_info
26
+ server_info = @conn.server_info
27
+ assert server_info.keys.include?("version")
28
+ assert Mongo::Support.ok?(server_info)
29
+ end
30
+
31
+ def test_ping
32
+ ping = @conn.ping
33
+ assert ping['ok']
34
+ end
35
+
36
+ def test_connection_uri
37
+ con = Connection.from_uri("mongodb://#{host_port}")
38
+ assert_equal mongo_host, con.primary_pool.host
39
+ assert_equal mongo_port, con.primary_pool.port
40
+ end
41
+
42
+ def test_server_version
43
+ assert_match /\d\.\d+(\.\d+)?/, @conn.server_version.to_s
44
+ end
45
+
46
+ def test_invalid_database_names
47
+ assert_raise TypeError do @conn.db(4) end
48
+
49
+ assert_raise Mongo::InvalidNSName do @conn.db('') end
50
+ assert_raise Mongo::InvalidNSName do @conn.db('te$t') end
51
+ assert_raise Mongo::InvalidNSName do @conn.db('te.t') end
52
+ assert_raise Mongo::InvalidNSName do @conn.db('te\\t') end
53
+ assert_raise Mongo::InvalidNSName do @conn.db('te/t') end
54
+ assert_raise Mongo::InvalidNSName do @conn.db('te st') end
55
+ end
56
+
57
+ def test_options_passed_to_db
58
+ @pk_mock = Object.new
59
+ db = @conn.db('test', :pk => @pk_mock, :strict => true)
60
+ assert_equal @pk_mock, db.pk_factory
61
+ assert db.strict?
62
+ end
63
+
64
+ def test_database_info
65
+ @conn.drop_database(MONGO_TEST_DB)
66
+ @conn.db(MONGO_TEST_DB).collection('info-test').insert('a' => 1)
67
+
68
+ info = @conn.database_info
69
+ assert_not_nil info
70
+ assert_kind_of Hash, info
71
+ assert_not_nil info[MONGO_TEST_DB]
72
+ assert info[MONGO_TEST_DB] > 0
73
+
74
+ @conn.drop_database(MONGO_TEST_DB)
75
+ end
76
+
77
+ def test_copy_database
78
+ @conn.db('old').collection('copy-test').insert('a' => 1)
79
+ @conn.copy_database('old', 'new', host_port)
80
+ old_object = @conn.db('old').collection('copy-test').find.next_document
81
+ new_object = @conn.db('new').collection('copy-test').find.next_document
82
+ assert_equal old_object, new_object
83
+ @conn.drop_database('old')
84
+ @conn.drop_database('new')
85
+ end
86
+
87
+ def test_copy_database_with_auth
88
+ @conn.db('old').collection('copy-test').insert('a' => 1)
89
+ @conn.db('old').add_user('bob', 'secret')
90
+
91
+ assert_raise Mongo::OperationFailure do
92
+ @conn.copy_database('old', 'new', host_port, 'bob', 'badpassword')
93
+ end
94
+
95
+ result = @conn.copy_database('old', 'new', host_port, 'bob', 'secret')
96
+ assert Mongo::Support.ok?(result)
97
+
98
+ @conn.drop_database('old')
99
+ @conn.drop_database('new')
100
+ end
101
+
102
+ def test_database_names
103
+ @conn.drop_database(MONGO_TEST_DB)
104
+ @conn.db(MONGO_TEST_DB).collection('info-test').insert('a' => 1)
105
+
106
+ names = @conn.database_names
107
+ assert_not_nil names
108
+ assert_kind_of Array, names
109
+ assert names.length >= 1
110
+ assert names.include?(MONGO_TEST_DB)
111
+ end
112
+
113
+ def test_logging
114
+ output = StringIO.new
115
+ logger = Logger.new(output)
116
+ logger.level = Logger::DEBUG
117
+ connection = standard_connection(:logger => logger).db(MONGO_TEST_DB)
118
+ assert output.string.include?("admin['$cmd'].find")
119
+ end
120
+
121
+ def test_connection_logger
122
+ output = StringIO.new
123
+ logger = Logger.new(output)
124
+ logger.level = Logger::DEBUG
125
+ connection = standard_connection(:logger => logger)
126
+ assert_equal logger, connection.logger
127
+
128
+ connection.logger.debug 'testing'
129
+ assert output.string.include?('testing')
130
+ end
131
+
132
+ def test_drop_database
133
+ db = @conn.db('ruby-mongo-will-be-deleted')
134
+ coll = db.collection('temp')
135
+ coll.remove
136
+ coll.insert(:name => 'temp')
137
+ assert_equal 1, coll.count()
138
+ assert @conn.database_names.include?('ruby-mongo-will-be-deleted')
139
+
140
+ @conn.drop_database('ruby-mongo-will-be-deleted')
141
+ assert !@conn.database_names.include?('ruby-mongo-will-be-deleted')
142
+ end
143
+
144
+ def test_nodes
145
+ db = Connection.multi([['foo', 27017], ['bar', 27018]], :connect => false)
146
+ nodes = db.nodes
147
+ assert_equal 2, nodes.length
148
+ assert_equal ['foo', 27017], nodes[0]
149
+ assert_equal ['bar', 27018], nodes[1]
150
+ end
151
+
152
+ def test_fsync_lock
153
+ assert !@conn.locked?
154
+ @conn.lock!
155
+ assert @conn.locked?
156
+ assert_equal 1, @conn['admin']['$cmd.sys.inprog'].find_one['fsyncLock'], "Not fsync-locked"
157
+ assert_equal "unlock requested", @conn.unlock!['info']
158
+ unlocked = false
159
+ counter = 0
160
+ while counter < 5
161
+ if @conn['admin']['$cmd.sys.inprog'].find_one['fsyncLock'].nil?
162
+ unlocked = true
163
+ break
164
+ else
165
+ sleep(1)
166
+ counter += 1
167
+ end
168
+ end
169
+ assert !@conn.locked?
170
+ assert unlocked, "mongod failed to unlock"
171
+ end
172
+
173
+ def test_max_bson_size_value
174
+ conn = standard_connection
175
+ if conn.server_version > "1.7.2"
176
+ assert_equal conn['admin'].command({:ismaster => 1})['maxBsonObjectSize'], conn.max_bson_size
177
+ end
178
+
179
+ conn.connect
180
+ assert_equal BSON::BSON_CODER.max_bson_size, conn.max_bson_size
181
+ doc = {'n' => 'a' * (BSON_CODER.max_bson_size - 11)}
182
+ assert_raise InvalidDocument do
183
+ assert BSON::BSON_CODER.serialize(doc)
184
+ end
185
+
186
+ limit = 7 * 1024 * 1024
187
+ conn.stubs(:max_bson_size).returns(limit)
188
+ conn.connect
189
+ assert_equal limit, conn.max_bson_size
190
+ assert_equal limit, BSON::BSON_CODER.max_bson_size
191
+ doc = {'n' => 'a' * ((limit) - 11)}
192
+ assert_raise_error InvalidDocument, "limited to #{limit}" do
193
+ assert BSON::BSON_CODER.serialize(doc)
194
+ end
195
+ end
196
+
197
+ def test_max_bson_size_with_old_mongod
198
+ conn = standard_connection(:connect => false)
199
+
200
+ admin_db = Object.new
201
+ admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1}).twice
202
+ conn.expects(:[]).with('admin').returns(admin_db).twice
203
+
204
+ conn.connect
205
+ assert_equal Mongo::DEFAULT_MAX_BSON_SIZE, BSON::BSON_CODER.max_bson_size
206
+ end
207
+
208
+ def test_connection_activity
209
+ conn = standard_connection
210
+ assert conn.active?
211
+
212
+ conn.primary_pool.close
213
+ assert !conn.active?
214
+
215
+ # Simulate a dropped connection.
216
+ dropped_socket = Mocha::Mock.new
217
+ dropped_socket.stubs(:read).raises(Errno::ECONNRESET)
218
+ dropped_socket.stubs(:send).raises(Errno::ECONNRESET)
219
+ dropped_socket.stub_everything
220
+
221
+ conn.primary_pool.host = 'localhost'
222
+ conn.primary_pool.port = Mongo::Connection::DEFAULT_PORT
223
+ conn.primary_pool.instance_variable_set("@sockets", [dropped_socket])
224
+
225
+ assert !conn.active?
226
+ end
227
+
228
+ context "Saved authentications" do
229
+ setup do
230
+ @conn = standard_connection
231
+ @auth = {'db_name' => 'test', 'username' => 'bob', 'password' => 'secret'}
232
+ @conn.add_auth(@auth['db_name'], @auth['username'], @auth['password'])
233
+ end
234
+
235
+ should "save the authentication" do
236
+ assert_equal @auth, @conn.auths[0]
237
+ end
238
+
239
+ should "replace the auth if given a new auth for the same db" do
240
+ auth = {'db_name' => 'test', 'username' => 'mickey', 'password' => 'm0u53'}
241
+ @conn.add_auth(auth['db_name'], auth['username'], auth['password'])
242
+ assert_equal 1, @conn.auths.length
243
+ assert_equal auth, @conn.auths[0]
244
+ end
245
+
246
+ should "remove auths by database" do
247
+ @conn.remove_auth('non-existent database')
248
+ assert_equal 1, @conn.auths.length
249
+
250
+ @conn.remove_auth('test')
251
+ assert_equal 0, @conn.auths.length
252
+ end
253
+
254
+ should "remove all auths" do
255
+ @conn.clear_auths
256
+ assert_equal 0, @conn.auths.length
257
+ end
258
+ end
259
+
260
+ context "Connection exceptions" do
261
+ setup do
262
+ @con = standard_connection(:pool_size => 10, :timeout => 10)
263
+ @coll = @con[MONGO_TEST_DB]['test-connection-exceptions']
264
+ end
265
+
266
+ should "release connection if an exception is raised on send_message" do
267
+ @con.stubs(:send_message_on_socket).raises(ConnectionFailure)
268
+ assert_equal 0, @con.primary_pool.checked_out.size
269
+ assert_raise ConnectionFailure do
270
+ @coll.insert({:test => "insert"})
271
+ end
272
+ assert_equal 0, @con.primary_pool.checked_out.size
273
+ end
274
+
275
+ should "release connection if an exception is raised on send_with_safe_check" do
276
+ @con.stubs(:receive).raises(ConnectionFailure)
277
+ assert_equal 0, @con.primary_pool.checked_out.size
278
+ assert_raise ConnectionFailure do
279
+ @coll.insert({:test => "insert"}, :safe => true)
280
+ end
281
+ assert_equal 0, @con.primary_pool.checked_out.size
282
+ end
283
+
284
+ should "release connection if an exception is raised on receive_message" do
285
+ @con.stubs(:receive).raises(ConnectionFailure)
286
+ assert_equal 0, @con.primary_pool.checked_out.size
287
+ assert_raise ConnectionFailure do
288
+ @coll.find.to_a
289
+ end
290
+ assert_equal 0, @con.primary_pool.checked_out.size
291
+ end
292
+
293
+ should "show a proper exception message if an IOError is raised while closing a socket" do
294
+ fake_socket = Mocha::Mock.new
295
+ fake_socket.stubs(:close).raises(IOError.new)
296
+ fake_socket.stub_everything
297
+ TCPSocket.expects(:new).returns(fake_socket)
298
+
299
+ @con.primary_pool.checkout_new_socket
300
+ assert_equal [], @con.primary_pool.close
301
+ end
302
+ end
303
+ end
@@ -0,0 +1,120 @@
1
+ require './test/test_helper'
2
+ require 'mongo/exceptions'
3
+ require 'mongo/util/conversions'
4
+ require 'bson/ordered_hash'
5
+
6
+ class ConversionsTest < Test::Unit::TestCase
7
+ include Mongo::Conversions
8
+
9
+ def test_array_as_sort_parameters_with_array_of_key_and_value
10
+ params = array_as_sort_parameters(["field1", "asc"])
11
+ assert_equal({"field1" => 1}, params)
12
+ end
13
+
14
+ def test_array_as_sort_parameters_with_array_of_string_and_values
15
+ params = array_as_sort_parameters([["field1", :asc], ["field2", :desc]])
16
+ assert_equal({ "field1" => 1, "field2" => -1 }, params)
17
+ end
18
+
19
+ def test_string_as_sort_parameters_with_string
20
+ params = string_as_sort_parameters("field")
21
+ assert_equal({ "field" => 1 }, params)
22
+ end
23
+
24
+ def test_string_as_sort_parameters_with_empty_string
25
+ params = string_as_sort_parameters("")
26
+ assert_equal({}, params)
27
+ end
28
+
29
+ def test_symbol_as_sort_parameters
30
+ params = string_as_sort_parameters(:field)
31
+ assert_equal({ "field" => 1 }, params)
32
+ end
33
+
34
+ def test_sort_value_when_value_is_one
35
+ assert_equal 1, sort_value(1)
36
+ end
37
+
38
+ def test_sort_value_when_value_is_one_as_a_string
39
+ assert_equal 1, sort_value("1")
40
+ end
41
+
42
+ def test_sort_value_when_value_is_negative_one
43
+ assert_equal -1, sort_value(-1)
44
+ end
45
+
46
+ def test_sort_value_when_value_is_negative_one_as_a_string
47
+ assert_equal -1, sort_value("-1")
48
+ end
49
+
50
+ def test_sort_value_when_value_is_ascending
51
+ assert_equal 1, sort_value("ascending")
52
+ end
53
+
54
+ def test_sort_value_when_value_is_asc
55
+ assert_equal 1, sort_value("asc")
56
+ end
57
+
58
+ def test_sort_value_when_value_is_uppercase_ascending
59
+ assert_equal 1, sort_value("ASCENDING")
60
+ end
61
+
62
+ def test_sort_value_when_value_is_uppercase_asc
63
+ assert_equal 1, sort_value("ASC")
64
+ end
65
+
66
+ def test_sort_value_when_value_is_symbol_ascending
67
+ assert_equal 1, sort_value(:ascending)
68
+ end
69
+
70
+ def test_sort_value_when_value_is_symbol_asc
71
+ assert_equal 1, sort_value(:asc)
72
+ end
73
+
74
+ def test_sort_value_when_value_is_symbol_uppercase_ascending
75
+ assert_equal 1, sort_value(:ASCENDING)
76
+ end
77
+
78
+ def test_sort_value_when_value_is_symbol_uppercase_asc
79
+ assert_equal 1, sort_value(:ASC)
80
+ end
81
+
82
+ def test_sort_value_when_value_is_descending
83
+ assert_equal -1, sort_value("descending")
84
+ end
85
+
86
+ def test_sort_value_when_value_is_desc
87
+ assert_equal -1, sort_value("desc")
88
+ end
89
+
90
+ def test_sort_value_when_value_is_uppercase_descending
91
+ assert_equal -1, sort_value("DESCENDING")
92
+ end
93
+
94
+ def test_sort_value_when_value_is_uppercase_desc
95
+ assert_equal -1, sort_value("DESC")
96
+ end
97
+
98
+ def test_sort_value_when_value_is_symbol_descending
99
+ assert_equal -1, sort_value(:descending)
100
+ end
101
+
102
+ def test_sort_value_when_value_is_symbol_desc
103
+ assert_equal -1, sort_value(:desc)
104
+ end
105
+
106
+ def test_sort_value_when_value_is_uppercase_symbol_descending
107
+ assert_equal -1, sort_value(:DESCENDING)
108
+ end
109
+
110
+ def test_sort_value_when_value_is_uppercase_symbol_desc
111
+ assert_equal -1, sort_value(:DESC)
112
+ end
113
+
114
+ def test_sort_value_when_value_is_invalid
115
+ assert_raise Mongo::InvalidSortValueError do
116
+ sort_value(2)
117
+ end
118
+ end
119
+
120
+ end
@@ -0,0 +1,75 @@
1
+ require './test/test_helper'
2
+ require 'logger'
3
+
4
+ class CursorTest < Test::Unit::TestCase
5
+
6
+ include Mongo
7
+
8
+ @@connection = standard_connection
9
+ @@db = @@connection.db(MONGO_TEST_DB)
10
+ @@coll = @@db.collection('test')
11
+ @@version = @@connection.server_version
12
+
13
+ def setup
14
+ @@coll.remove
15
+ @@coll.insert('a' => 1) # collection not created until it's used
16
+ @@coll_full_name = "#{MONGO_TEST_DB}.test"
17
+ end
18
+
19
+ def test_refill_via_get_more
20
+ assert_equal 1, @@coll.count
21
+ 1000.times { |i|
22
+ assert_equal 1 + i, @@coll.count
23
+ @@coll.insert('a' => i)
24
+ }
25
+
26
+ assert_equal 1001, @@coll.count
27
+ count = 0
28
+ @@coll.find.each { |obj|
29
+ count += obj['a']
30
+ }
31
+ assert_equal 1001, @@coll.count
32
+
33
+ # do the same thing again for debugging
34
+ assert_equal 1001, @@coll.count
35
+ count2 = 0
36
+ @@coll.find.each { |obj|
37
+ count2 += obj['a']
38
+ }
39
+ assert_equal 1001, @@coll.count
40
+
41
+ assert_equal count, count2
42
+ assert_equal 499501, count
43
+ end
44
+
45
+ def test_refill_via_get_more_alt_coll
46
+ coll = @@db.collection('test-alt-coll')
47
+ coll.remove
48
+ coll.insert('a' => 1) # collection not created until it's used
49
+ assert_equal 1, coll.count
50
+
51
+ 1000.times { |i|
52
+ assert_equal 1 + i, coll.count
53
+ coll.insert('a' => i)
54
+ }
55
+
56
+ assert_equal 1001, coll.count
57
+ count = 0
58
+ coll.find.each { |obj|
59
+ count += obj['a']
60
+ }
61
+ assert_equal 1001, coll.count
62
+
63
+ # do the same thing again for debugging
64
+ assert_equal 1001, coll.count
65
+ count2 = 0
66
+ coll.find.each { |obj|
67
+ count2 += obj['a']
68
+ }
69
+ assert_equal 1001, coll.count
70
+
71
+ assert_equal count, count2
72
+ assert_equal 499501, count
73
+ end
74
+
75
+ end