1 # -*- encoding: binary -*-
7 $stderr.sync = $stdout.sync = true
9 class Test_POSIX_MQ < Test::Unit::TestCase
10 METHODS = Set.new(POSIX_MQ.instance_methods.map { |x| x.to_sym })
12 METHODS.include?(:to_io) or
13 warn "POSIX_MQ#to_io not supported on this platform: #{RUBY_PLATFORM}"
14 METHODS.include?(:notify) or
15 warn "POSIX_MQ#notify not supported on this platform: #{RUBY_PLATFORM}"
19 @path = "/posix_mq.rb.#{Time.now.to_i}.#$$.#{rand}"
24 assert_equal @mq, @mq.unlink
31 assert_nothing_raised do
32 2025.times { POSIX_MQ.new(@path, :rw) }
36 def test_name_clobber_proof
37 @mq = POSIX_MQ.new(@path, :rw)
40 assert_nothing_raised { @mq.name.gsub!(/\A/, "foo") }
41 assert_equal tmp, @mq.name
42 assert tmp.object_id != @mq.name.object_id
46 @mq = POSIX_MQ.new(@path, :rw)
48 assert_equal @mq.object_id, dup.object_id
50 assert_equal @mq.object_id, clone.object_id
53 def test_timed_receive
55 @mq = POSIX_MQ.new(@path, :rw)
56 assert ! @mq.nonblock?
58 assert_raises(Errno::ETIMEDOUT) { @mq.receive "", interval }
59 elapsed = Time.now - t0
60 assert elapsed > interval
65 @mq = POSIX_MQ.new(@path, :rw, 0666, POSIX_MQ::Attr[0, 1, 1, 0])
66 assert ! @mq.nonblock?
67 assert_nothing_raised { @mq.send "A", 1, interval }
69 assert_raises(Errno::ETIMEDOUT) { @mq.send "B", 1, interval }
70 elapsed = Time.now - t0
71 assert elapsed > interval
75 POSIX_MQ.open(@path, IO::CREAT|IO::WRONLY, 0666) do |mq|
77 assert mq.kind_of?(POSIX_MQ)
78 assert_equal @path, mq.name
79 assert_nil mq.send("HI", 0)
80 assert_equal 1, mq.attr.curmsgs
82 assert_raises(IOError) { mq.close }
86 POSIX_MQ.unlink(@path)
90 path = "" << @path.dup
92 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
93 assert_equal path, @mq.name
97 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
98 rd = POSIX_MQ.new @path, IO::RDONLY
99 assert_equal @mq.name, rd.name
103 def test_send0_receive
104 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
105 assert_equal(@mq, @mq << "hello")
106 assert_equal [ "hello", 0 ], @mq.receive
110 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
111 @mq << "hello" << "world"
112 assert_equal [ "hello", 0 ], @mq.receive
113 assert_equal [ "world", 0 ], @mq.receive
117 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
119 assert_equal "hello", @mq.shift
124 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
126 assert_equal "hello", @mq.shift(buf)
127 assert_equal "hello", buf
130 def test_send_receive
131 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
132 assert_nil @mq.send("hello", 0)
133 assert_equal [ "hello", 0 ], @mq.receive
136 def test_send_receive_buf
138 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
139 assert_nil @mq.send("hello", 0)
140 assert_equal [ "hello", 0 ], @mq.receive(buf)
141 assert_equal "hello", buf
144 def test_send_receive_prio
145 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
146 assert_nil @mq.send("hello", 2)
147 assert_equal [ "hello", 2 ], @mq.receive
151 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
153 assert_equal POSIX_MQ::Attr, mq_attr.class
154 assert mq_attr.flags.kind_of?(Integer)
155 assert mq_attr.maxmsg.kind_of?(Integer)
156 assert mq_attr.msgsize.kind_of?(Integer)
157 assert mq_attr.curmsgs.kind_of?(Integer)
161 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
162 assert @mq.to_io.kind_of?(IO)
163 assert_nothing_raised { IO.select([@mq], nil, nil, 0) }
164 end if METHODS.include?(:to_io)
168 orig = trap(:USR1) { wr.syswrite('.') }
169 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
170 assert_nothing_raised { @mq.notify = :SIGUSR1 }
171 assert_nothing_raised { @mq.send("hello", 0) }
172 assert_equal [[rd], [], []], IO.select([rd], nil, nil, 10)
173 assert_equal '.', rd.sysread(1)
174 assert_nil(@mq.notify = nil)
175 assert_nothing_raised { @mq.send("hello", 0) }
176 assert_nil IO.select([rd], nil, nil, 0.1)
182 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
183 assert_nothing_raised { @mq.notify = false }
194 _, status = Process.waitpid2(pid)
195 assert status.success?, status.inspect
199 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
200 mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK)
202 assert_equal IO::NONBLOCK, @mq.attr.flags
203 assert mq_attr.flags.kind_of?(Integer)
207 assert_equal 0, @mq.attr.flags
210 def test_new_nonblocking
211 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY|IO::NONBLOCK, 0666
215 def test_new_blocking
216 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
217 assert ! @mq.nonblock?
220 def test_nonblock_toggle
221 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
222 assert ! @mq.nonblock?
226 assert ! @mq.nonblock?
227 assert_raises(ArgumentError) { @mq.nonblock = nil }
231 @mq = POSIX_MQ.new @path, :w
232 assert_equal IO::WRONLY, @mq.to_io.fcntl(Fcntl::F_GETFL)
233 end if METHODS.include?(:to_io)
236 @mq = POSIX_MQ.new @path, :w
238 assert_nothing_raised { mq = POSIX_MQ.new @path, :r }
239 assert_equal IO::RDONLY, mq.to_io.fcntl(Fcntl::F_GETFL)
241 end if METHODS.include?(:to_io)
243 def test_new_path_only
244 @mq = POSIX_MQ.new @path, :w
246 assert_nothing_raised { mq = POSIX_MQ.new @path }
247 assert_equal IO::RDONLY, mq.to_io.fcntl(Fcntl::F_GETFL)
249 end if METHODS.include?(:to_io)
252 @mq = POSIX_MQ.new @path, :rw
253 assert_equal IO::RDWR, @mq.to_io.fcntl(Fcntl::F_GETFL)
254 end if METHODS.include?(:to_io)
257 mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK, 1, 1, 0)
258 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666, mq_attr
260 assert_equal mq_attr, @mq.attr
262 assert_raises(Errno::EAGAIN) { @mq.receive }
263 assert_raises(Errno::EMSGSIZE) { @mq << '..' }
264 assert_nothing_raised { @mq << '.' }
265 assert_equal [ '.', 0 ], @mq.receive
266 assert_nothing_raised { @mq << '.' }
267 assert_raises(Errno::EAGAIN) { @mq << '.' }
271 min_posix_mq_prio_max = 31 # defined by POSIX
272 assert POSIX_MQ::PRIO_MAX >= min_posix_mq_prio_max
276 assert POSIX_MQ::OPEN_MAX.kind_of?(Integer)
279 def test_notify_block_replace
281 @mq = POSIX_MQ.new(@path, :rw)
282 assert_nothing_raised { @mq.notify { |mq| q << mq } }
283 assert_nothing_raised { Process.waitpid2(fork { @mq << "hi" }) }
284 assert_equal @mq.object_id, q.pop.object_id
285 assert_equal "hi", @mq.receive.first
286 assert_nothing_raised { @mq.notify { |mq| q << "hi" } }
287 assert_nothing_raised { Process.waitpid2(fork { @mq << "bye" }) }
288 assert_equal "hi", q.pop
289 end if METHODS.include?(:notify)
291 def test_notify_thread
293 @mq = POSIX_MQ.new(@path, :rw)
294 @mq.notify { |mq| q << Thread.current }
297 assert x.instance_of?(Thread)
298 assert Thread.current != x
299 end if METHODS.include?(:notify)