kbaum-mongo 0.18.3p
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.
- data/LICENSE.txt +202 -0
- data/README.rdoc +339 -0
- data/Rakefile +138 -0
- data/bin/bson_benchmark.rb +59 -0
- data/bin/fail_if_no_c.rb +11 -0
- data/examples/admin.rb +42 -0
- data/examples/capped.rb +22 -0
- data/examples/cursor.rb +48 -0
- data/examples/gridfs.rb +88 -0
- data/examples/index_test.rb +126 -0
- data/examples/info.rb +31 -0
- data/examples/queries.rb +70 -0
- data/examples/simple.rb +24 -0
- data/examples/strict.rb +35 -0
- data/examples/types.rb +36 -0
- data/lib/mongo/collection.rb +609 -0
- data/lib/mongo/connection.rb +672 -0
- data/lib/mongo/cursor.rb +403 -0
- data/lib/mongo/db.rb +555 -0
- data/lib/mongo/exceptions.rb +66 -0
- data/lib/mongo/gridfs/chunk.rb +91 -0
- data/lib/mongo/gridfs/grid.rb +79 -0
- data/lib/mongo/gridfs/grid_file_system.rb +101 -0
- data/lib/mongo/gridfs/grid_io.rb +338 -0
- data/lib/mongo/gridfs/grid_store.rb +580 -0
- data/lib/mongo/gridfs.rb +25 -0
- data/lib/mongo/types/binary.rb +52 -0
- data/lib/mongo/types/code.rb +36 -0
- data/lib/mongo/types/dbref.rb +40 -0
- data/lib/mongo/types/min_max_keys.rb +58 -0
- data/lib/mongo/types/objectid.rb +180 -0
- data/lib/mongo/types/regexp_of_holding.rb +45 -0
- data/lib/mongo/util/bson_c.rb +18 -0
- data/lib/mongo/util/bson_ruby.rb +606 -0
- data/lib/mongo/util/byte_buffer.rb +222 -0
- data/lib/mongo/util/conversions.rb +87 -0
- data/lib/mongo/util/ordered_hash.rb +140 -0
- data/lib/mongo/util/server_version.rb +69 -0
- data/lib/mongo/util/support.rb +26 -0
- data/lib/mongo.rb +63 -0
- data/mongo-ruby-driver.gemspec +28 -0
- data/test/auxillary/autoreconnect_test.rb +42 -0
- data/test/binary_test.rb +15 -0
- data/test/bson_test.rb +427 -0
- data/test/byte_buffer_test.rb +81 -0
- data/test/chunk_test.rb +82 -0
- data/test/collection_test.rb +515 -0
- data/test/connection_test.rb +160 -0
- data/test/conversions_test.rb +120 -0
- data/test/cursor_test.rb +379 -0
- data/test/db_api_test.rb +780 -0
- data/test/db_connection_test.rb +16 -0
- data/test/db_test.rb +272 -0
- data/test/grid_file_system_test.rb +210 -0
- data/test/grid_io_test.rb +78 -0
- data/test/grid_store_test.rb +334 -0
- data/test/grid_test.rb +87 -0
- data/test/objectid_test.rb +125 -0
- data/test/ordered_hash_test.rb +172 -0
- data/test/replica/count_test.rb +34 -0
- data/test/replica/insert_test.rb +50 -0
- data/test/replica/pooled_insert_test.rb +54 -0
- data/test/replica/query_test.rb +39 -0
- data/test/slave_connection_test.rb +36 -0
- data/test/test_helper.rb +42 -0
- data/test/threading/test_threading_large_pool.rb +90 -0
- data/test/threading_test.rb +87 -0
- data/test/unit/collection_test.rb +61 -0
- data/test/unit/connection_test.rb +117 -0
- data/test/unit/cursor_test.rb +93 -0
- data/test/unit/db_test.rb +98 -0
- metadata +127 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
# NOTE: assumes Mongo is running
|
4
|
+
class DBConnectionTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include Mongo
|
7
|
+
|
8
|
+
def test_no_exceptions
|
9
|
+
host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
10
|
+
port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
|
11
|
+
db = Connection.new(host, port).db('ruby-mongo-demo')
|
12
|
+
coll = db.collection('test')
|
13
|
+
coll.remove
|
14
|
+
db.error
|
15
|
+
end
|
16
|
+
end
|
data/test/db_test.rb
ADDED
@@ -0,0 +1,272 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
require 'digest/md5'
|
3
|
+
require 'stringio'
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
class TestPKFactory
|
7
|
+
def create_pk(row)
|
8
|
+
row['_id'] ||= Mongo::ObjectID.new
|
9
|
+
row
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# NOTE: assumes Mongo is running
|
14
|
+
class DBTest < Test::Unit::TestCase
|
15
|
+
|
16
|
+
include Mongo
|
17
|
+
|
18
|
+
@@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
19
|
+
@@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
|
20
|
+
@@conn = Connection.new(@@host, @@port)
|
21
|
+
@@db = @@conn.db('ruby-mongo-test')
|
22
|
+
@@users = @@db.collection('system.users')
|
23
|
+
|
24
|
+
def test_close
|
25
|
+
@@conn.close
|
26
|
+
assert !@@conn.connected?
|
27
|
+
begin
|
28
|
+
@@db.collection('test').insert('a' => 1)
|
29
|
+
fail "expected 'NilClass' exception"
|
30
|
+
rescue => ex
|
31
|
+
assert_match /NilClass/, ex.to_s
|
32
|
+
ensure
|
33
|
+
@@db = Connection.new(@@host, @@port).db('ruby-mongo-test')
|
34
|
+
@@users = @@db.collection('system.users')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_logger
|
39
|
+
output = StringIO.new
|
40
|
+
logger = Logger.new(output)
|
41
|
+
logger.level = Logger::DEBUG
|
42
|
+
conn = Connection.new(@host, @port, :logger => logger)
|
43
|
+
assert_equal logger, conn.logger
|
44
|
+
|
45
|
+
conn.logger.debug 'testing'
|
46
|
+
assert output.string.include?('testing')
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_full_coll_name
|
50
|
+
coll = @@db.collection('test')
|
51
|
+
assert_equal 'ruby-mongo-test.test', @@db.full_collection_name(coll.name)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_collection_names
|
55
|
+
@@db.collection("test").insert("foo" => 5)
|
56
|
+
@@db.collection("test.mike").insert("bar" => 0)
|
57
|
+
|
58
|
+
colls = @@db.collection_names()
|
59
|
+
assert colls.include?("test")
|
60
|
+
assert colls.include?("test.mike")
|
61
|
+
colls.each { |name|
|
62
|
+
assert !name.include?("$")
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_collections
|
67
|
+
@@db.collection("test.durran").insert("foo" => 5)
|
68
|
+
@@db.collection("test.les").insert("bar" => 0)
|
69
|
+
|
70
|
+
colls = @@db.collections()
|
71
|
+
assert_not_nil colls.select { |coll| coll.name == "test.durran" }
|
72
|
+
assert_not_nil colls.select { |coll| coll.name == "test.les" }
|
73
|
+
assert_equal [], colls.select { |coll| coll.name == "does_not_exist" }
|
74
|
+
|
75
|
+
assert_kind_of Collection, colls[0]
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_pair
|
79
|
+
@@conn.close
|
80
|
+
@@users = nil
|
81
|
+
@@conn = Connection.new({:left => "this-should-fail", :right => [@@host, @@port]})
|
82
|
+
@@db = @@conn['ruby-mongo-test']
|
83
|
+
assert @@conn.connected?
|
84
|
+
ensure
|
85
|
+
unless @@conn.connected?
|
86
|
+
@@conn = Connection.new(@@host, @@port)
|
87
|
+
@@db = @@conn.db('ruby-mongo-test')
|
88
|
+
end
|
89
|
+
@@users = @@db.collection('system.users')
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_pk_factory
|
93
|
+
db = Connection.new(@@host, @@port).db('ruby-mongo-test', :pk => TestPKFactory.new)
|
94
|
+
coll = db.collection('test')
|
95
|
+
coll.remove
|
96
|
+
|
97
|
+
insert_id = coll.insert('name' => 'Fred', 'age' => 42)
|
98
|
+
# new id gets added to returned object
|
99
|
+
row = coll.find_one({'name' => 'Fred'})
|
100
|
+
oid = row['_id']
|
101
|
+
assert_not_nil oid
|
102
|
+
assert_equal insert_id, oid
|
103
|
+
|
104
|
+
oid = ObjectID.new
|
105
|
+
data = {'_id' => oid, 'name' => 'Barney', 'age' => 41}
|
106
|
+
coll.insert(data)
|
107
|
+
row = coll.find_one({'name' => data['name']})
|
108
|
+
db_oid = row['_id']
|
109
|
+
assert_equal oid, db_oid
|
110
|
+
assert_equal data, row
|
111
|
+
|
112
|
+
coll.remove
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_pk_factory_reset
|
116
|
+
conn = Connection.new(@@host, @@port)
|
117
|
+
db = conn.db('ruby-mongo-test')
|
118
|
+
db.pk_factory = Object.new # first time
|
119
|
+
begin
|
120
|
+
db.pk_factory = Object.new
|
121
|
+
fail "error: expected exception"
|
122
|
+
rescue => ex
|
123
|
+
assert_match /Cannot change/, ex.to_s
|
124
|
+
ensure
|
125
|
+
conn.close
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_authenticate
|
130
|
+
@@db.add_user('spongebob', 'squarepants')
|
131
|
+
assert_raise Mongo::AuthenticationError do
|
132
|
+
assert !@@db.authenticate('nobody', 'nopassword')
|
133
|
+
end
|
134
|
+
assert_raise Mongo::AuthenticationError do
|
135
|
+
assert !@@db.authenticate('spongebob' , 'squareliederhosen')
|
136
|
+
end
|
137
|
+
assert @@db.authenticate('spongebob', 'squarepants')
|
138
|
+
@@db.logout
|
139
|
+
@@db.remove_user('spongebob')
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_authenticate_with_connection_uri
|
143
|
+
@@db.add_user('spongebob', 'squarepants')
|
144
|
+
assert Mongo::Connection.from_uri("mongodb://spongebob:squarepants@localhost/#{@@db.name}")
|
145
|
+
|
146
|
+
assert_raise Mongo::AuthenticationError do
|
147
|
+
Mongo::Connection.from_uri("mongodb://wrong:info@localhost/#{@@db.name}")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_logout
|
152
|
+
assert @@db.logout
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_error
|
156
|
+
@@db.reset_error_history
|
157
|
+
assert_nil @@db.error
|
158
|
+
assert !@@db.error?
|
159
|
+
assert_nil @@db.previous_error
|
160
|
+
|
161
|
+
@@db.send(:command, :forceerror => 1)
|
162
|
+
assert @@db.error?
|
163
|
+
assert_not_nil @@db.error
|
164
|
+
assert_not_nil @@db.previous_error
|
165
|
+
|
166
|
+
@@db.send(:command, :forceerror => 1)
|
167
|
+
assert @@db.error?
|
168
|
+
assert @@db.error
|
169
|
+
prev_error = @@db.previous_error
|
170
|
+
assert_equal 1, prev_error['nPrev']
|
171
|
+
assert_equal prev_error["err"], @@db.error
|
172
|
+
|
173
|
+
@@db.collection('test').find_one
|
174
|
+
assert_nil @@db.error
|
175
|
+
assert !@@db.error?
|
176
|
+
assert @@db.previous_error
|
177
|
+
assert_equal 2, @@db.previous_error['nPrev']
|
178
|
+
|
179
|
+
@@db.reset_error_history
|
180
|
+
assert_nil @@db.error
|
181
|
+
assert !@@db.error?
|
182
|
+
assert_nil @@db.previous_error
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_check_command_response
|
186
|
+
command = {:forceerror => 1}
|
187
|
+
assert_raise OperationFailure do
|
188
|
+
@@db.command(command, false, true)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_last_status
|
193
|
+
@@db['test'].remove
|
194
|
+
@@db['test'].save("i" => 1)
|
195
|
+
|
196
|
+
@@db['test'].update({"i" => 1}, {"$set" => {"i" => 2}})
|
197
|
+
assert @@db.last_status()["updatedExisting"]
|
198
|
+
|
199
|
+
@@db['test'].update({"i" => 1}, {"$set" => {"i" => 500}})
|
200
|
+
assert !@@db.last_status()["updatedExisting"]
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_text_port_number_raises_no_errors
|
204
|
+
conn = Connection.new(@@host, @@port.to_s)
|
205
|
+
db = conn['ruby-mongo-test']
|
206
|
+
assert db.collection('users').remove
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_user_management
|
210
|
+
@@db.add_user("bob", "secret")
|
211
|
+
assert @@db.authenticate("bob", "secret")
|
212
|
+
@@db.logout
|
213
|
+
assert @@db.remove_user("bob")
|
214
|
+
assert_raise Mongo::AuthenticationError do
|
215
|
+
@@db.authenticate("bob", "secret")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_remove_non_existant_user
|
220
|
+
assert !@@db.remove_user("joe")
|
221
|
+
end
|
222
|
+
|
223
|
+
context "database profiling" do
|
224
|
+
setup do
|
225
|
+
@db = @@conn['ruby-mongo-test-admin-functions']
|
226
|
+
@coll = @db['test']
|
227
|
+
@coll.remove
|
228
|
+
@r1 = @coll.insert('a' => 1) # collection not created until it's used
|
229
|
+
end
|
230
|
+
|
231
|
+
should "set default profiling level" do
|
232
|
+
assert_equal :off, @db.profiling_level
|
233
|
+
end
|
234
|
+
|
235
|
+
should "change profiling level" do
|
236
|
+
@db.profiling_level = :slow_only
|
237
|
+
assert_equal :slow_only, @db.profiling_level
|
238
|
+
@db.profiling_level = :off
|
239
|
+
assert_equal :off, @db.profiling_level
|
240
|
+
@db.profiling_level = :all
|
241
|
+
assert_equal :all, @db.profiling_level
|
242
|
+
begin
|
243
|
+
@db.profiling_level = :medium
|
244
|
+
fail "shouldn't be able to do this"
|
245
|
+
rescue
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
should "return profiling info" do
|
250
|
+
@db.profiling_level = :all
|
251
|
+
@coll.find()
|
252
|
+
@db.profiling_level = :off
|
253
|
+
|
254
|
+
info = @db.profiling_info
|
255
|
+
assert_kind_of Array, info
|
256
|
+
assert info.length >= 1
|
257
|
+
first = info.first
|
258
|
+
assert_kind_of String, first['info']
|
259
|
+
assert_kind_of Time, first['ts']
|
260
|
+
assert_kind_of Numeric, first['millis']
|
261
|
+
end
|
262
|
+
|
263
|
+
should "validate collection" do
|
264
|
+
doc = @db.validate_collection(@coll.name)
|
265
|
+
assert_not_nil doc
|
266
|
+
result = doc['result']
|
267
|
+
assert_not_nil result
|
268
|
+
assert_match /firstExtent/, result
|
269
|
+
end
|
270
|
+
|
271
|
+
end
|
272
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
include Mongo
|
3
|
+
|
4
|
+
class GridFileSystemTest < Test::Unit::TestCase
|
5
|
+
context "GridFileSystem:" do
|
6
|
+
setup do
|
7
|
+
@con = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
|
8
|
+
ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT)
|
9
|
+
@db = @con.db('mongo-ruby-test')
|
10
|
+
end
|
11
|
+
|
12
|
+
teardown do
|
13
|
+
@db['fs.files'].remove
|
14
|
+
@db['fs.chunks'].remove
|
15
|
+
end
|
16
|
+
|
17
|
+
context "When reading:" do
|
18
|
+
setup do
|
19
|
+
@chunks_data = "CHUNKS" * 50000
|
20
|
+
@grid = GridFileSystem.new(@db)
|
21
|
+
@grid.open('sample.file', 'w') do |f|
|
22
|
+
f.write @chunks_data
|
23
|
+
end
|
24
|
+
|
25
|
+
@grid = GridFileSystem.new(@db)
|
26
|
+
end
|
27
|
+
|
28
|
+
should "read sample data" do
|
29
|
+
data = @grid.open('sample.file', 'r') { |f| f.read }
|
30
|
+
assert_equal data.length, @chunks_data.length
|
31
|
+
end
|
32
|
+
|
33
|
+
should "return an empty string if length is zero" do
|
34
|
+
data = @grid.open('sample.file', 'r') { |f| f.read(0) }
|
35
|
+
assert_equal '', data
|
36
|
+
end
|
37
|
+
|
38
|
+
should "return the first n bytes" do
|
39
|
+
data = @grid.open('sample.file', 'r') {|f| f.read(288888) }
|
40
|
+
assert_equal 288888, data.length
|
41
|
+
assert_equal @chunks_data[0...288888], data
|
42
|
+
end
|
43
|
+
|
44
|
+
should "return the first n bytes even with an offset" do
|
45
|
+
data = @grid.open('sample.file', 'r') do |f|
|
46
|
+
f.seek(1000)
|
47
|
+
f.read(288888)
|
48
|
+
end
|
49
|
+
assert_equal 288888, data.length
|
50
|
+
assert_equal @chunks_data[1000...289888], data
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "When writing:" do
|
55
|
+
setup do
|
56
|
+
@data = "BYTES" * 50
|
57
|
+
@grid = GridFileSystem.new(@db)
|
58
|
+
@grid.open('sample', 'w') do |f|
|
59
|
+
f.write @data
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
should "read sample data" do
|
64
|
+
data = @grid.open('sample', 'r') { |f| f.read }
|
65
|
+
assert_equal data.length, @data.length
|
66
|
+
end
|
67
|
+
|
68
|
+
should "return the total number of bytes written" do
|
69
|
+
data = 'a' * 300000
|
70
|
+
assert_equal 300000, @grid.open('sample', 'w') {|f| f.write(data) }
|
71
|
+
end
|
72
|
+
|
73
|
+
should "more read sample data" do
|
74
|
+
data = @grid.open('sample', 'r') { |f| f.read }
|
75
|
+
assert_equal data.length, @data.length
|
76
|
+
end
|
77
|
+
|
78
|
+
should "raise exception if not opened for write" do
|
79
|
+
assert_raise GridError do
|
80
|
+
@grid.open('io', 'r') { |f| f.write('hello') }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "and when overwriting the file" do
|
85
|
+
setup do
|
86
|
+
@old = @grid.open('sample', 'r')
|
87
|
+
|
88
|
+
@new_data = "DATA" * 10
|
89
|
+
sleep(2)
|
90
|
+
@grid.open('sample', 'w') do |f|
|
91
|
+
f.write @new_data
|
92
|
+
end
|
93
|
+
|
94
|
+
@new = @grid.open('sample', 'r')
|
95
|
+
end
|
96
|
+
|
97
|
+
should "have a newer upload date" do
|
98
|
+
assert @new.upload_date > @old.upload_date, "New data is not greater than old date."
|
99
|
+
end
|
100
|
+
|
101
|
+
should "have a different files_id" do
|
102
|
+
assert_not_equal @new.files_id, @old.files_id
|
103
|
+
end
|
104
|
+
|
105
|
+
should "contain the new data" do
|
106
|
+
assert_equal @new_data, @new.read, "Expected DATA"
|
107
|
+
end
|
108
|
+
|
109
|
+
context "and on a second overwrite" do
|
110
|
+
setup do
|
111
|
+
sleep(2)
|
112
|
+
new_data = "NEW" * 1000
|
113
|
+
@grid.open('sample', 'w') do |f|
|
114
|
+
f.write new_data
|
115
|
+
end
|
116
|
+
|
117
|
+
@ids = @db['fs.files'].find({'filename' => 'sample'}).map {|file| file['_id']}
|
118
|
+
end
|
119
|
+
|
120
|
+
should "write a third version of the file" do
|
121
|
+
assert_equal 3, @db['fs.files'].find({'filename' => 'sample'}).count
|
122
|
+
assert_equal 3, @db['fs.chunks'].find({'files_id' => {'$in' => @ids}}).count
|
123
|
+
end
|
124
|
+
|
125
|
+
should "remove all versions and their data on delete" do
|
126
|
+
@grid.delete('sample')
|
127
|
+
assert_equal 0, @db['fs.files'].find({'filename' => 'sample'}).count
|
128
|
+
assert_equal 0, @db['fs.chunks'].find({'files_id' => {'$in' => @ids}}).count
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "When writing chunks:" do
|
135
|
+
setup do
|
136
|
+
data = "B" * 50000
|
137
|
+
@grid = GridFileSystem.new(@db)
|
138
|
+
@grid.open('sample', 'w', :chunk_size => 1000) do |f|
|
139
|
+
f.write data
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
should "write the correct number of chunks" do
|
144
|
+
file = @db['fs.files'].find_one({:filename => 'sample'})
|
145
|
+
chunks = @db['fs.chunks'].find({'files_id' => file['_id']}).to_a
|
146
|
+
assert_equal 50, chunks.length
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "Positioning:" do
|
151
|
+
setup do
|
152
|
+
data = 'hello, world' + '1' * 5000 + 'goodbye!' + '2' * 1000 + '!'
|
153
|
+
@grid = GridFileSystem.new(@db)
|
154
|
+
@grid.open('hello', 'w', :chunk_size => 1000) do |f|
|
155
|
+
f.write data
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
should "seek within chunks" do
|
160
|
+
@grid.open('hello', 'r') do |f|
|
161
|
+
f.seek(0)
|
162
|
+
assert_equal 'h', f.read(1)
|
163
|
+
f.seek(7)
|
164
|
+
assert_equal 'w', f.read(1)
|
165
|
+
f.seek(4)
|
166
|
+
assert_equal 'o', f.read(1)
|
167
|
+
f.seek(0)
|
168
|
+
f.seek(7, IO::SEEK_CUR)
|
169
|
+
assert_equal 'w', f.read(1)
|
170
|
+
f.seek(-2, IO::SEEK_CUR)
|
171
|
+
assert_equal ' ', f.read(1)
|
172
|
+
f.seek(-4, IO::SEEK_CUR)
|
173
|
+
assert_equal 'l', f.read(1)
|
174
|
+
f.seek(3, IO::SEEK_CUR)
|
175
|
+
assert_equal 'w', f.read(1)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
should "seek between chunks" do
|
180
|
+
@grid.open('hello', 'r') do |f|
|
181
|
+
f.seek(1000)
|
182
|
+
assert_equal '11111', f.read(5)
|
183
|
+
|
184
|
+
f.seek(5009)
|
185
|
+
assert_equal '111goodbye!222', f.read(14)
|
186
|
+
|
187
|
+
f.seek(-1, IO::SEEK_END)
|
188
|
+
assert_equal '!', f.read(1)
|
189
|
+
f.seek(-6, IO::SEEK_END)
|
190
|
+
assert_equal '2', f.read(1)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
should "tell the current position" do
|
195
|
+
@grid.open('hello', 'r') do |f|
|
196
|
+
assert_equal 0, f.tell
|
197
|
+
|
198
|
+
f.seek(999)
|
199
|
+
assert_equal 999, f.tell
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
should "seek only in read mode" do
|
204
|
+
assert_raise GridError do
|
205
|
+
@grid.open('hello', 'w') {|f| f.seek(0) }
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
include Mongo
|
3
|
+
|
4
|
+
class GridIOTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "GridIO" do
|
7
|
+
setup do
|
8
|
+
@db ||= Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
|
9
|
+
ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT).db('ruby-mongo-test')
|
10
|
+
@files = @db.collection('fs.files')
|
11
|
+
@chunks = @db.collection('fs.chunks')
|
12
|
+
@chunks.create_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]])
|
13
|
+
end
|
14
|
+
|
15
|
+
teardown do
|
16
|
+
@files.remove
|
17
|
+
@chunks.remove
|
18
|
+
end
|
19
|
+
|
20
|
+
context "Options" do
|
21
|
+
setup do
|
22
|
+
@filename = 'test'
|
23
|
+
@mode = 'w'
|
24
|
+
end
|
25
|
+
|
26
|
+
should "set default 256k chunk size" do
|
27
|
+
file = GridIO.new(@files, @chunks, @filename, @mode)
|
28
|
+
assert_equal 256 * 1024, file.chunk_size
|
29
|
+
end
|
30
|
+
|
31
|
+
should "set chunk size" do
|
32
|
+
file = GridIO.new(@files, @chunks, @filename, @mode, :chunk_size => 1000)
|
33
|
+
assert_equal 1000, file.chunk_size
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "Grid MD5 check" do
|
38
|
+
should "run in safe mode" do
|
39
|
+
file = GridIO.new(@files, @chunks, 'smallfile', 'w', :safe => true)
|
40
|
+
file.write("DATA" * 100)
|
41
|
+
assert file.close
|
42
|
+
assert_equal file.server_md5, file.client_md5
|
43
|
+
end
|
44
|
+
|
45
|
+
should "validate with a large file" do
|
46
|
+
io = File.open(File.join(File.dirname(__FILE__), 'data', 'sample_file.pdf'), 'r')
|
47
|
+
file = GridIO.new(@files, @chunks, 'bigfile', 'w', :safe => true)
|
48
|
+
file.write(io)
|
49
|
+
assert file.close
|
50
|
+
assert_equal file.server_md5, file.client_md5
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "Content types" do
|
55
|
+
|
56
|
+
if defined?(MIME)
|
57
|
+
should "determine common content types from the extension" do
|
58
|
+
file = GridIO.new(@files, @chunks, 'sample.pdf', 'w')
|
59
|
+
assert_equal 'application/pdf', file.content_type
|
60
|
+
|
61
|
+
file = GridIO.new(@files, @chunks, 'sample.txt', 'w')
|
62
|
+
assert_equal 'text/plain', file.content_type
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
should "default to binary/octet-stream when type is unknown" do
|
67
|
+
file = GridIO.new(@files, @chunks, 'sample.l33t', 'w')
|
68
|
+
assert_equal 'binary/octet-stream', file.content_type
|
69
|
+
end
|
70
|
+
|
71
|
+
should "use any provided content type by default" do
|
72
|
+
file = GridIO.new(@files, @chunks, 'sample.l33t', 'w', :content_type => 'image/jpg')
|
73
|
+
assert_equal 'image/jpg', file.content_type
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|