From 9c66bad9f3d522d50d4a45ef8a3a92abbf93229f Mon Sep 17 00:00:00 2001 From: drbrain Date: Thu, 15 Nov 2012 21:59:37 +0000 Subject: * 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 --- test/rake/test_rake_thread_pool.rb | 123 +++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 test/rake/test_rake_thread_pool.rb (limited to 'test/rake/test_rake_thread_pool.rb') 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 -- cgit v1.2.3