PageRenderTime 62ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/TDDBC_Yokohama2_PCUnit/Ruby/doc/ruby/ruby-1.9.2/test/ruby/test_thread.rb

https://bitbucket.org/aetos/tddbc_yokohama2
Ruby | 535 lines | 462 code | 70 blank | 3 comment | 18 complexity | 6c76af52035b38a3c4f75ed81ae5b1bc MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, AGPL-3.0, 0BSD, Unlicense
  1. require 'test/unit'
  2. require 'thread'
  3. require_relative 'envutil'
  4. class TestThread < Test::Unit::TestCase
  5. class Thread < ::Thread
  6. Threads = []
  7. def self.new(*)
  8. th = super
  9. th.abort_on_exception = true
  10. Threads << th
  11. th
  12. end
  13. end
  14. def setup
  15. Thread::Threads.clear
  16. end
  17. def teardown
  18. Thread::Threads.each do |t|
  19. t.kill if t.alive?
  20. begin
  21. t.join
  22. rescue Exception
  23. end
  24. end
  25. end
  26. def test_mutex_synchronize
  27. m = Mutex.new
  28. r = 0
  29. max = 10
  30. (1..max).map{
  31. Thread.new{
  32. i=0
  33. while i<max*max
  34. i+=1
  35. m.synchronize{
  36. r += 1
  37. }
  38. end
  39. }
  40. }.each{|e|
  41. e.join
  42. }
  43. assert_equal(max * max * max, r)
  44. end
  45. def test_condvar
  46. mutex = Mutex.new
  47. condvar = ConditionVariable.new
  48. result = []
  49. mutex.synchronize do
  50. t = Thread.new do
  51. mutex.synchronize do
  52. result << 1
  53. condvar.signal
  54. end
  55. end
  56. result << 0
  57. condvar.wait(mutex)
  58. result << 2
  59. t.join
  60. end
  61. assert_equal([0, 1, 2], result)
  62. end
  63. def test_condvar_wait_not_owner
  64. mutex = Mutex.new
  65. condvar = ConditionVariable.new
  66. assert_raise(ThreadError) { condvar.wait(mutex) }
  67. end
  68. def test_condvar_wait_exception_handling
  69. # Calling wait in the only thread running should raise a ThreadError of
  70. # 'stopping only thread'
  71. mutex = Mutex.new
  72. condvar = ConditionVariable.new
  73. locked = false
  74. thread = Thread.new do
  75. Thread.current.abort_on_exception = false
  76. mutex.synchronize do
  77. begin
  78. condvar.wait(mutex)
  79. rescue Exception
  80. locked = mutex.locked?
  81. raise
  82. end
  83. end
  84. end
  85. until thread.stop?
  86. sleep(0.1)
  87. end
  88. thread.raise Interrupt, "interrupt a dead condition variable"
  89. assert_raise(Interrupt) { thread.value }
  90. assert(locked)
  91. end
  92. def test_local_barrier
  93. dir = File.dirname(__FILE__)
  94. lbtest = File.join(dir, "lbtest.rb")
  95. $:.unshift File.join(File.dirname(dir), 'ruby')
  96. require 'envutil'
  97. $:.shift
  98. 3.times {
  99. result = `#{EnvUtil.rubybin} #{lbtest}`
  100. assert(!$?.coredump?, '[ruby-dev:30653]')
  101. assert_equal("exit.", result[/.*\Z/], '[ruby-dev:30653]')
  102. }
  103. end
  104. def test_priority
  105. c1 = c2 = 0
  106. t1 = Thread.new { loop { c1 += 1 } }
  107. t1.priority = -1
  108. t2 = Thread.new { loop { c2 += 1 } }
  109. t2.priority = -3
  110. assert_equal(-1, t1.priority)
  111. assert_equal(-3, t2.priority)
  112. sleep 0.5
  113. 5.times do
  114. break if c1 > c2
  115. sleep 0.1
  116. end
  117. t1.kill
  118. t2.kill
  119. # assert_operator(c1, :>, c2, "[ruby-dev:33124]") # not guaranteed
  120. end
  121. def test_new
  122. assert_raise(ThreadError) do
  123. Thread.new
  124. end
  125. t1 = Thread.new { sleep }
  126. assert_raise(ThreadError) do
  127. t1.instance_eval { initialize { } }
  128. end
  129. t2 = Thread.new(&method(:sleep).to_proc)
  130. assert_raise(ThreadError) do
  131. t2.instance_eval { initialize { } }
  132. end
  133. ensure
  134. t1.kill if t1
  135. t2.kill if t2
  136. end
  137. def test_join
  138. t = Thread.new { sleep }
  139. assert_nil(t.join(0.5))
  140. ensure
  141. t.kill if t
  142. end
  143. def test_join2
  144. t1 = Thread.new { sleep(1.5) }
  145. t2 = Thread.new do
  146. t1.join(1)
  147. end
  148. t3 = Thread.new do
  149. sleep 0.5
  150. t1.join
  151. end
  152. assert_nil(t2.value)
  153. assert_equal(t1, t3.value)
  154. ensure
  155. t1.kill if t1
  156. t2.kill if t2
  157. t3.kill if t3
  158. end
  159. def test_kill_main_thread
  160. assert_in_out_err([], <<-INPUT, %w(1), [])
  161. p 1
  162. Thread.kill Thread.current
  163. p 2
  164. INPUT
  165. end
  166. def test_exit
  167. s = 0
  168. Thread.new do
  169. s += 1
  170. Thread.exit
  171. s += 2
  172. end.join
  173. assert_equal(1, s)
  174. end
  175. def test_wakeup
  176. s = 0
  177. t = Thread.new do
  178. s += 1
  179. Thread.stop
  180. s += 1
  181. end
  182. sleep 0.5
  183. assert_equal(1, s)
  184. t.wakeup
  185. sleep 0.5
  186. assert_equal(2, s)
  187. assert_raise(ThreadError) { t.wakeup }
  188. ensure
  189. t.kill if t
  190. end
  191. def test_stop
  192. assert_in_out_err([], <<-INPUT, %w(2), [])
  193. begin
  194. Thread.stop
  195. p 1
  196. rescue ThreadError
  197. p 2
  198. end
  199. INPUT
  200. end
  201. def test_list
  202. assert_in_out_err([], <<-INPUT) do |r, e|
  203. t1 = Thread.new { sleep }
  204. Thread.pass
  205. t2 = Thread.new { loop { } }
  206. t3 = Thread.new { }.join
  207. p [Thread.current, t1, t2].map{|t| t.object_id }.sort
  208. p Thread.list.map{|t| t.object_id }.sort
  209. INPUT
  210. assert_equal(r.first, r.last)
  211. assert_equal([], e)
  212. end
  213. end
  214. def test_main
  215. assert_in_out_err([], <<-INPUT, %w(true false), [])
  216. p Thread.main == Thread.current
  217. Thread.new { p Thread.main == Thread.current }.join
  218. INPUT
  219. end
  220. def test_abort_on_exception
  221. assert_in_out_err([], <<-INPUT, %w(false 1), [])
  222. p Thread.abort_on_exception
  223. begin
  224. Thread.new { raise }
  225. sleep 0.5
  226. p 1
  227. rescue
  228. p 2
  229. end
  230. INPUT
  231. assert_in_out_err([], <<-INPUT, %w(true 2), [])
  232. Thread.abort_on_exception = true
  233. p Thread.abort_on_exception
  234. begin
  235. Thread.new { raise }
  236. sleep 0.5
  237. p 1
  238. rescue
  239. p 2
  240. end
  241. INPUT
  242. assert_in_out_err(%w(-d), <<-INPUT, %w(false 2), /.+/)
  243. p Thread.abort_on_exception
  244. begin
  245. Thread.new { raise }
  246. sleep 0.5
  247. p 1
  248. rescue
  249. p 2
  250. end
  251. INPUT
  252. assert_in_out_err([], <<-INPUT, %w(false true 2), [])
  253. p Thread.abort_on_exception
  254. begin
  255. t = Thread.new { sleep 0.5; raise }
  256. t.abort_on_exception = true
  257. p t.abort_on_exception
  258. sleep 1
  259. p 1
  260. rescue
  261. p 2
  262. end
  263. INPUT
  264. end
  265. def test_status_and_stop_p
  266. a = ::Thread.new { raise("die now") }
  267. b = Thread.new { Thread.stop }
  268. c = Thread.new { Thread.exit }
  269. d = Thread.new { sleep }
  270. e = Thread.current
  271. sleep 0.5
  272. assert_equal(nil, a.status)
  273. assert(a.stop?)
  274. assert_equal("sleep", b.status)
  275. assert(b.stop?)
  276. assert_equal(false, c.status)
  277. assert_match(/^#<TestThread::Thread:.* dead>$/, c.inspect)
  278. assert(c.stop?)
  279. d.kill
  280. assert_equal(["aborting", false], [d.status, d.stop?])
  281. assert_equal(["run", false], [e.status, e.stop?])
  282. ensure
  283. a.kill if a
  284. b.kill if b
  285. c.kill if c
  286. d.kill if d
  287. end
  288. def test_safe_level
  289. t = Thread.new { $SAFE = 3; sleep }
  290. sleep 0.5
  291. assert_equal(0, Thread.current.safe_level)
  292. assert_equal(3, t.safe_level)
  293. ensure
  294. t.kill if t
  295. end
  296. def test_thread_local
  297. t = Thread.new { sleep }
  298. assert_equal(false, t.key?(:foo))
  299. t["foo"] = "foo"
  300. t["bar"] = "bar"
  301. t["baz"] = "baz"
  302. assert_equal(true, t.key?(:foo))
  303. assert_equal(true, t.key?("foo"))
  304. assert_equal(false, t.key?(:qux))
  305. assert_equal(false, t.key?("qux"))
  306. assert_equal([:foo, :bar, :baz], t.keys)
  307. ensure
  308. t.kill if t
  309. end
  310. def test_thread_local_security
  311. t = Thread.new { sleep }
  312. assert_raise(SecurityError) do
  313. Thread.new { $SAFE = 4; t[:foo] }.join
  314. end
  315. assert_raise(SecurityError) do
  316. Thread.new { $SAFE = 4; t[:foo] = :baz }.join
  317. end
  318. assert_raise(RuntimeError) do
  319. Thread.new do
  320. Thread.current[:foo] = :bar
  321. Thread.current.freeze
  322. Thread.current[:foo] = :baz
  323. end.join
  324. end
  325. end
  326. def test_select_wait
  327. assert_nil(IO.select(nil, nil, nil, 1))
  328. t = Thread.new do
  329. IO.select(nil, nil, nil, nil)
  330. end
  331. sleep 0.5
  332. t.kill
  333. end
  334. def test_mutex_deadlock
  335. m = Mutex.new
  336. m.synchronize do
  337. assert_raise(ThreadError) do
  338. m.synchronize do
  339. assert(false)
  340. end
  341. end
  342. end
  343. end
  344. def test_mutex_interrupt
  345. m = Mutex.new
  346. m.lock
  347. t = Thread.new do
  348. m.lock
  349. :foo
  350. end
  351. sleep 0.5
  352. t.kill
  353. assert_nil(t.value)
  354. end
  355. def test_mutex_illegal_unlock
  356. m = Mutex.new
  357. m.lock
  358. assert_raise(ThreadError) do
  359. Thread.new do
  360. m.unlock
  361. end.join
  362. end
  363. end
  364. def test_mutex_fifo_like_lock
  365. m1 = Mutex.new
  366. m2 = Mutex.new
  367. m1.lock
  368. m2.lock
  369. m1.unlock
  370. m2.unlock
  371. assert_equal(false, m1.locked?)
  372. assert_equal(false, m2.locked?)
  373. m3 = Mutex.new
  374. m1.lock
  375. m2.lock
  376. m3.lock
  377. m1.unlock
  378. m2.unlock
  379. m3.unlock
  380. assert_equal(false, m1.locked?)
  381. assert_equal(false, m2.locked?)
  382. assert_equal(false, m3.locked?)
  383. end
  384. def test_mutex_trylock
  385. m = Mutex.new
  386. assert_equal(true, m.try_lock)
  387. assert_equal(false, m.try_lock, '[ruby-core:20943]')
  388. Thread.new{
  389. assert_equal(false, m.try_lock)
  390. }.join
  391. m.unlock
  392. end
  393. def test_recursive_outer
  394. arr = []
  395. obj = Struct.new(:foo, :visited).new(arr, false)
  396. arr << obj
  397. def obj.hash
  398. self[:visited] = true
  399. super
  400. raise "recursive_outer should short circuit intermediate calls"
  401. end
  402. assert_nothing_raised {arr.hash}
  403. assert(obj[:visited])
  404. end
  405. end
  406. class TestThreadGroup < Test::Unit::TestCase
  407. def test_thread_init
  408. thgrp = ThreadGroup.new
  409. Thread.new{
  410. thgrp.add(Thread.current)
  411. assert_equal(thgrp, Thread.new{sleep 1}.group)
  412. }.join
  413. end
  414. def test_frozen_thgroup
  415. thgrp = ThreadGroup.new
  416. t = Thread.new{1}
  417. Thread.new{
  418. thgrp.add(Thread.current)
  419. thgrp.freeze
  420. assert_raise(ThreadError) do
  421. Thread.new{1}.join
  422. end
  423. assert_raise(ThreadError) do
  424. thgrp.add(t)
  425. end
  426. assert_raise(ThreadError) do
  427. ThreadGroup.new.add Thread.current
  428. end
  429. }.join
  430. t.join
  431. end
  432. def test_enclosed_thgroup
  433. thgrp = ThreadGroup.new
  434. assert_equal(false, thgrp.enclosed?)
  435. t = Thread.new{1}
  436. Thread.new{
  437. thgrp.add(Thread.current)
  438. thgrp.enclose
  439. assert_equal(true, thgrp.enclosed?)
  440. assert_nothing_raised do
  441. Thread.new{1}.join
  442. end
  443. assert_raise(ThreadError) do
  444. thgrp.add t
  445. end
  446. assert_raise(ThreadError) do
  447. ThreadGroup.new.add Thread.current
  448. end
  449. }.join
  450. t.join
  451. end
  452. def test_uninitialized
  453. c = Class.new(Thread)
  454. c.class_eval { def initialize; end }
  455. assert_raise(ThreadError) { c.new.start }
  456. end
  457. def test_backtrace
  458. Thread.new{
  459. assert_equal(Array, Thread.main.backtrace.class)
  460. }.join
  461. t = Thread.new{}
  462. t.join
  463. assert_equal(nil, t.backtrace)
  464. end
  465. end