Skip to content

Commit

Permalink
Manage parallel test workers after timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
nobu committed Oct 17, 2023
1 parent 8b520bd commit 776d4de
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 13 deletions.
28 changes: 15 additions & 13 deletions tool/lib/test/unit.rb
Expand Up @@ -267,7 +267,7 @@ def non_options(files, options)
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)
Expand Down Expand Up @@ -661,10 +661,18 @@ def _run_parallel suites, type, result
@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
Expand All @@ -678,15 +686,9 @@ def _run_parallel suites, type, result
}
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
Expand Down
7 changes: 7 additions & 0 deletions tool/test/testunit/test_parallel.rb
Expand Up @@ -211,5 +211,12 @@ def test_hungup
assert_match(/^Retrying hung up testcases\.+$/, buf)
assert_match(/^2 tests,.* 0 failures,/, buf)
end

def test_retry_workers
spawn_runner "--worker-timeout=1", "test4test_slow_0.rb", "test4test_slow_1.rb", jobs: "2"
buf = Timeout.timeout(TIMEOUT) {@test_out.read}
assert_match(/^Retrying hung up testcases\.+$/, buf)
assert_match(/^2 tests,.* 0 failures,/, buf)
end
end
end
7 changes: 7 additions & 0 deletions tool/test/testunit/tests_for_parallel/slow_helper.rb
@@ -0,0 +1,7 @@
require 'test/unit'

module TestSlowTimeout
def test_slow
sleep (ENV['sec'] || 3).to_i if on_parallel_worker?
end
end
5 changes: 5 additions & 0 deletions tool/test/testunit/tests_for_parallel/test4test_slow_0.rb
@@ -0,0 +1,5 @@
require_relative 'slow_helper'

class TestSlowV0 < Test::Unit::TestCase
include TestSlowTimeout
end
5 changes: 5 additions & 0 deletions tool/test/testunit/tests_for_parallel/test4test_slow_1.rb
@@ -0,0 +1,5 @@
require_relative 'slow_helper'

class TestSlowV1 < Test::Unit::TestCase
include TestSlowTimeout
end

0 comments on commit 776d4de

Please sign in to comment.