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
23 tmp = Tempfile.new('accept')
24 accept = File.open(tmp.path, "ab")
25 svr = Proc.new do |serv, port|
26 client, client_addr = serv.accept
28 readed = client.recv(4096, 0)
30 %r{\AGET /dev[12]/0/000/000/0000000062\.fid HTTP/1.[01]\r\n\r\n\Z})
32 client.send("HTTP/1.0 200 OK\r\nContent-Length: 5\r\n\r\ndata!", 0)
35 t1 = TempServer.new(svr)
36 t2 = TempServer.new(svr)
37 path1 = "http://127.0.0.1:#{t1.port}/dev1/0/000/000/0000000062.fid"
38 path2 = "http://127.0.0.1:#{t2.port}/dev2/0/000/000/0000000062.fid"
40 @backend.get_paths = { 'paths' => 2, 'path1' => path1, 'path2' => path2 }
42 assert_equal 'data!', @client.get_file_data('key')
43 assert_equal 1, accept.stat.size
45 TempServer.destroy_all!
48 def test_get_file_data_http_not_found_failover
49 tmp = Tempfile.new('accept')
50 accept = File.open(tmp.path, 'ab')
51 svr1 = Proc.new do |serv, port|
52 client, client_addr = serv.accept
54 readed = client.recv(4096, 0)
56 %r{\AGET /dev1/0/000/000/0000000062\.fid HTTP/1.[01]\r\n\r\n\Z})
58 client.send("HTTP/1.0 404 Not Found\r\n\r\ndata!", 0)
62 svr2 = Proc.new do |serv, port|
63 client, client_addr = serv.accept
65 readed = client.recv(4096, 0)
67 %r{\AGET /dev2/0/000/000/0000000062\.fid HTTP/1.[01]\r\n\r\n\Z})
69 client.send("HTTP/1.0 200 OK\r\nContent-Length: 5\r\n\r\ndata!", 0)
73 t1 = TempServer.new(svr1)
74 t2 = TempServer.new(svr2)
75 path1 = "http://127.0.0.1:#{t1.port}/dev1/0/000/000/0000000062.fid"
76 path2 = "http://127.0.0.1:#{t2.port}/dev2/0/000/000/0000000062.fid"
77 @backend.get_paths = { 'paths' => 2, 'path1' => path1, 'path2' => path2 }
79 assert_equal 'data!', @client.get_file_data('key')
80 assert_equal 2, accept.stat.size
82 TempServer.destroy_all!
85 def test_get_file_data_http_block
86 tmpfp = Tempfile.new('test_mogilefs.open_data')
88 chunk_size = 1024 * 1024
89 expect_size = nr * chunk_size
90 header = "HTTP/1.0 200 OK\r\n" \
91 "Content-Length: #{expect_size}\r\n\r\n"
92 assert_equal header.size, tmpfp.syswrite(header)
93 nr.times { assert_equal chunk_size, tmpfp.syswrite(' ' * chunk_size) }
94 assert_equal expect_size + header.size, File.size(tmpfp.path)
97 accept = Tempfile.new('accept')
98 svr = Proc.new do |serv, port|
99 client, client_addr = serv.accept
102 readed = client.recv(4096, 0)
104 %r{\AGET /dev[12]/0/000/000/0000000062\.fid HTTP/1.[01]\r\n\r\n\Z})
105 sysrwloop(tmpfp, client)
109 t1 = TempServer.new(svr)
110 t2 = TempServer.new(svr)
111 path1 = "http://127.0.0.1:#{t1.port}/dev1/0/000/000/0000000062.fid"
112 path2 = "http://127.0.0.1:#{t2.port}/dev2/0/000/000/0000000062.fid"
114 @backend.get_paths = { 'paths' => 2, 'path1' => path1, 'path2' => path2 }
116 data = Tempfile.new('test_mogilefs.dest_data')
118 @client.get_file_data('key') do |fp|
122 fp.sysread(16384, buf)
125 assert_equal read_nr, data.syswrite(buf), "partial write"
133 assert_equal expect_size, nr, "size mismatch"
134 assert_equal 1, accept.stat.size
138 path1 = 'http://rur-1/dev1/0/000/000/0000000062.fid'
139 path2 = 'http://rur-2/dev2/0/000/000/0000000062.fid'
141 @backend.get_paths = { 'paths' => 2, 'path1' => path1, 'path2' => path2 }
143 expected = [ path1, path2 ]
145 assert_equal expected, @client.get_paths('key').sort
149 path1 = 'http://rur-1/dev1/0/000/000/0000000062.fid'
150 path2 = 'http://rur-2/dev2/0/000/000/0000000062.fid'
152 @backend.get_paths = { 'paths' => 2, 'path1' => path1, 'path2' => path2 }
154 expected = [ URI.parse(path1), URI.parse(path2) ]
156 assert_equal expected, @client.get_uris('key')
160 def test_get_paths_unknown_key
161 @backend.get_paths = ['unknown_key', '']
163 assert_raises MogileFS::Backend::UnknownKeyError do
164 assert_equal nil, @client.get_paths('key')
168 def test_delete_existing
169 @backend.delete = { }
170 assert_nothing_raised do
171 @client.delete 'no_such_key'
175 def test_delete_nonexisting
176 @backend.delete = 'unknown_key', ''
177 assert_raises MogileFS::Backend::UnknownKeyError do
178 @client.delete('no_such_key')
182 def test_delete_readonly
183 @client.readonly = true
184 assert_raises MogileFS::ReadOnlyError do
185 @client.delete 'no_such_key'
190 @backend.list_keys = { 'key_count' => 2, 'next_after' => 'new_key_2',
191 'key_1' => 'new_key_1', 'key_2' => 'new_key_2' }
192 @backend.list_keys = { 'key_count' => 2, 'next_after' => 'new_key_4',
193 'key_1' => 'new_key_3', 'key_2' => 'new_key_4' }
194 @backend.list_keys = { 'key_count' => 0, 'next_after' => 'new_key_4' }
196 @client.each_key 'new' do |key|
200 assert_equal %w[new_key_1 new_key_2 new_key_3 new_key_4], keys
204 @backend.list_keys = { 'key_count' => '2', 'next_after' => 'new_key_2',
205 'key_1' => 'new_key_1', 'key_2' => 'new_key_2' }
207 keys, next_after = @client.list_keys 'new'
208 assert_equal ['new_key_1', 'new_key_2'], keys.sort
209 assert_equal 'new_key_2', next_after
212 def test_list_keys_block
213 @backend.list_keys = { 'key_count' => '2', 'next_after' => 'new_key_2',
214 'key_1' => 'new_key_1', 'key_2' => 'new_key_2' }
215 http_resp = "HTTP/1.0 200 OK\r\nContent-Length: %u\r\n"
216 srv = Proc.new do |serv, port, size|
217 client, client_addr = serv.accept
219 readed = client.readpartial(4096)
220 assert %r{\AHEAD } =~ readed
221 client.send(http_resp % size, 0)
224 t1 = TempServer.new(Proc.new { |serv, port| srv.call(serv, port, 5) })
225 t2 = TempServer.new(Proc.new { |serv, port| srv.call(serv, port, 5) })
226 t3 = TempServer.new(Proc.new { |serv, port| srv.call(serv, port, 10) })
227 @backend.get_paths = { 'paths' => '2',
228 'path1' => "http://127.0.0.1:#{t1.port}/",
229 'path2' => "http://127.0.0.1:#{t2.port}/" }
230 @backend.get_paths = { 'paths' => '1',
231 'path1' => "http://127.0.0.1:#{t3.port}/" }
234 keys, next_after = @client.list_keys('new') do |key,length,devcount|
235 res << [ key, length, devcount ]
238 expect_res = [ [ 'new_key_1', 5, 2 ], [ 'new_key_2', 10, 1 ] ]
239 assert_equal expect_res, res
240 assert_equal ['new_key_1', 'new_key_2'], keys.sort
241 assert_equal 'new_key_2', next_after
243 TempServer.destroy_all!
246 def test_new_file_http
247 @client.readonly = true
248 assert_raises MogileFS::ReadOnlyError do
249 @client.new_file 'new_key', 'test'
253 def test_new_file_readonly
254 @client.readonly = true
255 assert_raises MogileFS::ReadOnlyError do
256 @client.new_file 'new_key', 'test'
261 accept = Tempfile.new('accept')
262 t = TempServer.new(Proc.new do |serv,port|
263 client, client_addr = serv.accept
265 readed = client.recv(4096, 0) rescue nil
267 assert_equal "HEAD /path HTTP/1.0\r\n\r\n", readed
268 client.send("HTTP/1.0 200 OK\r\nContent-Length: 5\r\n\r\n", 0)
272 path = "http://127.0.0.1:#{t.port}/path"
273 @backend.get_paths = { 'paths' => 1, 'path1' => path }
275 assert_equal 5, @client.size('key')
276 assert_equal 1, accept.stat.size
279 def test_bad_size_http
280 tmp = Tempfile.new('accept')
281 t = TempServer.new(Proc.new do |serv,port|
282 client, client_addr = serv.accept
284 readed = client.recv(4096, 0) rescue nil
285 assert_equal "HEAD /path HTTP/1.0\r\n\r\n", readed
287 client.send("HTTP/1.0 404 Not Found\r\nContent-Length: 5\r\n\r\n", 0)
291 path = "http://127.0.0.1:#{t.port}/path"
292 @backend.get_paths = { 'paths' => 1, 'path1' => path }
294 assert_nil @client.size('key')
295 assert_equal 1, tmp.stat.size
298 def test_store_content_http
299 received = Tempfile.new('recieved')
300 expected = "PUT /path HTTP/1.0\r\nContent-Length: 4\r\n\r\ndata"
302 t = TempServer.new(Proc.new do |serv, accept|
303 client, client_addr = serv.accept
305 received.syswrite(client.recv(4096, 0))
306 client.send("HTTP/1.0 200 OK\r\n\r\n", 0)
310 @backend.create_open = {
312 'path' => "http://127.0.0.1:#{t.port}/path",
315 @client.store_content 'new_key', 'test', 'data'
318 assert_equal expected, received.sysread(4096)
320 TempServer.destroy_all!
324 def test_store_content_with_writer_callback
325 received = Tempfile.new('recieved')
326 expected = "PUT /path HTTP/1.0\r\nContent-Length: 40\r\n\r\n"
330 t = TempServer.new(Proc.new do |serv, accept|
331 client, client_addr = serv.accept
335 buf = client.readpartial(8192) or break
336 break if buf.length == 0
337 assert_equal buf.length, received.syswrite(buf)
339 break if nr >= expected.size
341 client.send("HTTP/1.0 200 OK\r\n\r\n", 0)
345 @backend.create_open = {
347 'path' => "http://127.0.0.1:#{t.port}/path",
350 cbk = MogileFS::Util::StoreContent.new(40) do |write_callback|
352 write_callback.call("data")
355 @client.store_content('new_key', 'test', cbk)
358 assert_equal expected, received.sysread(4096)
360 TempServer.destroy_all!
363 def test_store_content_multi_dest_failover
364 received1 = Tempfile.new('received')
365 received2 = Tempfile.new('received')
366 expected = "PUT /path HTTP/1.0\r\nContent-Length: 4\r\n\r\ndata"
368 t1 = TempServer.new(Proc.new do |serv, accept|
369 client, client_addr = serv.accept
371 received1.syswrite(client.recv(4096, 0))
372 client.send("HTTP/1.0 500 Internal Server Error\r\n\r\n", 0)
376 t2 = TempServer.new(Proc.new do |serv, accept|
377 client, client_addr = serv.accept
379 received2.syswrite(client.recv(4096, 0))
380 client.send("HTTP/1.0 200 OK\r\n\r\n", 0)
384 @backend.create_open = {
387 'path_1' => "http://127.0.0.1:#{t1.port}/path",
389 'path_2' => "http://127.0.0.1:#{t2.port}/path",
392 @client.store_content 'new_key', 'test', 'data'
395 assert_equal expected, received1.sysread(4096)
396 assert_equal expected, received2.sysread(4096)
398 TempServer.destroy_all!
401 def test_store_content_http_fail
402 t = TempServer.new(Proc.new do |serv, accept|
403 client, client_addr = serv.accept
406 client.send("HTTP/1.0 500 Internal Server Error\r\n\r\n", 0)
410 @backend.create_open = {
412 'path' => "http://127.0.0.1:#{t.port}/path",
415 assert_raises MogileFS::HTTPFile::BadResponseError do
416 @client.store_content 'new_key', 'test', 'data'
420 def test_store_content_http_empty
421 received = Tempfile.new('received')
422 expected = "PUT /path HTTP/1.0\r\nContent-Length: 0\r\n\r\n"
423 t = TempServer.new(Proc.new do |serv, accept|
424 client, client_addr = serv.accept
426 received.syswrite(client.recv(4096, 0))
427 client.send("HTTP/1.0 200 OK\r\n\r\n", 0)
431 @backend.create_open = {
433 'path' => "http://127.0.0.1:#{t.port}/path",
436 @client.store_content 'new_key', 'test', ''
438 assert_equal expected, received.sysread(4096)
441 def test_store_content_nfs
442 @backend.create_open = {
447 assert_raises MogileFS::UnsupportedPathError do
448 @client.store_content 'new_key', 'test', 'data'
452 def test_new_file_http_large
453 expect = Tempfile.new('test_mogilefs.expect')
454 to_put = Tempfile.new('test_mogilefs.to_put')
455 received = Tempfile.new('test_mogilefs.received')
458 chunk_size = 1024 * 1024
459 expect_size = nr * chunk_size
461 header = "PUT /path HTTP/1.0\r\n" \
462 "Content-Length: #{expect_size}\r\n\r\n"
463 assert_equal header.size, expect.syswrite(header)
465 assert_equal chunk_size, expect.syswrite(' ' * chunk_size)
466 assert_equal chunk_size, to_put.syswrite(' ' * chunk_size)
468 assert_equal expect_size + header.size, expect.stat.size
469 assert_equal expect_size, to_put.stat.size
471 readed = Tempfile.new('readed')
472 t = TempServer.new(Proc.new do |serv, accept|
473 client, client_addr = serv.accept
477 buf = client.readpartial(8192) or break
478 break if buf.length == 0
479 assert_equal buf.length, received.syswrite(buf)
481 break if nr >= expect.stat.size
483 readed.syswrite("#{nr}")
484 client.send("HTTP/1.0 200 OK\r\n\r\n", 0)
488 @backend.create_open = {
490 'path' => "http://127.0.0.1:#{t.port}/path",
493 @client.store_file('new_key', 'test', to_put.path)
495 assert_equal expect.stat.size, readed.sysread(4096).to_i
497 ENV['PATH'].split(/:/).each do |path|
498 cmp_bin = "#{path}/cmp"
499 File.executable?(cmp_bin) or next
500 # puts "running #{cmp_bin} #{expect.path} #{received.path}"
501 assert( system(cmp_bin, expect.path, received.path) )
506 TempServer.destroy_all!
509 def test_store_content_readonly
510 @client.readonly = true
512 assert_raises MogileFS::ReadOnlyError do
513 @client.store_content 'new_key', 'test', nil
517 def test_store_file_readonly
518 @client.readonly = true
519 assert_raises MogileFS::ReadOnlyError do
520 @client.store_file 'new_key', 'test', nil
524 def test_rename_existing
527 assert_nil @client.rename('from_key', 'to_key')
530 def test_rename_nonexisting
531 @backend.rename = 'unknown_key', ''
533 assert_raises MogileFS::Backend::UnknownKeyError do
534 @client.rename('from_key', 'to_key')
538 def test_rename_no_key
539 @backend.rename = 'no_key', 'no_key'
541 e = assert_raises MogileFS::Backend::NoKeyError do
542 @client.rename 'new_key', 'test'
545 assert_equal 'no_key', e.message
548 def test_rename_readonly
549 @client.readonly = true
551 e = assert_raises MogileFS::ReadOnlyError do
552 @client.rename 'new_key', 'test'
555 assert_equal 'readonly mogilefs', e.message
560 assert_nothing_raised do
561 assert_equal({}, @client.sleep(2))
567 # tested with 1000, though it takes a while
569 ENV['NR_CHUNKS'] ? ENV['NR_CHUNKS'].to_i : 10