mongo 0.18.3 → 0.19
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +41 -50
- data/Rakefile +14 -4
- data/examples/gridfs.rb +25 -70
- data/lib/mongo.rb +4 -2
- data/lib/mongo/collection.rb +70 -89
- data/lib/mongo/connection.rb +203 -43
- data/lib/mongo/cursor.rb +7 -7
- data/lib/mongo/db.rb +61 -18
- data/lib/mongo/exceptions.rb +7 -1
- data/lib/mongo/gridfs.rb +8 -1
- data/lib/mongo/gridfs/chunk.rb +2 -1
- data/lib/mongo/gridfs/grid.rb +90 -0
- data/lib/mongo/gridfs/grid_file_system.rb +113 -0
- data/lib/mongo/gridfs/grid_io.rb +339 -0
- data/lib/mongo/gridfs/grid_store.rb +43 -18
- data/lib/mongo/types/binary.rb +5 -1
- data/lib/mongo/types/code.rb +1 -1
- data/lib/mongo/types/dbref.rb +3 -1
- data/lib/mongo/types/min_max_keys.rb +1 -1
- data/lib/mongo/types/objectid.rb +16 -55
- data/lib/mongo/types/regexp_of_holding.rb +1 -1
- data/lib/mongo/util/bson_c.rb +2 -2
- data/lib/mongo/util/bson_ruby.rb +22 -11
- data/lib/mongo/util/byte_buffer.rb +1 -1
- data/lib/mongo/util/conversions.rb +1 -1
- data/lib/mongo/util/ordered_hash.rb +6 -1
- data/lib/mongo/util/server_version.rb +1 -1
- data/lib/mongo/util/support.rb +1 -1
- data/mongo-ruby-driver.gemspec +1 -1
- data/test/auxillary/authentication_test.rb +68 -0
- data/test/auxillary/autoreconnect_test.rb +41 -0
- data/test/binary_test.rb +15 -0
- data/test/{test_bson.rb → bson_test.rb} +63 -6
- data/test/{test_byte_buffer.rb → byte_buffer_test.rb} +0 -0
- data/test/{test_chunk.rb → chunk_test.rb} +0 -0
- data/test/{test_collection.rb → collection_test.rb} +35 -39
- data/test/{test_connection.rb → connection_test.rb} +33 -3
- data/test/{test_conversions.rb → conversions_test.rb} +0 -0
- data/test/{test_cursor.rb → cursor_test.rb} +0 -7
- data/test/{test_db_api.rb → db_api_test.rb} +3 -6
- data/test/{test_db_connection.rb → db_connection_test.rb} +0 -0
- data/test/{test_db.rb → db_test.rb} +33 -15
- data/test/grid_file_system_test.rb +210 -0
- data/test/grid_io_test.rb +78 -0
- data/test/{test_grid_store.rb → grid_store_test.rb} +33 -2
- data/test/grid_test.rb +87 -0
- data/test/{test_objectid.rb → objectid_test.rb} +2 -33
- data/test/{test_ordered_hash.rb → ordered_hash_test.rb} +4 -0
- data/test/{test_slave_connection.rb → slave_connection_test.rb} +0 -0
- data/test/test_helper.rb +2 -2
- data/test/{test_threading.rb → threading_test.rb} +0 -0
- data/test/unit/collection_test.rb +12 -3
- data/test/unit/connection_test.rb +85 -24
- data/test/unit/cursor_test.rb +1 -2
- data/test/unit/db_test.rb +70 -69
- metadata +27 -23
- data/bin/objectid_benchmark.rb +0 -23
- data/bin/perf.rb +0 -30
- data/lib/mongo/admin.rb +0 -95
- data/lib/mongo/util/xml_to_ruby.rb +0 -112
- data/test/test_admin.rb +0 -67
- data/test/test_round_trip.rb +0 -114
@@ -539,22 +539,19 @@ class DBAPITest < Test::Unit::TestCase
|
|
539
539
|
test = @@db.collection("test")
|
540
540
|
|
541
541
|
assert_equal [], test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")
|
542
|
-
assert_equal [], test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }"
|
542
|
+
assert_equal [], test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")
|
543
543
|
|
544
544
|
test.insert("a" => 2)
|
545
545
|
test.insert("b" => 5)
|
546
546
|
test.insert("a" => 1)
|
547
547
|
|
548
548
|
assert_equal 3, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
|
549
|
-
assert_equal 3, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }"
|
549
|
+
assert_equal 3, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
|
550
|
+
assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
|
550
551
|
assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
|
551
|
-
assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true)[0]["count"]
|
552
552
|
|
553
553
|
finalize = "function (obj) { obj.f = obj.count - 1; }"
|
554
554
|
assert_equal 2, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true, finalize)[0]["f"]
|
555
|
-
assert_raise OperationFailure do
|
556
|
-
test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }", false, finalize)[0]["f"]
|
557
|
-
end
|
558
555
|
|
559
556
|
test.insert("a" => 2, "b" => 3)
|
560
557
|
expected = [{"a" => 2, "count" => 2},
|
File without changes
|
@@ -21,18 +21,6 @@ class DBTest < Test::Unit::TestCase
|
|
21
21
|
@@db = @@conn.db('ruby-mongo-test')
|
22
22
|
@@users = @@db.collection('system.users')
|
23
23
|
|
24
|
-
def setup
|
25
|
-
@spongebob = 'spongebob'
|
26
|
-
@spongebob_password = 'squarepants'
|
27
|
-
@@users.remove
|
28
|
-
@@users.insert(:user => @spongebob, :pwd => @@db.send(:hash_password, @spongebob, @spongebob_password))
|
29
|
-
end
|
30
|
-
|
31
|
-
def teardown
|
32
|
-
@@users.remove if @@users
|
33
|
-
@@db.error
|
34
|
-
end
|
35
|
-
|
36
24
|
def test_close
|
37
25
|
@@conn.close
|
38
26
|
assert !@@conn.connected?
|
@@ -139,9 +127,25 @@ class DBTest < Test::Unit::TestCase
|
|
139
127
|
end
|
140
128
|
|
141
129
|
def test_authenticate
|
142
|
-
|
143
|
-
|
144
|
-
|
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
|
145
149
|
end
|
146
150
|
|
147
151
|
def test_logout
|
@@ -202,6 +206,20 @@ class DBTest < Test::Unit::TestCase
|
|
202
206
|
assert db.collection('users').remove
|
203
207
|
end
|
204
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
|
+
|
205
223
|
context "database profiling" do
|
206
224
|
setup do
|
207
225
|
@db = @@conn['ruby-mongo-test-admin-functions']
|
@@ -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
|
@@ -130,7 +130,22 @@ class GridStoreTest < Test::Unit::TestCase
|
|
130
130
|
}
|
131
131
|
|
132
132
|
assert_equal 3, @@chunks.count
|
133
|
-
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_binary
|
136
|
+
file = File.open(File.join(File.dirname(__FILE__), 'data', 'data.tar.gz'), 'r')
|
137
|
+
GridStore.open(@@db, 'zip', 'w') do |f|
|
138
|
+
f.write(file.read)
|
139
|
+
end
|
140
|
+
|
141
|
+
file.rewind
|
142
|
+
data = file.read
|
143
|
+
if data.respond_to?(:force_encoding)
|
144
|
+
data.force_encoding(:binary)
|
145
|
+
end
|
146
|
+
GridStore.open(@@db, 'zip', 'r') do |f|
|
147
|
+
assert_equal data.length, f.read.length
|
148
|
+
end
|
134
149
|
end
|
135
150
|
|
136
151
|
def test_puts_and_readlines
|
@@ -151,7 +166,23 @@ class GridStoreTest < Test::Unit::TestCase
|
|
151
166
|
assert_equal 0, @@files.count
|
152
167
|
assert_equal 0, @@chunks.count
|
153
168
|
end
|
154
|
-
|
169
|
+
|
170
|
+
def test_unlink_alternate_root_collection
|
171
|
+
GridStore.default_root_collection = 'gridfs'
|
172
|
+
GridStore.open(@@db, 'foobar', 'w') do |f|
|
173
|
+
f.puts "Hello"
|
174
|
+
end
|
175
|
+
assert GridStore.exist?(@@db, 'foobar')
|
176
|
+
|
177
|
+
GridStore.default_root_collection = 'fs'
|
178
|
+
GridStore.unlink(@@db, 'foobar')
|
179
|
+
assert !GridStore.exist?(@@db, 'foobar')
|
180
|
+
|
181
|
+
GridStore.default_root_collection = 'gridfs'
|
182
|
+
GridStore.unlink(@@db, 'foobar')
|
183
|
+
assert !GridStore.exist?(@@db, 'foobar')
|
184
|
+
end
|
185
|
+
|
155
186
|
def test_mv
|
156
187
|
assert_equal 1, @@files.count
|
157
188
|
assert_equal 1, @@chunks.count
|
data/test/grid_test.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
include Mongo
|
3
|
+
|
4
|
+
class GridTest < Test::Unit::TestCase
|
5
|
+
context "Tests:" do
|
6
|
+
setup do
|
7
|
+
@db ||= Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
|
8
|
+
ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT).db('ruby-mongo-test')
|
9
|
+
@files = @db.collection('test-fs.files')
|
10
|
+
@chunks = @db.collection('test-fs.chunks')
|
11
|
+
end
|
12
|
+
|
13
|
+
teardown do
|
14
|
+
@files.remove
|
15
|
+
@chunks.remove
|
16
|
+
end
|
17
|
+
|
18
|
+
context "A basic grid-stored file" do
|
19
|
+
setup do
|
20
|
+
@data = "GRIDDATA" * 50000
|
21
|
+
@grid = Grid.new(@db, 'test-fs')
|
22
|
+
@id = @grid.put(@data, 'sample', :metadata => {'app' => 'photos'})
|
23
|
+
end
|
24
|
+
|
25
|
+
should "retrieve the stored data" do
|
26
|
+
data = @grid.get(@id).data
|
27
|
+
assert_equal @data, data
|
28
|
+
end
|
29
|
+
|
30
|
+
should "store the filename" do
|
31
|
+
file = @grid.get(@id)
|
32
|
+
assert_equal 'sample', file.filename
|
33
|
+
end
|
34
|
+
|
35
|
+
should "store any relevant metadata" do
|
36
|
+
file = @grid.get(@id)
|
37
|
+
assert_equal 'photos', file.metadata['app']
|
38
|
+
end
|
39
|
+
|
40
|
+
should "delete the file and any chunks" do
|
41
|
+
@grid.delete(@id)
|
42
|
+
assert_raise GridError do
|
43
|
+
@grid.get(@id)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "Streaming: " do || {}
|
49
|
+
setup do
|
50
|
+
def read_and_write_stream(filename, read_length, opts={})
|
51
|
+
io = File.open(File.join(File.dirname(__FILE__), 'data', filename), 'r')
|
52
|
+
id = @grid.put(io, filename + read_length.to_s, opts)
|
53
|
+
file = @grid.get(id)
|
54
|
+
io.rewind
|
55
|
+
data = io.read
|
56
|
+
if data.respond_to?(:force_encoding)
|
57
|
+
data.force_encoding(:binary)
|
58
|
+
end
|
59
|
+
read_data = ""
|
60
|
+
while(chunk = file.read(read_length))
|
61
|
+
read_data << chunk
|
62
|
+
end
|
63
|
+
assert_equal data.length, read_data.length
|
64
|
+
assert_equal data, read_data, "Unequal!"
|
65
|
+
end
|
66
|
+
|
67
|
+
@grid = Grid.new(@db, 'test-fs')
|
68
|
+
end
|
69
|
+
|
70
|
+
should "put and get a small io object with a small chunk size" do
|
71
|
+
read_and_write_stream('small_data.txt', 1, :chunk_size => 2)
|
72
|
+
end
|
73
|
+
|
74
|
+
should "put and get a small io object" do
|
75
|
+
read_and_write_stream('small_data.txt', 1)
|
76
|
+
end
|
77
|
+
|
78
|
+
should "put and get a large io object when reading smaller than the chunk size" do
|
79
|
+
read_and_write_stream('sample_file.pdf', 256 * 1024)
|
80
|
+
end
|
81
|
+
|
82
|
+
should "put and get a large io object when reading larger than the chunk size" do
|
83
|
+
read_and_write_stream('sample_file.pdf', 300 * 1024)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|