1# -*- coding: us-ascii -*- 2# frozen_string_literal: false 3require 'test/unit' 4require 'timeout' 5require 'socket' 6begin 7 require 'io/wait' 8rescue LoadError 9end 10 11class TestIOWait < Test::Unit::TestCase 12 13 def setup 14 if /mswin|mingw/ =~ RUBY_PLATFORM 15 @r, @w = Socket.pair(Socket::AF_INET, Socket::SOCK_STREAM, 0) 16 else 17 @r, @w = IO.pipe 18 end 19 end 20 21 def teardown 22 @r.close unless @r.closed? 23 @w.close unless @w.closed? 24 end 25 26 def test_nread 27 assert_equal 0, @r.nread 28 @w.syswrite "." 29 sleep 0.1 30 assert_equal 1, @r.nread 31 end 32 33 def test_nread_buffered 34 @w.syswrite ".\n!" 35 assert_equal ".\n", @r.gets 36 assert_equal 1, @r.nread 37 end 38 39 def test_ready? 40 assert_not_predicate @r, :ready?, "shouldn't ready, but ready" 41 @w.syswrite "." 42 sleep 0.1 43 assert_predicate @r, :ready?, "should ready, but not" 44 end 45 46 def test_buffered_ready? 47 @w.syswrite ".\n!" 48 assert_equal ".\n", @r.gets 49 assert_predicate @r, :ready? 50 end 51 52 def test_wait 53 assert_nil @r.wait(0) 54 @w.syswrite "." 55 sleep 0.1 56 assert_equal @r, @r.wait(0) 57 end 58 59 def test_wait_buffered 60 @w.syswrite ".\n!" 61 assert_equal ".\n", @r.gets 62 assert_equal true, @r.wait(0) 63 end 64 65 def test_wait_forever 66 th = Thread.new { sleep 0.01; @w.syswrite "." } 67 assert_equal @r, @r.wait 68 ensure 69 th.join 70 end 71 72 def test_wait_eof 73 th = Thread.new { sleep 0.01; @w.close } 74 ret = nil 75 assert_nothing_raised(Timeout::Error) do 76 Timeout.timeout(0.1) { ret = @r.wait } 77 end 78 assert_equal @r, ret 79 ensure 80 th.join 81 end 82 83 def test_wait_readable 84 assert_nil @r.wait_readable(0) 85 @w.syswrite "." 86 sleep 0.1 87 assert_equal @r, @r.wait_readable(0) 88 end 89 90 def test_wait_readable_buffered 91 @w.syswrite ".\n!" 92 assert_equal ".\n", @r.gets 93 assert_equal true, @r.wait_readable(0) 94 end 95 96 def test_wait_readable_forever 97 th = Thread.new { sleep 0.01; @w.syswrite "." } 98 assert_equal @r, @r.wait_readable 99 ensure 100 th.join 101 end 102 103 def test_wait_readable_eof 104 th = Thread.new { sleep 0.01; @w.close } 105 ret = nil 106 assert_nothing_raised(Timeout::Error) do 107 Timeout.timeout(0.1) { ret = @r.wait_readable } 108 end 109 assert_equal @r, ret 110 ensure 111 th.join 112 end 113 114 def test_wait_writable 115 assert_equal @w, @w.wait_writable 116 end 117 118 def test_wait_writable_timeout 119 assert_equal @w, @w.wait_writable(0.01) 120 written = fill_pipe 121 assert_nil @w.wait_writable(0.01) 122 @r.read(written) 123 assert_equal @w, @w.wait_writable(0.01) 124 end 125 126 def test_wait_writable_EPIPE 127 fill_pipe 128 @r.close 129 assert_equal @w, @w.wait_writable 130 end 131 132 def test_wait_writable_closed 133 @w.close 134 assert_raise(IOError) { @w.wait_writable } 135 end 136 137 def test_wait_readwrite 138 assert_equal @r.wait(0, :write), @r.wait(0, :read_write) 139 end 140 141 def test_wait_readwrite_timeout 142 assert_equal @w, @w.wait(0.01, :read_write) 143 written = fill_pipe 144 if /aix/ =~ RUBY_PLATFORM 145 # IO#wait internally uses select(2) on AIX. 146 # AIX's select(2) returns "readable" for the write-side fd 147 # of a pipe, so @w.wait(0.01, :read_write) does not return nil. 148 assert_equal @w, @w.wait(0.01, :read_write) 149 else 150 assert_nil @w.wait(0.01, :read_write) 151 end 152 @r.read(written) 153 assert_equal @w, @w.wait(0.01, :read_write) 154 end 155 156private 157 158 def fill_pipe 159 written = 0 160 buf = " " * 4096 161 begin 162 written += @w.write_nonblock(buf) 163 rescue Errno::EAGAIN, Errno::EWOULDBLOCK 164 return written 165 end while true 166 end 167end if IO.method_defined?(:wait) 168