1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
| | #!/usr/bin/env ruby
# -*- encoding: binary -*-
# Copyright (C) 2012-2013, Eric Wong <normalperson@yhbt.net>
# License: GPLv3 or later (see COPYING for details)
require 'test/test_helper'
require 'timeout'
class TestMgmtIostat < Test::Unit::TestCase
TEST_PATH = File.dirname(__FILE__) + ":#{ENV['PATH']}"
RUBY = ENV["RUBY"] || "ruby"
def iostat_mock
"#{RUBY} #{File.dirname(__FILE__)}/iostat-mock.rb"
end
def setup
@iostat_pid = Tempfile.new('testt-iostat-pid')
@tmpdir = Dir.mktmpdir('cmogstored-mgmt-iostat-test')
@host = TEST_HOST
srv = TCPServer.new(@host, 0)
@port = srv.addr[1]
srv.close
cmd = [ "cmogstored", "--docroot=#@tmpdir", "--mgmtlisten=#@host:#@port",
"--maxconns=500" ]
vg = ENV["VALGRIND"] and cmd = vg.split(/\s+/).concat(cmd)
@cmd = cmd
@pid = nil
@to_close = []
end
def teardown
@to_close.each { |io| io.close unless io.closed? }
if @pid
Process.kill(:QUIT, @pid) rescue nil
_, status = Process.waitpid2(@pid)
assert status.success?, status.inspect
end
FileUtils.rm_rf(@tmpdir)
end
def __test_iostat_dies(workers = false)
Dir.mkdir "#@tmpdir/dev666"
err = Tempfile.new('err')
@pid = fork do
ENV["PATH"] = TEST_PATH
ENV["MOG_IOSTAT_CMD"] = "#{iostat_mock} #{@iostat_pid.path} slow"
$stderr.reopen(err.path, 'a')
@cmd << workers if workers
exec(*@cmd)
end
iostat_pid = nil
Timeout.timeout(30) do
begin
iostat_pid = @iostat_pid.read.to_i
end while iostat_pid == 0 && sleep(0.05)
Process.kill(:TERM, iostat_pid)
end
expect = %r{iostat done \(pid=#{iostat_pid}, status=\d}
Timeout.timeout(30) do
loop do
stderr = File.read(err.path)
break if stderr =~ expect
sleep 0.05
end
end
ensure
err.close!
end
def test_iostat_dies
__test_iostat_dies
end
def test_iostat_dies_with_workers
__test_iostat_dies("--worker-processes=1")
end
def test_iostat_fast
Dir.mkdir "#@tmpdir/dev666"
@pid = fork do
ENV["PATH"] = TEST_PATH
ENV["MOG_IOSTAT_CMD"] = "#{iostat_mock} #{@iostat_pid.path} fast"
exec(*@cmd)
end
og = get_client
og.write "watch\n"
threads = []
nr = RUBY_PLATFORM =~ /linux/ ? 400 : 10
nr.times do
threads << Thread.new do
c = get_client
assert_equal 6, c.write("watch\n")
100.times { assert_kind_of(String, c.gets) }
c
end
end
sleep 1
threads.each { |th| th.value.close }
assert og.readpartial(16384)
sleep 1
assert og.read_nonblock(512)
sleep 1
assert og.read_nonblock(512)
iostat_pid = @iostat_pid.read.to_i
if iostat_pid > 0
Process.kill(:TERM, iostat_pid)
end
end
def test_iostat_bursty1
iostat_edge_case("bursty1")
end
def test_iostat_bursty2
iostat_edge_case("bursty2")
end
def test_iostat_slow
iostat_edge_case("slow")
end
def iostat_edge_case(type)
Dir.mkdir "#@tmpdir/dev666"
@pid = fork do
ENV["PATH"] = TEST_PATH
ENV["MOG_IOSTAT_CMD"] = "#{iostat_mock} #{@iostat_pid.path} #{type}"
exec(*@cmd)
end
og = get_client
og.write "watch\n"
5.times do
assert_match(/\n$/, x = og.gets)
p(x) if $DEBUG
end
og.close
end
end
|