summaryrefslogtreecommitdiff
path: root/tool/lib/test
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2023-10-17 20:13:04 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2023-10-18 02:55:42 +0900
commit776d4dec69c81e2c94c36648205f513baa05551f (patch)
tree213580c98ba2ef814f5b874b155a3b4667e59d73 /tool/lib/test
parent8b520bd3fb239cbfba150644bf7c5676bb07a579 (diff)
Manage parallel test workers after timeout
Diffstat (limited to 'tool/lib/test')
-rw-r--r--tool/lib/test/unit.rb28
1 files changed, 15 insertions, 13 deletions
diff --git a/tool/lib/test/unit.rb b/tool/lib/test/unit.rb
index 23dfbd8f0f..87e05ea62e 100644
--- a/tool/lib/test/unit.rb
+++ b/tool/lib/test/unit.rb
@@ -267,7 +267,7 @@ module Test
r.close_on_exec = true
w.close_on_exec = true
@jobserver = [r, w]
- options[:parallel] ||= 1
+ options[:parallel] ||= 256 # number of tokens to acquire first
end
end
@worker_timeout = EnvUtil.apply_timeout_scale(options[:worker_timeout] || 180)
@@ -661,10 +661,18 @@ module Test
@ios = [] # Array of worker IOs
@job_tokens = String.new(encoding: Encoding::ASCII_8BIT) if @jobserver
begin
- [@tasks.size, @options[:parallel]].min.times {launch_worker}
-
while true
- timeout = [(@workers.filter_map {|w| w.response_at}.min&.-(Time.now) || 0) + @worker_timeout, 1].max
+ newjobs = [@tasks.size, @options[:parallel]].min - @workers.size
+ if newjobs > 0
+ if @jobserver
+ t = @jobserver[0].read_nonblock(newjobs, exception: false)
+ @job_tokens << t if String === t
+ newjobs = @job_tokens.size + 1 - @workers.size
+ end
+ newjobs.times {launch_worker}
+ end
+
+ timeout = [(@workers.filter_map {|w| w.response_at}.min&.-(Time.now) || 0), 0].max + @worker_timeout
if !(_io = IO.select(@ios, nil, nil, timeout))
timeout = Time.now - @worker_timeout
@@ -678,15 +686,9 @@ module Test
}
break
end
- break if @tasks.empty? and @workers.empty?
- if @jobserver and @job_tokens and !@tasks.empty? and
- ((newjobs = [@tasks.size, @options[:parallel]].min) > @workers.size or
- !@workers.any? {|x| x.status == :ready})
- t = @jobserver[0].read_nonblock(newjobs, exception: false)
- if String === t
- @job_tokens << t
- t.size.times {launch_worker}
- end
+ if @tasks.empty?
+ break if @workers.empty?
+ next # wait for all workers to finish
end
end
rescue Interrupt => ex