optionally use net-http-persistent for StringIO
[ruby-mogilefs-client.git] / test / test_mogtool_bigfile.rb
blob05769cd61fc31f2b41d71f271b96ff1a61349663
1 # -*- encoding: binary -*-
2 require "./test/integration"
3 require "net/http"
4 ok = true
5 unless File.executable?(`which mogtool 2>/dev/null`.strip)
6   warn "mogtool not found, skipping #{__FILE__}"
7   ok = false
8 end
10 class TestMogtoolBigfile < TestMogIntegration
11   buf = File.open("/dev/urandom") { |fp| fp.read(1024) }
12   buf *= 1024
13   RAND = Tempfile.new("rand")
14   RAND.sync = true
15   sha1 = Digest::SHA1.new
16   100.times { sha1 << buf; RAND.write(buf) }
17   buf = nil
18   RAND_SHA1 = sha1.hexdigest
20   def setup
21     super
22     RAND.rewind
23     @big_uuid = "big-#{uuid}"
24     @client = MogileFS::MogileFS.new(:hosts => @trackers, :domain => @domain)
25   end
27   def mogtool!(*args)
28     x!("mogtool", "--trackers=#{@trackers.join(',')}",
29        "--domain=#@domain", *args)
30   end
32   # the mogtool definition of gzip is wrong and just raw zlib deflate
33   def test_bigfile_gzip_mogtool
34     mogtool!("inject", "--gzip", "--bigfile", RAND.path, @big_uuid)
35     sha1_check
36   end
38   def test_bigfile_mogtool
39     mogtool!("inject", "--bigfile", RAND.path, @big_uuid)
40     sha1_check
42     # ensure fallback works for rebalanced/replaced files
43     part1 = "#@big_uuid,1"
44     tmp = tmpfile("part1")
45     before_uris = @client.get_uris(part1)
46     @client.get_file_data(part1, tmp)
47     @client.delete(part1)
48     @client.store_file(part1, nil, tmp.path)
49     wait_for_DELETE(before_uris)
50     sha1_check
52     # corrupt the existing data in part1
53     @client.store_content(part1, nil, "HELLO")
54     assert_nothing_raised { @client.get_uris(part1) }
56     # corruption is detected on verify
57     junk = tmpfile("junk")
58     assert_raises(MogileFS::ChecksumMismatchError) do
59       @client.bigfile_write("_big_info:#@big_uuid", junk, :verify => true)
60     end
62     # corruption is NOT detected on verify
63     junk = tmpfile("junk")
64     assert_nothing_raised do
65       @client.bigfile_write("_big_info:#@big_uuid", junk, :verify => false)
66     end
68     # restoring no-corrupted data succeeds!
69     @client.store_file(part1, nil, tmp.path)
70     sha1_check
72     # missing parts fail
73     before_uris = @client.get_uris(part1)
74     @client.delete(part1)
75     junk = tmpfile("junk")
76     assert_raises(MogileFS::Backend::UnknownKeyError) do
77       @client.bigfile_write("_big_info:#@big_uuid", junk, :verify => true)
78     end
79   end
81   def wait_for_DELETE(uris)
82     uris.each do |uri|
83       tries = 0
84       begin
85         Net::HTTP.start(uri.host, uri.port) do |http|
86           sleep(0.1) while Net::HTTPOK === http.head(uri.path)
87         end
88       rescue
89         if (tries += 1) < 666
90           sleep(0.1)
91           retry
92         end
93         raise
94       end
95     end
96   end
98   def sha1_check
99     r, w = IO.pipe
100     @to_close << r
101     @to_close << w
102     th = Thread.new do
103       sha1 = Digest::SHA1.new
104       buf = ""
105       while r.read(16384, buf)
106         sha1 << buf
107       end
108       sha1.hexdigest
109     end
110     res = @client.bigfile_write("_big_info:#@big_uuid", w, :verify => true)
111     w.close
112     read_sha1 = th.value
113     assert_equal RAND_SHA1, read_sha1
114     assert_equal RAND.size, res[0]
115   end
116 end if ok