sleepy_penguin.git  about / heads / tags
Linux I/O events for Ruby
blob 15d3da49d124be74c9f3fa744a268e7e58dc910d 3756 bytes (raw)
$ git show pu:test/test_epoll_optimizations.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
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)

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