kgio.git  about / heads / tags
kinder, gentler I/O for Ruby
blob d9a2b07848ca0ad22c334588557b3651b4730ac9 3241 bytes (raw)
$ git show v2.8.1:test/test_poll.rb	# shows this blob on the CLI

  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
 
require 'test/unit'
$-w = true
require 'kgio'

class TestPoll < Test::Unit::TestCase
  def teardown
    [ @rd, @wr ].each { |io| io.close unless io.closed? }
  end

  def setup
    @rd, @wr = IO.pipe
  end

  def test_constants
    assert_kind_of Integer, Kgio::POLLIN
    assert_kind_of Integer, Kgio::POLLOUT
    assert_kind_of Integer, Kgio::POLLPRI
    assert_kind_of Integer, Kgio::POLLHUP
    assert_kind_of Integer, Kgio::POLLERR
    assert_kind_of Integer, Kgio::POLLNVAL
  end

  def test_poll_symbol
    set = { @rd => :wait_readable, @wr => :wait_writable }
    res = Kgio.poll(set)
    assert_equal({@wr => Kgio::POLLOUT}, res)
    assert_equal set.object_id, res.object_id
  end

  def test_poll_integer
    set = { @wr => Kgio::POLLOUT|Kgio::POLLHUP }
    res = Kgio.poll(set)
    assert_equal({@wr => Kgio::POLLOUT}, res)
    assert_equal set.object_id, res.object_id
  end

  def test_poll_timeout
    t0 = Time.now
    res = Kgio.poll({}, 10)
    diff = Time.now - t0
    assert diff >= 0.010, "diff=#{diff}"
    assert_nil res
  end

  def test_poll_close
    foo = nil
    thr = Thread.new { sleep 0.100; @wr.close }
    t0 = Time.now
    res = Kgio.poll({@rd => Kgio::POLLIN})
    diff = Time.now - t0
    thr.join
    assert_equal([ @rd ], res.keys)
    assert diff >= 0.010, "diff=#{diff}"
  end

  def test_signal_close
    orig = trap(:USR1) { @rd.close }
    res = nil
    thr = Thread.new { sleep 0.100; Process.kill(:USR1, $$) }
    t0 = Time.now
    assert_raises(IOError) do
      result = Kgio.poll({@rd => Kgio::POLLIN})
      result.each_key { |io| io.read_nonblock(1) }
    end
    diff = Time.now - t0
    thr.join
    assert diff >= 0.010, "diff=#{diff}"
    ensure
      trap(:USR1, orig)
  end

  def test_poll_EINTR
    ok = false
    orig = trap(:USR1) { ok = true }
    thr = Thread.new do
      sleep 0.100
      Process.kill(:USR1, $$)
    end
    t0 = Time.now
    res = Kgio.poll({@rd => Kgio::POLLIN}, 1000)
    diff = Time.now - t0
    thr.join
    assert_nil res
    assert diff >= 1.0, "diff=#{diff}"
    assert ok
    ensure
      trap(:USR1, orig)
  end

  def test_poll_EINTR_changed
    ok = false
    pollset = { @rd => Kgio::POLLIN }
    orig = trap(:USR1) do
      pollset[@wr] = Kgio::POLLOUT
      ok = true
    end
    thr = Thread.new do
      sleep 0.100
      100.times do
        Process.kill(:USR1, $$)
        Thread.pass
      end
    end
    t0 = Time.now
    res = Kgio.poll(pollset, 1000)
    diff = Time.now - t0
    thr.join
    assert_equal({@wr => Kgio::POLLOUT}, res)
    assert diff < 1.0, "diff=#{diff}"
    assert ok
    ensure
      trap(:USR1, orig)
  end

  def test_poll_signal_torture
    usr1 = 0
    empty = 0
    nr = 100
    set = { @rd => Kgio::POLLIN }
    orig = trap(:USR1) { usr1 += 1 }
    pid = fork do
      trap(:USR1, "DEFAULT")
      sleep 0.1
      ppid = Process.ppid
      nr.times { Process.kill(:USR1, ppid); sleep 0.05 }
      @wr.syswrite('.')
      exit!(0)
    end

    empty += 1 until Kgio.poll(set.dup, 100)
    _, status = Process.waitpid2(pid)
    assert status.success?, status.inspect
    assert usr1 > 0, "usr1: #{usr1}"
  ensure
    trap(:USR1, orig)
  end unless RUBY_PLATFORM =~ /kfreebsd-gnu/
end if Kgio.respond_to?(:poll)

git clone git://yhbt.net/kgio.git
git clone https://yhbt.net/kgio.git