1 # -*- encoding: binary -*-
4 # cmogstored allows Content-Range on PUT, unlike the original mogstored
5 class Test_cmogstored < Test::Unit::TestCase
7 alias setup setup_mogilefs
8 alias teardown teardown_mogilefs
10 def test_range_put_new_file
11 add_host_device_domain
12 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
14 io = client.new_file "range0", :largefile => :content_range
16 assert_equal "", client.get_file_data("range0")
18 io = client.new_file "writes", :largefile => :content_range
19 %w(a b c d e).each { |x| io.write(x) }
21 assert_equal "abcde", client.get_file_data("writes")
23 io = client.new_file "puts", :largefile => :content_range
24 %w(a b c d e).each { |x| io.puts(x) }
25 assert ! client.exist?("puts")
27 assert_equal "a\nb\nc\nd\ne\n", client.get_file_data("puts")
31 add_host_device_domain
32 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain,
34 nr = 1024 * 1024 * 1024
35 client.new_file('giant', :largefile => :stream,
36 :content_length => nr) do |io|
37 assert_instance_of MogileFS::NewFile::Stream, io
40 wr = IO.copy_stream(zero, io, nr)
43 assert_in_delta before, after, 1
45 end if IO.respond_to?(:copy_stream) && defined?(Zero) &&
46 GC.respond_to?(:count) && defined?(RUBY_ENGINE) &&
47 RUBY_ENGINE == 'ruby' && ENV['TEST_EXPENSIVE'].to_i != 0
49 def test_stream_new_file
50 add_host_device_domain
51 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
52 client.new_file("chunky", :largefile => :stream) do |io|
53 assert_instance_of MogileFS::NewFile::Stream, io
54 assert_equal(5, io.write("HELLO"))
57 assert_equal "HELLO", client.get_file_data("chunky")
59 io = client.new_file("puts", :largefile => :stream)
60 assert_instance_of MogileFS::NewFile::Stream, io
61 assert_equal io, IO.select(nil, [io])[1][0], "IO.select-able"
63 assert_nil(io.puts("PUTS!"))
64 assert_nil(io.puts("PUTZ"))
66 assert_equal "PUTS!\nPUTZ\n", client.get_file_data("puts")
68 io = client.new_file("putc", :largefile => :stream)
69 assert_equal(0x20, io.putc(0x20))
71 assert_equal " ", client.get_file_data("putc")
73 io = client.new_file("print splat", :largefile => :stream)
76 assert_equal "123", client.get_file_data("print splat")
78 io = client.new_file("printf", :largefile => :stream)
79 assert_nil io.printf("%x", 1638)
81 assert_equal "666", client.get_file_data("printf")
83 io = client.new_file("syswrite", :largefile => :stream)
84 assert_equal 4, io.syswrite("good")
85 assert_equal 7, io.syswrite("morning")
87 assert_equal "goodmorning", client.get_file_data("syswrite")
89 io = client.new_file("md5", :largefile=>:stream, :content_md5=>:trailer)
90 assert_instance_of Digest::MD5, io.md5
91 assert_nil io.puts("HIHI")
93 assert_equal "HIHI\n", client.get_file_data("md5")
94 assert_equal Digest::MD5.hexdigest("HIHI\n"), io.md5.hexdigest
96 io = client.new_file("<<", :largefile=>:stream)
97 assert_equal(io, io << ">>")
99 assert_equal ">>", client.get_file_data("<<")
102 def test_stream_new_file_with_content_length
103 add_host_device_domain
104 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
105 io = client.new_file("clen", :largefile=>:stream,:content_length=>6)
108 assert_equal "HIHIHI", client.get_file_data("clen")
110 io = client.new_file("clen", :largefile=>:stream,:content_length=>1)
112 assert_raises(MogileFS::SizeMismatchError) { io.close }
113 assert_equal "HIHIHI", client.get_file_data("clen")
115 io = client.new_file("md5", :largefile=>:stream,
116 :content_length=>6, :content_md5=>:trailer)
117 assert_equal(io, io << "MD5MD5")
119 assert_equal "MD5MD5", client.get_file_data("md5")
120 assert_equal Digest::MD5.hexdigest("MD5MD5"), io.md5.hexdigest
122 io = client.new_file("md5", :largefile=>:stream,
123 :content_length=>6, :content_md5=>:trailer)
124 assert_equal(io, io << "MD5MD")
125 assert_raises(MogileFS::SizeMismatchError) { io.close }
126 assert_equal Digest::MD5.hexdigest("MD5MD"), io.md5.hexdigest
130 add_host_device_domain
131 client = MogileFS::MogileFS.new :hosts => @hosts, :domain => @domain
132 node = "#@test_host:#@mogstored_http_port"
134 # not modifying this hash in the same process
135 MogileFS::HTTPFile::MD5_TRAILER_NODES[node] = true
136 client.store_content("md5_me", nil, "HELLO WORLD")
138 _, status = Process.waitpid2(pid)
139 assert status.success?, status.inspect
140 assert_equal "HELLO WORLD", client.get_file_data("md5_me")
144 @docroot = Dir.mktmpdir(["mogfresh", "docroot"])
145 Dir.mkdir("#@docroot/dev1")
146 Dir.mkdir("#@docroot/dev2")
147 @mogstored_mgmt = TCPServer.new(@test_host, 0)
148 @mogstored_http = TCPServer.new(@test_host, 0)
149 @mogstored_mgmt_port = @mogstored_mgmt.addr[1]
150 @mogstored_http_port = @mogstored_http.addr[1]
152 @mogstored_pid = fork do
153 mgmt_fd = @mogstored_mgmt.fileno
154 http_fd = @mogstored_http.fileno
156 ENV["CMOGSTORED_FD"] = "#{mgmt_fd},#{http_fd}"
157 if @mogstored_mgmt.respond_to?(:close_on_exec=)
158 @mogstored_mgmt.close_on_exec = @mogstored_http.close_on_exec = false
159 args << { mgmt_fd => mgmt_fd, http_fd => http_fd }
161 $stderr.reopen('/dev/null', 'a')
162 exec "cmogstored", "--httplisten=#@test_host:#@mogstored_http_port",
163 "--mgmtlisten=#@test_host:#@mogstored_mgmt_port",
164 "--maxconns=1000", "--docroot=#@docroot", *args
167 end if `which cmogstored`.chomp.size > 0
169 # The goal of this is to use a synthetic (non-IO) reader
170 # to trigger the read/write loop of IO.copy_stream,
171 # bypassing in-kernel mechanisms like sendfile for zero copy,
172 # so we wrap the /dev/zero IO object:
175 @in = File.open('/dev/zero', 'rb')
181 end if File.readable?('/dev/zero')