mongo 1.3.0 → 1.12.5
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/{LICENSE.txt → LICENSE} +1 -1
- data/README.md +122 -271
- data/Rakefile +25 -209
- data/VERSION +1 -0
- data/bin/mongo_console +31 -9
- data/lib/mongo/bulk_write_collection_view.rb +387 -0
- data/lib/mongo/collection.rb +576 -269
- data/lib/mongo/collection_writer.rb +364 -0
- data/lib/mongo/connection/node.rb +249 -0
- data/lib/mongo/connection/pool.rb +340 -0
- data/lib/mongo/connection/pool_manager.rb +320 -0
- data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
- data/lib/mongo/connection/socket/socket_util.rb +37 -0
- data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
- data/lib/mongo/connection/socket/tcp_socket.rb +87 -0
- data/lib/mongo/connection/socket/unix_socket.rb +39 -0
- data/lib/mongo/connection/socket.rb +18 -0
- data/lib/mongo/connection.rb +7 -875
- data/lib/mongo/cursor.rb +403 -117
- data/lib/mongo/db.rb +444 -243
- data/lib/mongo/exception.rb +145 -0
- data/lib/mongo/functional/authentication.rb +455 -0
- data/lib/mongo/functional/logging.rb +85 -0
- data/lib/mongo/functional/read_preference.rb +183 -0
- data/lib/mongo/functional/scram.rb +556 -0
- data/lib/mongo/functional/uri_parser.rb +409 -0
- data/lib/mongo/functional/write_concern.rb +66 -0
- data/lib/mongo/functional.rb +20 -0
- data/lib/mongo/gridfs/grid.rb +30 -24
- data/lib/mongo/gridfs/grid_ext.rb +6 -10
- data/lib/mongo/gridfs/grid_file_system.rb +38 -20
- data/lib/mongo/gridfs/grid_io.rb +84 -75
- data/lib/mongo/gridfs.rb +18 -0
- data/lib/mongo/legacy.rb +140 -0
- data/lib/mongo/mongo_client.rb +697 -0
- data/lib/mongo/mongo_replica_set_client.rb +535 -0
- data/lib/mongo/mongo_sharded_client.rb +159 -0
- data/lib/mongo/networking.rb +372 -0
- data/lib/mongo/{util → utils}/conversions.rb +29 -8
- data/lib/mongo/{util → utils}/core_ext.rb +28 -18
- data/lib/mongo/{util → utils}/server_version.rb +4 -6
- data/lib/mongo/{util → utils}/support.rb +29 -31
- data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
- data/lib/mongo/utils.rb +19 -0
- data/lib/mongo.rb +51 -50
- data/mongo.gemspec +29 -32
- data/test/functional/authentication_test.rb +39 -0
- data/test/functional/bulk_api_stress_test.rb +133 -0
- data/test/functional/bulk_write_collection_view_test.rb +1198 -0
- data/test/functional/client_test.rb +627 -0
- data/test/functional/collection_test.rb +2175 -0
- data/test/functional/collection_writer_test.rb +83 -0
- data/test/{conversions_test.rb → functional/conversions_test.rb} +47 -3
- data/test/functional/cursor_fail_test.rb +57 -0
- data/test/functional/cursor_message_test.rb +56 -0
- data/test/functional/cursor_test.rb +683 -0
- data/test/functional/db_api_test.rb +835 -0
- data/test/functional/db_connection_test.rb +25 -0
- data/test/functional/db_test.rb +348 -0
- data/test/functional/grid_file_system_test.rb +285 -0
- data/test/{grid_io_test.rb → functional/grid_io_test.rb} +72 -11
- data/test/{grid_test.rb → functional/grid_test.rb} +88 -15
- data/test/functional/pool_test.rb +136 -0
- data/test/functional/safe_test.rb +98 -0
- data/test/functional/ssl_test.rb +29 -0
- data/test/functional/support_test.rb +62 -0
- data/test/functional/timeout_test.rb +60 -0
- data/test/functional/uri_test.rb +446 -0
- data/test/functional/write_concern_test.rb +118 -0
- data/test/helpers/general.rb +50 -0
- data/test/helpers/test_unit.rb +476 -0
- data/test/replica_set/authentication_test.rb +37 -0
- data/test/replica_set/basic_test.rb +189 -0
- data/test/replica_set/client_test.rb +393 -0
- data/test/replica_set/connection_test.rb +138 -0
- data/test/replica_set/count_test.rb +66 -0
- data/test/replica_set/cursor_test.rb +220 -0
- data/test/replica_set/insert_test.rb +157 -0
- data/test/replica_set/max_values_test.rb +151 -0
- data/test/replica_set/pinning_test.rb +105 -0
- data/test/replica_set/query_test.rb +73 -0
- data/test/replica_set/read_preference_test.rb +219 -0
- data/test/replica_set/refresh_test.rb +211 -0
- data/test/replica_set/replication_ack_test.rb +95 -0
- data/test/replica_set/ssl_test.rb +32 -0
- data/test/sharded_cluster/basic_test.rb +203 -0
- data/test/shared/authentication/basic_auth_shared.rb +260 -0
- data/test/shared/authentication/bulk_api_auth_shared.rb +249 -0
- data/test/shared/authentication/gssapi_shared.rb +176 -0
- data/test/shared/authentication/sasl_plain_shared.rb +96 -0
- data/test/shared/authentication/scram_shared.rb +92 -0
- data/test/shared/ssl_shared.rb +235 -0
- data/test/test_helper.rb +53 -94
- data/test/threading/basic_test.rb +120 -0
- data/test/tools/mongo_config.rb +708 -0
- data/test/tools/mongo_config_test.rb +160 -0
- data/test/unit/client_test.rb +381 -0
- data/test/unit/collection_test.rb +89 -53
- data/test/unit/connection_test.rb +282 -32
- data/test/unit/cursor_test.rb +206 -8
- data/test/unit/db_test.rb +55 -13
- data/test/unit/grid_test.rb +43 -16
- data/test/unit/mongo_sharded_client_test.rb +48 -0
- data/test/unit/node_test.rb +93 -0
- data/test/unit/pool_manager_test.rb +111 -0
- data/test/unit/read_pref_test.rb +406 -0
- data/test/unit/read_test.rb +159 -0
- data/test/unit/safe_test.rb +69 -36
- data/test/unit/sharding_pool_manager_test.rb +84 -0
- data/test/unit/write_concern_test.rb +175 -0
- data.tar.gz.sig +3 -0
- metadata +227 -216
- metadata.gz.sig +0 -0
- data/docs/CREDITS.md +0 -123
- data/docs/FAQ.md +0 -116
- data/docs/GridFS.md +0 -158
- data/docs/HISTORY.md +0 -244
- data/docs/RELEASES.md +0 -33
- data/docs/REPLICA_SETS.md +0 -72
- data/docs/TUTORIAL.md +0 -247
- data/docs/WRITE_CONCERN.md +0 -28
- data/lib/mongo/exceptions.rb +0 -71
- data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
- data/lib/mongo/repl_set_connection.rb +0 -342
- data/lib/mongo/test.rb +0 -20
- data/lib/mongo/util/pool.rb +0 -177
- data/lib/mongo/util/uri_parser.rb +0 -185
- data/test/async/collection_test.rb +0 -224
- data/test/async/connection_test.rb +0 -24
- data/test/async/cursor_test.rb +0 -162
- data/test/async/worker_pool_test.rb +0 -99
- data/test/auxillary/1.4_features.rb +0 -166
- data/test/auxillary/authentication_test.rb +0 -68
- data/test/auxillary/autoreconnect_test.rb +0 -41
- data/test/auxillary/fork_test.rb +0 -30
- data/test/auxillary/repl_set_auth_test.rb +0 -58
- data/test/auxillary/slave_connection_test.rb +0 -36
- data/test/auxillary/threaded_authentication_test.rb +0 -101
- data/test/bson/binary_test.rb +0 -15
- data/test/bson/bson_test.rb +0 -649
- data/test/bson/byte_buffer_test.rb +0 -208
- data/test/bson/hash_with_indifferent_access_test.rb +0 -38
- data/test/bson/json_test.rb +0 -17
- data/test/bson/object_id_test.rb +0 -154
- data/test/bson/ordered_hash_test.rb +0 -204
- data/test/bson/timestamp_test.rb +0 -24
- data/test/collection_test.rb +0 -910
- data/test/connection_test.rb +0 -309
- data/test/cursor_fail_test.rb +0 -75
- data/test/cursor_message_test.rb +0 -43
- data/test/cursor_test.rb +0 -483
- data/test/db_api_test.rb +0 -726
- data/test/db_connection_test.rb +0 -15
- data/test/db_test.rb +0 -287
- data/test/grid_file_system_test.rb +0 -243
- data/test/load/resque/load.rb +0 -21
- data/test/load/resque/processor.rb +0 -26
- data/test/load/thin/load.rb +0 -24
- data/test/load/unicorn/load.rb +0 -23
- data/test/load/unicorn/unicorn.rb +0 -29
- data/test/replica_sets/connect_test.rb +0 -94
- data/test/replica_sets/connection_string_test.rb +0 -32
- data/test/replica_sets/count_test.rb +0 -35
- data/test/replica_sets/insert_test.rb +0 -53
- data/test/replica_sets/pooled_insert_test.rb +0 -55
- data/test/replica_sets/query_secondaries.rb +0 -96
- data/test/replica_sets/query_test.rb +0 -51
- data/test/replica_sets/replication_ack_test.rb +0 -66
- data/test/replica_sets/rs_test_helper.rb +0 -27
- data/test/safe_test.rb +0 -68
- data/test/support/hash_with_indifferent_access.rb +0 -186
- data/test/support/keys.rb +0 -45
- data/test/support_test.rb +0 -18
- data/test/threading/threading_with_large_pool_test.rb +0 -90
- data/test/threading_test.rb +0 -87
- data/test/tools/auth_repl_set_manager.rb +0 -14
- data/test/tools/load.rb +0 -58
- data/test/tools/repl_set_manager.rb +0 -266
- data/test/tools/sharding_manager.rb +0 -202
- data/test/tools/test.rb +0 -4
- data/test/unit/pool_test.rb +0 -9
- data/test/unit/repl_set_connection_test.rb +0 -59
- data/test/uri_test.rb +0 -91
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class DBConnectionTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
def test_no_exceptions
|
20
|
+
db = standard_connection.db(TEST_DB)
|
21
|
+
coll = db.collection('test')
|
22
|
+
coll.remove
|
23
|
+
db.get_last_error
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,348 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
require 'digest/md5'
|
17
|
+
require 'stringio'
|
18
|
+
require 'logger'
|
19
|
+
|
20
|
+
class TestPKFactory
|
21
|
+
def create_pk(row)
|
22
|
+
row['_id'] ||= BSON::ObjectId.new
|
23
|
+
row
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class DBTest < Test::Unit::TestCase
|
28
|
+
|
29
|
+
include Mongo
|
30
|
+
|
31
|
+
def setup
|
32
|
+
@client = standard_connection
|
33
|
+
@db = @client.db(TEST_DB)
|
34
|
+
@version = @client.server_version
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_close
|
38
|
+
@client.close
|
39
|
+
assert !@client.connected?
|
40
|
+
begin
|
41
|
+
@db.collection('test').insert('a' => 1)
|
42
|
+
fail "expected 'NilClass' exception"
|
43
|
+
rescue => ex
|
44
|
+
assert_match(/NilClass/, ex.to_s)
|
45
|
+
ensure
|
46
|
+
@db = standard_connection.db(TEST_DB)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_create_collection
|
51
|
+
col = @db.create_collection('foo')
|
52
|
+
assert_equal @db['foo'].name, col.name
|
53
|
+
|
54
|
+
col = @db.create_collection(:foo)
|
55
|
+
assert_equal @db['foo'].name, col.name
|
56
|
+
|
57
|
+
@db.drop_collection('foo')
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_get_and_drop_collection
|
61
|
+
db = @client.db(TEST_DB, :strict => true)
|
62
|
+
db.create_collection('foo')
|
63
|
+
assert db.collection('foo')
|
64
|
+
assert db.drop_collection('foo')
|
65
|
+
|
66
|
+
db.create_collection(:foo)
|
67
|
+
assert db.collection(:foo)
|
68
|
+
# Use a string because of SERVER-16260
|
69
|
+
assert db.drop_collection('foo')
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_logger
|
73
|
+
output = StringIO.new
|
74
|
+
logger = Logger.new(output)
|
75
|
+
logger.level = Logger::DEBUG
|
76
|
+
conn = standard_connection(:logger => logger)
|
77
|
+
assert_equal logger, conn.logger
|
78
|
+
|
79
|
+
conn.logger.debug 'testing'
|
80
|
+
assert output.string.include?('testing')
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_full_coll_name
|
84
|
+
coll = @db.collection('test')
|
85
|
+
assert_equal "#{TEST_DB}.test", @db.full_collection_name(coll.name)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_collection_names
|
89
|
+
@db.collection("test").insert("foo" => 5)
|
90
|
+
@db.collection("test.mike").insert("bar" => 0)
|
91
|
+
|
92
|
+
colls = @db.collection_names()
|
93
|
+
assert colls.include?("test")
|
94
|
+
assert colls.include?("test.mike")
|
95
|
+
colls.each { |name|
|
96
|
+
assert !name.include?("$")
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_collections
|
101
|
+
@db.collection("test.durran").insert("foo" => 5)
|
102
|
+
@db.collection("test.les").insert("bar" => 0)
|
103
|
+
|
104
|
+
colls = @db.collections()
|
105
|
+
assert_not_nil colls.select { |coll| coll.name == "test.durran" }
|
106
|
+
assert_not_nil colls.select { |coll| coll.name == "test.les" }
|
107
|
+
assert_equal [], colls.select { |coll| coll.name == "does_not_exist" }
|
108
|
+
|
109
|
+
assert_kind_of Collection, colls[0]
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_pk_factory
|
113
|
+
db = standard_connection.db(TEST_DB, :pk => TestPKFactory.new)
|
114
|
+
coll = db.collection('test')
|
115
|
+
coll.remove
|
116
|
+
|
117
|
+
insert_id = coll.insert('name' => 'Fred', 'age' => 42)
|
118
|
+
# new id gets added to returned object
|
119
|
+
row = coll.find_one({'name' => 'Fred'})
|
120
|
+
oid = row['_id']
|
121
|
+
assert_not_nil oid
|
122
|
+
assert_equal insert_id, oid
|
123
|
+
|
124
|
+
oid = BSON::ObjectId.new
|
125
|
+
data = {'_id' => oid, 'name' => 'Barney', 'age' => 41}
|
126
|
+
coll.insert(data)
|
127
|
+
row = coll.find_one({'name' => data['name']})
|
128
|
+
db_oid = row['_id']
|
129
|
+
assert_equal oid, db_oid
|
130
|
+
assert_equal data, row
|
131
|
+
|
132
|
+
coll.remove
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_pk_factory_reset
|
136
|
+
conn = standard_connection
|
137
|
+
db = conn.db(TEST_DB)
|
138
|
+
db.pk_factory = Object.new # first time
|
139
|
+
begin
|
140
|
+
db.pk_factory = Object.new
|
141
|
+
fail "error: expected exception"
|
142
|
+
rescue => ex
|
143
|
+
assert_match(/Cannot change/, ex.to_s)
|
144
|
+
ensure
|
145
|
+
conn.close
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_command
|
150
|
+
assert_raise OperationFailure do
|
151
|
+
@db.command({:non_command => 1}, :check_response => true)
|
152
|
+
end
|
153
|
+
|
154
|
+
result = @db.command({:non_command => 1}, :check_response => false)
|
155
|
+
assert !Mongo::Support.ok?(result)
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_error
|
159
|
+
@db.reset_error_history
|
160
|
+
assert_nil @db.get_last_error['err']
|
161
|
+
assert !@db.error?
|
162
|
+
assert_nil @db.previous_error
|
163
|
+
|
164
|
+
@db.command({:forceerror => 1}, :check_response => false)
|
165
|
+
assert @db.error?
|
166
|
+
assert_not_nil @db.get_last_error['err']
|
167
|
+
assert_not_nil @db.previous_error
|
168
|
+
|
169
|
+
@db.command({:forceerror => 1}, :check_response => false)
|
170
|
+
assert @db.error?
|
171
|
+
assert @db.get_last_error['err']
|
172
|
+
prev_error = @db.previous_error
|
173
|
+
assert_equal 1, prev_error['nPrev']
|
174
|
+
assert_equal prev_error["err"], @db.get_last_error['err']
|
175
|
+
|
176
|
+
@db.collection('test').find_one
|
177
|
+
assert_nil @db.get_last_error['err']
|
178
|
+
assert !@db.error?
|
179
|
+
assert @db.previous_error
|
180
|
+
assert_equal 2, @db.previous_error['nPrev']
|
181
|
+
|
182
|
+
@db.reset_error_history
|
183
|
+
assert_nil @db.get_last_error['err']
|
184
|
+
assert !@db.error?
|
185
|
+
assert_nil @db.previous_error
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_check_command_response
|
189
|
+
if @version >= "2.1.0"
|
190
|
+
command = {:create => "$$$$"}
|
191
|
+
expected_codes = [10356, 2]
|
192
|
+
expected_msg = "invalid"
|
193
|
+
raised = false
|
194
|
+
begin
|
195
|
+
@db.command(command)
|
196
|
+
rescue => ex
|
197
|
+
raised = true
|
198
|
+
assert ex.message.include?(expected_msg) ||
|
199
|
+
(ex.result.has_key?("assertion") &&
|
200
|
+
ex.result["assertion"].include?(expected_msg)),
|
201
|
+
"error message does not contain '#{expected_msg}'"
|
202
|
+
assert expected_codes.include?(ex.error_code)
|
203
|
+
assert expected_codes.include?(ex.result['code'])
|
204
|
+
ensure
|
205
|
+
assert raised, "No assertion raised!"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_arbitrary_command_opts
|
211
|
+
with_forced_timeout(@client) do
|
212
|
+
assert_raise ExecutionTimeout do
|
213
|
+
cmd = OrderedHash.new
|
214
|
+
cmd[:ping] = 1
|
215
|
+
cmd[:maxTimeMS] = 100
|
216
|
+
@db.command(cmd)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_command_with_bson
|
222
|
+
normal_response = @db.command({:buildInfo => 1})
|
223
|
+
bson = BSON::BSON_CODER.serialize({:buildInfo => 1}, false, false)
|
224
|
+
bson_response = @db.command({:bson => bson})
|
225
|
+
assert_equal normal_response, bson_response
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_last_status
|
229
|
+
@db['test'].remove
|
230
|
+
@db['test'].save("i" => 1)
|
231
|
+
|
232
|
+
@db['test'].update({"i" => 1}, {"$set" => {"i" => 2}})
|
233
|
+
assert @db.get_last_error()["updatedExisting"]
|
234
|
+
|
235
|
+
@db['test'].update({"i" => 1}, {"$set" => {"i" => 500}})
|
236
|
+
assert !@db.get_last_error()["updatedExisting"]
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_text_port_number_raises_no_errors
|
240
|
+
client = standard_connection
|
241
|
+
db = client[TEST_DB]
|
242
|
+
db.collection('users').remove
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_stored_function_management
|
246
|
+
grant_admin_user_eval_role(@client)
|
247
|
+
@db.add_stored_function("sum", "function (x, y) { return x + y; }")
|
248
|
+
assert_equal @db.eval("return sum(2,3);"), 5
|
249
|
+
assert @db.remove_stored_function("sum")
|
250
|
+
assert_raise OperationFailure do
|
251
|
+
@db.eval("return sum(2,3);")
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_eval
|
256
|
+
grant_admin_user_eval_role(@client)
|
257
|
+
@db.eval("db.system.save({_id:'hello', value: function() { print('hello'); } })")
|
258
|
+
assert_equal 'hello', @db['system'].find_one['_id']
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_eval_nook
|
262
|
+
grant_admin_user_eval_role(@client)
|
263
|
+
function = "db.system.save({_id:'hello', value: function(string) { print(string); } })"
|
264
|
+
@db.expects(:command).with do |selector, opts|
|
265
|
+
selector[:nolock] == true
|
266
|
+
end.returns({ 'ok' => 1, 'retval' => 1 })
|
267
|
+
@db.eval(function, 'hello', :nolock => true)
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_default_admin_roles
|
271
|
+
return unless @version >= '2.5.3'
|
272
|
+
# admin user
|
273
|
+
@db.stubs(:command).returns({}, true)
|
274
|
+
@db.expects(:command).with do |command, cmd_opts|
|
275
|
+
command[:createUser] == TEST_USER
|
276
|
+
cmd_opts[:roles] == ['root'] if cmd_opts
|
277
|
+
end
|
278
|
+
|
279
|
+
silently { @db.add_user(TEST_USER, TEST_USER_PWD) }
|
280
|
+
|
281
|
+
@db.stubs(:command).returns({}, true)
|
282
|
+
@db.expects(:command).with do |command, cmd_opts|
|
283
|
+
command[:createUser] == TEST_USER
|
284
|
+
cmd_opts[:roles] == ['readAnyDatabase'] if cmd_opts
|
285
|
+
end
|
286
|
+
|
287
|
+
silently { @db.add_user(TEST_USER, TEST_USER_PWD, true) }
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_db_stats
|
291
|
+
return unless @version >= "1.3.5"
|
292
|
+
stats = @db.stats
|
293
|
+
assert stats.has_key?('collections')
|
294
|
+
assert stats.has_key?('dataSize')
|
295
|
+
end
|
296
|
+
|
297
|
+
context "database profiling" do
|
298
|
+
setup do
|
299
|
+
@db = @client[TEST_DB]
|
300
|
+
@coll = @db['test']
|
301
|
+
@coll.remove
|
302
|
+
@r1 = @coll.insert('a' => 1) # collection not created until it's used
|
303
|
+
end
|
304
|
+
|
305
|
+
should "set default profiling level" do
|
306
|
+
assert_equal :off, @db.profiling_level
|
307
|
+
end
|
308
|
+
|
309
|
+
should "change profiling level" do
|
310
|
+
@db.profiling_level = :slow_only
|
311
|
+
assert_equal :slow_only, @db.profiling_level
|
312
|
+
@db.profiling_level = :off
|
313
|
+
assert_equal :off, @db.profiling_level
|
314
|
+
@db.profiling_level = :all
|
315
|
+
assert_equal :all, @db.profiling_level
|
316
|
+
begin
|
317
|
+
@db.profiling_level = :medium
|
318
|
+
fail "shouldn't be able to do this"
|
319
|
+
rescue
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
should "return profiling info" do
|
324
|
+
if @version >= "2.2" && @version < "3.0"
|
325
|
+
@db.profiling_level = :all
|
326
|
+
@coll.find()
|
327
|
+
@db.profiling_level = :off
|
328
|
+
|
329
|
+
info = @db.profiling_info
|
330
|
+
assert_kind_of Array, info
|
331
|
+
assert info.length >= 1
|
332
|
+
first = info.first
|
333
|
+
assert_kind_of Time, first['ts']
|
334
|
+
assert_kind_of Numeric, first['millis']
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
should "validate collection" do
|
339
|
+
doc = @db.validate_collection(@coll.name)
|
340
|
+
if @version >= "1.9.1"
|
341
|
+
assert doc['valid']
|
342
|
+
else
|
343
|
+
assert doc['result']
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
end
|
348
|
+
end
|
@@ -0,0 +1,285 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class GridFileSystemTest < Test::Unit::TestCase
|
18
|
+
context "GridFileSystem:" do
|
19
|
+
setup do
|
20
|
+
@con = standard_connection
|
21
|
+
@db = @con.db(TEST_DB)
|
22
|
+
end
|
23
|
+
|
24
|
+
teardown do
|
25
|
+
@db.drop_collection('fs.files')
|
26
|
+
@db.drop_collection('fs.chunks')
|
27
|
+
end
|
28
|
+
|
29
|
+
context "Initialization" do
|
30
|
+
setup do
|
31
|
+
@chunks_data = "CHUNKS" * 50000
|
32
|
+
@grid = GridFileSystem.new(@db)
|
33
|
+
@opts = {:w => 1}
|
34
|
+
@original_opts = @opts.dup
|
35
|
+
@grid.open('sample.file', 'w', @opts) do |f|
|
36
|
+
f.write @chunks_data
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
should "not modify original opts" do
|
41
|
+
assert_equal @original_opts, @opts
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "When reading:" do
|
46
|
+
setup do
|
47
|
+
@chunks_data = "CHUNKS" * 50000
|
48
|
+
@grid = GridFileSystem.new(@db)
|
49
|
+
@grid.open('sample.file', 'w') do |f|
|
50
|
+
f.write @chunks_data
|
51
|
+
end
|
52
|
+
|
53
|
+
@grid = GridFileSystem.new(@db)
|
54
|
+
end
|
55
|
+
|
56
|
+
should "return existence of the file" do
|
57
|
+
file = @grid.exist?(:filename => 'sample.file')
|
58
|
+
assert_equal 'sample.file', file['filename']
|
59
|
+
end
|
60
|
+
|
61
|
+
should "return nil if the file doesn't exist" do
|
62
|
+
assert_nil @grid.exist?(:filename => 'foo.file')
|
63
|
+
end
|
64
|
+
|
65
|
+
should "read sample data" do
|
66
|
+
data = @grid.open('sample.file', 'r') { |f| f.read }
|
67
|
+
assert_equal data.length, @chunks_data.length
|
68
|
+
end
|
69
|
+
|
70
|
+
should "have a unique index on chunks" do
|
71
|
+
assert @db['fs.chunks'].index_information['files_id_1_n_1']['unique']
|
72
|
+
end
|
73
|
+
|
74
|
+
should "have an index on filename" do
|
75
|
+
assert @db['fs.files'].index_information['filename_1_uploadDate_-1']
|
76
|
+
end
|
77
|
+
|
78
|
+
should "return an empty string if length is zero" do
|
79
|
+
data = @grid.open('sample.file', 'r') { |f| f.read(0) }
|
80
|
+
assert_equal '', data
|
81
|
+
end
|
82
|
+
|
83
|
+
should "return the first n bytes" do
|
84
|
+
data = @grid.open('sample.file', 'r') {|f| f.read(288888) }
|
85
|
+
assert_equal 288888, data.length
|
86
|
+
assert_equal @chunks_data[0...288888], data
|
87
|
+
end
|
88
|
+
|
89
|
+
should "return the first n bytes even with an offset" do
|
90
|
+
data = @grid.open('sample.file', 'r') do |f|
|
91
|
+
f.seek(1000)
|
92
|
+
f.read(288888)
|
93
|
+
end
|
94
|
+
assert_equal 288888, data.length
|
95
|
+
assert_equal @chunks_data[1000...289888], data
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "When writing:" do
|
100
|
+
setup do
|
101
|
+
@data = "BYTES" * 50
|
102
|
+
@grid = GridFileSystem.new(@db)
|
103
|
+
@grid.open('sample', 'w') do |f|
|
104
|
+
f.write @data
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
should "read sample data" do
|
109
|
+
data = @grid.open('sample', 'r') { |f| f.read }
|
110
|
+
assert_equal data.length, @data.length
|
111
|
+
end
|
112
|
+
|
113
|
+
should "return the total number of bytes written" do
|
114
|
+
data = 'a' * 300000
|
115
|
+
assert_equal 300000, @grid.open('sample', 'w') {|f| f.write(data) }
|
116
|
+
end
|
117
|
+
|
118
|
+
should "more read sample data" do
|
119
|
+
data = @grid.open('sample', 'r') { |f| f.read }
|
120
|
+
assert_equal data.length, @data.length
|
121
|
+
end
|
122
|
+
|
123
|
+
should "raise exception if file not found" do
|
124
|
+
assert_raise GridFileNotFound do
|
125
|
+
@grid.open('io', 'r') { |f| f.write('hello') }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
should "raise exception if not opened for write" do
|
130
|
+
assert_raise GridError do
|
131
|
+
@grid.open('sample', 'r') { |f| f.write('hello') }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "and when overwriting the file" do
|
136
|
+
setup do
|
137
|
+
@old = @grid.open('sample', 'r')
|
138
|
+
|
139
|
+
@new_data = "DATA" * 10
|
140
|
+
@grid.open('sample', 'w') do |f|
|
141
|
+
f.write @new_data
|
142
|
+
end
|
143
|
+
|
144
|
+
@new = @grid.open('sample', 'r')
|
145
|
+
end
|
146
|
+
|
147
|
+
should "have a newer upload date" do
|
148
|
+
assert @new.upload_date > @old.upload_date, "New data is not greater than old date."
|
149
|
+
end
|
150
|
+
|
151
|
+
should "have a different files_id" do
|
152
|
+
assert_not_equal @new.files_id, @old.files_id
|
153
|
+
end
|
154
|
+
|
155
|
+
should "contain the new data" do
|
156
|
+
assert_equal @new_data, @new.read, "Expected DATA"
|
157
|
+
end
|
158
|
+
|
159
|
+
context "and on a second overwrite" do
|
160
|
+
setup do
|
161
|
+
@new_data = "NEW" * 1000
|
162
|
+
@grid.open('sample', 'w') do |f|
|
163
|
+
f.write @new_data
|
164
|
+
end
|
165
|
+
|
166
|
+
@ids = @db['fs.files'].find({'filename' => 'sample'}).map {|file| file['_id']}
|
167
|
+
end
|
168
|
+
|
169
|
+
should "write a third version of the file" do
|
170
|
+
assert_equal 3, @db['fs.files'].find({'filename' => 'sample'}).count
|
171
|
+
assert_equal 3, @db['fs.chunks'].find({'files_id' => {'$in' => @ids}}).count
|
172
|
+
end
|
173
|
+
|
174
|
+
should "remove all versions and their data on delete" do
|
175
|
+
@grid.delete('sample')
|
176
|
+
assert_equal 0, @db['fs.files'].find({'filename' => 'sample'}).count
|
177
|
+
assert_equal 0, @db['fs.chunks'].find({'files_id' => {'$in' => @ids}}).count
|
178
|
+
end
|
179
|
+
|
180
|
+
should "delete all versions which exceed the number of versions to keep specified by the option :versions" do
|
181
|
+
@versions = 1 + rand(4-1)
|
182
|
+
@grid.open('sample', 'w', :versions => @versions) do |f|
|
183
|
+
f.write @new_data
|
184
|
+
end
|
185
|
+
@new_ids = @db['fs.files'].find({'filename' => 'sample'}).map {|file| file['_id']}
|
186
|
+
assert_equal @versions, @new_ids.length
|
187
|
+
id = @new_ids.first
|
188
|
+
assert !@ids.include?(id)
|
189
|
+
assert_equal @versions, @db['fs.files'].find({'filename' => 'sample'}).count
|
190
|
+
end
|
191
|
+
|
192
|
+
should "delete old versions on write with :delete_old is passed in" do
|
193
|
+
@grid.open('sample', 'w', :delete_old => true) do |f|
|
194
|
+
f.write @new_data
|
195
|
+
end
|
196
|
+
@new_ids = @db['fs.files'].find({'filename' => 'sample'}).map {|file| file['_id']}
|
197
|
+
assert_equal 1, @new_ids.length
|
198
|
+
id = @new_ids.first
|
199
|
+
assert !@ids.include?(id)
|
200
|
+
assert_equal 1, @db['fs.files'].find({'filename' => 'sample'}).count
|
201
|
+
assert_equal 1, @db['fs.chunks'].find({'files_id' => id}).count
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context "When writing chunks:" do
|
208
|
+
setup do
|
209
|
+
data = "B" * 50000
|
210
|
+
@grid = GridFileSystem.new(@db)
|
211
|
+
@grid.open('sample', 'w', :chunk_size => 1000) do |f|
|
212
|
+
f.write data
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
should "write the correct number of chunks" do
|
217
|
+
file = @db['fs.files'].find_one({:filename => 'sample'})
|
218
|
+
chunks = @db['fs.chunks'].find({'files_id' => file['_id']}).to_a
|
219
|
+
assert_equal 50, chunks.length
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
context "Positioning:" do
|
224
|
+
setup do
|
225
|
+
data = 'hello, world' + '1' * 5000 + 'goodbye!' + '2' * 1000 + '!'
|
226
|
+
@grid = GridFileSystem.new(@db)
|
227
|
+
@grid.open('hello', 'w', :chunk_size => 1000) do |f|
|
228
|
+
f.write data
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
should "seek within chunks" do
|
233
|
+
@grid.open('hello', 'r') do |f|
|
234
|
+
f.seek(0)
|
235
|
+
assert_equal 'h', f.read(1)
|
236
|
+
f.seek(7)
|
237
|
+
assert_equal 'w', f.read(1)
|
238
|
+
f.seek(4)
|
239
|
+
assert_equal 'o', f.read(1)
|
240
|
+
f.seek(0)
|
241
|
+
f.seek(7, IO::SEEK_CUR)
|
242
|
+
assert_equal 'w', f.read(1)
|
243
|
+
f.seek(-2, IO::SEEK_CUR)
|
244
|
+
assert_equal ' ', f.read(1)
|
245
|
+
f.seek(-4, IO::SEEK_CUR)
|
246
|
+
assert_equal 'l', f.read(1)
|
247
|
+
f.seek(3, IO::SEEK_CUR)
|
248
|
+
assert_equal 'w', f.read(1)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
should "seek between chunks" do
|
253
|
+
@grid.open('hello', 'r') do |f|
|
254
|
+
f.seek(1000)
|
255
|
+
assert_equal '11111', f.read(5)
|
256
|
+
|
257
|
+
f.seek(5009)
|
258
|
+
assert_equal '111goodbye!222', f.read(14)
|
259
|
+
|
260
|
+
f.seek(-1, IO::SEEK_END)
|
261
|
+
assert_equal '!', f.read(1)
|
262
|
+
f.seek(-6, IO::SEEK_END)
|
263
|
+
assert_equal '2', f.read(1)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
should "tell the current position" do
|
268
|
+
@grid.open('hello', 'r') do |f|
|
269
|
+
assert_equal 0, f.tell
|
270
|
+
|
271
|
+
f.seek(999)
|
272
|
+
assert_equal 999, f.tell
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
should "seek only in read mode" do
|
277
|
+
assert_raise GridError do
|
278
|
+
silently do
|
279
|
+
@grid.open('hello', 'w') { |f| f.seek(0) }
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|