sleepy_penguin.git  about / heads / tags
Linux I/O events for Ruby
blob 7df145d42e4c80bbf78da2a9a4088c41b4389d1a 3114 bytes (raw)
$ git show HEAD:test/test_kqueue_io.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
 
require_relative 'helper'

class TestKqueueIO < Test::Unit::TestCase
  include SleepyPenguin

  def setup
    @to_close = []
  end

  def teardown
    @to_close.each do |io|
      io.close unless io.closed?
    end
  end

  def test_io_like
    kq = Kqueue::IO.new
    @to_close << kq
    assert_equal kq, kq.to_io
    assert_kind_of Integer, kq.fileno
  end

  def test_bad_type
    kq = Kqueue::IO.new
    @to_close << kq
    assert_raises(TypeError) { kq.kevent("HI") }
  end

  def test_delete
    kq = Kqueue::IO.new
    @to_close << kq
    r, w = IO.pipe
    @to_close << r
    @to_close << w
    kq.kevent(Kevent[r.fileno, EvFilt::READ, Ev::ADD, 0, 0, r])
    w.syswrite "."
    2.times do
      got = []
      kq.kevent(nil, 1, 0) { |*args| got << args }
      assert_equal 1, got.size
    end
    kq.kevent(Kevent[r.fileno, EvFilt::READ|EvFilt::WRITE, Ev::DELETE, 0, 0, 0])
    got = []
    kq.kevent(nil, 1, 0) { |*args| got << args }
    assert_equal 0, got.size
  end

  def test_multi_event
    kq = Kqueue::IO.new
    @to_close << kq
    list = []
    pipes = [ IO.pipe, IO.pipe, IO.pipe, IO.pipe ]
    pipes.each do |(r,w)|
      @to_close << r
      @to_close << w
      list << Kevent[r.fileno, EvFilt::READ, Ev::ADD|Ev::ONESHOT, 0, 0, r]
    end
    kq.kevent(list)

    pipes.each do |(_,w)|
      w.syswrite('.')
    end
    received = []
    seen = {}
    kq.kevent(nil, 1) do |*args|
      received << args
      assert_equal 6, args.size
      assert_kind_of IO, args[5]
      assert_nil seen[args[5]]
      seen[args[5]] = true
    end

    assert_equal 1, received.size

    kq.kevent(nil, 666) do |*args|
      received << args
      assert_equal 6, args.size
      assert_kind_of IO, args[5]
      assert_nil seen[args[5]]
      seen[args[5]] = true
    end
    assert_equal 4, received.size
  end

  def test_xthread
    kq = Kqueue::IO.new
    assert_kind_of IO, kq
    rd, wr = IO.pipe
    ev = Kevent[rd.fileno, EvFilt::READ, Ev::ADD|Ev::ONESHOT, 0, 0, rd]
    thr = Thread.new do
      kq.kevent(ev)
      wr.syswrite "."
    end

    events = []
    n = kq.kevent(nil, 1) do |ident,filter,flags,fflags,data,udata|
      events << [ ident,filter,flags,fflags,data,udata ]
    end
    assert_equal 1, events.size
    assert_equal rd.fileno, events[0][0]
    assert_equal EvFilt::READ, events[0][1]
    assert_equal 1, n

    thr.join

    # we should be drained
    events = []
    n = kq.kevent(nil, 1, 0) do |ident,filter,flags,fflags,data,udata|
      events << [ ident,filter,flags,fflags,data,udata ]
    end
    assert_equal 0, events.size
    assert_equal 0, n

    # synchronous add
    events = []
    ev = Kevent[wr.fileno, EvFilt::WRITE, Ev::ADD|Ev::ONESHOT, 0, 0, wr]
    kq.kevent(ev)
    n = kq.kevent(nil, 1, 0) do |ident,filter,flags,fflags,data,udata|
      events << [ ident,filter,flags,fflags,data,udata ]
    end
    assert_equal 1, events.size
    assert_equal wr.fileno, events[0][0]
    assert_equal EvFilt::WRITE, events[0][1]
    assert_equal 1, n
  ensure
    kq.close
    rd.close if rd
    wr.close if wr
  end
end if defined?(SleepyPenguin::Kqueue::IO)

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