Fix spec runner: read command output during run

IO.pipe buffers 4096 bytes. If the command output fills that up,
Process.waitpid will hang waiting for the spawned process to finish.

Read command output from the pipe in a thread. This thread will self-exit
when the pipe is closed.

Fixes #1287
This commit is contained in:
Bill Ruddock 2020-04-27 17:51:59 +01:00 committed by Elliot Winkler
parent 51bc311548
commit 2a4ef99020
1 changed files with 18 additions and 2 deletions

View File

@ -25,6 +25,7 @@ module Tests
def initialize(*args)
@reader, @writer = IO.pipe
@command_output = ''
options = (args.last.is_a?(Hash) ? args.pop : {})
@args = args
@options = options.merge(
@ -84,7 +85,7 @@ module Tests
def output
@_output ||= begin
stop
without_colors(reader.read)
without_colors(command_output)
end
end
@ -126,7 +127,7 @@ Output:
protected
attr_reader :args, :reader, :writer, :wrapper
attr_reader :args, :command_output, :reader, :writer, :wrapper
private
@ -149,8 +150,23 @@ Output:
def run
pid = spawn(env, *command, options)
t = Thread.new do
loop do
begin
@command_output += reader.read_nonblock(4096)
rescue IO::WaitReadable
IO.select([reader])
retry
rescue EOFError
break
end
end
end
Process.waitpid(pid)
@status = $?
ensure
writer.close unless writer.closed?
t.join
end
def run_with_wrapper