summaryrefslogtreecommitdiff
path: root/test/rake/test_rake_thread_pool.rb
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-15 21:59:37 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-15 21:59:37 +0000
commit9c66bad9f3d522d50d4a45ef8a3a92abbf93229f (patch)
tree8fc1ae219e41bdd711442b1d35149da4f45dfa8a /test/rake/test_rake_thread_pool.rb
parentbfc95c6e1639edc909338ef4d20d990caf6f630e (diff)
* lib/rake*: Updated to rake 0.9.3
* test/rake*: ditto * bin/rake: ditto * NEWS: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37664 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/rake/test_rake_thread_pool.rb')
-rw-r--r--test/rake/test_rake_thread_pool.rb123
1 files changed, 123 insertions, 0 deletions
diff --git a/test/rake/test_rake_thread_pool.rb b/test/rake/test_rake_thread_pool.rb
new file mode 100644
index 0000000000..90c8bf577a
--- /dev/null
+++ b/test/rake/test_rake_thread_pool.rb
@@ -0,0 +1,123 @@
+require File.expand_path('../helper', __FILE__)
+require 'rake/thread_pool'
+require 'test/unit/assertions'
+
+class TestRakeTestThreadPool < Rake::TestCase
+ include Rake
+
+ def test_pool_executes_in_current_thread_for_zero_threads
+ pool = ThreadPool.new(0)
+ f = pool.future{Thread.current}
+ pool.join
+ assert_equal Thread.current, f.value
+ end
+
+ def test_pool_executes_in_other_thread_for_pool_of_size_one
+ pool = ThreadPool.new(1)
+ f = pool.future{Thread.current}
+ pool.join
+ refute_equal Thread.current, f.value
+ end
+
+ def test_pool_executes_in_two_other_threads_for_pool_of_size_two
+ pool = ThreadPool.new(2)
+ threads = 2.times.collect{ pool.future{ sleep 0.1; Thread.current } }.each{|f|f.value}
+
+ refute_equal threads[0], threads[1]
+ refute_equal Thread.current, threads[0]
+ refute_equal Thread.current, threads[1]
+ end
+
+ def test_pool_creates_the_correct_number_of_threads
+ pool = ThreadPool.new(2)
+ threads = Set.new
+ t_mutex = Mutex.new
+ 10.times.each do
+ pool.future do
+ sleep 0.02
+ t_mutex.synchronize{ threads << Thread.current }
+ end
+ end
+ pool.join
+ assert_equal 2, threads.count
+ end
+
+ def test_pool_future_captures_arguments
+ pool = ThreadPool.new(2)
+ a = 'a'
+ b = 'b'
+ c = 5 # 5 throws an execption with 5.dup. It should be ignored
+ pool.future(a,c){ |a_var,ignore| a_var.capitalize!; b.capitalize! }
+ pool.join
+ assert_equal 'a', a
+ assert_equal 'b'.capitalize, b
+ end
+
+ def test_pool_join_empties_queue
+ pool = ThreadPool.new(2)
+ repeat = 25
+ repeat.times {
+ pool.future do
+ repeat.times {
+ pool.future do
+ repeat.times {
+ pool.future do end
+ }
+ end
+ }
+ end
+ }
+
+ pool.join
+ assert_equal true, pool.__send__(:__queue__).empty?, "queue should be empty"
+ end
+
+ # test that throwing an exception way down in the blocks propagates
+ # to the top
+ def test_exceptions
+ pool = ThreadPool.new(10)
+
+ deep_exception_block = lambda do |count|
+ next raise Exception.new if ( count < 1 )
+ pool.future(count-1, &deep_exception_block).value
+ end
+
+ assert_raises(Exception) do
+ pool.future(2, &deep_exception_block).value
+ end
+
+ end
+
+ def test_pool_prevents_deadlock
+ pool = ThreadPool.new(5)
+
+ common_dependency_a = pool.future { sleep 0.2 }
+ futures_a = 10.times.collect { pool.future{ common_dependency_a.value; sleep(rand() * 0.01) } }
+
+ common_dependency_b = pool.future { futures_a.each { |f| f.value } }
+ futures_b = 10.times.collect { pool.future{ common_dependency_b.value; sleep(rand() * 0.01) } }
+
+ futures_b.each{|f|f.value}
+ pool.join
+ end
+
+ def test_pool_reports_correct_results
+ pool = ThreadPool.new(7)
+
+ a = 18
+ b = 5
+ c = 3
+
+ result = a.times.collect do
+ pool.future do
+ b.times.collect do
+ pool.future { sleep rand * 0.001; c }
+ end.inject(0) { |m,f| m+f.value }
+ end
+ end.inject(0) { |m,f| m+f.value }
+
+ assert_equal( (a*b*c), result )
+ pool.join
+ end
+
+end