Namespace
Methods
- #
- A
- D
- J
- P
- S
Included Modules
- Test::Unit::Options
- Test::Unit::GlobOption
- Test::Unit::LoadPathOption
- Test::Unit::GCStressOption
- Test::Unit::RunCount
Class Public methods
autorun()
Link
Instance Public methods
_run_parallel(suites, type, result)
Link
# File ../ruby/lib/test/unit.rb, line 386 def _run_parallel suites, type, result if @options[:parallel] < 1 warn "Error: parameter of -j option should be greater than 0." return end begin # Require needed things for parallel running require 'thread' require 'timeout' @tasks = @files.dup # Array of filenames. @need_quit = false @dead_workers = [] # Array of dead workers. @warnings = [] shutting_down = false rep = [] # FIXME: more good naming # Array of workers. @workers = @options[:parallel].times.map { worker = Worker.launch(@options[:ruby],@args) worker.hook(:dead) do |w,info| after_worker_quit w after_worker_down w, *info unless info.empty? end worker } # Thread: watchdog watchdog = Thread.new do while stat = Process.wait2 break if @interrupt # Break when interrupt pid, stat = stat w = (@workers + @dead_workers).find{|x| pid == x.pid }.dup next unless w unless w.status == :quit # Worker down w.died(nil, !stat.signaled? && stat.exitstatus) end end end @workers_hash = Hash[@workers.map {|w| [w.io,w] }] # out-IO => worker @ios = @workers.map{|w| w.io } # Array of worker IOs while _io = IO.select(@ios)[0] break unless _io.each do |io| break if @need_quit worker = @workers_hash[io] case worker.read when /^okay$/ worker.status = :running jobs_status when /^ready$/ worker.status = :ready if @tasks.empty? break unless @workers.find{|x| x.status == :running } else worker.run(@tasks.shift, type) end jobs_status when /^done (.+?)$/ r = Marshal.load($1.unpack("m")[0]) result << r[0..1] unless r[0..1] == [nil,nil] rep << {file: worker.real_file, report: r[2], result: r[3], testcase: r[5]} $:.push(*r[4]).uniq! when /^p (.+?)$/ del_jobs_status print $1.unpack("m")[0] jobs_status if @options[:job_status] == :replace when /^after (.+?)$/ @warnings << Marshal.load($1.unpack("m")[0]) when /^bye (.+?)$/ after_worker_down worker, Marshal.load($1.unpack("m")[0]) when /^bye$/ if shutting_down after_worker_quit worker else after_worker_down worker end end break if @need_quit end end rescue Interrupt => e @interrupt = e return result ensure shutting_down = true watchdog.kill if watchdog if @interrupt @ios.select!{|x| @workers_hash[x].status == :running } while !@ios.empty? && (__io = IO.select(@ios,[],[],10)) _io = __io[0] _io.each do |io| worker = @workers_hash[io] case worker.read when /^done (.+?)$/ r = Marshal.load($1.unpack("m")[0]) result << r[0..1] unless r[0..1] == [nil,nil] rep << {file: worker.real_file, report: r[2], result: r[3], testcase: r[5]} $:.push(*r[4]).uniq! @ios.delete(io) end end end end @workers.each do |worker| begin timeout(1) do worker.puts "quit" end rescue Errno::EPIPE rescue Timeout::Error end worker.close end begin timeout(0.2*@workers.size) do Process.waitall end rescue Timeout::Error @workers.each do |worker| begin Process.kill(:KILL,worker.pid) rescue Errno::ESRCH; end end end if @interrupt || @options[:no_retry] || @need_quit rep.each do |r| report.push(*r[:report]) end @errors += rep.map{|x| x[:result][0] }.inject(:+) @failures += rep.map{|x| x[:result][1] }.inject(:+) @skips += rep.map{|x| x[:result][2] }.inject(:+) else puts "" puts "Retrying..." puts "" rep.each do |r| if r[:testcase] && r[:file] && !r[:report].empty? require r[:file] _run_suite(eval(r[:testcase]),type) else report.push(*r[:report]) @errors += r[:result][0] @failures += r[:result][1] @skips += r[:result][2] end end end if @warnings warn "" ary = [] @warnings.reject! do |w| r = ary.include?(w[1].message) ary << w[1].message r end @warnings.each do |w| warn "#{w[0]}: #{w[1].message} (#{w[1].class})" end warn "" end end end
_run_suites(suites, type)
Link
# File ../ruby/lib/test/unit.rb, line 557 def _run_suites suites, type @interrupt = nil result = [] if @options[:parallel] _run_parallel suites, type, result else suites.each {|suite| begin result << _run_suite(suite, type) rescue Interrupt => e @interrupt = e break end } end report.reject!{|r| r.start_with? "Skipped:" } if @options[:hide_skip] result end
after_worker_down(worker, e=nil, c=false)
Link
# File ../ruby/lib/test/unit.rb, line 332 def after_worker_down(worker, e=nil, c=false) return unless @options[:parallel] return if @interrupt if e b = e.backtrace warn "#{b.shift}: #{e.message} (#{e.class})" STDERR.print b.map{|s| "\tfrom #{s}"}.join("\n") end @need_quit = true warn "" warn "Some worker was crashed. It seems ruby interpreter's bug" warn "or, a bug of test/unit/parallel.rb. try again without -j" warn "option." warn "" STDERR.flush exit c end
after_worker_quit(worker)
Link
del_jobs_status()
Link
jobs_status()
Link
# File ../ruby/lib/test/unit.rb, line 350 def jobs_status return unless @options[:job_status] puts "" unless @options[:verbose] status_line = @workers.map(&:to_s).join(" ") if @options[:job_status] == :replace and $stdout.tty? @terminal_width ||= begin require 'io/console' $stdout.winsize[1] rescue LoadError, NoMethodError ENV["COLUMNS"].to_i.nonzero? || 80 end @jstr_size ||= 0 del_jobs_status $stdout.flush print status_line[0...@terminal_width] $stdout.flush @jstr_size = [status_line.size, @terminal_width].min else puts status_line end end
puke(klass, meth, e)
Link
Overriding of MiniTest::Unit#puke
# File ../ruby/lib/test/unit.rb, line 577 def puke klass, meth, e # TODO: # this overriding is for minitest feature that skip messages are # hidden when not verbose (-v), note this is temporally. e = case e when MiniTest::Skip then @skips += 1 "Skipped:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n" when MiniTest::Assertion then @failures += 1 "Failure:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n" else @errors += 1 bt = MiniTest::filter_backtrace(e.backtrace).join "\n " "Error:\n#{meth}(#{klass}):\n#{e.class}: #{e.message}\n #{bt}\n" end @report << e e[0, 1] end