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
| | require_relative 'helper'
begin
require 'strace'
rescue LoadError
end
$-w = true
require 'sleepy_penguin'
class TestEpollOptimizations < Test::Unit::TestCase
include SleepyPenguin
IO_PURGATORY = []
def setup
@rd, @wr = IO.pipe
@ep = Epoll.new
end
def teardown
[ @ep, @rd, @wr ].each { |io| io.close unless io.closed? }
end
def test_set
io, err = Strace.me do
@ep.set(@wr, Epoll::OUT)
@ep.set(@wr, Epoll::OUT)
end
assert_nil err
lines = io.readlines; io.close
assert_equal 1, lines.grep(/^epoll_ctl/).size, lines.inspect
assert_match(/EPOLL_CTL_ADD/, lines.grep(/^epoll_ctl/)[0])
io, err = Strace.me { @ep.set(@wr, Epoll::OUT | Epoll::ONESHOT) }
assert_nil err
lines = io.readlines; io.close
assert_equal 1, lines.grep(/^epoll_ctl/).size
assert_match(/EPOLL_CTL_MOD/, lines.grep(/^epoll_ctl/)[0])
io, err = Strace.me { @ep.set(@wr, Epoll::OUT) }
assert_nil err
lines = io.readlines; io.close
assert_equal 1, lines.grep(/^epoll_ctl/).size
assert_match(/EPOLL_CTL_MOD/, lines.grep(/^epoll_ctl/)[0])
@wr.close
@rd.close
@rd, @wr = IO.pipe
io, err = Strace.me { @ep.set(@wr, Epoll::OUT) }
assert_nil err
lines = io.readlines; io.close
assert_equal 1, lines.grep(/^epoll_ctl/).size
assert_match(/EPOLL_CTL_ADD/, lines.grep(/^epoll_ctl/)[0])
end
def test_delete
@ep.set(@wr, Epoll::OUT)
rv = true
io, err = Strace.me { rv = @ep.delete(@wr) }
assert_equal @wr, rv
assert_nil err
lines = io.readlines; io.close
assert_equal 1, lines.grep(/^epoll_ctl/).size
assert_match(%r{=\s+0$}, lines.grep(/^epoll_ctl/)[0])
rv = true
io, err = Strace.me { rv = @ep.delete(@wr) }
assert_nil rv
assert_nil err
lines = io.readlines; io.close
assert_equal 0, lines.grep(/^epoll_ctl/).size
end
def test_delete_closed
a = @wr.fileno
@ep.set(@wr, Epoll::OUT)
@rd.close
@wr.close
@rd, @wr = IO.pipe
assert_equal a, @wr.fileno
rv = true
io, err = Strace.me { rv = @ep.delete(@wr) }
lines = io.readlines; io.close
assert_nil err
assert_nil rv
assert_equal 0, lines.grep(/^epoll_ctl/).size
end
def test_delete_closed_proxy
obj = Struct.new(:to_io).new(@wr)
rv = nil
@ep.add(obj, Epoll::OUT)
@wr.close
io, err = Strace.me { rv = @ep.delete(obj) }
lines = io.readlines; io.close
assert_kind_of IOError, err
assert_nil rv
assert_equal 0, lines.grep(/^epoll_ctl/).size
end
def test_delete_aliased_a
tmp = IO.for_fd @wr.fileno
IO_PURGATORY << tmp
@ep.set(tmp, Epoll::OUT)
rv = nil
io, err = Strace.me { rv = @ep.delete(@wr) }
lines = io.readlines; io.close
assert_equal @wr, rv
assert_nil err
assert_equal 1, lines.grep(/^epoll_ctl/).size
assert_match %r{=\s+0$}, lines.grep(/^epoll_ctl/)[0]
assert_equal 0, lines.grep(/ENOENT/).size
end
def test_delete_aliased_b
tmp = IO.for_fd @wr.fileno
IO_PURGATORY << tmp
@ep.set(@wr, Epoll::OUT)
rv = nil
io, err = Strace.me { rv = @ep.delete(tmp) }
lines = io.readlines; io.close
assert_equal tmp, rv
assert_nil err
assert_equal 1, lines.grep(/^epoll_ctl/).size
assert_match(%r{=\s+0$}, lines.grep(/^epoll_ctl/)[0])
assert_equal 0, lines.grep(/ENOENT/).size
end
def test_delete_aliased_closed
tmp = IO.for_fd @wr.fileno
IO_PURGATORY << tmp
@ep.set(tmp, Epoll::OUT)
@wr.close
rv = nil
io, err = Strace.me { rv = @ep.delete(tmp) }
lines = io.readlines; io.close
assert_nil rv
assert_nil err
assert_equal 1, lines.grep(/^epoll_ctl/).size
assert_equal 1, lines.grep(/EBADF/).size
end
end if defined?(Strace)
|