1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
require "childprocess"
require "expect"
require "minitest/autorun"
module IntegrationStartHelper
def command_for(app_file)
[
"ruby",
app_file,
"-p",
"0", # any free port
"-s",
"puma",
]
end
def with_process(command:, env: {}, debug: false)
process = ChildProcess.build(*command)
process.leader = true # ensure entire process tree dies
process.environment.merge!(env)
read_io, write_io = IO.pipe
process.io.stdout = write_io
process.io.stderr = write_io
process.start
# Close parent's copy of the write end of the pipe so when the (forked) child
# process closes its write end of the pipe the parent receives EOF when
# attempting to read from it. If the parent leaves its write end open, it
# will not detect EOF.
write_io.close
echo_output(read_io) if debug || debug_all?
yield process, read_io
ensure
read_io.close
process.stop
end
def echo_output(read_io)
Thread.new do
begin
loop { print read_io.readpartial(8192) }
rescue EOFError
end
end
end
def debug_all?
ENV.key?("DEBUG_START_PROCESS")
end
def wait_timeout
case RUBY_ENGINE
when "jruby", "truffleruby"
# takes some time to start the JVM
10.0
else
3.0
end
end
def wait_for_output(read_io, matcher, timeout = wait_timeout)
return true if read_io.expect(matcher, timeout).to_a.any?
raise "Waited for #{timeout} seconds, but received no output matching: " \
"#{matcher.source}"
end
end
|