5 require 'rinda/tuplespace'
14 class MyTS < Rinda::TupleSpace
37 now ,= @ts.take([nil, :now])
40 @ts.write([@now, :now])
51 now ,= @ts.take([nil, :now])
52 @ts.write([@inf, :now])
64 now ,= @ts.read([nil, :now])
65 @ts.read([(now + n)..@inf, :now])
70 sz = Thread.current.group.list.find_all {|x| x.status != 'sleep'}.size
79 module_function :sleep
94 module_function :rewind
99 module_function :forward
101 @m = MockClock.instance
110 module TupleSpaceTestModule
112 if Thread.current == Thread.main
120 tuple = Rinda::TupleEntry.new([1,2,3])
121 assert(!tuple.canceled?)
122 assert(!tuple.expired?)
127 tmpl = Rinda::Template.new([1,2,3])
128 assert_equal(3, tmpl.size)
129 assert_equal(3, tmpl[2])
130 assert(tmpl.match([1,2,3]))
131 assert(!tmpl.match([1,nil,3]))
133 tmpl = Rinda::Template.new([/^rinda/i, nil, :hello])
134 assert_equal(3, tmpl.size)
135 assert(tmpl.match(['Rinda', 2, :hello]))
136 assert(!tmpl.match(['Rinda', 2, Symbol]))
137 assert(!tmpl.match([1, 2, :hello]))
138 assert(tmpl.match([/^rinda/i, 2, :hello]))
140 tmpl = Rinda::Template.new([Symbol])
141 assert_equal(1, tmpl.size)
142 assert(tmpl.match([:hello]))
143 assert(tmpl.match([Symbol]))
144 assert(!tmpl.match(['Symbol']))
146 tmpl = Rinda::Template.new({"message"=>String, "name"=>String})
147 assert_equal(2, tmpl.size)
148 assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
149 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
150 assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
151 assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
153 assert_raises(Rinda::InvalidHashTupleKey) do
154 tmpl = Rinda::Template.new({:message=>String, "name"=>String})
156 tmpl = Rinda::Template.new({"name"=>String})
157 assert_equal(1, tmpl.size)
158 assert(tmpl.match({"name"=>"Foo"}))
159 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
160 assert(!tmpl.match({"message"=>:symbol, "name"=>"Foo", "1"=>2}))
161 assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
162 assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
164 tmpl = Rinda::Template.new({"message"=>String, "name"=>String})
165 assert_equal(2, tmpl.size)
166 assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
167 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
168 assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
169 assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
171 tmpl = Rinda::Template.new({"message"=>String})
172 assert_equal(1, tmpl.size)
173 assert(tmpl.match({"message"=>"Hello"}))
174 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
175 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
176 assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
177 assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
179 tmpl = Rinda::Template.new({"message"=>String, "name"=>nil})
180 assert_equal(2, tmpl.size)
181 assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
182 assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
183 assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
184 assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
186 assert_raises(Rinda::InvalidHashTupleKey) do
187 @ts.write({:message=>String, "name"=>String})
191 assert_equal([1, 2, 3], @ts.take([1, 2, 3]))
193 @ts.write({'1'=>1, '2'=>2, '3'=>3})
194 assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.take({'1'=>1, '2'=>2, '3'=>3}))
196 entry = @ts.write(['1'=>1, '2'=>2, '3'=>3])
197 assert_raises(Rinda::RequestExpiredError) do
198 assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.read({'1'=>1}, 0))
203 def test_00_DRbObject
204 ro = DRbObject.new(nil, "druby://host:1234")
205 tmpl = Rinda::DRbObjectTemplate.new
208 tmpl = Rinda::DRbObjectTemplate.new("druby://host:1234")
211 tmpl = Rinda::DRbObjectTemplate.new("druby://host:12345")
212 assert(!(tmpl === ro))
214 tmpl = Rinda::DRbObjectTemplate.new(/^druby:\/\/host:/)
217 ro = DRbObject.new_with(12345, 1234)
218 assert(!(tmpl === ro))
220 ro = DRbObject.new_with("druby://foo:12345", 1234)
221 assert(!(tmpl === ro))
223 tmpl = Rinda::DRbObjectTemplate.new(/^druby:\/\/(foo|bar):/)
226 ro = DRbObject.new_with("druby://bar:12345", 1234)
229 ro = DRbObject.new_with("druby://baz:12345", 1234)
230 assert(!(tmpl === ro))
234 assert_raises(Rinda::RequestExpiredError) do
235 @ts.take([:empty], 0)
238 assert_raises(Rinda::RequestExpiredError) do
239 @ts.read([:empty], 0)
248 assert_equal([[:req, 2], [:req, 2], [:req, 2], [:req, 2], [:req, 2]],
249 @ts.read_all([nil, nil]))
251 taker = Thread.new do
255 tuple = @ts.take([:req, Integer], 0.5)
256 assert_equal(2, tuple[1])
258 rescue Rinda::RequestExpiredError
267 tuple = @ts.take([:ans, nil])
268 assert_equal(10, tuple[1])
269 assert_equal(10, taker.value)
273 taker = Thread.new do
277 tuple = @ts.take([:req, Integer], 1.0)
278 assert_equal(2, tuple[1])
280 rescue Rinda::RequestExpiredError
293 tuple = @ts.take([:ans, nil])
294 assert_equal(10, tuple[1])
295 assert_equal(10, taker.value)
296 assert_equal([], @ts.read_all([nil, nil]))
299 def test_core_03_notify
300 notify1 = @ts.notify(nil, [:req, Integer])
301 notify2 = @ts.notify(nil, [:ans, Integer], 5)
302 notify3 = @ts.notify(nil, {"message"=>String, "name"=>String}, 5)
304 @ts.write({"message"=>"first", "name"=>"3"}, 3)
305 @ts.write({"message"=>"second", "name"=>"1"}, 1)
306 @ts.write({"message"=>"third", "name"=>"0"})
307 @ts.take({"message"=>"third", "name"=>"0"})
309 listener1 = Thread.new do
312 notify1.each do |ev, tuple|
322 assert_equal([:req, 2], tuple)
327 listener2 = Thread.new do
335 elsif ev[0] == 'take'
337 elsif ev[0] == 'close'
343 assert_equal([:ans, 10], ev[1])
348 taker = Thread.new do
352 tuple = @ts.take([:req, Integer], 1.0)
354 rescue Rinda::RequestExpiredError
362 writer = Thread.new do
369 @ts.take({"message"=>"first", "name"=>"3"})
372 tuple = @ts.take([:ans, nil])
373 assert_equal(10, tuple[1])
374 assert_equal(10, taker.value)
375 assert_equal([], @ts.read_all([nil, nil]))
378 sleep(3) # notify2 expired
380 assert_equal([0, 11], listener1.value)
381 assert_equal([0, 3], listener2.value)
384 ary.push(["write", {"message"=>"first", "name"=>"3"}])
385 ary.push(["write", {"message"=>"second", "name"=>"1"}])
386 ary.push(["write", {"message"=>"third", "name"=>"0"}])
387 ary.push(["take", {"message"=>"third", "name"=>"0"}])
388 ary.push(["take", {"message"=>"first", "name"=>"3"}])
389 ary.push(["delete", {"message"=>"second", "name"=>"1"}])
393 assert_equal(ary.shift, ev)
395 assert_equal([], ary)
399 entry = @ts.write([:removeme, 1])
400 assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
402 assert_equal([], @ts.read_all([nil, nil]))
405 taker = Thread.new do
406 @ts.take([:take, nil], 10) do |template|
415 assert(template.canceled?)
417 @ts.write([:take, 1])
419 assert_raises(Rinda::RequestCanceledError) do
420 assert_nil(taker.value)
423 assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
427 entry = @ts.write([:removeme, 1])
428 assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
430 assert_equal([], @ts.read_all([nil, nil]))
433 reader = Thread.new do
434 @ts.read([:take, nil], 10) do |template|
443 assert(template.canceled?)
445 @ts.write([:take, 1])
447 assert_raises(Rinda::RequestCanceledError) do
448 assert_nil(reader.value)
451 assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
455 def initialize(sec, n = 1)
468 tuple = Rinda::TupleEntry.new([1,2,3], true)
469 assert(!tuple.canceled?)
470 assert(tuple.expired?)
471 assert(!tuple.alive?)
473 tuple = Rinda::TupleEntry.new([1,2,3], 1)
474 assert(!tuple.canceled?)
475 assert(!tuple.expired?)
478 assert(tuple.expired?)
479 assert(!tuple.alive?)
481 tuple = Rinda::TupleEntry.new([1,2,3], SimpleRenewer.new(1,2))
482 assert(!tuple.canceled?)
483 assert(!tuple.expired?)
486 assert(!tuple.canceled?)
487 assert(!tuple.expired?)
490 assert(tuple.expired?)
491 assert(!tuple.alive?)
495 class TupleSpaceTest < Test::Unit::TestCase
496 include TupleSpaceTestModule
499 ThreadGroup.new.add(Thread.current)
500 @ts = Rinda::TupleSpace.new(1)
504 class TupleSpaceProxyTest < Test::Unit::TestCase
505 include TupleSpaceTestModule
508 ThreadGroup.new.add(Thread.current)
509 @ts_base = Rinda::TupleSpace.new(1)
510 @ts = Rinda::TupleSpaceProxy.new(@ts_base)
513 def test_remote_array_and_hash
514 @ts.write(DRbObject.new([1, 2, 3]))
515 assert_equal([1, 2, 3], @ts.take([1, 2, 3], 0))
516 @ts.write(DRbObject.new({'head' => 1, 'tail' => 2}))
517 assert_equal({'head' => 1, 'tail' => 2},
518 @ts.take({'head' => 1, 'tail' => 2}, 0))
521 @server = DRb.primary_server || DRb.start_service