mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
Extract Test::JobServer module
A placeholder to handle GNU make jobserver option. spec/default.mspec didn't handle the jobserver using a FIFO.
This commit is contained in:
parent
42d66b894c
commit
bfba65d8c1
Notes:
git
2025-12-19 05:19:39 +00:00
@ -16,6 +16,7 @@ rescue LoadError
|
||||
$:.unshift File.join(File.dirname(__FILE__), '../lib')
|
||||
retry
|
||||
end
|
||||
require_relative '../tool/lib/test/jobserver'
|
||||
|
||||
if !Dir.respond_to?(:mktmpdir)
|
||||
# copied from lib/tmpdir.rb
|
||||
@ -110,35 +111,7 @@ BT = Class.new(bt) do
|
||||
|
||||
def wn=(wn)
|
||||
unless wn == 1
|
||||
if /(?:\A|\s)--jobserver-(?:auth|fds)=(?:(\d+),(\d+)|fifo:((?:\\.|\S)+))/ =~ ENV.delete("MAKEFLAGS")
|
||||
begin
|
||||
if fifo = $3
|
||||
fifo.gsub!(/\\(?=.)/, '')
|
||||
r = File.open(fifo, IO::RDONLY|IO::NONBLOCK|IO::BINARY)
|
||||
w = File.open(fifo, IO::WRONLY|IO::NONBLOCK|IO::BINARY)
|
||||
else
|
||||
r = IO.for_fd($1.to_i(10), "rb", autoclose: false)
|
||||
w = IO.for_fd($2.to_i(10), "wb", autoclose: false)
|
||||
end
|
||||
rescue
|
||||
r.close if r
|
||||
else
|
||||
r.close_on_exec = true
|
||||
w.close_on_exec = true
|
||||
tokens = r.read_nonblock(wn > 0 ? wn : 1024, exception: false)
|
||||
r.close
|
||||
if String === tokens
|
||||
tokens.freeze
|
||||
auth = w
|
||||
w = nil
|
||||
at_exit {auth << tokens; auth.close}
|
||||
wn = tokens.size + 1
|
||||
else
|
||||
w.close
|
||||
wn = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
wn = Test::JobServer.max_jobs(wn > 0 ? wn : 1024, ENV.delete("MAKEFLAGS")) || wn
|
||||
if wn <= 0
|
||||
require 'etc'
|
||||
wn = [Etc.nprocessors / 2, 1].max
|
||||
|
||||
@ -9,6 +9,7 @@ ENV["CHECK_CONSTANT_LEAKS"] ||= "true"
|
||||
|
||||
require "./rbconfig" unless defined?(RbConfig)
|
||||
require_relative "../tool/test-coverage" if ENV.key?("COVERAGE")
|
||||
require_relative "../tool/lib/test/jobserver"
|
||||
load File.dirname(__FILE__) + '/ruby/default.mspec'
|
||||
OBJDIR = File.expand_path("spec/ruby/optional/capi/ext") unless defined?(OBJDIR)
|
||||
class MSpecScript
|
||||
@ -50,34 +51,10 @@ end
|
||||
|
||||
module MSpecScript::JobServer
|
||||
def cores(max = 1)
|
||||
if max > 1 and /(?:\A|\s)--jobserver-(?:auth|fds)=(\d+),(\d+)/ =~ ENV["MAKEFLAGS"]
|
||||
cores = 1
|
||||
begin
|
||||
r = IO.for_fd($1.to_i(10), "rb", autoclose: false)
|
||||
w = IO.for_fd($2.to_i(10), "wb", autoclose: false)
|
||||
jobtokens = r.read_nonblock(max - 1)
|
||||
cores = jobtokens.size
|
||||
if cores > 0
|
||||
cores += 1
|
||||
jobserver = w
|
||||
w = nil
|
||||
at_exit {
|
||||
jobserver.print(jobtokens)
|
||||
jobserver.close
|
||||
}
|
||||
MSpecScript::JobServer.module_eval do
|
||||
remove_method :cores
|
||||
define_method(:cores) do
|
||||
cores
|
||||
end
|
||||
end
|
||||
return cores
|
||||
end
|
||||
rescue Errno::EBADF
|
||||
ensure
|
||||
r&.close
|
||||
w&.close
|
||||
end
|
||||
MSpecScript::JobServer.remove_method :cores
|
||||
if cores = Test::JobServer.max_jobs(max)
|
||||
MSpecScript::JobServer.define_method(:cores) { cores }
|
||||
return cores
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
47
tool/lib/test/jobserver.rb
Normal file
47
tool/lib/test/jobserver.rb
Normal file
@ -0,0 +1,47 @@
|
||||
module Test
|
||||
module JobServer
|
||||
end
|
||||
end
|
||||
|
||||
class << Test::JobServer
|
||||
def connect(makeflags = ENV["MAKEFLAGS"])
|
||||
return unless /(?:\A|\s)--jobserver-(?:auth|fds)=(?:(\d+),(\d+)|fifo:((?:\\.|\S)+))/ =~ makeflags
|
||||
begin
|
||||
if fifo = $3
|
||||
fifo.gsub!(/\\(?=.)/, '')
|
||||
r = File.open(fifo, IO::RDONLY|IO::NONBLOCK|IO::BINARY)
|
||||
w = File.open(fifo, IO::WRONLY|IO::NONBLOCK|IO::BINARY)
|
||||
else
|
||||
r = IO.for_fd($1.to_i(10), "rb", autoclose: false)
|
||||
w = IO.for_fd($2.to_i(10), "wb", autoclose: false)
|
||||
end
|
||||
rescue
|
||||
r&.close
|
||||
nil
|
||||
else
|
||||
return r, w
|
||||
end
|
||||
end
|
||||
|
||||
def acquire_possible(r, w, max)
|
||||
return unless tokens = r.read_nonblock(max - 1, exception: false)
|
||||
if (jobs = tokens.size) > 0
|
||||
jobserver, w = w, nil
|
||||
at_exit do
|
||||
jobserver.print(tokens)
|
||||
jobserver.close
|
||||
end
|
||||
end
|
||||
return jobs + 1
|
||||
rescue Errno::EBADF
|
||||
ensure
|
||||
r&.close
|
||||
w&.close
|
||||
end
|
||||
|
||||
def max_jobs(max = 2, makeflags = ENV["MAKEFLAGS"])
|
||||
if max > 1 and (r, w = connect(makeflags))
|
||||
acquire_possible(r, w, max)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -19,6 +19,7 @@ require_relative '../envutil'
|
||||
require_relative '../colorize'
|
||||
require_relative '../leakchecker'
|
||||
require_relative '../test/unit/testcase'
|
||||
require_relative '../test/jobserver'
|
||||
require 'optparse'
|
||||
|
||||
# See Test::Unit
|
||||
@ -262,27 +263,8 @@ module Test
|
||||
|
||||
def non_options(files, options)
|
||||
@jobserver = nil
|
||||
makeflags = ENV.delete("MAKEFLAGS")
|
||||
if !options[:parallel] and
|
||||
/(?:\A|\s)--jobserver-(?:auth|fds)=(?:(\d+),(\d+)|fifo:((?:\\.|\S)+))/ =~ makeflags
|
||||
begin
|
||||
if fifo = $3
|
||||
fifo.gsub!(/\\(?=.)/, '')
|
||||
r = File.open(fifo, IO::RDONLY|IO::NONBLOCK|IO::BINARY)
|
||||
w = File.open(fifo, IO::WRONLY|IO::NONBLOCK|IO::BINARY)
|
||||
else
|
||||
r = IO.for_fd($1.to_i(10), "rb", autoclose: false)
|
||||
w = IO.for_fd($2.to_i(10), "wb", autoclose: false)
|
||||
end
|
||||
rescue
|
||||
r.close if r
|
||||
nil
|
||||
else
|
||||
r.close_on_exec = true
|
||||
w.close_on_exec = true
|
||||
@jobserver = [r, w]
|
||||
options[:parallel] ||= 256 # number of tokens to acquire first
|
||||
end
|
||||
if !options[:parallel] and @jobserver = Test::JobServer.connect(ENV.delete("MAKEFLAGS"))
|
||||
options[:parallel] ||= 256 # number of tokens to acquire first
|
||||
end
|
||||
@worker_timeout = EnvUtil.apply_timeout_scale(options[:worker_timeout] || 1200)
|
||||
super
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user