2 # -*- encoding: binary -*-
3 # Copyright (C) 2012-2020 all contributors <cmogstored-public@yhbt.net>
4 # License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
5 require 'test/test_helper'
8 TEST_PROG = 'test/pwrite-wrap'
9 class TestPwriteWrap < Test::Unit::TestCase
11 @tmpdir = Dir.mktmpdir('cmogstored-pwrite-wrap-test')
15 srv = TCPServer.new(@host, 0)
19 srv = TCPServer.new(@host, 0)
20 @mgmt_port = srv.addr[1]
23 Dir.mkdir("#@tmpdir/dev666")
24 Dir.mkdir("#@tmpdir/dev333")
25 File.open("#@tmpdir/dev666/get.fid", "w") { |fp|
30 @err = Tempfile.new("stderr")
31 cmd = [ TEST_PROG, "--docroot=#@tmpdir", "--httplisten=#@host:#@port",
32 "--mgmtlisten=#@host:#@mgmt_port", "--maxconns=500" ]
35 if vg = ENV["VALGRIND"]
36 cmd = vg.split(/\s+/).concat(cmd)
37 # valgrind slows everything down, so increase the sleep time
40 ENV["PWRITE_WRAP_SLOW_MSEC"] ||= (@slow_time * 2).to_s
42 $stderr.reopen(@err.path, "a")
47 @mgmt_client = get_client(300, @mgmt_port)
48 @mgmt_client.write "server aio_threads = 1\r\n"
50 warning = "fewer aio_threads(1) than devices(2)"
51 wait_for(30, warning) do
52 buf = File.read(@err.path)
57 def wait_for(sec, reason, res = 0.1)
62 end while Time.now < stop
66 def test_pwrite_slow_chunked
67 __test_pwrite_slow(true)
70 def test_pwrite_slow_identity
71 __test_pwrite_slow(false)
74 def __test_pwrite_slow(chunked)
75 Process.kill(:VTALRM, @pid) # move knob to PWRITE_WRAP_SLOW
76 wait_for(5, 'move to slow knob', 0.01) do
77 File.readlines(@err.path).grep(/knob set: slow/)[0]
79 Process.kill(:TTIN, @pid) # turn on the switch for where the knob is
80 wait_for(5, 'enable slow knob', 0.01) do
81 File.readlines(@err.path).grep(/flag set: slow/)[0]
88 size = 100 * 1024 * 1024
90 @client.write("PUT /dev666/foo.fid HTTP/1.1\r\n" \
91 "Host: example.com\r\n" \
92 "Transfer-Encoding: chunked\r\n\r\n" \
95 @client.write("PUT /dev666/foo.fid HTTP/1.0\r\n" \
96 "Content-Length: #{size}\r\n\r\n")
98 IO.copy_stream("/dev/zero", @client, size)
104 wait_for(5, "temporary file to exist", 0.05) do
105 Dir["#@tmpdir/dev666/foo.*tmp"][0]
109 # this should cause mog_ioq_contended to return true in http_put.c
111 Timeout.timeout(@slow_time * 4) {
112 client_2.write("GET /dev666/get.fid HTTP/1.0\r\n\r\n")
113 assert_match(%r{HTTP/1\.1 200 OK}, client_2.gets)
116 assert_operator diff, :<, (@slow_time * 2), "diff=#{diff}"
119 Process.kill(:TTOU, @pid)
120 wait_for(5, "clear slow flag") do
121 File.readlines(@err.path).grep(/flag set: slow/)[0]
126 Process.kill(:QUIT, @pid) rescue nil
127 _, status = Process.waitpid2(@pid)
128 @to_close.each { |io| io.close unless io.closed? }
129 FileUtils.rm_rf(@tmpdir)
131 $stderr.write(@err.read) if $DEBUG
132 assert status.success?, status.inspect
135 # this test is horribly slow under valgrind, and we probably don't need
137 end if File.exist?(TEST_PROG) && ! ENV["VALGRIND"]