jonbell-mongo 1.3.1.2

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