mongo-lyon 1.2.4

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