kgio 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,240 @@
1
+ require 'test/unit'
2
+ require 'io/nonblock'
3
+ $-w = true
4
+ require 'kgio'
5
+
6
+ module LibReadWriteTest
7
+ RANDOM_BLOB = File.open("/dev/urandom") { |fp| fp.read(10 * 1024 * 1024) }
8
+
9
+ def teardown
10
+ assert_nothing_raised do
11
+ @rd.close unless @rd.closed?
12
+ @wr.close unless @wr.closed?
13
+ end
14
+ assert_nothing_raised do
15
+ Kgio.wait_readable = Kgio.wait_writable = nil
16
+ end
17
+ end
18
+
19
+ def test_read_eof
20
+ @wr.close
21
+ assert_nil @rd.kgio_read(5)
22
+ end
23
+
24
+ def test_tryread_eof
25
+ @wr.close
26
+ assert_nil @rd.kgio_tryread(5)
27
+ end
28
+
29
+ def test_write_closed
30
+ @rd.close
31
+ assert_raises(Errno::EPIPE, Errno::ECONNRESET) {
32
+ loop { @wr.kgio_write "HI" }
33
+ }
34
+ end
35
+
36
+ def test_trywrite_closed
37
+ @rd.close
38
+ assert_raises(Errno::EPIPE, Errno::ECONNRESET) {
39
+ loop { @wr.kgio_trywrite "HI" }
40
+ }
41
+ end
42
+
43
+ def test_write_conv
44
+ assert_equal nil, @wr.kgio_write(10)
45
+ assert_equal "10", @rd.kgio_read(2)
46
+ end
47
+
48
+ def test_trywrite_conv
49
+ assert_equal nil, @wr.kgio_trywrite(10)
50
+ assert_equal "10", @rd.kgio_tryread(2)
51
+ end
52
+
53
+ def test_tryread_empty
54
+ assert_equal Kgio::WaitReadable, @rd.kgio_tryread(1)
55
+ end
56
+
57
+ def test_read_too_much
58
+ assert_equal nil, @wr.kgio_write("hi")
59
+ assert_equal "hi", @rd.kgio_read(4)
60
+ end
61
+
62
+ def test_tryread_too_much
63
+ assert_equal nil, @wr.kgio_trywrite("hi")
64
+ assert_equal "hi", @rd.kgio_tryread(4)
65
+ end
66
+
67
+ def test_read_short
68
+ assert_equal nil, @wr.kgio_write("hi")
69
+ assert_equal "h", @rd.kgio_read(1)
70
+ assert_equal "i", @rd.kgio_read(1)
71
+ end
72
+
73
+ def test_tryread_short
74
+ assert_equal nil, @wr.kgio_trywrite("hi")
75
+ assert_equal "h", @rd.kgio_tryread(1)
76
+ assert_equal "i", @rd.kgio_tryread(1)
77
+ end
78
+
79
+ def test_read_extra_buf
80
+ tmp = ""
81
+ tmp_object_id = tmp.object_id
82
+ assert_equal nil, @wr.kgio_write("hi")
83
+ rv = @rd.kgio_read(2, tmp)
84
+ assert_equal "hi", rv
85
+ assert_equal rv.object_id, tmp.object_id
86
+ assert_equal tmp_object_id, rv.object_id
87
+ end
88
+
89
+ def test_trywrite_return_wait_writable
90
+ tmp = []
91
+ tmp << @wr.kgio_trywrite("HI") until tmp[-1] == Kgio::WaitWritable
92
+ assert_equal Kgio::WaitWritable, tmp.pop
93
+ assert tmp.size > 0
94
+ penultimate = tmp.pop
95
+ assert(penultimate == "I" || penultimate == nil)
96
+ assert tmp.size > 0
97
+ tmp.each { |count| assert_equal nil, count }
98
+ end
99
+
100
+ def test_tryread_extra_buf_eagain_clears_buffer
101
+ tmp = "hello world"
102
+ rv = @rd.kgio_tryread(2, tmp)
103
+ assert_equal Kgio::WaitReadable, rv
104
+ assert_equal "", tmp
105
+ end
106
+
107
+ def test_tryread_extra_buf_eof_clears_buffer
108
+ tmp = "hello world"
109
+ @wr.close
110
+ assert_nil @rd.kgio_tryread(2, tmp)
111
+ assert_equal "", tmp
112
+ end
113
+
114
+ def test_monster_trywrite
115
+ buf = RANDOM_BLOB.dup
116
+ rv = @wr.kgio_trywrite(buf)
117
+ assert_kind_of String, rv
118
+ assert rv.size < buf.size
119
+ @rd.nonblock = false
120
+ assert_equal(buf, @rd.read(buf.size - rv.size) + rv)
121
+ end
122
+
123
+ def test_monster_write
124
+ buf = RANDOM_BLOB.dup
125
+ thr = Thread.new { @wr.kgio_write(buf) }
126
+ @rd.nonblock = false
127
+ readed = @rd.read(buf.size)
128
+ thr.join
129
+ assert_nil thr.value
130
+ assert_equal buf, readed
131
+ end
132
+
133
+ def test_monster_write_wait_writable
134
+ @wr.instance_variable_set :@nr, 0
135
+ def @wr.wait_writable
136
+ @nr += 1
137
+ IO.select(nil, [self])
138
+ end
139
+ Kgio.wait_writable = :wait_writable
140
+ buf = "." * 1024 * 1024 * 10
141
+ thr = Thread.new { @wr.kgio_write(buf) }
142
+ readed = @rd.read(buf.size)
143
+ thr.join
144
+ assert_nil thr.value
145
+ assert_equal buf, readed
146
+ assert @wr.instance_variable_get(:@nr) > 0
147
+ end
148
+
149
+ def test_wait_readable_ruby_default
150
+ assert_nothing_raised { Kgio.wait_readable = nil }
151
+ elapsed = 0
152
+ foo = nil
153
+ t0 = Time.now
154
+ thr = Thread.new { sleep 1; @wr.write "HELLO" }
155
+ assert_nothing_raised do
156
+ foo = @rd.kgio_read(5)
157
+ elapsed = Time.now - t0
158
+ end
159
+ assert elapsed >= 1.0, "elapsed: #{elapsed}"
160
+ assert_equal "HELLO", foo
161
+ thr.join
162
+ assert_equal 5, thr.value
163
+ end
164
+
165
+ def test_wait_writable_ruby_default
166
+ buf = "." * 512
167
+ nr = 0
168
+ begin
169
+ nr += @wr.write_nonblock(buf)
170
+ rescue Errno::EAGAIN
171
+ break
172
+ end while true
173
+ assert_nothing_raised { Kgio.wait_writable = nil }
174
+ elapsed = 0
175
+ foo = nil
176
+ t0 = Time.now
177
+ thr = Thread.new { sleep 1; @rd.readpartial(nr) }
178
+ assert_nothing_raised do
179
+ foo = @wr.kgio_write("HELLO")
180
+ elapsed = Time.now - t0
181
+ end
182
+ assert_nil foo
183
+ if @wr.stat.pipe?
184
+ assert elapsed >= 1.0, "elapsed: #{elapsed}"
185
+ end
186
+ assert(String === foo || foo == nil)
187
+ assert_kind_of String, thr.value
188
+ end
189
+
190
+ def test_wait_readable_method
191
+ def @rd.moo
192
+ defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
193
+ end
194
+ assert_nothing_raised { Kgio.wait_readable = :moo }
195
+ foo = nil
196
+ begin
197
+ foo = @rd.kgio_read(5)
198
+ assert false
199
+ rescue RuntimeError => e
200
+ assert_equal("Hello", e.message)
201
+ end
202
+ assert_equal "HI", @rd.instance_variable_get(:@z)
203
+ assert_nil foo
204
+ end
205
+
206
+ def test_tryread_wait_readable_method
207
+ def @rd.moo
208
+ raise "Hello"
209
+ end
210
+ assert_nothing_raised { Kgio.wait_readable = :moo }
211
+ assert_equal Kgio::WaitReadable, @rd.kgio_tryread(5)
212
+ end
213
+
214
+ def test_trywrite_wait_readable_method
215
+ def @wr.moo
216
+ raise "Hello"
217
+ end
218
+ assert_nothing_raised { Kgio.wait_writable = :moo }
219
+ tmp = []
220
+ buf = "." * 1024
221
+ 10000.times { tmp << @wr.kgio_trywrite(buf) }
222
+ assert_equal Kgio::WaitWritable, tmp.pop
223
+ end
224
+
225
+ def test_wait_writable_method
226
+ def @wr.moo
227
+ defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
228
+ end
229
+ assert_nothing_raised { Kgio.wait_writable = :moo }
230
+ n = []
231
+ begin
232
+ loop { n << @wr.kgio_write("HIHIHIHIHIHI") }
233
+ assert false
234
+ rescue RuntimeError => e
235
+ assert_equal("Hello", e.message)
236
+ end
237
+ assert n.size > 0
238
+ assert_equal "HI", @wr.instance_variable_get(:@z)
239
+ end
240
+ end
@@ -0,0 +1,70 @@
1
+ require 'test/unit'
2
+ require 'io/nonblock'
3
+ $-w = true
4
+ require 'kgio'
5
+
6
+ module LibServerAccept
7
+
8
+ def teardown
9
+ @srv.close unless @srv.closed?
10
+ Kgio.accept_cloexec = true
11
+ Kgio.accept_nonblock = false
12
+ end
13
+
14
+ def test_tryaccept_success
15
+ a = client_connect
16
+ IO.select([@srv])
17
+ b = @srv.kgio_tryaccept
18
+ assert_kind_of Kgio::Socket, b
19
+ assert_equal @host, b.kgio_addr
20
+ end
21
+
22
+ def test_tryaccept_fail
23
+ assert_equal nil, @srv.kgio_tryaccept
24
+ end
25
+
26
+ def test_blocking_accept
27
+ t0 = Time.now
28
+ pid = fork { sleep 1; a = client_connect; sleep }
29
+ b = @srv.kgio_accept
30
+ elapsed = Time.now - t0
31
+ assert_kind_of Kgio::Socket, b
32
+ assert_equal @host, b.kgio_addr
33
+ Process.kill(:TERM, pid)
34
+ Process.waitpid(pid)
35
+ assert elapsed >= 1, "elapsed: #{elapsed}"
36
+ end
37
+
38
+ def test_blocking_accept_with_nonblock_socket
39
+ @srv.nonblock = true
40
+ t0 = Time.now
41
+ pid = fork { sleep 1; a = client_connect; sleep }
42
+ b = @srv.kgio_accept
43
+ elapsed = Time.now - t0
44
+ assert_kind_of Kgio::Socket, b
45
+ assert_equal @host, b.kgio_addr
46
+ Process.kill(:TERM, pid)
47
+ Process.waitpid(pid)
48
+ assert elapsed >= 1, "elapsed: #{elapsed}"
49
+
50
+ t0 = Time.now
51
+ pid = fork { sleep 6; a = client_connect; sleep }
52
+ b = @srv.kgio_accept
53
+ elapsed = Time.now - t0
54
+ assert_kind_of Kgio::Socket, b
55
+ assert_equal @host, b.kgio_addr
56
+ Process.kill(:TERM, pid)
57
+ Process.waitpid(pid)
58
+ assert elapsed >= 6, "elapsed: #{elapsed}"
59
+
60
+ t0 = Time.now
61
+ pid = fork { sleep 1; a = client_connect; sleep }
62
+ b = @srv.kgio_accept
63
+ elapsed = Time.now - t0
64
+ assert_kind_of Kgio::Socket, b
65
+ assert_equal @host, b.kgio_addr
66
+ Process.kill(:TERM, pid)
67
+ Process.waitpid(pid)
68
+ assert elapsed >= 1, "elapsed: #{elapsed}"
69
+ end
70
+ end
@@ -0,0 +1,23 @@
1
+ require 'test/unit'
2
+ require 'io/nonblock'
3
+ $-w = true
4
+ require 'kgio'
5
+
6
+ class TestConnectFDLeak < Test::Unit::TestCase
7
+
8
+ def teardown
9
+ Kgio.wait_readable = Kgio.wait_writable = nil
10
+ end
11
+
12
+ def test_unix_socket
13
+ nr = 0
14
+ path = "/non/existent/path"
15
+ assert(! File.exist?(path), "#{path} should not exist")
16
+ assert_nothing_raised do
17
+ begin
18
+ sock = Kgio::UNIXSocket.new(path)
19
+ rescue Errno::ENOENT
20
+ end while (nr += 1) < 10000
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ require 'test/unit'
2
+ require 'io/nonblock'
3
+ $-w = true
4
+ require 'kgio'
5
+
6
+ class TestPipePopen < Test::Unit::TestCase
7
+ def test_popen
8
+ io = Kgio::Pipe.popen("sleep 1 && echo HI")
9
+ assert_equal Kgio::WaitReadable, io.kgio_tryread(2)
10
+ sleep 1.5
11
+ assert_equal "HI\n", io.kgio_read(3)
12
+ assert_nil io.kgio_read(5)
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ require './test/lib_read_write.rb'
2
+
3
+ class TestKgioPipe < Test::Unit::TestCase
4
+ def setup
5
+ @rd, @wr = Kgio::Pipe.new
6
+ end
7
+
8
+ include LibReadWriteTest
9
+ end
@@ -0,0 +1,9 @@
1
+ require './test/lib_read_write.rb'
2
+
3
+ class TestKgioUNIXSocketPair < Test::Unit::TestCase
4
+ def setup
5
+ @rd, @wr = Kgio::UNIXSocket.pair
6
+ end
7
+
8
+ include LibReadWriteTest
9
+ end
@@ -0,0 +1,13 @@
1
+ require './test/lib_read_write'
2
+
3
+ class TesTcpClientReadServerWrite < Test::Unit::TestCase
4
+ def setup
5
+ @host = ENV["TEST_HOST"] || '127.0.0.1'
6
+ @srv = Kgio::TCPServer.new(@host, 0)
7
+ @port = @srv.addr[1]
8
+ @wr = Kgio::TCPSocket.new(@host, @port)
9
+ @rd = @srv.kgio_accept
10
+ end
11
+
12
+ include LibReadWriteTest
13
+ end
@@ -0,0 +1,73 @@
1
+ require 'test/unit'
2
+ require 'io/nonblock'
3
+ $-w = true
4
+ require 'kgio'
5
+
6
+ class SubSocket < Kgio::Socket
7
+ attr_accessor :foo
8
+ def wait_writable
9
+ @foo = "waited"
10
+ end
11
+ end
12
+
13
+ class TestKgioTcpConnect < Test::Unit::TestCase
14
+
15
+ def setup
16
+ @host = ENV["TEST_HOST"] || '127.0.0.1'
17
+ @srv = Kgio::TCPServer.new(@host, 0)
18
+ @port = @srv.addr[1]
19
+ @addr = Socket.pack_sockaddr_in(@port, @host)
20
+ end
21
+
22
+ def teardown
23
+ @srv.close unless @srv.closed?
24
+ Kgio.accept_cloexec = true
25
+ Kgio.accept_nonblock = false
26
+ Kgio.wait_readable = Kgio.wait_writable = nil
27
+ end
28
+
29
+ def test_new
30
+ sock = Kgio::Socket.new(@addr)
31
+ assert_kind_of Kgio::Socket, sock
32
+ ready = IO.select(nil, [ sock ])
33
+ assert_equal sock, ready[1][0]
34
+ assert_equal nil, sock.kgio_write("HELLO")
35
+ end
36
+
37
+ def test_start
38
+ sock = Kgio::Socket.start(@addr)
39
+ assert_kind_of Kgio::Socket, sock
40
+ ready = IO.select(nil, [ sock ])
41
+ assert_equal sock, ready[1][0]
42
+ assert_equal nil, sock.kgio_write("HELLO")
43
+ end
44
+
45
+ def test_tcp_socket_new_invalid
46
+ assert_raises(ArgumentError) { Kgio::TCPSocket.new('example.com', 80) }
47
+ assert_raises(ArgumentError) { Kgio::TCPSocket.new('999.999.999.999', 80) }
48
+ end
49
+
50
+ def test_tcp_socket_new
51
+ sock = Kgio::TCPSocket.new(@host, @port)
52
+ assert_instance_of Kgio::TCPSocket, sock
53
+ ready = IO.select(nil, [ sock ])
54
+ assert_equal sock, ready[1][0]
55
+ assert_equal nil, sock.kgio_write("HELLO")
56
+ end
57
+
58
+ def test_socket_start
59
+ Kgio::wait_writable = :wait_writable
60
+ sock = SubSocket.start(@addr)
61
+ assert_nil sock.foo
62
+ ready = IO.select(nil, [ sock ])
63
+ assert_equal sock, ready[1][0]
64
+ assert_equal nil, sock.kgio_write("HELLO")
65
+ end
66
+
67
+ def test_wait_writable_set
68
+ Kgio::wait_writable = :wait_writable
69
+ sock = SubSocket.new(@addr)
70
+ assert_equal "waited", sock.foo
71
+ assert_equal nil, sock.kgio_write("HELLO")
72
+ end
73
+ end