6 class TestMogileFS__MogileFS < TestMogileFS
10 @klass = MogileFS::MogileFS
15 assert_equal 'test', @client.domain
17 assert_raises ArgumentError do
18 MogileFS::MogileFS.new :hosts => ['kaa:6001']
22 def test_get_file_data_http
24 svr = Proc.new do |serv, port|
25 client, client_addr = serv.accept
27 readed = client.recv(4096, 0)
29 %r{\AGET /dev[12]/0/000/000/0000000062\.fid HTTP/1.[01]\r\n\r\n\Z})
30 client.send("HTTP/1.0 200 OK\r\nContent-Length: 5\r\n\r\ndata!", 0)
34 t1 = TempServer.new(svr)
35 t2 = TempServer.new(svr)
36 path1 = "http://127.0.0.1:#{t1.port}/dev1/0/000/000/0000000062.fid"
37 path2 = "http://127.0.0.1:#{t2.port}/dev2/0/000/000/0000000062.fid"
39 @backend.get_paths = { 'paths' => 2, 'path1' => path1, 'path2' => path2 }
41 assert_equal 'data!', @client.get_file_data('key')
42 assert_equal 1, accept_nr
44 TempServer.destroy_all!
47 def test_get_file_data_http_block
48 tmpfp = Tempfile.new('test_mogilefs.open_data')
50 chunk_size = 1024 * 1024
51 expect_size = nr * chunk_size
52 header = "HTTP/1.0 200 OK\r\n" \
53 "Content-Length: #{expect_size}\r\n\r\n"
54 assert_equal header.size, tmpfp.syswrite(header)
55 nr.times { assert_equal chunk_size, tmpfp.syswrite(' ' * chunk_size) }
56 assert_equal expect_size + header.size, File.size(tmpfp.path)
60 svr = Proc.new do |serv, port|
61 client, client_addr = serv.accept
64 readed = client.recv(4096, 0)
66 %r{\AGET /dev[12]/0/000/000/0000000062\.fid HTTP/1.[01]\r\n\r\n\Z})
67 sysrwloop(tmpfp, client)
70 t1 = TempServer.new(svr)
71 t2 = TempServer.new(svr)
72 path1 = "http://127.0.0.1:#{t1.port}/dev1/0/000/000/0000000062.fid"
73 path2 = "http://127.0.0.1:#{t2.port}/dev2/0/000/000/0000000062.fid"
75 @backend.get_paths = { 'paths' => 2, 'path1' => path1, 'path2' => path2 }
77 data = Tempfile.new('test_mogilefs.dest_data')
79 @client.get_file_data('key') do |fp|
83 fp.sysread(16384, buf)
86 assert_equal read_nr, data.syswrite(buf), "partial write"
92 assert_equal expect_size, nr, "size mismatch"
93 assert_equal 1, accept_nr
97 path1 = 'http://rur-1/dev1/0/000/000/0000000062.fid'
98 path2 = 'http://rur-2/dev2/0/000/000/0000000062.fid'
100 @backend.get_paths = { 'paths' => 2, 'path1' => path1, 'path2' => path2 }
102 expected = [ path1, path2 ]
104 assert_equal expected, @client.get_paths('key').sort
107 def test_get_paths_unknown_key
108 @backend.get_paths = ['unknown_key', '']
110 assert_raises MogileFS::Backend::UnknownKeyError do
111 assert_equal nil, @client.get_paths('key')
115 def test_delete_existing
116 @backend.delete = { }
117 assert_nothing_raised do
118 @client.delete 'no_such_key'
122 def test_delete_nonexisting
123 @backend.delete = 'unknown_key', ''
124 assert_raises MogileFS::Backend::UnknownKeyError do
125 @client.delete('no_such_key')
129 def test_delete_readonly
130 @client.readonly = true
131 assert_raises MogileFS::ReadOnlyError do
132 @client.delete 'no_such_key'
137 @backend.list_keys = { 'key_count' => 2, 'next_after' => 'new_key_2',
138 'key_1' => 'new_key_1', 'key_2' => 'new_key_2' }
139 @backend.list_keys = { 'key_count' => 2, 'next_after' => 'new_key_4',
140 'key_1' => 'new_key_3', 'key_2' => 'new_key_4' }
141 @backend.list_keys = { 'key_count' => 0, 'next_after' => 'new_key_4' }
143 @client.each_key 'new' do |key|
147 assert_equal %w[new_key_1 new_key_2 new_key_3 new_key_4], keys
151 @backend.list_keys = { 'key_count' => 2, 'next_after' => 'new_key_2',
152 'key_1' => 'new_key_1', 'key_2' => 'new_key_2' }
154 keys, next_after = @client.list_keys 'new'
155 assert_equal ['new_key_1', 'new_key_2'], keys.sort
156 assert_equal 'new_key_2', next_after
159 def test_list_keys_block
160 @backend.list_keys = { 'key_count' => 2, 'next_after' => 'new_key_2',
161 'key_1' => 'new_key_1', 'key_2' => 'new_key_2' }
162 http_resp = "HTTP/1.0 200 OK\r\nContent-Length: %u\r\n"
163 srv = Proc.new do |serv, port, size|
164 client, client_addr = serv.accept
166 readed = client.readpartial(4096)
167 assert %r{\AHEAD } =~ readed
168 client.send(http_resp % size, 0)
171 t1 = TempServer.new(Proc.new { |serv, port| srv.call(serv, port, 5) })
172 t2 = TempServer.new(Proc.new { |serv, port| srv.call(serv, port, 5) })
173 t3 = TempServer.new(Proc.new { |serv, port| srv.call(serv, port, 10) })
174 @backend.get_paths = { 'paths' => 2,
175 'path1' => "http://127.0.0.1:#{t1.port}/",
176 'path2' => "http://127.0.0.1:#{t2.port}/" }
177 @backend.get_paths = { 'paths' => 1,
178 'path1' => "http://127.0.0.1:#{t3.port}/" }
181 keys, next_after = @client.list_keys('new') do |key,length,devcount|
182 res << [ key, length, devcount ]
185 expect_res = [ [ 'new_key_1', 5, 2 ], [ 'new_key_2', 10, 1 ] ]
186 assert_equal expect_res, res
187 assert_equal ['new_key_1', 'new_key_2'], keys.sort
188 assert_equal 'new_key_2', next_after
190 TempServer.destroy_all!
193 def test_new_file_http
194 @client.readonly = true
195 assert_raises MogileFS::ReadOnlyError do
196 @client.new_file 'new_key', 'test'
200 def test_new_file_readonly
201 @client.readonly = true
202 assert_raises MogileFS::ReadOnlyError do
203 @client.new_file 'new_key', 'test'
209 t = TempServer.new(Proc.new do |serv,port|
210 client, client_addr = serv.accept
212 readed = client.recv(4096, 0) rescue nil
213 assert_equal "HEAD /path HTTP/1.0\r\n\r\n", readed
214 client.send("HTTP/1.0 200 OK\r\nContent-Length: 5\r\n\r\n", 0)
219 path = "http://127.0.0.1:#{t.port}/path"
220 @backend.get_paths = { 'paths' => 1, 'path1' => path }
222 assert_equal 5, @client.size('key')
223 assert_equal 1, accept_nr
226 def test_store_content_http
228 expected = "PUT /path HTTP/1.0\r\nContent-Length: 4\r\n\r\ndata"
230 t = TempServer.new(Proc.new do |serv, accept|
231 client, client_addr = serv.accept
233 received = client.recv(4096, 0)
234 client.send("HTTP/1.0 200 OK\r\n\r\n", 0)
238 @backend.create_open = {
240 'path' => "http://127.0.0.1:#{t.port}/path",
243 @client.store_content 'new_key', 'test', 'data'
245 assert_equal expected, received
247 TempServer.destroy_all!
250 def test_store_content_multi_dest_failover
251 received1 = received2 = nil
252 expected = "PUT /path HTTP/1.0\r\nContent-Length: 4\r\n\r\ndata"
254 t1 = TempServer.new(Proc.new do |serv, accept|
255 client, client_addr = serv.accept
257 received1 = client.recv(4096, 0)
258 client.send("HTTP/1.0 500 Internal Server Error\r\n\r\n", 0)
262 t2 = TempServer.new(Proc.new do |serv, accept|
263 client, client_addr = serv.accept
265 received2 = client.recv(4096, 0)
266 client.send("HTTP/1.0 200 OK\r\n\r\n", 0)
270 @backend.create_open = {
273 'path_1' => "http://127.0.0.1:#{t1.port}/path",
275 'path_2' => "http://127.0.0.1:#{t2.port}/path",
278 @client.store_content 'new_key', 'test', 'data'
279 assert_equal expected, received1
280 assert_equal expected, received2
282 TempServer.destroy_all!
285 def test_store_content_http_fail
286 t = TempServer.new(Proc.new do |serv, accept|
287 client, client_addr = serv.accept
290 client.send("HTTP/1.0 500 Internal Server Error\r\n\r\n", 0)
294 @backend.create_open = {
296 'path' => "http://127.0.0.1:#{t.port}/path",
299 assert_raises MogileFS::HTTPFile::BadResponseError do
300 @client.store_content 'new_key', 'test', 'data'
304 def test_store_content_http_empty
306 expected = "PUT /path HTTP/1.0\r\nContent-Length: 0\r\n\r\n"
307 t = TempServer.new(Proc.new do |serv, accept|
308 client, client_addr = serv.accept
310 received = client.recv(4096, 0)
311 client.send("HTTP/1.0 200 OK\r\n\r\n", 0)
315 @backend.create_open = {
317 'path' => "http://127.0.0.1:#{t.port}/path",
320 @client.store_content 'new_key', 'test', ''
321 assert_equal expected, received
324 def test_store_content_nfs
325 @backend.create_open = {
330 assert_raises MogileFS::UnsupportedPathError do
331 @client.store_content 'new_key', 'test', 'data'
335 def test_new_file_http_large
336 expect = Tempfile.new('test_mogilefs.expect')
337 to_put = Tempfile.new('test_mogilefs.to_put')
338 received = Tempfile.new('test_mogilefs.received')
341 chunk_size = 1024 * 1024
342 expect_size = nr * chunk_size
344 header = "PUT /path HTTP/1.0\r\n" \
345 "Content-Length: #{expect_size}\r\n\r\n"
346 assert_equal header.size, expect.syswrite(header)
348 assert_equal chunk_size, expect.syswrite(' ' * chunk_size)
349 assert_equal chunk_size, to_put.syswrite(' ' * chunk_size)
351 assert_equal expect_size + header.size, expect.stat.size
352 assert_equal expect_size, to_put.stat.size
355 t = TempServer.new(Proc.new do |serv, accept|
356 client, client_addr = serv.accept
359 buf = client.readpartial(8192) or break
360 break if buf.length == 0
361 assert_equal buf.length, received.syswrite(buf)
363 break if readed >= expect.stat.size
365 client.send("HTTP/1.0 200 OK\r\n\r\n", 0)
369 @backend.create_open = {
371 'path' => "http://127.0.0.1:#{t.port}/path",
374 @client.store_file('new_key', 'test', to_put.path)
375 assert_equal expect.stat.size, readed
377 ENV['PATH'].split(/:/).each do |path|
378 cmp_bin = "#{path}/cmp"
379 File.executable?(cmp_bin) or next
380 # puts "running #{cmp_bin} #{expect.path} #{received.path}"
381 assert( system(cmp_bin, expect.path, received.path) )
386 TempServer.destroy_all!
389 def test_store_content_readonly
390 @client.readonly = true
392 assert_raises MogileFS::ReadOnlyError do
393 @client.store_content 'new_key', 'test', nil
397 def test_store_file_readonly
398 @client.readonly = true
399 assert_raises MogileFS::ReadOnlyError do
400 @client.store_file 'new_key', 'test', nil
404 def test_rename_existing
407 assert_nil @client.rename('from_key', 'to_key')
410 def test_rename_nonexisting
411 @backend.rename = 'unknown_key', ''
413 assert_raises MogileFS::Backend::UnknownKeyError do
414 @client.rename('from_key', 'to_key')
418 def test_rename_no_key
419 @backend.rename = 'no_key', 'no_key'
421 e = assert_raises MogileFS::Backend::NoKeyError do
422 @client.rename 'new_key', 'test'
425 assert_equal 'no_key', e.message
428 def test_rename_readonly
429 @client.readonly = true
431 e = assert_raises MogileFS::ReadOnlyError do
432 @client.rename 'new_key', 'test'
435 assert_equal 'readonly mogilefs', e.message
440 assert_nothing_raised do
441 assert_equal({}, @client.sleep(2))
447 # tested with 1000, though it takes a while
449 ENV['NR_CHUNKS'] ? ENV['NR_CHUNKS'].to_i : 10