cmogstored 1.8.1 - use default system stack size
[cmogstored.git] / test / pwrite_wrap.rb
blob6731ba51668aa4cb1a0614be570d9a686d1bc125
1 #!/usr/bin/env ruby
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'
6 require 'timeout'
8 TEST_PROG = 'test/pwrite-wrap'
9 class TestPwriteWrap < Test::Unit::TestCase
10   def setup
11     @tmpdir = Dir.mktmpdir('cmogstored-pwrite-wrap-test')
12     @to_close = []
13     @host = TEST_HOST
15     srv = TCPServer.new(@host, 0)
16     @port = srv.addr[1]
17     srv.close
19     srv = TCPServer.new(@host, 0)
20     @mgmt_port = srv.addr[1]
21     srv.close
23     Dir.mkdir("#@tmpdir/dev666")
24     Dir.mkdir("#@tmpdir/dev333")
25     File.open("#@tmpdir/dev666/get.fid", "w") { |fp|
26       fp.seek(1000)
27       fp.write("\0")
28     }
30     @err = Tempfile.new("stderr")
31     cmd = [ TEST_PROG, "--docroot=#@tmpdir", "--httplisten=#@host:#@port",
32             "--mgmtlisten=#@host:#@mgmt_port", "--maxconns=500" ]
34     @slow_time = 5000
35     if vg = ENV["VALGRIND"]
36       cmd = vg.split(/\s+/).concat(cmd)
37       # valgrind slows everything down, so increase the sleep time
38       @slow_time *= 2
39     end
40     ENV["PWRITE_WRAP_SLOW_MSEC"] ||= (@slow_time * 2).to_s
41     @pid = fork {
42       $stderr.reopen(@err.path, "a")
43       @err.close
44       exec(*cmd)
45     }
46     @client = get_client
47     @mgmt_client = get_client(300, @mgmt_port)
48     @mgmt_client.write "server aio_threads = 1\r\n"
49     @mgmt_client.gets
50     warning = "fewer aio_threads(1) than devices(2)"
51     wait_for(30, warning) do
52       buf = File.read(@err.path)
53       buf.include?(warning)
54     end
55   end
57   def wait_for(sec, reason, res = 0.1)
58     stop = Time.now + sec
59     begin
60       return if yield
61       sleep res
62     end while Time.now < stop
63     assert false, reason
64   end
66   def test_pwrite_slow_chunked
67     __test_pwrite_slow(true)
68   end
70   def test_pwrite_slow_identity
71     __test_pwrite_slow(false)
72   end
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]
78     end
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]
82     end
84     client_2 = get_client
86     thr = Thread.new do
87       begin
88         size = 100 * 1024 * 1024
89         if chunked
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" \
93                         "#{'%x' % size}\r\n")
94         else
95           @client.write("PUT /dev666/foo.fid HTTP/1.0\r\n" \
96                         "Content-Length: #{size}\r\n\r\n")
97         end
98         IO.copy_stream("/dev/zero", @client, size)
99       rescue => err
100       end
101       err
102     end
104     wait_for(5, "temporary file to exist", 0.05) do
105       Dir["#@tmpdir/dev666/foo.*tmp"][0]
106     end
107     t_yield
109     # this should cause mog_ioq_contended to return true in http_put.c
110     a = Time.now
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)
114     }
115     diff = Time.now - a
116     assert_operator diff, :<, (@slow_time * 2), "diff=#{diff}"
117     @client.shutdown
118     thr.join
119     Process.kill(:TTOU, @pid)
120     wait_for(5, "clear slow flag") do
121       File.readlines(@err.path).grep(/flag set: slow/)[0]
122     end
123   end
125   def teardown
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)
130     @err.rewind
131     $stderr.write(@err.read) if $DEBUG
132     assert status.success?, status.inspect
133   end
135 # this test is horribly slow under valgrind, and we probably don't need
136 # valgrind, here...
137 end if File.exist?(TEST_PROG) && ! ENV["VALGRIND"]