about summary refs log tree commit homepage
path: root/test/test_posix_mq.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_posix_mq.rb')
-rw-r--r--test/test_posix_mq.rb225
1 files changed, 225 insertions, 0 deletions
diff --git a/test/test_posix_mq.rb b/test/test_posix_mq.rb
new file mode 100644
index 0000000..00b0f5a
--- /dev/null
+++ b/test/test_posix_mq.rb
@@ -0,0 +1,225 @@
+# -*- encoding: binary -*-
+require 'test/unit'
+require 'posix_mq'
+require 'fcntl'
+$stderr.sync = $stdout.sync = true
+
+class Test_POSIX_MQ < Test::Unit::TestCase
+
+  HAVE_TO_IO = if POSIX_MQ.instance_methods.grep(/\Ato_io\z/).empty?
+    warn "POSIX_MQ#to_io not supported on this platform: #{RUBY_PLATFORM}"
+    false
+  else
+    true
+  end
+
+  def setup
+    @mq = nil
+    @path = "/posix_mq.rb.#{Time.now.to_i}.#$$.#{rand}"
+  end
+
+  def teardown
+    @mq or return
+    assert_equal @mq, @mq.unlink
+    assert ! @mq.closed?
+    assert_nil @mq.close
+    assert @mq.closed?
+  end
+
+  def test_timed_receive
+    interval = 0.01
+    @mq = POSIX_MQ.new(@path, :rw)
+    assert ! @mq.nonblock?
+    t0 = Time.now
+    assert_raises(Errno::ETIMEDOUT) { @mq.receive "", interval }
+    elapsed = Time.now - t0
+    assert elapsed > interval
+  end
+
+  def test_timed_send
+    interval = 0.01
+    @mq = POSIX_MQ.new(@path, :rw, 0666, POSIX_MQ::Attr[0, 1, 1, 0])
+    assert ! @mq.nonblock?
+    assert_nothing_raised { @mq.send "A", 1, interval }
+    t0 = Time.now
+    assert_raises(Errno::ETIMEDOUT) { @mq.send "B", 1, interval }
+    elapsed = Time.now - t0
+    assert elapsed > interval
+  end
+
+  def test_open
+    POSIX_MQ.open(@path, IO::CREAT|IO::WRONLY, 0666) do |mq|
+      @mq = mq
+      assert mq.kind_of?(POSIX_MQ)
+      assert_equal @path, mq.name
+      assert_nil mq.send("HI", 0)
+      assert_equal 1, mq.attr.curmsgs
+      assert_nil mq.close
+      assert_raises(IOError) { mq.close }
+    end
+    assert @mq.closed?
+    @mq = nil
+    POSIX_MQ.unlink(@path)
+  end
+
+  def test_name
+    path = "" << @path.dup
+    path.freeze
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
+    assert_equal path, @mq.name
+  end
+
+  def test_new_readonly
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
+    rd = POSIX_MQ.new @path, IO::RDONLY
+    assert_equal @mq.name, rd.name
+    assert_nil rd.close
+  end
+
+  def test_send0_receive
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
+    assert_equal(@mq, @mq << "hello")
+    assert_equal [ "hello", 0 ], @mq.receive
+  end
+
+  def test_send0_chain
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
+    @mq << "hello" << "world"
+    assert_equal [ "hello", 0 ], @mq.receive
+    assert_equal [ "world", 0 ], @mq.receive
+  end
+
+  def test_send_receive
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
+    assert_nil @mq.send("hello", 0)
+    assert_equal [ "hello", 0 ], @mq.receive
+  end
+
+  def test_send_receive_buf
+    buf = ""
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
+    assert_nil @mq.send("hello", 0)
+    assert_equal [ "hello", 0 ], @mq.receive(buf)
+    assert_equal "hello", buf
+  end
+
+  def test_send_receive_prio
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
+    assert_nil @mq.send("hello", 2)
+    assert_equal [ "hello", 2 ], @mq.receive
+  end
+
+  def test_getattr
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
+    mq_attr = @mq.attr
+    assert_equal POSIX_MQ::Attr, mq_attr.class
+    assert mq_attr.flags.kind_of?(Integer)
+    assert mq_attr.maxmsg.kind_of?(Integer)
+    assert mq_attr.msgsize.kind_of?(Integer)
+    assert mq_attr.curmsgs.kind_of?(Integer)
+  end
+
+  def test_to_io
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
+    assert @mq.to_io.kind_of?(IO)
+    assert_nothing_raised { IO.select([@mq], nil, nil, 0) }
+  end if HAVE_TO_IO
+
+  def test_notify
+    rd, wr = IO.pipe
+    orig = trap(:USR1) { wr.syswrite('.') }
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
+    assert_nothing_raised { @mq.notify = :SIGUSR1 }
+    assert_nothing_raised { @mq.send("hello", 0) }
+    assert_equal [[rd], [], []], IO.select([rd], nil, nil, 10)
+    assert_equal '.', rd.sysread(1)
+    assert_nil(@mq.notify = nil)
+    assert_nothing_raised { @mq.send("hello", 0) }
+    assert_nil IO.select([rd], nil, nil, 0.1)
+    assert_raises(Errno::EBUSY) { @mq.notify = :USR1 }
+    ensure
+      trap(:USR1, orig)
+  end
+
+  def test_setattr
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
+    mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK)
+    @mq.attr = mq_attr
+    assert_equal IO::NONBLOCK, @mq.attr.flags
+    assert mq_attr.flags.kind_of?(Integer)
+
+    mq_attr.flags = 0
+    @mq.attr = mq_attr
+    assert_equal 0, @mq.attr.flags
+  end
+
+  def test_new_nonblocking
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY|IO::NONBLOCK, 0666
+    assert @mq.nonblock?
+  end
+
+  def test_new_blocking
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
+    assert ! @mq.nonblock?
+  end
+
+  def test_nonblock_toggle
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
+    assert ! @mq.nonblock?
+    @mq.nonblock = true
+    assert @mq.nonblock?
+    @mq.nonblock = false
+    assert ! @mq.nonblock?
+    assert_raises(ArgumentError) { @mq.nonblock = nil }
+  end
+
+  def test_new_sym_w
+    @mq = POSIX_MQ.new @path, :w
+    assert_equal IO::WRONLY, @mq.to_io.fcntl(Fcntl::F_GETFL)
+  end if HAVE_TO_IO
+
+  def test_new_sym_r
+    @mq = POSIX_MQ.new @path, :w
+    mq = nil
+    assert_nothing_raised { mq = POSIX_MQ.new @path, :r }
+    assert_equal IO::RDONLY, mq.to_io.fcntl(Fcntl::F_GETFL)
+    assert_nil mq.close
+  end if HAVE_TO_IO
+
+  def test_new_path_only
+    @mq = POSIX_MQ.new @path, :w
+    mq = nil
+    assert_nothing_raised { mq = POSIX_MQ.new @path }
+    assert_equal IO::RDONLY, mq.to_io.fcntl(Fcntl::F_GETFL)
+    assert_nil mq.close
+  end if HAVE_TO_IO
+
+  def test_new_sym_wr
+    @mq = POSIX_MQ.new @path, :rw
+    assert_equal IO::RDWR, @mq.to_io.fcntl(Fcntl::F_GETFL)
+  end if HAVE_TO_IO
+
+  def test_new_attr
+    mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK, 1, 1, 0)
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666, mq_attr
+    assert @mq.nonblock?
+    assert_equal mq_attr, @mq.attr
+
+    assert_raises(Errno::EAGAIN) { @mq.receive }
+    assert_raises(Errno::EMSGSIZE) { @mq << '..' }
+    assert_nothing_raised { @mq << '.' }
+    assert_equal [ '.', 0 ], @mq.receive
+    assert_nothing_raised { @mq << '.' }
+    assert_raises(Errno::EAGAIN) { @mq << '.' }
+  end
+
+  def test_prio_max
+    min_posix_mq_prio_max = 31 # defined by POSIX
+    assert POSIX_MQ::PRIO_MAX >= min_posix_mq_prio_max
+  end
+
+  def test_open_max
+    assert POSIX_MQ::OPEN_MAX.kind_of?(Integer)
+  end
+
+end