From f4e451ce4b79bd9fb1a4a01229a2a8928b2d1f8a Mon Sep 17 00:00:00 2001 From: normal Date: Tue, 15 May 2018 00:08:33 +0000 Subject: test_io_wait_uncommon: new test for uncommon file types This should make portability problems more apparent when we try using ppoll with rb_wait_for_single_fd on FreeBSD or other non-Linux platforms. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63423 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/io/wait/test_io_wait_uncommon.rb | 72 +++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 test/io/wait/test_io_wait_uncommon.rb diff --git a/test/io/wait/test_io_wait_uncommon.rb b/test/io/wait/test_io_wait_uncommon.rb new file mode 100644 index 0000000000..03041fcaf1 --- /dev/null +++ b/test/io/wait/test_io_wait_uncommon.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true +require 'test/unit' +require 'io/wait' + +# test uncommon device types to check portability problems +# We may optimize IO#wait_*able for non-Linux kernels in the future +class TestIOWaitUncommon < Test::Unit::TestCase + def test_tty_wait + begin + tty = File.open('/dev/tty', 'w+') + rescue Errno::ENOENT, Errno::ENXIO => e + skip "/dev/tty: #{e.message} (#{e.class})" + end + assert_include [ nil, tty ], tty.wait_readable(0) + assert_equal tty, tty.wait_writable(0), 'portability test' + ensure + tty&.close + end + + def test_fifo_wait + skip 'no mkfifo' unless File.respond_to?(:mkfifo) && IO.const_defined?(:NONBLOCK) + Dir.mktmpdir('rubytest-fifo') do |dir| + fifo = "#{dir}/fifo" + assert_equal 0, File.mkfifo(fifo) + rd = Thread.new { File.open(fifo, IO::RDONLY|IO::NONBLOCK) } + begin + wr = File.open(fifo, IO::WRONLY|IO::NONBLOCK) + rescue Errno::ENXIO + Thread.pass + end until wr + assert_instance_of File, rd.value + assert_instance_of File, wr + rd = rd.value + assert_nil rd.wait_readable(0) + assert_same wr, wr.wait_writable(0) + wr.syswrite 'hi' + assert_same rd, rd.wait_readable(1) + wr.close + assert_equal 'hi', rd.gets + rd.close + end + end + + # used to find portability problems because some ppoll implementations + # are incomplete and do not work for certain "file" types + def check_dev(dev, m = :wait_readable) + begin + fp = File.open("/dev/#{dev}", m == :wait_readable ? 'r' : 'w') + rescue SystemCallError => e + skip "#{dev} could not be opened #{e.message} (#{e.class})" + end + assert_same fp, fp.__send__(m) + ensure + fp&.close + end + + def test_wait_readable_urandom + check_dev 'urandom' + end + + def test_wait_readable_random + check_dev 'random' + end + + def test_wait_readable_zero + check_dev 'zero' + end + + def test_wait_writable_null + check_dev 'null', :wait_writable + end +end -- cgit v1.2.3