preliminary kqueue support
[sleepy_penguin.git] / test / test_signalfd.rb
blob0330e70512e5f8142b36866ac5c441aeeccde2aa
1 require 'test/unit'
2 require "dl"
3 begin
4   require "dl/func"
5 rescue LoadError
6 end
7 $-w = true
8 require 'sleepy_penguin'
10 class TestSignalFD < Test::Unit::TestCase
11   include SleepyPenguin
13   def setup
14     @sfd = nil
15     trap(:USR1, "IGNORE")
16     trap(:USR2, "IGNORE")
17   end
19   def teardown
20     @sfd.close if @sfd && ! @sfd.closed?
21     trap(:USR1, "DEFAULT")
22     trap(:USR2, "DEFAULT")
23   end
25   def test_rt_constants
26     assert [33,34].include?(SignalFD::RTMIN)
27     assert_equal 64, SignalFD::RTMAX
28   end
30   def test_new_with_flags
31     @sfd = SignalFD.new(%w(USR1), [:CLOEXEC,:NONBLOCK])
32     assert_instance_of SignalFD, @sfd
33   end if defined?(SignalFD::CLOEXEC) && defined?(SignalFD::NONBLOCK)
35   def test_new_with_sym_flag
36     @sfd = SignalFD.new(%w(USR1), :CLOEXEC)
37     assert_instance_of SignalFD, @sfd
38   end if defined?(SignalFD::CLOEXEC)
40   def test_take
41     @sfd = SignalFD.new(%w(USR1), 0)
42     pid = fork { sleep 0.01; Process.kill(:USR1, Process.ppid) }
43     siginfo = @sfd.take
44     assert_equal Signal.list["USR1"], siginfo.signo
45     assert_equal pid, siginfo.pid
46     assert Process.waitpid2(pid)[1].success?
47   end if RUBY_VERSION =~ %r{\A1\.9}
49   def test_take_nonblock
50     @sfd = SignalFD.new(%w(USR1), :NONBLOCK)
51     assert_nil @sfd.take(true)
52     assert_nil IO.select [ @sfd ], nil, nil, 0
53     pid = fork { sleep 0.01; Process.kill(:USR1, Process.ppid) }
54     siginfo = @sfd.take(true)
55     if siginfo
56       assert_equal Signal.list["USR1"], siginfo.signo
57       assert_equal pid, siginfo.pid
58     else
59       warn "WARNING: SignalFD#take(nonblock=true) broken"
60     end
61     assert Process.waitpid2(pid)[1].success?
62   end if RUBY_VERSION =~ %r{\A1\.9}
64   def test_update
65     assert_nothing_raised do
66       @sfd = SignalFD.new
67       @sfd.update! Signal.list["USR1"]
68       @sfd.update! [ "USR1", Signal.list["USR2"] ]
69       @sfd.update! [ "USR1", :USR2 ]
70       @sfd.update! [ Signal.list["USR1"], Signal.list["USR2"] ]
71     end
72   end
74   def test_with_sigqueue
75     sig = Signal.list["USR2"]
76     @sfd = SignalFD.new(:USR2)
77     libc = DL::Handle.new("libc.so.6")
78     if defined?(DL::Function)
79       sigqueue = libc["sigqueue"]
80       sigqueue = DL::CFunc.new(sigqueue, DL::TYPE_INT, "sigqueue")
81       args = [DL::TYPE_INT, DL::TYPE_INT,DL::TYPE_INT]
82       sigqueue = DL::Function.new(sigqueue, args, DL::TYPE_INT)
83     else
84       sigqueue = libc["sigqueue", "IIII"]
85     end
86     pid = fork { sleep 0.01; sigqueue.call(Process.ppid, sig, 666)  }
87     siginfo = @sfd.take
88     assert_equal sig, siginfo.signo
89     assert_equal pid, siginfo.pid
90     assert Process.waitpid2(pid)[1].success?
91     assert_equal 666, siginfo.ptr
92     assert_equal 666, siginfo.int
93   end if RUBY_VERSION =~ %r{\A1\.9}
94 end if defined?(SleepyPenguin::SignalFD)