initial commit
[ruby_posix_mq.git] / test / test_posix_mq.rb
blob00b0f5a2963ac3fe901a530a9a6f8ec5a7c28b8e
1 # -*- encoding: binary -*-
2 require 'test/unit'
3 require 'posix_mq'
4 require 'fcntl'
5 $stderr.sync = $stdout.sync = true
7 class Test_POSIX_MQ < Test::Unit::TestCase
9   HAVE_TO_IO = if POSIX_MQ.instance_methods.grep(/\Ato_io\z/).empty?
10     warn "POSIX_MQ#to_io not supported on this platform: #{RUBY_PLATFORM}"
11     false
12   else
13     true
14   end
16   def setup
17     @mq = nil
18     @path = "/posix_mq.rb.#{Time.now.to_i}.#$$.#{rand}"
19   end
21   def teardown
22     @mq or return
23     assert_equal @mq, @mq.unlink
24     assert ! @mq.closed?
25     assert_nil @mq.close
26     assert @mq.closed?
27   end
29   def test_timed_receive
30     interval = 0.01
31     @mq = POSIX_MQ.new(@path, :rw)
32     assert ! @mq.nonblock?
33     t0 = Time.now
34     assert_raises(Errno::ETIMEDOUT) { @mq.receive "", interval }
35     elapsed = Time.now - t0
36     assert elapsed > interval
37   end
39   def test_timed_send
40     interval = 0.01
41     @mq = POSIX_MQ.new(@path, :rw, 0666, POSIX_MQ::Attr[0, 1, 1, 0])
42     assert ! @mq.nonblock?
43     assert_nothing_raised { @mq.send "A", 1, interval }
44     t0 = Time.now
45     assert_raises(Errno::ETIMEDOUT) { @mq.send "B", 1, interval }
46     elapsed = Time.now - t0
47     assert elapsed > interval
48   end
50   def test_open
51     POSIX_MQ.open(@path, IO::CREAT|IO::WRONLY, 0666) do |mq|
52       @mq = mq
53       assert mq.kind_of?(POSIX_MQ)
54       assert_equal @path, mq.name
55       assert_nil mq.send("HI", 0)
56       assert_equal 1, mq.attr.curmsgs
57       assert_nil mq.close
58       assert_raises(IOError) { mq.close }
59     end
60     assert @mq.closed?
61     @mq = nil
62     POSIX_MQ.unlink(@path)
63   end
65   def test_name
66     path = "" << @path.dup
67     path.freeze
68     @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
69     assert_equal path, @mq.name
70   end
72   def test_new_readonly
73     @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
74     rd = POSIX_MQ.new @path, IO::RDONLY
75     assert_equal @mq.name, rd.name
76     assert_nil rd.close
77   end
79   def test_send0_receive
80     @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
81     assert_equal(@mq, @mq << "hello")
82     assert_equal [ "hello", 0 ], @mq.receive
83   end
85   def test_send0_chain
86     @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
87     @mq << "hello" << "world"
88     assert_equal [ "hello", 0 ], @mq.receive
89     assert_equal [ "world", 0 ], @mq.receive
90   end
92   def test_send_receive
93     @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
94     assert_nil @mq.send("hello", 0)
95     assert_equal [ "hello", 0 ], @mq.receive
96   end
98   def test_send_receive_buf
99     buf = ""
100     @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
101     assert_nil @mq.send("hello", 0)
102     assert_equal [ "hello", 0 ], @mq.receive(buf)
103     assert_equal "hello", buf
104   end
106   def test_send_receive_prio
107     @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
108     assert_nil @mq.send("hello", 2)
109     assert_equal [ "hello", 2 ], @mq.receive
110   end
112   def test_getattr
113     @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
114     mq_attr = @mq.attr
115     assert_equal POSIX_MQ::Attr, mq_attr.class
116     assert mq_attr.flags.kind_of?(Integer)
117     assert mq_attr.maxmsg.kind_of?(Integer)
118     assert mq_attr.msgsize.kind_of?(Integer)
119     assert mq_attr.curmsgs.kind_of?(Integer)
120   end
122   def test_to_io
123     @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
124     assert @mq.to_io.kind_of?(IO)
125     assert_nothing_raised { IO.select([@mq], nil, nil, 0) }
126   end if HAVE_TO_IO
128   def test_notify
129     rd, wr = IO.pipe
130     orig = trap(:USR1) { wr.syswrite('.') }
131     @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666
132     assert_nothing_raised { @mq.notify = :SIGUSR1 }
133     assert_nothing_raised { @mq.send("hello", 0) }
134     assert_equal [[rd], [], []], IO.select([rd], nil, nil, 10)
135     assert_equal '.', rd.sysread(1)
136     assert_nil(@mq.notify = nil)
137     assert_nothing_raised { @mq.send("hello", 0) }
138     assert_nil IO.select([rd], nil, nil, 0.1)
139     assert_raises(Errno::EBUSY) { @mq.notify = :USR1 }
140     ensure
141       trap(:USR1, orig)
142   end
144   def test_setattr
145     @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
146     mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK)
147     @mq.attr = mq_attr
148     assert_equal IO::NONBLOCK, @mq.attr.flags
149     assert mq_attr.flags.kind_of?(Integer)
151     mq_attr.flags = 0
152     @mq.attr = mq_attr
153     assert_equal 0, @mq.attr.flags
154   end
156   def test_new_nonblocking
157     @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY|IO::NONBLOCK, 0666
158     assert @mq.nonblock?
159   end
161   def test_new_blocking
162     @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
163     assert ! @mq.nonblock?
164   end
166   def test_nonblock_toggle
167     @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
168     assert ! @mq.nonblock?
169     @mq.nonblock = true
170     assert @mq.nonblock?
171     @mq.nonblock = false
172     assert ! @mq.nonblock?
173     assert_raises(ArgumentError) { @mq.nonblock = nil }
174   end
176   def test_new_sym_w
177     @mq = POSIX_MQ.new @path, :w
178     assert_equal IO::WRONLY, @mq.to_io.fcntl(Fcntl::F_GETFL)
179   end if HAVE_TO_IO
181   def test_new_sym_r
182     @mq = POSIX_MQ.new @path, :w
183     mq = nil
184     assert_nothing_raised { mq = POSIX_MQ.new @path, :r }
185     assert_equal IO::RDONLY, mq.to_io.fcntl(Fcntl::F_GETFL)
186     assert_nil mq.close
187   end if HAVE_TO_IO
189   def test_new_path_only
190     @mq = POSIX_MQ.new @path, :w
191     mq = nil
192     assert_nothing_raised { mq = POSIX_MQ.new @path }
193     assert_equal IO::RDONLY, mq.to_io.fcntl(Fcntl::F_GETFL)
194     assert_nil mq.close
195   end if HAVE_TO_IO
197   def test_new_sym_wr
198     @mq = POSIX_MQ.new @path, :rw
199     assert_equal IO::RDWR, @mq.to_io.fcntl(Fcntl::F_GETFL)
200   end if HAVE_TO_IO
202   def test_new_attr
203     mq_attr = POSIX_MQ::Attr.new(IO::NONBLOCK, 1, 1, 0)
204     @mq = POSIX_MQ.new @path, IO::CREAT|IO::RDWR, 0666, mq_attr
205     assert @mq.nonblock?
206     assert_equal mq_attr, @mq.attr
208     assert_raises(Errno::EAGAIN) { @mq.receive }
209     assert_raises(Errno::EMSGSIZE) { @mq << '..' }
210     assert_nothing_raised { @mq << '.' }
211     assert_equal [ '.', 0 ], @mq.receive
212     assert_nothing_raised { @mq << '.' }
213     assert_raises(Errno::EAGAIN) { @mq << '.' }
214   end
216   def test_prio_max
217     min_posix_mq_prio_max = 31 # defined by POSIX
218     assert POSIX_MQ::PRIO_MAX >= min_posix_mq_prio_max
219   end
221   def test_open_max
222     assert POSIX_MQ::OPEN_MAX.kind_of?(Integer)
223   end