1 # -*- encoding: binary -*-
6 $stderr.sync = $stdout.sync = true
8 class Test_POSIX_MQ < Test::Unit::TestCase
10 POSIX_MQ.method_defined?(:to_io) or
11 warn "POSIX_MQ#to_io not supported on this platform: #{RUBY_PLATFORM}"
12 POSIX_MQ.method_defined?(:notify) or
13 warn "POSIX_MQ#notify not supported on this platform: #{RUBY_PLATFORM}"
17 @path = "/posix_mq.rb.#{Time.now.to_i}.#$$.#{rand}"
22 assert_equal @mq, @mq.unlink
29 assert_nothing_raised do
30 2025.times { POSIX_MQ.new(@path, :rw) }
31 2025.times { @mq = POSIX_MQ.new(@path, :rw); @mq.to_io }
35 def test_name_clobber_proof
36 @mq = POSIX_MQ.new(@path, :rw)
39 assert_nothing_raised { @mq.name.gsub!(/\A/, "foo") }
40 assert_equal tmp, @mq.name
41 assert tmp.object_id != @mq.name.object_id
45 @mq = POSIX_MQ.new(@path, :rw)
47 assert_equal @mq.object_id, dup.object_id
49 assert_equal @mq.object_id, clone.object_id
52 def test_timed_receive_float
54 @mq = POSIX_MQ.new(@path, :rw)
55 assert ! @mq.nonblock?
57 assert_raises(Errno::ETIMEDOUT) { @mq.receive "", interval }
58 elapsed = Time.now - t0
59 assert elapsed > interval, elapsed.inspect
60 assert elapsed < 0.02, elapsed.inspect
63 def test_timed_receive_divmod
65 def interval.divmod(num)
66 num == 1 ? [ 0, 0.01 ] : nil
68 @mq = POSIX_MQ.new(@path, :rw)
69 assert ! @mq.nonblock?
71 assert_raises(Errno::ETIMEDOUT) { @mq.receive "", interval }
72 elapsed = Time.now - t0
73 assert elapsed >= 0.01, elapsed.inspect
74 assert elapsed <= 0.02, elapsed.inspect
77 def test_timed_receive_fixnum
79 @mq = POSIX_MQ.new(@path, :rw)
80 assert ! @mq.nonblock?
82 assert_raises(Errno::ETIMEDOUT) { @mq.receive "", interval }
83 elapsed = Time.now - t0
84 assert elapsed >= interval, elapsed.inspect
85 assert elapsed < 1.10, elapsed.inspect
90 @mq = POSIX_MQ.new(@path, :rw, 0666, POSIX_MQ::Attr[0, 1, 1, 0])
91 assert ! @mq.nonblock?
92 assert_nothing_raised { @mq.send "A", 1, interval }
94 assert_raises(Errno::ETIMEDOUT) { @mq.send "B", 1, interval }
95 elapsed = Time.now - t0
96 assert elapsed > interval
100 POSIX_MQ.open(@path, IO::CREAT|IO::WRONLY, 0666) do |mq|
102 assert mq.kind_of?(POSIX_MQ)
103 assert_equal @path, mq.name
104 assert_nil mq.send("HI", 0)
105 assert_equal 1, mq.attr.curmsgs
107 assert_raises(IOError) { mq.close }
111 POSIX_MQ.unlink(@path)
115 path = "" << @path.dup
117 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
118 assert_equal path, @mq.name
121 def test_new_readonly
122 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
123 rd = POSIX_MQ.new @path, IO::RDONLY
124 assert_equal @mq.name, rd.name
128 def test_send0_receive
129 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
130 assert_equal(@mq, @mq << "hello")
131 assert_equal [ "hello", 0 ], @mq.receive
135 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
136 @mq << "hello" << "world"
137 assert_equal [ "hello", 0 ], @mq.receive
138 assert_equal [ "world", 0 ], @mq.receive
142 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
144 assert_equal "hello", @mq.shift
149 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
151 assert_equal "hello", @mq.shift(buf)
152 assert_equal "hello", buf
155 def test_send_receive
156 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
157 assert_nil @mq.send("hello", 0)
158 assert_equal [ "hello", 0 ], @mq.receive
161 def test_send_receive_buf
163 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
164 assert_nil @mq.send("hello", 0)
165 assert_equal [ "hello", 0 ], @mq.receive(buf)
166 assert_equal "hello", buf
169 def test_send_receive_prio
170 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
171 assert_nil @mq.send("hello", 2)
172 assert_equal [ "hello", 2 ], @mq.receive
176 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
178 assert_equal POSIX_MQ::Attr, mq_attr.class
179 assert mq_attr.flags.kind_of?(Integer)
180 assert mq_attr.maxmsg.kind_of?(Integer)
181 assert mq_attr.msgsize.kind_of?(Integer)
182 assert mq_attr.curmsgs.kind_of?(Integer)
186 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
187 assert @mq.to_io.kind_of?(IO)
188 assert_nothing_raised { IO.select([@mq], nil, nil, 0) }
189 end if POSIX_MQ.method_defined?(:to_io)
193 orig = trap(:USR1) { wr.syswrite('.') }
194 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
195 assert_nothing_raised { @mq.notify = :SIGUSR1 }
196 assert_nothing_raised { @mq.send("hello", 0) }
197 assert_equal [[rd], [], []], IO.select([rd], nil, nil, 10)
198 assert_equal '.', rd.sysread(1)
199 assert_nil(@mq.notify = nil)
200 assert_nothing_raised { @mq.send("hello", 0) }
201 assert_nil IO.select([rd], nil, nil, 0.1)
207 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
208 assert_nothing_raised { @mq.notify = false }
219 _, status = Process.waitpid2(pid)
220 assert status.success?, status.inspect
224 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
225 mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK)
227 assert_equal IO::NONBLOCK, @mq.attr.flags
228 assert mq_attr.flags.kind_of?(Integer)
232 assert_equal 0, @mq.attr.flags
235 def test_new_nonblocking
236 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY|IO::NONBLOCK, 0666
240 def test_new_blocking
241 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
242 assert ! @mq.nonblock?
245 def test_nonblock_toggle
246 @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
247 assert ! @mq.nonblock?
251 assert ! @mq.nonblock?
252 assert_raises(ArgumentError) { @mq.nonblock = nil }
256 @mq = POSIX_MQ.new @path, :w
257 assert_equal IO::WRONLY, @mq.to_io.fcntl(Fcntl::F_GETFL)
258 end if POSIX_MQ.method_defined?(:to_io)
261 @mq = POSIX_MQ.new @path, :w
263 assert_nothing_raised { mq = POSIX_MQ.new @path, :r }
264 assert_equal IO::RDONLY, mq.to_io.fcntl(Fcntl::F_GETFL)
266 end if POSIX_MQ.method_defined?(:to_io)
268 def test_new_path_only
269 @mq = POSIX_MQ.new @path, :w
271 assert_nothing_raised { mq = POSIX_MQ.new @path }
272 assert_equal IO::RDONLY, mq.to_io.fcntl(Fcntl::F_GETFL)
274 end if POSIX_MQ.method_defined?(:to_io)
277 @mq = POSIX_MQ.new @path, :rw
278 assert_equal IO::RDWR, @mq.to_io.fcntl(Fcntl::F_GETFL)
279 end if POSIX_MQ.method_defined?(:to_io)
282 mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK, 1, 1, 0)
283 @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666, mq_attr
285 assert_equal mq_attr, @mq.attr
287 assert_raises(Errno::EAGAIN) { @mq.receive }
288 assert_raises(Errno::EMSGSIZE) { @mq << '..' }
289 assert_nothing_raised { @mq << '.' }
290 assert_equal [ '.', 0 ], @mq.receive
291 assert_nothing_raised { @mq << '.' }
292 assert_raises(Errno::EAGAIN) { @mq << '.' }
296 min_posix_mq_prio_max = 31 # defined by POSIX
297 assert POSIX_MQ::PRIO_MAX >= min_posix_mq_prio_max
301 assert POSIX_MQ::OPEN_MAX.kind_of?(Integer)
304 def test_notify_block_replace
306 @mq = POSIX_MQ.new(@path, :rw)
307 assert_nothing_raised { @mq.notify { |mq| q << mq } }
308 assert_nothing_raised { Process.waitpid2(fork { @mq << "hi" }) }
309 assert_equal @mq.object_id, q.pop.object_id
310 assert_equal "hi", @mq.receive.first
311 assert_nothing_raised { @mq.notify { |mq| q << "hi" } }
312 assert_nothing_raised { Process.waitpid2(fork { @mq << "bye" }) }
313 assert_equal "hi", q.pop
314 end if POSIX_MQ.method_defined?(:notify)
316 def test_notify_thread
318 @mq = POSIX_MQ.new(@path, :rw)
319 @mq.notify { |mq| q << Thread.current }
322 assert x.instance_of?(Thread)
323 assert Thread.current != x
324 end if POSIX_MQ.method_defined?(:notify)