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/helper.rb | 30 +++++++ test/rake/test_private_reader.rb | 42 ++++++++++ test/rake/test_rake_application.rb | 13 ++- test/rake/test_rake_application_options.rb | 118 ++++++++++++++++++++++++++- test/rake/test_rake_backtrace.rb | 81 +++++++++++++++++++ test/rake/test_rake_directory_task.rb | 43 +++++----- test/rake/test_rake_file_task.rb | 22 +++++- test/rake/test_rake_functional.rb | 26 +++++- test/rake/test_rake_multi_task.rb | 8 ++ test/rake/test_rake_rake_test_loader.rb | 2 +- test/rake/test_rake_reduce_compat.rb | 65 +++++++++++++++ test/rake/test_rake_task.rb | 51 +++++++++++- test/rake/test_rake_thread_pool.rb | 123 +++++++++++++++++++++++++++++ test/rake/test_rake_top_level_functions.rb | 2 +- test/rake/test_thread_history_display.rb | 91 +++++++++++++++++++++ 15 files changed, 687 insertions(+), 30 deletions(-) create mode 100644 test/rake/test_private_reader.rb create mode 100644 test/rake/test_rake_backtrace.rb create mode 100644 test/rake/test_rake_reduce_compat.rb create mode 100644 test/rake/test_rake_thread_pool.rb create mode 100644 test/rake/test_thread_history_display.rb (limited to 'test') diff --git a/test/rake/helper.rb b/test/rake/helper.rb index 65443fc111..5a373d3043 100644 --- a/test/rake/helper.rb +++ b/test/rake/helper.rb @@ -1,4 +1,5 @@ require 'rubygems' +$:.unshift File.expand_path('../../lib', __FILE__) begin gem 'minitest' @@ -488,5 +489,34 @@ end VERBOSE end + def rakefile_test_signal + rakefile <<-TEST_SIGNAL +require 'rake/testtask' + +Rake::TestTask.new(:a) do |t| + t.test_files = ['a_test.rb'] +end + +Rake::TestTask.new(:b) do |t| + t.test_files = ['b_test.rb'] +end + +task :test do + Rake::Task[:a].invoke rescue nil + Rake::Task[:b].invoke rescue nil end +task :default => :test + TEST_SIGNAL + open 'a_test.rb', 'w' do |io| + io << 'puts "ATEST"' << "\n" + io << '$stdout.flush' << "\n" + io << 'Process.kill("TERM", $$)' << "\n" + end + open 'b_test.rb', 'w' do |io| + io << 'puts "BTEST"' << "\n" + io << '$stdout.flush' << "\n" + end + end + +end diff --git a/test/rake/test_private_reader.rb b/test/rake/test_private_reader.rb new file mode 100644 index 0000000000..f86d4249b2 --- /dev/null +++ b/test/rake/test_private_reader.rb @@ -0,0 +1,42 @@ +require File.expand_path('../helper', __FILE__) +require 'rake/private_reader' + +class TestPrivateAttrs < Rake::TestCase + + class Sample + include Rake::PrivateReader + + private_reader :reader, :a + + def initialize + @reader = :RVALUE + end + + def get_reader + reader + end + + end + + def setup + super + @sample = Sample.new + end + + def test_private_reader_is_private + assert_private do @sample.reader end + assert_private do @sample.a end + end + + def test_private_reader_returns_data + assert_equal :RVALUE, @sample.get_reader + end + + private + + def assert_private + ex = assert_raises(NoMethodError) do yield end + assert_match(/private/, ex.message) + end + +end diff --git a/test/rake/test_rake_application.rb b/test/rake/test_rake_application.rb index b5d8c652c4..eb6d148a65 100644 --- a/test/rake/test_rake_application.rb +++ b/test/rake/test_rake_application.rb @@ -385,6 +385,18 @@ class TestRakeApplication < Rake::TestCase ARGV.clear end + def test_bad_run_with_backtrace + @app.intern(Rake::Task, "default").enhance { fail } + ARGV.clear + ARGV << '-f' << '-s' << '--backtrace' + assert_raises(SystemExit) { + _, err = capture_io { @app.run } + refute_match(/see full trace/, err) + } + ensure + ARGV.clear + end + def test_run_with_bad_options @app.intern(Rake::Task, "default").enhance { fail } ARGV.clear @@ -486,4 +498,3 @@ class TestRakeApplication < Rake::TestCase end end - diff --git a/test/rake/test_rake_application_options.rb b/test/rake/test_rake_application_options.rb index c1471f443e..004b8ef3ac 100644 --- a/test/rake/test_rake_application_options.rb +++ b/test/rake/test_rake_application_options.rb @@ -29,10 +29,12 @@ class TestRakeApplicationOptions < Rake::TestCase def test_default_options opts = command_line + assert_nil opts.backtrace assert_nil opts.classic_namespace assert_nil opts.dryrun assert_nil opts.ignore_system assert_nil opts.load_system + assert_nil opts.always_multitask assert_nil opts.nosearch assert_equal ['rakelib'], opts.rakelib assert_nil opts.show_prereqs @@ -40,6 +42,7 @@ class TestRakeApplicationOptions < Rake::TestCase assert_nil opts.show_tasks assert_nil opts.silent assert_nil opts.trace + assert_nil opts.thread_pool_size assert_equal ['rakelib'], opts.rakelib assert ! Rake::FileUtilsExt.verbose_flag assert ! Rake::FileUtilsExt.nowrite_flag @@ -110,6 +113,18 @@ class TestRakeApplicationOptions < Rake::TestCase assert_equal :exit, @exit end + def test_jobs + flags(['--jobs', '4'], ['-j', '4']) do |opts| + assert_equal 4, opts.thread_pool_size + end + flags(['--jobs', 'asdas'], ['-j', 'asdas']) do |opts| + assert_equal 2, opts.thread_pool_size + end + flags('--jobs', '-j') do |opts| + assert_equal 2, opts.thread_pool_size + end + end + def test_libdir flags(['--libdir', 'xx'], ['-I', 'xx'], ['-Ixx']) do |opts| $:.include?('xx') @@ -118,6 +133,12 @@ class TestRakeApplicationOptions < Rake::TestCase $:.delete('xx') end + def test_multitask + flags('--multitask', '-m') do |opts| + assert_equal opts.always_multitask, true + end + end + def test_rakefile flags(['--rakefile', 'RF'], ['--rakefile=RF'], ['-f', 'RF'], ['-fRF']) do |opts| assert_equal ['RF'], @app.instance_eval { @rakefiles } @@ -125,7 +146,8 @@ class TestRakeApplicationOptions < Rake::TestCase end def test_rakelib - flags(['--rakelibdir', 'A:B:C'], ['--rakelibdir=A:B:C'], ['-R', 'A:B:C'], ['-RA:B:C']) do |opts| + dirs = %w(A B C).join(File::PATH_SEPARATOR) + flags(['--rakelibdir', dirs], ["--rakelibdir=#{dirs}"], ['-R', dirs], ["-R#{dirs}"]) do |opts| assert_equal ['A', 'B', 'C'], opts.rakelib end end @@ -197,12 +219,76 @@ class TestRakeApplicationOptions < Rake::TestCase def test_trace flags('--trace', '-t') do |opts| - assert opts.trace + assert opts.trace, "should enable trace option" + assert opts.backtrace, "should enabled backtrace option" + assert_equal $stderr, opts.trace_output + assert Rake::FileUtilsExt.verbose_flag + assert ! Rake::FileUtilsExt.nowrite_flag + end + end + + def test_trace_with_stdout + flags('--trace=stdout', '-tstdout', '-t stdout') do |opts| + assert opts.trace, "should enable trace option" + assert opts.backtrace, "should enabled backtrace option" + assert_equal $stdout, opts.trace_output assert Rake::FileUtilsExt.verbose_flag assert ! Rake::FileUtilsExt.nowrite_flag end end + def test_trace_with_stderr + flags('--trace=stderr', '-tstderr', '-t stderr') do |opts| + assert opts.trace, "should enable trace option" + assert opts.backtrace, "should enabled backtrace option" + assert_equal $stderr, opts.trace_output + assert Rake::FileUtilsExt.verbose_flag + assert ! Rake::FileUtilsExt.nowrite_flag + end + end + + def test_trace_with_error + ex = assert_raises(Rake::CommandLineOptionError) do + flags('--trace=xyzzy') do |opts| end + end + assert_match(/un(known|recognized).*\btrace\b.*xyzzy/i, ex.message) + end + + + def test_backtrace + flags('--backtrace') do |opts| + assert opts.backtrace, "should enable backtrace option" + assert_equal $stderr, opts.trace_output + assert ! opts.trace, "should not enable trace option" + assert ! Rake::FileUtilsExt.verbose_flag + end + end + + def test_backtrace_with_stdout + flags('--backtrace=stdout') do |opts| + assert opts.backtrace, "should enable backtrace option" + assert_equal $stdout, opts.trace_output + assert ! opts.trace, "should not enable trace option" + assert ! Rake::FileUtilsExt.verbose_flag + end + end + + def test_backtrace_with_stderr + flags('--backtrace=stderr') do |opts| + assert opts.backtrace, "should enable backtrace option" + assert_equal $stderr, opts.trace_output + assert ! opts.trace, "should not enable trace option" + assert ! Rake::FileUtilsExt.verbose_flag + end + end + + def test_backtrace_with_error + ex = assert_raises(Rake::CommandLineOptionError) do + flags('--backtrace=xyzzy') do |opts| end + end + assert_match(/un(known|recognized).*\bbacktrace\b.*xyzzy/i, ex.message) + end + def test_trace_rules flags('--rules') do |opts| assert opts.trace_rules @@ -213,10 +299,17 @@ class TestRakeApplicationOptions < Rake::TestCase flags('--tasks', '-T') do |opts| assert_equal :tasks, opts.show_tasks assert_equal(//.to_s, opts.show_task_pattern.to_s) + assert_equal nil, opts.show_all_tasks end flags(['--tasks', 'xyz'], ['-Txyz']) do |opts| assert_equal :tasks, opts.show_tasks assert_equal(/xyz/.to_s, opts.show_task_pattern.to_s) + assert_equal nil, opts.show_all_tasks + end + flags(['--tasks', 'xyz', '--comments']) do |opts| + assert_equal :tasks, opts.show_tasks + assert_equal(/xyz/.to_s, opts.show_task_pattern.to_s) + assert_equal false, opts.show_all_tasks end end @@ -224,10 +317,17 @@ class TestRakeApplicationOptions < Rake::TestCase flags('--where', '-W') do |opts| assert_equal :lines, opts.show_tasks assert_equal(//.to_s, opts.show_task_pattern.to_s) + assert_equal true, opts.show_all_tasks end flags(['--where', 'xyz'], ['-Wxyz']) do |opts| assert_equal :lines, opts.show_tasks assert_equal(/xyz/.to_s, opts.show_task_pattern.to_s) + assert_equal true, opts.show_all_tasks + end + flags(['--where', 'xyz', '--comments'], ['-Wxyz', '--comments']) do |opts| + assert_equal :lines, opts.show_tasks + assert_equal(/xyz/.to_s, opts.show_task_pattern.to_s) + assert_equal false, opts.show_all_tasks end end @@ -268,7 +368,7 @@ class TestRakeApplicationOptions < Rake::TestCase assert_equal opts.trace, $trace assert_equal opts.dryrun, $dryrun assert_equal opts.silent, $silent - end + end end assert_match(/deprecated/, err) @@ -308,6 +408,17 @@ class TestRakeApplicationOptions < Rake::TestCase assert '12', ENV['TESTKEY'] end + def test_rake_explicit_task_library + Rake.add_rakelib 'app/task', 'other' + + libs = Rake.application.options.rakelib + + assert libs.include?("app/task") + assert libs.include?("other") + end + + private + def flags(*sets) sets.each do |set| ARGV.clear @@ -332,4 +443,3 @@ class TestRakeApplicationOptions < Rake::TestCase @app.options end end - diff --git a/test/rake/test_rake_backtrace.rb b/test/rake/test_rake_backtrace.rb new file mode 100644 index 0000000000..4d84becf98 --- /dev/null +++ b/test/rake/test_rake_backtrace.rb @@ -0,0 +1,81 @@ +require File.expand_path('../helper', __FILE__) +require 'open3' + +class TestRakeBacktrace < Rake::TestCase + # TODO: factor out similar code in test_rake_functional.rb + def rake(*args) + lib = File.join(@orig_PWD, "lib") + bin_rake = File.join(@orig_PWD, "bin", "rake") + Open3.popen3(RUBY, "-I", lib, bin_rake, *args) { |_, _, err, _| err.read } + end + + def invoke(task_name) + rake task_name.to_s + end + + def test_single_collapse + rakefile %q{ + task :foo do + raise "foooo!" + end + } + + lines = invoke(:foo).split("\n") + + assert_equal "rake aborted!", lines[0] + assert_equal "foooo!", lines[1] + assert_something_matches %r!\A#{Regexp.quote Dir.pwd}/Rakefile:3!i, lines + assert_something_matches %r!\ATasks:!, lines + end + + def test_multi_collapse + rakefile %q{ + task :foo do + Rake.application.invoke_task(:bar) + end + task :bar do + raise "barrr!" + end + } + + lines = invoke(:foo).split("\n") + + assert_equal "rake aborted!", lines[0] + assert_equal "barrr!", lines[1] + assert_something_matches %r!\A#{Regexp.quote Dir.pwd}/Rakefile:6!i, lines + assert_something_matches %r!\A#{Regexp.quote Dir.pwd}/Rakefile:3!i, lines + assert_something_matches %r!\ATasks:!, lines + end + + def test_suppress_option + rakefile %q{ + task :baz do + raise "bazzz!" + end + } + + lines = rake("baz").split("\n") + assert_equal "rake aborted!", lines[0] + assert_equal "bazzz!", lines[1] + assert_something_matches %r!Rakefile!i, lines + + lines = rake("--suppress-backtrace", ".ak.file", "baz").split("\n") + assert_equal "rake aborted!", lines[0] + assert_equal "bazzz!", lines[1] + refute_match %r!Rakefile!i, lines[2] + end + + private + + # Assert that the pattern matches at least one line in +lines+. + def assert_something_matches(pattern, lines) + lines.each do |ln| + if pattern =~ ln + assert_match pattern, ln + return + end + end + flunk "expected #{pattern.inspect} to match something in:\n #{lines.join("\n ")}" + end + +end diff --git a/test/rake/test_rake_directory_task.rb b/test/rake/test_rake_directory_task.rb index 6ddb0d2870..d1154f90d5 100644 --- a/test/rake/test_rake_directory_task.rb +++ b/test/rake/test_rake_directory_task.rb @@ -27,26 +27,31 @@ class TestRakeDirectoryTask < Rake::TestCase if Rake::Win32.windows? def test_directory_win32 - drive = Dir.pwd - while drive != File.dirname(drive) - drive = File.dirname(drive) - end - drive = drive[0...-1] if drive[-1] == ?/ - desc "WIN32 DESC" - directory File.join(Dir.pwd, 'a/b/c') - assert_equal FileTask, Task[drive].class if drive[-1] == ?: - assert_equal FileCreationTask, Task[File.join(Dir.pwd, 'a')].class - assert_equal FileCreationTask, Task[File.join(Dir.pwd, 'a/b')].class - assert_equal FileCreationTask, Task[File.join(Dir.pwd, 'a/b/c')].class - assert_nil Task[drive].comment - assert_equal "WIN32 DESC", Task[File.join(Dir.pwd, 'a/b/c')].comment - assert_nil Task[File.join(Dir.pwd, 'a/b')].comment - verbose(false) { - Task[File.join(Dir.pwd, 'a/b')].invoke - } - assert File.exist?(File.join(Dir.pwd, 'a/b')) - refute File.exist?(File.join(Dir.pwd, 'a/b/c')) + directory 'c:/a/b/c' + assert_equal FileTask, Task['c:'].class + assert_equal FileCreationTask, Task['c:/a'].class + assert_equal FileCreationTask, Task['c:/a/b'].class + assert_equal FileCreationTask, Task['c:/a/b/c'].class + assert_nil Task['c:/'].comment + assert_equal "WIN32 DESC", Task['c:/a/b/c'].comment + assert_nil Task['c:/a/b'].comment end end + + def test_can_use_blocks + runlist = [] + + t1 = directory("a/b/c" => :t2) { |t| runlist << t.name } + t2 = task(:t2) { |t| runlist << t.name } + + verbose(false) { + t1.invoke + } + + assert_equal Task["a/b/c"], t1 + assert_equal FileCreationTask, Task["a/b/c"].class + assert_equal ["t2", "a/b/c"], runlist + assert File.directory?("a/b/c") + end end diff --git a/test/rake/test_rake_file_task.rb b/test/rake/test_rake_file_task.rb index e586551237..a46851bd01 100644 --- a/test/rake/test_rake_file_task.rb +++ b/test/rake/test_rake_file_task.rb @@ -41,6 +41,23 @@ class TestRakeFileTask < Rake::TestCase assert ! t1.needed?, "Should not need to rebuild new file because of old" end + def test_file_times_new_depend_on_regular_task_timestamps + load_phony + + name = "dummy" + task name + + create_timed_files(NEWFILE) + + t1 = Rake.application.intern(FileTask, NEWFILE).enhance([name]) + + assert t1.needed?, "depending on non-file task uses Time.now" + + task(name => :phony) + + assert ! t1.needed?, "unless the non-file task has a timestamp" + end + def test_file_times_old_depends_on_new create_timed_files(OLDFILE, NEWFILE) @@ -98,5 +115,8 @@ class TestRakeFileTask < Rake::TestCase assert( ! File.exist?(NEWFILE), "NEWFILE should be deleted") end -end + def load_phony + load File.join(@orig_PWD, "lib/rake/phony.rb") + end +end diff --git a/test/rake/test_rake_functional.rb b/test/rake/test_rake_functional.rb index 3764709f38..ad59f7b9f8 100644 --- a/test/rake/test_rake_functional.rb +++ b/test/rake/test_rake_functional.rb @@ -5,8 +5,8 @@ require 'open3' class TestRakeFunctional < Rake::TestCase def setup - @rake_path = File.expand_path("../../../bin/rake", __FILE__) - lib_path = File.expand_path("../../../lib", __FILE__) + @rake_path = File.expand_path("bin/rake") + lib_path = File.expand_path("lib") @ruby_options = ["-I#{lib_path}", "-I."] @verbose = ENV['VERBOSE'] @@ -417,6 +417,28 @@ class TestRakeFunctional < Rake::TestCase assert_equal "1\n", @out end + def can_detect_signals? + system "ruby -e 'Process.kill \"TERM\", $$'" + status = $? + if @verbose + puts " SIG status = #{$?.inspect}" + puts " SIG status.respond_to?(:signaled?) = #{$?.respond_to?(:signaled?).inspect}" + puts " SIG status.signaled? = #{status.signaled?}" if status.respond_to?(:signaled?) + end + status.respond_to?(:signaled?) && status.signaled? + end + + def test_signal_propagation_in_tests + if can_detect_signals? + rakefile_test_signal + rake + assert_match(/ATEST/, @out) + refute_match(/BTEST/, @out) + else + skip "Signal detect seems broken on this system" + end + end + private # Run a shell Ruby command with command line options (using the diff --git a/test/rake/test_rake_multi_task.rb b/test/rake/test_rake_multi_task.rb index cac235b9d3..22d13d27a0 100644 --- a/test/rake/test_rake_multi_task.rb +++ b/test/rake/test_rake_multi_task.rb @@ -47,5 +47,13 @@ class TestRakeMultiTask < Rake::TestCase assert @runs.index("B0") < @runs.index("B1") assert @runs.index("B1") < @runs.index("B2") end + + def test_multitasks_with_parameters + task :a, [:arg] do |t,args| add_run(args[:arg]) end + multitask :b, [:arg] => [:a] do |t,args| add_run(args[:arg]+'mt') end + Task[:b].invoke "b" + assert @runs[0] == "b" + assert @runs[1] == "bmt" + end end diff --git a/test/rake/test_rake_rake_test_loader.rb b/test/rake/test_rake_rake_test_loader.rb index be3c7da61f..5b5e81d06d 100644 --- a/test/rake/test_rake_rake_test_loader.rb +++ b/test/rake/test_rake_rake_test_loader.rb @@ -10,7 +10,7 @@ class TestRakeRakeTestLoader < Rake::TestCase ARGV.replace %w[foo.rb test_*.rb -v] - load File.expand_path('../../../lib/rake/rake_test_loader.rb', __FILE__) + load File.join(@orig_PWD, 'lib/rake/rake_test_loader.rb') assert_equal %w[-v], ARGV ensure diff --git a/test/rake/test_rake_reduce_compat.rb b/test/rake/test_rake_reduce_compat.rb new file mode 100644 index 0000000000..12872614db --- /dev/null +++ b/test/rake/test_rake_reduce_compat.rb @@ -0,0 +1,65 @@ +require File.expand_path('../helper', __FILE__) +require 'open3' + +class TestRakeReduceCompat < Rake::TestCase + # TODO: factor out similar code in test_rake_functional.rb + def rake(*args) + lib = File.join(@orig_PWD, "lib") + bin_rake = File.join(@orig_PWD, "bin", "rake") + Open3.popen3(RUBY, "-I", lib, bin_rake, *args) { |_, out, _, _| out.read } + end + + def invoke_normal(task_name) + rake task_name.to_s + end + + def invoke_reduce_compat(task_name) + rake "--reduce-compat", task_name.to_s + end + + def test_no_deprecated_dsl + rakefile %q{ + task :check_task do + Module.new { p defined?(task) } + end + + task :check_file do + Module.new { p defined?(file) } + end + } + + assert_equal %{"method"}, invoke_normal(:check_task).chomp + assert_equal %{"method"}, invoke_normal(:check_file).chomp + + assert_equal "nil", invoke_reduce_compat(:check_task).chomp + assert_equal "nil", invoke_reduce_compat(:check_file).chomp + end + + def test_no_classic_namespace + rakefile %q{ + task :check_task do + begin + Task + print "present" + rescue NameError + print "absent" + end + end + + task :check_file_task do + begin + FileTask + print "present" + rescue NameError + print "absent" + end + end + } + + assert_equal "present", invoke_normal(:check_task) + assert_equal "present", invoke_normal(:check_file_task) + + assert_equal "absent", invoke_reduce_compat(:check_task) + assert_equal "absent", invoke_reduce_compat(:check_file_task) + end +end diff --git a/test/rake/test_rake_task.rb b/test/rake/test_rake_task.rb index a5bc693237..836e930ee4 100644 --- a/test/rake/test_rake_task.rb +++ b/test/rake/test_rake_task.rb @@ -104,10 +104,12 @@ class TestRakeTask < Rake::TestCase end def test_clear + desc "a task" t = task("t" => "a") { } t.clear assert t.prerequisites.empty?, "prerequisites should be empty" assert t.actions.empty?, "actions should be empty" + assert_nil t.comment, "comments should be empty" end def test_clear_prerequisites @@ -123,6 +125,22 @@ class TestRakeTask < Rake::TestCase assert t.actions.empty?, "actions should be empty" end + def test_clear_comments + desc "the original foo" + task :foo => [:x] do + # Dummy action + end + + task(:foo).clear_comments + + desc "a slightly different foo" + task :foo + + assert_equal "a slightly different foo", task(:foo).comment + assert_equal ["x"], task(:foo).prerequisites + assert_equal 1, task(:foo).actions.size + end + def test_find task :tfind assert_equal "tfind", Task[:tfind].name @@ -223,6 +241,38 @@ class TestRakeTask < Rake::TestCase assert_in_delta now + 10, a.timestamp, 0.1, 'computer too slow?' end + def test_always_multitask + mx = Mutex.new + result = [] + + t_a = task(:a) do |t| + sleep 0.02 + mx.synchronize{ result << t.name } + end + + t_b = task(:b) do |t| + mx.synchronize{ result << t.name } + end + + t_c = task(:c => [:a,:b]) do |t| + mx.synchronize{ result << t.name } + end + + t_c.invoke + + # task should always run in order + assert_equal ['a', 'b', 'c'], result + + [t_a, t_b, t_c].each { |t| t.reenable } + result.clear + + Rake.application.options.always_multitask = true + t_c.invoke + + # with multitask, task 'b' should grab the mutex first + assert_equal ['b', 'a', 'c'], result + end + def test_investigation_output t1 = task(:t1 => [:t2, :t3]) { |t| runlist << t.name; 3321 } task(:t2) @@ -264,4 +314,3 @@ class TestRakeTask < Rake::TestCase assert_equal "HI", t.comment end end - 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 diff --git a/test/rake/test_rake_top_level_functions.rb b/test/rake/test_rake_top_level_functions.rb index 4cc4b4cfdd..1ed1af02e3 100644 --- a/test/rake/test_rake_top_level_functions.rb +++ b/test/rake/test_rake_top_level_functions.rb @@ -23,7 +23,7 @@ class TestRakeTopLevelFunctions < Rake::TestCase def test_namespace block = proc do end - namespace("xyz", &block) + namespace("xyz", &block) expected = [ [[:in_namespace, 'xyz'], block] diff --git a/test/rake/test_thread_history_display.rb b/test/rake/test_thread_history_display.rb new file mode 100644 index 0000000000..2ac83b0dc0 --- /dev/null +++ b/test/rake/test_thread_history_display.rb @@ -0,0 +1,91 @@ +require File.expand_path('../helper', __FILE__) + +require 'rake/thread_history_display' + +class TestThreadHistoryDisplay < Rake::TestCase + def setup + super + @time = 1000000 + @stats = [] + @display = Rake::ThreadHistoryDisplay.new(@stats) + end + + def test_banner + out, _ = capture_io do + @display.show + end + assert_match(/Job History/i, out) + end + + def test_item_queued + @stats << event(:item_queued, :item_id => 123) + out, _ = capture_io do + @display.show + end + assert_match(/^ *1000000 +A +item_queued +item_id:1$/, out) + end + + def test_item_dequeued + @stats << event(:item_dequeued, :item_id => 123) + out, _ = capture_io do + @display.show + end + assert_match(/^ *1000000 +A +item_dequeued +item_id:1$/, out) + end + + def test_multiple_items + @stats << event(:item_queued, :item_id => 123) + @stats << event(:item_queued, :item_id => 124) + out, _ = capture_io do + @display.show + end + assert_match(/^ *1000000 +A +item_queued +item_id:1$/, out) + assert_match(/^ *1000001 +A +item_queued +item_id:2$/, out) + end + + def test_waiting + @stats << event(:waiting, :item_id => 123) + out, _ = capture_io do + @display.show + end + assert_match(/^ *1000000 +A +waiting +item_id:1$/, out) + end + + def test_continue + @stats << event(:continue, :item_id => 123) + out, _ = capture_io do + @display.show + end + assert_match(/^ *1000000 +A +continue +item_id:1$/, out) + end + + def test_thread_deleted + @stats << event(:thread_deleted, :deleted_thread => 123456, :thread_count => 12) + out, _ = capture_io do + @display.show + end + assert_match(/^ *1000000 +A +thread_deleted( +deleted_thread:B| +thread_count:12){2}$/, out) + end + + def test_thread_created + @stats << event(:thread_created, :new_thread => 123456, :thread_count => 13) + out, _ = capture_io do + @display.show + end + assert_match(/^ *1000000 +A +thread_created( +new_thread:B| +thread_count:13){2}$/, out) + end + + private + + def event(type, data={}) + result = { + :event => type, + :time => @time / 1_000_000.0, + :data => data, + :thread => Thread.current.object_id + } + @time += 1 + result + end + +end -- cgit v1.2.3