5 require 'rinda/tuplespace'
14 class MyTS < Rinda::TupleSpace
37 now ,= @ts.take([nil, :now])
40 @ts.write([@now, :now])
52 now ,= @ts.take([nil, :now])
53 @ts.write([@inf, :now])
60 now ,= @ts.read([nil, :now])
61 @ts.read([(now + n)..@inf, :now])
70 module_function :sleep
85 module_function :rewind
90 module_function :forward
92 @m = MockClock.instance
101 module TupleSpaceTestModule
103 if Thread.current == Thread.main
119 tuple = Rinda::TupleEntry.new([1,2,3])
120 assert(!tuple.canceled?)
121 assert(!tuple.expired?)
126 tmpl = Rinda::Template.new([1,2,3])
127 assert_equal(3, tmpl.size)
128 assert_equal(3, tmpl[2])
129 assert(tmpl.match([1,2,3]))
130 assert(!tmpl.match([1,nil,3]))
132 tmpl = Rinda::Template.new([/^rinda/i, nil, :hello])
133 assert_equal(3, tmpl.size)
134 assert(tmpl.match(['Rinda', 2, :hello]))
135 assert(!tmpl.match(['Rinda', 2, Symbol]))
136 assert(!tmpl.match([1, 2, :hello]))
137 assert(tmpl.match([/^rinda/i, 2, :hello]))
139 tmpl = Rinda::Template.new([Symbol])
140 assert_equal(1, tmpl.size)
141 assert(tmpl.match([:hello]))
142 assert(tmpl.match([Symbol]))
143 assert(!tmpl.match(['Symbol']))
145 tmpl = Rinda::Template.new({"message"=>String, "name"=>String})
146 assert_equal(2, tmpl.size)
147 assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
148 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
149 assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
150 assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
152 assert_raises(Rinda::InvalidHashTupleKey) do
153 tmpl = Rinda::Template.new({:message=>String, "name"=>String})
155 tmpl = Rinda::Template.new({"name"=>String})
156 assert_equal(1, tmpl.size)
157 assert(tmpl.match({"name"=>"Foo"}))
158 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
159 assert(!tmpl.match({"message"=>:symbol, "name"=>"Foo", "1"=>2}))
160 assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
161 assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
163 tmpl = Rinda::Template.new({"message"=>String, "name"=>String})
164 assert_equal(2, tmpl.size)
165 assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
166 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
167 assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
168 assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
170 tmpl = Rinda::Template.new({"message"=>String})
171 assert_equal(1, tmpl.size)
172 assert(tmpl.match({"message"=>"Hello"}))
173 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
174 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
175 assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
176 assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
178 tmpl = Rinda::Template.new({"message"=>String, "name"=>nil})
179 assert_equal(2, tmpl.size)
180 assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
181 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
182 assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
183 assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
185 assert_raises(Rinda::InvalidHashTupleKey) do
186 @ts.write({:message=>String, "name"=>String})
190 assert_equal([1, 2, 3], @ts.take([1, 2, 3]))
192 @ts.write({'1'=>1, '2'=>2, '3'=>3})
193 assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.take({'1'=>1, '2'=>2, '3'=>3}))
195 entry = @ts.write(['1'=>1, '2'=>2, '3'=>3])
196 assert_raises(Rinda::RequestExpiredError) do
197 assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.read({'1'=>1}, 0))
202 def test_00_DRbObject
203 ro = DRbObject.new(nil, "druby://host:1234")
204 tmpl = Rinda::DRbObjectTemplate.new
207 tmpl = Rinda::DRbObjectTemplate.new("druby://host:1234")
210 tmpl = Rinda::DRbObjectTemplate.new("druby://host:12345")
211 assert(!(tmpl === ro))
213 tmpl = Rinda::DRbObjectTemplate.new(/^druby:\/\/host:/)
216 ro = DRbObject.new_with(12345, 1234)
217 assert(!(tmpl === ro))
219 ro = DRbObject.new_with("druby://foo:12345", 1234)
220 assert(!(tmpl === ro))
222 tmpl = Rinda::DRbObjectTemplate.new(/^druby:\/\/(foo|bar):/)
225 ro = DRbObject.new_with("druby://bar:12345", 1234)
228 ro = DRbObject.new_with("druby://baz:12345", 1234)
229 assert(!(tmpl === ro))
233 assert_raises(Rinda::RequestExpiredError) do
234 @ts.take([:empty], 0)
237 assert_raises(Rinda::RequestExpiredError) do
238 @ts.read([:empty], 0)
242 def test_ruby_talk_264062
243 th = Thread.new { @ts.take([:empty], 1) }
245 assert_raises(Rinda::RequestExpiredError) do
249 th = Thread.new { @ts.read([:empty], 1) }
251 assert_raises(Rinda::RequestExpiredError) do
256 def test_symbol_tuple
257 @ts.write([:symbol, :symbol])
258 @ts.write(['string', :string])
259 assert_equal([[:symbol, :symbol]], @ts.read_all([:symbol, nil]))
260 assert_equal([[:symbol, :symbol]], @ts.read_all([Symbol, nil]))
261 assert_equal([], @ts.read_all([:nil, nil]))
269 assert_equal([[:req, 2], [:req, 2], [:req, 2], [:req, 2], [:req, 2]],
270 @ts.read_all([nil, nil]))
272 taker = Thread.new do
276 tuple = @ts.take([:req, Integer], 1)
277 assert_equal(2, tuple[1])
279 rescue Rinda::RequestExpiredError
287 assert_equal(10, thread_join(taker))
288 tuple = @ts.take([:ans, nil])
289 assert_equal(10, tuple[1])
293 taker = Thread.new do
297 tuple = @ts.take([:req, Integer], 1)
298 assert_equal(2, tuple[1])
300 rescue Rinda::RequestExpiredError
312 assert_equal(10, thread_join(taker))
313 tuple = @ts.take([:ans, nil])
314 assert_equal(10, tuple[1])
315 assert_equal([], @ts.read_all([nil, nil]))
318 def test_core_03_notify
319 notify1 = @ts.notify(nil, [:req, Integer])
320 notify2 = @ts.notify(nil, [:ans, Integer], 5)
321 notify3 = @ts.notify(nil, {"message"=>String, "name"=>String}, 5)
323 @ts.write({"message"=>"first", "name"=>"3"}, 3)
324 @ts.write({"message"=>"second", "name"=>"1"}, 1)
325 @ts.write({"message"=>"third", "name"=>"0"})
326 @ts.take({"message"=>"third", "name"=>"0"})
328 listener1 = Thread.new do
331 notify1.each do |ev, tuple|
341 assert_equal([:req, 2], tuple)
346 listener2 = Thread.new do
354 elsif ev[0] == 'take'
356 elsif ev[0] == 'close'
362 assert_equal([:ans, 10], ev[1])
367 taker = Thread.new do
371 tuple = @ts.take([:req, Integer], 1)
373 rescue Rinda::RequestExpiredError
385 @ts.take({"message"=>"first", "name"=>"3"})
388 assert_equal(10, thread_join(taker))
389 tuple = @ts.take([:ans, nil])
390 assert_equal(10, tuple[1])
391 assert_equal([], @ts.read_all([nil, nil]))
394 sleep(3) # notify2 expired
396 assert_equal([0, 11], thread_join(listener1))
397 assert_equal([0, 3], thread_join(listener2))
400 ary.push(["write", {"message"=>"first", "name"=>"3"}])
401 ary.push(["write", {"message"=>"second", "name"=>"1"}])
402 ary.push(["write", {"message"=>"third", "name"=>"0"}])
403 ary.push(["take", {"message"=>"third", "name"=>"0"}])
404 ary.push(["take", {"message"=>"first", "name"=>"3"}])
405 ary.push(["delete", {"message"=>"second", "name"=>"1"}])
409 assert_equal(ary.shift, ev)
411 assert_equal([], ary)
415 entry = @ts.write([:removeme, 1])
416 assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
418 assert_equal([], @ts.read_all([nil, nil]))
421 taker = Thread.new do
422 @ts.take([:take, nil], 10) do |t|
432 assert_raises(Rinda::RequestCanceledError) do
433 assert_nil(thread_join(taker))
436 assert(template.canceled?)
438 @ts.write([:take, 1])
440 assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
444 entry = @ts.write([:removeme, 1])
445 assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
447 assert_equal([], @ts.read_all([nil, nil]))
450 reader = Thread.new do
451 @ts.read([:take, nil], 10) do |t|
461 assert_raises(Rinda::RequestCanceledError) do
462 assert_nil(thread_join(reader))
465 assert(template.canceled?)
467 @ts.write([:take, 1])
469 assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
473 def initialize(sec, n = 1)
486 tuple = Rinda::TupleEntry.new([1,2,3], true)
487 assert(!tuple.canceled?)
488 assert(tuple.expired?)
489 assert(!tuple.alive?)
491 tuple = Rinda::TupleEntry.new([1,2,3], 1)
492 assert(!tuple.canceled?)
493 assert(!tuple.expired?)
496 assert(tuple.expired?)
497 assert(!tuple.alive?)
499 @renewer = SimpleRenewer.new(1,2)
500 tuple = Rinda::TupleEntry.new([1,2,3], @renewer)
501 assert(!tuple.canceled?)
502 assert(!tuple.expired?)
505 assert(!tuple.canceled?)
506 assert(!tuple.expired?)
509 assert(tuple.expired?)
510 assert(!tuple.alive?)
514 class TupleSpaceTest < Test::Unit::TestCase
515 include TupleSpaceTestModule
518 ThreadGroup.new.add(Thread.current)
519 @ts = Rinda::TupleSpace.new(1)
523 class TupleSpaceProxyTest < Test::Unit::TestCase
524 include TupleSpaceTestModule
527 ThreadGroup.new.add(Thread.current)
528 @ts_base = Rinda::TupleSpace.new(1)
529 @ts = Rinda::TupleSpaceProxy.new(@ts_base)
532 def test_remote_array_and_hash
533 @ts.write(DRbObject.new([1, 2, 3]))
534 assert_equal([1, 2, 3], @ts.take([1, 2, 3], 0))
535 @ts.write(DRbObject.new({'head' => 1, 'tail' => 2}))
536 assert_equal({'head' => 1, 'tail' => 2},
537 @ts.take({'head' => 1, 'tail' => 2}, 0))
540 @server = DRb.primary_server || DRb.start_service