PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/TDDBC_Yokohama2_PCUnit/Ruby/doc/ruby/ruby-1.9.2/test/rinda/test_rinda.rb

https://bitbucket.org/aetos/tddbc_yokohama2
Ruby | 553 lines | 455 code | 94 blank | 4 comment | 19 complexity | aa6e4f7c8acdb292e092bc6bafff2ef7 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, AGPL-3.0, 0BSD, Unlicense
  1. require 'test/unit'
  2. require 'drb/drb'
  3. require 'drb/eq'
  4. require 'rinda/tuplespace'
  5. require 'singleton'
  6. module Rinda
  7. class MockClock
  8. include Singleton
  9. class MyTS < Rinda::TupleSpace
  10. def keeper_thread
  11. nil
  12. end
  13. end
  14. def initialize
  15. @now = 2
  16. @reso = 1
  17. @ts = MyTS.new
  18. @ts.write([2, :now])
  19. @inf = 2**31 - 1
  20. end
  21. def now
  22. @now.to_f
  23. end
  24. def at(n)
  25. n
  26. end
  27. def _forward(n=nil)
  28. now ,= @ts.take([nil, :now])
  29. @now = now + n
  30. n = @reso if n.nil?
  31. @ts.write([@now, :now])
  32. end
  33. def forward(n)
  34. while n > 0
  35. _forward(@reso)
  36. n -= @reso
  37. Thread.pass
  38. end
  39. end
  40. def rewind
  41. now ,= @ts.take([nil, :now])
  42. @ts.write([@inf, :now])
  43. @ts.take([nil, :now])
  44. @now = 2
  45. @ts.write([2, :now])
  46. end
  47. def sleep(n=nil)
  48. now ,= @ts.read([nil, :now])
  49. @ts.read([(now + n)..@inf, :now])
  50. 0
  51. end
  52. end
  53. module Time
  54. def sleep(n)
  55. @m.sleep(n)
  56. end
  57. module_function :sleep
  58. def at(n)
  59. n
  60. end
  61. module_function :at
  62. def now
  63. @m ? @m.now : 2
  64. end
  65. module_function :now
  66. def rewind
  67. @m.rewind
  68. end
  69. module_function :rewind
  70. def forward(n)
  71. @m.forward(n)
  72. end
  73. module_function :forward
  74. @m = MockClock.instance
  75. end
  76. class TupleSpace
  77. def sleep(n)
  78. Time.sleep(n)
  79. end
  80. end
  81. module TupleSpaceTestModule
  82. def sleep(n)
  83. if Thread.current == Thread.main
  84. Time.forward(n)
  85. else
  86. Time.sleep(n)
  87. end
  88. end
  89. def thread_join(th)
  90. while th.alive?
  91. Kernel.sleep(0.1)
  92. sleep(1)
  93. end
  94. th.value
  95. end
  96. def test_00_tuple
  97. tuple = Rinda::TupleEntry.new([1,2,3])
  98. assert(!tuple.canceled?)
  99. assert(!tuple.expired?)
  100. assert(tuple.alive?)
  101. end
  102. def test_00_template
  103. tmpl = Rinda::Template.new([1,2,3])
  104. assert_equal(3, tmpl.size)
  105. assert_equal(3, tmpl[2])
  106. assert(tmpl.match([1,2,3]))
  107. assert(!tmpl.match([1,nil,3]))
  108. tmpl = Rinda::Template.new([/^rinda/i, nil, :hello])
  109. assert_equal(3, tmpl.size)
  110. assert(tmpl.match(['Rinda', 2, :hello]))
  111. assert(!tmpl.match(['Rinda', 2, Symbol]))
  112. assert(!tmpl.match([1, 2, :hello]))
  113. assert(tmpl.match([/^rinda/i, 2, :hello]))
  114. tmpl = Rinda::Template.new([Symbol])
  115. assert_equal(1, tmpl.size)
  116. assert(tmpl.match([:hello]))
  117. assert(tmpl.match([Symbol]))
  118. assert(!tmpl.match(['Symbol']))
  119. tmpl = Rinda::Template.new({"message"=>String, "name"=>String})
  120. assert_equal(2, tmpl.size)
  121. assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
  122. assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
  123. assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
  124. assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
  125. assert_raise(Rinda::InvalidHashTupleKey) do
  126. tmpl = Rinda::Template.new({:message=>String, "name"=>String})
  127. end
  128. tmpl = Rinda::Template.new({"name"=>String})
  129. assert_equal(1, tmpl.size)
  130. assert(tmpl.match({"name"=>"Foo"}))
  131. assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
  132. assert(!tmpl.match({"message"=>:symbol, "name"=>"Foo", "1"=>2}))
  133. assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
  134. assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
  135. tmpl = Rinda::Template.new({"message"=>String, "name"=>String})
  136. assert_equal(2, tmpl.size)
  137. assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
  138. assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
  139. assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
  140. assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
  141. tmpl = Rinda::Template.new({"message"=>String})
  142. assert_equal(1, tmpl.size)
  143. assert(tmpl.match({"message"=>"Hello"}))
  144. assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
  145. assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
  146. assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
  147. assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
  148. tmpl = Rinda::Template.new({"message"=>String, "name"=>nil})
  149. assert_equal(2, tmpl.size)
  150. assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
  151. assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
  152. assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
  153. assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
  154. assert_raise(Rinda::InvalidHashTupleKey) do
  155. @ts.write({:message=>String, "name"=>String})
  156. end
  157. @ts.write([1, 2, 3])
  158. assert_equal([1, 2, 3], @ts.take([1, 2, 3]))
  159. @ts.write({'1'=>1, '2'=>2, '3'=>3})
  160. assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.take({'1'=>1, '2'=>2, '3'=>3}))
  161. entry = @ts.write(['1'=>1, '2'=>2, '3'=>3])
  162. assert_raise(Rinda::RequestExpiredError) do
  163. assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.read({'1'=>1}, 0))
  164. end
  165. entry.cancel
  166. end
  167. def test_00_DRbObject
  168. ro = DRbObject.new(nil, "druby://host:1234")
  169. tmpl = Rinda::DRbObjectTemplate.new
  170. assert(tmpl === ro)
  171. tmpl = Rinda::DRbObjectTemplate.new("druby://host:1234")
  172. assert(tmpl === ro)
  173. tmpl = Rinda::DRbObjectTemplate.new("druby://host:12345")
  174. assert(!(tmpl === ro))
  175. tmpl = Rinda::DRbObjectTemplate.new(/^druby:\/\/host:/)
  176. assert(tmpl === ro)
  177. ro = DRbObject.new_with(12345, 1234)
  178. assert(!(tmpl === ro))
  179. ro = DRbObject.new_with("druby://foo:12345", 1234)
  180. assert(!(tmpl === ro))
  181. tmpl = Rinda::DRbObjectTemplate.new(/^druby:\/\/(foo|bar):/)
  182. assert(tmpl === ro)
  183. ro = DRbObject.new_with("druby://bar:12345", 1234)
  184. assert(tmpl === ro)
  185. ro = DRbObject.new_with("druby://baz:12345", 1234)
  186. assert(!(tmpl === ro))
  187. end
  188. def test_inp_rdp
  189. assert_raise(Rinda::RequestExpiredError) do
  190. @ts.take([:empty], 0)
  191. end
  192. assert_raise(Rinda::RequestExpiredError) do
  193. @ts.read([:empty], 0)
  194. end
  195. end
  196. def test_ruby_talk_264062
  197. th = Thread.new { @ts.take([:empty], 1) }
  198. sleep(10)
  199. assert_raise(Rinda::RequestExpiredError) do
  200. thread_join(th)
  201. end
  202. th = Thread.new { @ts.read([:empty], 1) }
  203. sleep(10)
  204. assert_raise(Rinda::RequestExpiredError) do
  205. thread_join(th)
  206. end
  207. end
  208. def test_symbol_tuple
  209. @ts.write([:symbol, :symbol])
  210. @ts.write(['string', :string])
  211. assert_equal([[:symbol, :symbol]], @ts.read_all([:symbol, nil]))
  212. assert_equal([[:symbol, :symbol]], @ts.read_all([Symbol, nil]))
  213. assert_equal([], @ts.read_all([:nil, nil]))
  214. end
  215. def test_core_01
  216. 5.times do |n|
  217. @ts.write([:req, 2])
  218. end
  219. assert_equal([[:req, 2], [:req, 2], [:req, 2], [:req, 2], [:req, 2]],
  220. @ts.read_all([nil, nil]))
  221. taker = Thread.new do
  222. s = 0
  223. while true
  224. begin
  225. tuple = @ts.take([:req, Integer], 1)
  226. assert_equal(2, tuple[1])
  227. s += tuple[1]
  228. rescue Rinda::RequestExpiredError
  229. break
  230. end
  231. end
  232. @ts.write([:ans, s])
  233. s
  234. end
  235. assert_equal(10, thread_join(taker))
  236. tuple = @ts.take([:ans, nil])
  237. assert_equal(10, tuple[1])
  238. end
  239. def test_core_02
  240. taker = Thread.new do
  241. s = 0
  242. while true
  243. begin
  244. tuple = @ts.take([:req, Integer], 1)
  245. assert_equal(2, tuple[1])
  246. s += tuple[1]
  247. rescue Rinda::RequestExpiredError
  248. break
  249. end
  250. end
  251. @ts.write([:ans, s])
  252. s
  253. end
  254. 5.times do |n|
  255. @ts.write([:req, 2])
  256. end
  257. assert_equal(10, thread_join(taker))
  258. tuple = @ts.take([:ans, nil])
  259. assert_equal(10, tuple[1])
  260. assert_equal([], @ts.read_all([nil, nil]))
  261. end
  262. def test_core_03_notify
  263. notify1 = @ts.notify(nil, [:req, Integer])
  264. notify2 = @ts.notify(nil, [:ans, Integer], 8)
  265. notify3 = @ts.notify(nil, {"message"=>String, "name"=>String}, 8)
  266. @ts.write({"message"=>"first", "name"=>"3"}, 3)
  267. @ts.write({"message"=>"second", "name"=>"1"}, 1)
  268. @ts.write({"message"=>"third", "name"=>"0"})
  269. @ts.take({"message"=>"third", "name"=>"0"})
  270. listener1 = Thread.new do
  271. lv = 0
  272. n = 0
  273. notify1.each do |ev, tuple|
  274. n += 1
  275. if ev == 'write'
  276. lv = lv + 1
  277. elsif ev == 'take'
  278. lv = lv - 1
  279. else
  280. break
  281. end
  282. assert(lv >= 0)
  283. assert_equal([:req, 2], tuple)
  284. end
  285. [lv, n]
  286. end
  287. listener2 = Thread.new do
  288. result = nil
  289. lv = 0
  290. n = 0
  291. notify2.each do |ev, tuple|
  292. n += 1
  293. if ev == 'write'
  294. lv = lv + 1
  295. elsif ev == 'take'
  296. lv = lv - 1
  297. elsif ev == 'close'
  298. result = [lv, n]
  299. break
  300. end
  301. assert(lv >= 0)
  302. assert_equal([:ans, 10], tuple)
  303. end
  304. result
  305. end
  306. taker = Thread.new do
  307. s = 0
  308. while true
  309. begin
  310. tuple = @ts.take([:req, Integer], 1)
  311. s += tuple[1]
  312. rescue Rinda::RequestExpiredError
  313. break
  314. end
  315. end
  316. @ts.write([:ans, s])
  317. s
  318. end
  319. 5.times do |n|
  320. @ts.write([:req, 2])
  321. end
  322. @ts.take({"message"=>"first", "name"=>"3"})
  323. sleep(4)
  324. assert_equal(10, thread_join(taker))
  325. # notify2 must not expire until this @ts.take.
  326. # sleep(4) might be short enough for the timeout of notify2 (8 secs)
  327. tuple = @ts.take([:ans, nil])
  328. assert_equal(10, tuple[1])
  329. assert_equal([], @ts.read_all([nil, nil]))
  330. notify1.cancel
  331. sleep(7) # notify2 expired (sleep(4)+sleep(7) > 8)
  332. assert_equal([0, 11], thread_join(listener1))
  333. assert_equal([0, 3], thread_join(listener2))
  334. ary = []
  335. ary.push(["write", {"message"=>"first", "name"=>"3"}])
  336. ary.push(["write", {"message"=>"second", "name"=>"1"}])
  337. ary.push(["write", {"message"=>"third", "name"=>"0"}])
  338. ary.push(["take", {"message"=>"third", "name"=>"0"}])
  339. ary.push(["take", {"message"=>"first", "name"=>"3"}])
  340. ary.push(["delete", {"message"=>"second", "name"=>"1"}])
  341. ary.push(["close"])
  342. notify3.each do |ev|
  343. assert_equal(ary.shift, ev)
  344. end
  345. assert_equal([], ary)
  346. end
  347. def test_cancel_01
  348. entry = @ts.write([:removeme, 1])
  349. assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
  350. entry.cancel
  351. assert_equal([], @ts.read_all([nil, nil]))
  352. template = nil
  353. taker = Thread.new do
  354. @ts.take([:take, nil], 10) do |t|
  355. template = t
  356. Thread.new do
  357. template.cancel
  358. end
  359. end
  360. end
  361. sleep(2)
  362. assert_raise(Rinda::RequestCanceledError) do
  363. assert_nil(thread_join(taker))
  364. end
  365. assert(template.canceled?)
  366. @ts.write([:take, 1])
  367. assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
  368. end
  369. def test_cancel_02
  370. entry = @ts.write([:removeme, 1])
  371. assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
  372. entry.cancel
  373. assert_equal([], @ts.read_all([nil, nil]))
  374. template = nil
  375. reader = Thread.new do
  376. @ts.read([:take, nil], 10) do |t|
  377. template = t
  378. Thread.new do
  379. template.cancel
  380. end
  381. end
  382. end
  383. sleep(2)
  384. assert_raise(Rinda::RequestCanceledError) do
  385. assert_nil(thread_join(reader))
  386. end
  387. assert(template.canceled?)
  388. @ts.write([:take, 1])
  389. assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
  390. end
  391. class SimpleRenewer
  392. def initialize(sec, n = 1)
  393. @sec = sec
  394. @n = n
  395. end
  396. def renew
  397. return -1 if @n <= 0
  398. @n -= 1
  399. return @sec
  400. end
  401. end
  402. def test_00_renewer
  403. tuple = Rinda::TupleEntry.new([1,2,3], true)
  404. assert(!tuple.canceled?)
  405. assert(tuple.expired?)
  406. assert(!tuple.alive?)
  407. tuple = Rinda::TupleEntry.new([1,2,3], 1)
  408. assert(!tuple.canceled?)
  409. assert(!tuple.expired?)
  410. assert(tuple.alive?)
  411. sleep(2)
  412. assert(tuple.expired?)
  413. assert(!tuple.alive?)
  414. @renewer = SimpleRenewer.new(1,2)
  415. tuple = Rinda::TupleEntry.new([1,2,3], @renewer)
  416. assert(!tuple.canceled?)
  417. assert(!tuple.expired?)
  418. assert(tuple.alive?)
  419. sleep(1)
  420. assert(!tuple.canceled?)
  421. assert(!tuple.expired?)
  422. assert(tuple.alive?)
  423. sleep(2)
  424. assert(tuple.expired?)
  425. assert(!tuple.alive?)
  426. end
  427. end
  428. class TupleSpaceTest < Test::Unit::TestCase
  429. include TupleSpaceTestModule
  430. def setup
  431. ThreadGroup.new.add(Thread.current)
  432. @ts = Rinda::TupleSpace.new(1)
  433. end
  434. def teardown
  435. # implementation-dependent
  436. @ts.instance_eval{@keeper.kill if @keeper}
  437. end
  438. end
  439. class TupleSpaceProxyTest < Test::Unit::TestCase
  440. include TupleSpaceTestModule
  441. def setup
  442. ThreadGroup.new.add(Thread.current)
  443. @ts_base = Rinda::TupleSpace.new(1)
  444. @ts = Rinda::TupleSpaceProxy.new(@ts_base)
  445. end
  446. def teardown
  447. # implementation-dependent
  448. @ts_base.instance_eval{@keeper.kill if @keeper}
  449. end
  450. def test_remote_array_and_hash
  451. @ts.write(DRbObject.new([1, 2, 3]))
  452. assert_equal([1, 2, 3], @ts.take([1, 2, 3], 0))
  453. @ts.write(DRbObject.new({'head' => 1, 'tail' => 2}))
  454. assert_equal({'head' => 1, 'tail' => 2},
  455. @ts.take({'head' => 1, 'tail' => 2}, 0))
  456. end
  457. @server = DRb.primary_server || DRb.start_service
  458. end
  459. end