summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorsorah <sorah@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-02-27 09:03:16 +0000
committersorah <sorah@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-02-27 09:03:16 +0000
commitc6598ffcaed5de0f936b62f3a29b725d6d5ca73d (patch)
tree30ab8eb800681c0d2bcacc202451421328de8588 /lib
parent6725dff1a187443c29a1f308e6ea7726111091bd (diff)
* lib/test/unit.rb: Refactoring; Worker never use Hash for internal storage.
* lib/test/unit.rb: Never use Kernel#spawn. Use IO.popen instead. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30968 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/test/unit.rb105
1 files changed, 55 insertions, 50 deletions
diff --git a/lib/test/unit.rb b/lib/test/unit.rb
index 0304638a66..baa828204f 100644
--- a/lib/test/unit.rb
+++ b/lib/test/unit.rb
@@ -4,6 +4,7 @@ require 'minitest/unit'
require 'test/unit/assertions'
require 'test/unit/testcase'
require 'optparse'
+require 'io/console'
module Test
module Unit
@@ -83,8 +84,7 @@ module Test
end
opts.on '--jobs-status [TYPE]', "Show status of jobs every file; Disabled when --jobs isn't specified." do |type|
- options[:job_status] = true
- options[:job_status_type] = type.to_sym if type
+ options[:job_status] = (type && type.to_sym) || :normal
end
opts.on '-j N', '--jobs N', "Allow run tests with N jobs at once" do |a|
@@ -231,30 +231,35 @@ module Test
class Worker
def self.launch(ruby,args=[])
- i,o = IO.pipe("ASCII-8BIT") # worker o>|i> master
- j,k = IO.pipe("ASCII-8BIT") # worker <j|<k master
- k.sync = true
- pid = spawn(*ruby,
- "#{File.dirname(__FILE__)}/unit/parallel.rb",
- *args, out: o, in: j)
- [o,j].each(&:close)
- new(in: k, out: i, pid: pid, status: :waiting)
+ io = IO.popen([*ruby,
+ "#{File.dirname(__FILE__)}/unit/parallel.rb",
+ *args], "r+")
+ io.sync = true
+ new(io: io, pid: io.pid, status: :waiting)
end
def initialize(h={})
- @worker = h
+ @io = h[:io]
+ @pid = h[:pid]
+ @status = h[:status]
+ @file = nil
+ @real_file = nil
+ @loadpath = []
@hooks = {}
end
+ def puts(*args)
+ @io.puts(*args)
+ end
+
def run(task,type)
- @worker[:file] = File.basename(task).gsub(/\.rb/,"")
- @worker[:real_file] = task
+ @file = File.basename(task).gsub(/\.rb/,"")
+ @real_file = task
begin
- @worker[:loadpath] ||= []
- @worker[:in].puts "loadpath #{[Marshal.dump($:-@worker[:loadpath])].pack("m").gsub("\n","")}"
- @worker[:loadpath] = $:.dup
- @worker[:in].puts "run #{task} #{type}"
- @worker[:status] = :prepare
+ puts "loadpath #{[Marshal.dump($:-@loadpath)].pack("m").gsub("\n","")}"
+ @loadpath = $:.dup
+ puts "run #{task} #{type}"
+ @status = :prepare
rescue Errno::EPIPE
dead
rescue IOError
@@ -270,28 +275,33 @@ module Test
end
def read
- ((self[:status] == :quit) ? self[:out].read : self[:out].gets).chomp
+ ((@status == :quit) ? @io.read : @io.gets).chomp
end
- def [](k); @worker[k]; end
- def []=(k,v); @worker[k]=v; end
+ def close
+ @io.close
+ self
+ end
def dead(*additional)
- @worker[:status] = :quit
- @worker[:in].close
- @worker[:out].close
+ @status = :quit
+ @in.close
+ @out.close
call_hook(:dead,*additional)
end
def to_s
- if self[:file]
- "#{self[:pid]}=#{self[:file]}"
+ if @file
+ "#{@pid}=#{@file}"
else
- "#{self[:pid]}:#{self[:status].to_s.ljust(7)}"
+ "#{@pid}:#{@status.to_s.ljust(7)}"
end
end
+ attr_reader :io, :pid
+ attr_accessor :status, :file, :real_file, :loadpath
+
private
def call_hook(id,*additional)
@@ -342,15 +352,13 @@ module Test
return unless @opts[:job_status]
puts "" unless @opts[:verbose]
status_line = @workers.map(&:to_s).join(" ")
- if @opts[:job_status_type] == :replace
- @terminal_width ||= %x{stty size 2>/dev/null}.split[1].to_i.nonzero? \
- || %x{tput cols 2>/dev/null}.to_i.nonzero? \
- || 80
+ if @opts[:job_status] == :replace
+ @terminal_width ||= $stdout.winsize[1] || ENV["COLUMNS"] || 80
@jstr_size ||= 0
del_jobs_status
- STDOUT.flush
+ $stdout.flush
print status_line[0...@terminal_width]
- STDOUT.flush
+ $stdout.flush
@jstr_size = status_line.size > @terminal_width ? \
@terminal_width : status_line.size
else
@@ -359,7 +367,7 @@ module Test
end
def del_jobs_status
- return unless @opts[:job_status_type] == :replace && @jstr_size
+ return unless @opts[:job_status] == :replace && @jstr_size
print "\r"+" "*@jstr_size+"\r"
end
@@ -368,7 +376,7 @@ module Test
return if @interrupt
@workers.delete(worker)
@dead_workers << worker
- @ios = @workers.map{|w| w[:out] }
+ @ios = @workers.map(&:io)
end
def _run_parallel suites, type, result
@@ -385,32 +393,29 @@ module Test
# Array of workers.
@workers = @opts[:parallel].times.map {
- begin
worker = Worker.launch(@opts[:ruby],@args)
worker.hook(:dead) do |w,info|
after_worker_dead w
after_worker_down w, *info unless info.empty?
end
worker
- rescue Exception; puts "#{$!.class}: #{$!.message}\n#{$!.backtrace}"
- end
}
# Thread: watchdog
watchdog = Thread.new do
while stat = Process.wait2
break if @interrupt # Break when interrupt
- w = (@workers + @dead_workers).find{|x| stat[0] == x[:pid] }.dup
+ w = (@workers + @dead_workers).find{|x| stat[0] == x.pid }.dup
next unless w
- unless w[:status] == :quit
+ unless w.status == :quit
# Worker down
w.dead(nil, stat[1].to_i)
end
end
end
- @workers_hash = Hash[@workers.map {|w| [w[:out],w] }] # out-IO => worker
- @ios = @workers.map{|w| w[:out] } # Array of worker IOs
+ @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|
@@ -418,12 +423,12 @@ module Test
worker = @workers_hash[io]
case worker.read
when /^okay$/
- worker[:status] = :running
+ worker.status = :running
jobs_status
when /^ready$/
- worker[:status] = :ready
+ worker.status = :ready
if @tasks.empty?
- break unless @workers.find{|x| x[:status] == :running }
+ break unless @workers.find{|x| x.status == :running }
else
worker.run(@tasks.shift, type)
end
@@ -432,13 +437,13 @@ module Test
when /^done (.+?)$/
r = Marshal.load($1.unpack("m")[0])
result << r[0..1]
- rep << {file: worker[:real_file],
+ 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 @opts[:job_status_type] == :replace
+ jobs_status if @opts[:job_status] == :replace
when /^after (.+?)$/
@warnings << Marshal.load($1.unpack("m")[0])
when /^bye (.+?)$/
@@ -463,12 +468,12 @@ module Test
@workers.each do |worker|
begin
timeout(1) do
- worker[:in].puts "quit"
+ worker.puts "quit"
end
rescue Errno::EPIPE
rescue Timeout::Error
end
- [:in,:out].each { |name| worker[name].close }
+ worker.close
end
begin
timeout(0.2*@workers.size) do
@@ -477,7 +482,7 @@ module Test
rescue Timeout::Error
@workers.each do |worker|
begin
- Process.kill(:KILL,worker[:pid])
+ Process.kill(:KILL,worker.pid)
rescue Errno::ESRCH; end
end
end