PageRenderTime 97ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/ruby-1.8.7/test/rinda/test_rinda.rb

https://github.com/replit/emscripted-ruby
Ruby | 542 lines | 448 code | 94 blank | 0 comment | 17 complexity | d6cabef8aff4475aa763733dbb643444 MD5 | raw file
  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_raises(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_raises(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_raises(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_raises(Rinda::RequestExpiredError) do
  190. @ts.take([:empty], 0)
  191. end
  192. assert_raises(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_raises(Rinda::RequestExpiredError) do
  200. thread_join(th)
  201. end
  202. th = Thread.new { @ts.read([:empty], 1) }
  203. sleep(10)
  204. assert_raises(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], 5)
  265. notify3 = @ts.notify(nil, {"message"=>String, "name"=>String}, 5)
  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|
  292. n += 1
  293. if ev[0] == 'write'
  294. lv = lv + 1
  295. elsif ev[0] == 'take'
  296. lv = lv - 1
  297. elsif ev[0] == 'close'
  298. result = [lv, n]
  299. else
  300. break
  301. end
  302. assert(lv >= 0)
  303. assert_equal([:ans, 10], ev[1])
  304. end
  305. result
  306. end
  307. taker = Thread.new do
  308. s = 0
  309. while true
  310. begin
  311. tuple = @ts.take([:req, Integer], 1)
  312. s += tuple[1]
  313. rescue Rinda::RequestExpiredError
  314. break
  315. end
  316. end
  317. @ts.write([:ans, s])
  318. s
  319. end
  320. 5.times do |n|
  321. @ts.write([:req, 2])
  322. end
  323. @ts.take({"message"=>"first", "name"=>"3"})
  324. sleep(4)
  325. assert_equal(10, thread_join(taker))
  326. tuple = @ts.take([:ans, nil])
  327. assert_equal(10, tuple[1])
  328. assert_equal([], @ts.read_all([nil, nil]))
  329. notify1.cancel
  330. sleep(3) # notify2 expired
  331. assert_equal([0, 11], thread_join(listener1))
  332. assert_equal([0, 3], thread_join(listener2))
  333. ary = []
  334. ary.push(["write", {"message"=>"first", "name"=>"3"}])
  335. ary.push(["write", {"message"=>"second", "name"=>"1"}])
  336. ary.push(["write", {"message"=>"third", "name"=>"0"}])
  337. ary.push(["take", {"message"=>"third", "name"=>"0"}])
  338. ary.push(["take", {"message"=>"first", "name"=>"3"}])
  339. ary.push(["delete", {"message"=>"second", "name"=>"1"}])
  340. ary.push(["close"])
  341. notify3.each do |ev|
  342. assert_equal(ary.shift, ev)
  343. end
  344. assert_equal([], ary)
  345. end
  346. def test_cancel_01
  347. entry = @ts.write([:removeme, 1])
  348. assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
  349. entry.cancel
  350. assert_equal([], @ts.read_all([nil, nil]))
  351. template = nil
  352. taker = Thread.new do
  353. @ts.take([:take, nil], 10) do |template|
  354. Thread.new do
  355. template.cancel
  356. end
  357. end
  358. end
  359. sleep(2)
  360. assert_raises(Rinda::RequestCanceledError) do
  361. assert_nil(thread_join(taker))
  362. end
  363. assert(template.canceled?)
  364. @ts.write([:take, 1])
  365. assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
  366. end
  367. def test_cancel_02
  368. entry = @ts.write([:removeme, 1])
  369. assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
  370. entry.cancel
  371. assert_equal([], @ts.read_all([nil, nil]))
  372. template = nil
  373. reader = Thread.new do
  374. @ts.read([:take, nil], 10) do |template|
  375. Thread.new do
  376. template.cancel
  377. end
  378. end
  379. end
  380. sleep(2)
  381. assert_raises(Rinda::RequestCanceledError) do
  382. assert_nil(thread_join(reader))
  383. end
  384. assert(template.canceled?)
  385. @ts.write([:take, 1])
  386. assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
  387. end
  388. class SimpleRenewer
  389. def initialize(sec, n = 1)
  390. @sec = sec
  391. @n = n
  392. end
  393. def renew
  394. return -1 if @n <= 0
  395. @n -= 1
  396. return @sec
  397. end
  398. end
  399. def test_00_renewer
  400. tuple = Rinda::TupleEntry.new([1,2,3], true)
  401. assert(!tuple.canceled?)
  402. assert(tuple.expired?)
  403. assert(!tuple.alive?)
  404. tuple = Rinda::TupleEntry.new([1,2,3], 1)
  405. assert(!tuple.canceled?)
  406. assert(!tuple.expired?)
  407. assert(tuple.alive?)
  408. sleep(2)
  409. assert(tuple.expired?)
  410. assert(!tuple.alive?)
  411. @renewer = SimpleRenewer.new(1,2)
  412. tuple = Rinda::TupleEntry.new([1,2,3], @renewer)
  413. assert(!tuple.canceled?)
  414. assert(!tuple.expired?)
  415. assert(tuple.alive?)
  416. sleep(1)
  417. assert(!tuple.canceled?)
  418. assert(!tuple.expired?)
  419. assert(tuple.alive?)
  420. sleep(2)
  421. assert(tuple.expired?)
  422. assert(!tuple.alive?)
  423. end
  424. end
  425. class TupleSpaceTest < Test::Unit::TestCase
  426. include TupleSpaceTestModule
  427. def setup
  428. ThreadGroup.new.add(Thread.current)
  429. @ts = Rinda::TupleSpace.new(1)
  430. end
  431. end
  432. class TupleSpaceProxyTest < Test::Unit::TestCase
  433. include TupleSpaceTestModule
  434. def setup
  435. ThreadGroup.new.add(Thread.current)
  436. @ts_base = Rinda::TupleSpace.new(1)
  437. @ts = Rinda::TupleSpaceProxy.new(@ts_base)
  438. end
  439. def test_remote_array_and_hash
  440. @ts.write(DRbObject.new([1, 2, 3]))
  441. assert_equal([1, 2, 3], @ts.take([1, 2, 3], 0))
  442. @ts.write(DRbObject.new({'head' => 1, 'tail' => 2}))
  443. assert_equal({'head' => 1, 'tail' => 2},
  444. @ts.take({'head' => 1, 'tail' => 2}, 0))
  445. end
  446. @server = DRb.primary_server || DRb.start_service
  447. end
  448. end