2015-11-14 10:43:23 +03:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2008-12-02 13:23:48 +03:00
|
|
|
require 'test/unit'
|
|
|
|
require 'open3'
|
2021-09-29 20:40:14 +03:00
|
|
|
|
|
|
|
if RUBY_ENGINE == 'ruby'
|
|
|
|
require_relative 'lib/jit_support'
|
|
|
|
end
|
2008-12-02 13:23:48 +03:00
|
|
|
|
|
|
|
class TestOpen3 < Test::Unit::TestCase
|
|
|
|
RUBY = EnvUtil.rubybin
|
|
|
|
|
|
|
|
def test_exit_status
|
|
|
|
Open3.popen3(RUBY, '-e', 'exit true') {|i,o,e,t|
|
|
|
|
assert_equal(true, t.value.success?)
|
|
|
|
}
|
|
|
|
Open3.popen3(RUBY, '-e', 'exit false') {|i,o,e,t|
|
|
|
|
assert_equal(false, t.value.success?)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_stdin
|
|
|
|
Open3.popen3(RUBY, '-e', 'exit STDIN.gets.chomp == "t"') {|i,o,e,t|
|
|
|
|
i.puts 't'
|
|
|
|
assert_equal(true, t.value.success?)
|
|
|
|
}
|
|
|
|
Open3.popen3(RUBY, '-e', 'exit STDIN.gets.chomp == "t"') {|i,o,e,t|
|
|
|
|
i.puts 'f'
|
|
|
|
assert_equal(false, t.value.success?)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_stdout
|
|
|
|
Open3.popen3(RUBY, '-e', 'STDOUT.print "foo"') {|i,o,e,t|
|
|
|
|
assert_equal("foo", o.read)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_stderr
|
|
|
|
Open3.popen3(RUBY, '-e', 'STDERR.print "bar"') {|i,o,e,t|
|
|
|
|
assert_equal("bar", e.read)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_block
|
|
|
|
r = Open3.popen3(RUBY, '-e', 'STDOUT.print STDIN.read') {|i,o,e,t|
|
|
|
|
i.print "baz"
|
|
|
|
i.close
|
|
|
|
assert_equal("baz", o.read)
|
|
|
|
"qux"
|
|
|
|
}
|
|
|
|
assert_equal("qux", r)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_noblock
|
|
|
|
i,o,e,t = Open3.popen3(RUBY, '-e', 'STDOUT.print STDIN.read')
|
|
|
|
i.print "baz"
|
|
|
|
i.close
|
|
|
|
assert_equal("baz", o.read)
|
|
|
|
ensure
|
2018-06-17 18:42:35 +03:00
|
|
|
i.close
|
|
|
|
o.close
|
|
|
|
e.close
|
2013-06-19 19:59:41 +04:00
|
|
|
t.join
|
2008-12-02 13:23:48 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_commandline
|
2010-04-30 16:40:40 +04:00
|
|
|
commandline = "echo quux\n"
|
2008-12-02 13:23:48 +03:00
|
|
|
Open3.popen3(commandline) {|i,o,e,t|
|
2010-04-30 16:40:40 +04:00
|
|
|
assert_equal("quux\n", o.read)
|
2008-12-02 13:23:48 +03:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_pid
|
|
|
|
Open3.popen3(RUBY, '-e', 'print $$') {|i,o,e,t|
|
|
|
|
pid = o.read.to_i
|
|
|
|
assert_equal(pid, t[:pid])
|
|
|
|
assert_equal(pid, t.pid)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2014-12-03 01:08:05 +03:00
|
|
|
def test_env
|
2019-06-29 15:19:01 +03:00
|
|
|
Open3.popen3({'A' => 'B', 'C' => 'D'}, RUBY, '-e' 'p ENV["A"]') do |i, out, err, thr|
|
2014-12-03 01:08:05 +03:00
|
|
|
output = out.read
|
|
|
|
assert_equal("\"B\"\n", output)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-01-08 18:38:13 +03:00
|
|
|
def test_numeric_file_descriptor2
|
|
|
|
with_pipe {|r, w|
|
|
|
|
Open3.popen2(RUBY, '-e', 'STDERR.puts "foo"', 2 => w) {|i,o,t|
|
|
|
|
assert_equal("foo\n", r.gets)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_numeric_file_descriptor3
|
2022-01-11 15:25:17 +03:00
|
|
|
omit "passing FDs bigger than 2 is not supported on Windows" if /mswin|mingw/ =~ RbConfig::CONFIG['host_os']
|
2015-01-08 18:38:13 +03:00
|
|
|
with_pipe {|r, w|
|
2015-01-07 18:29:28 +03:00
|
|
|
Open3.popen3(RUBY, '-e', 'IO.open(3).puts "foo"', 3 => w) {|i,o,e,t|
|
|
|
|
assert_equal("foo\n", r.gets, "[GH-808] [ruby-core:67347] [Bug #10699]")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2008-12-02 13:23:48 +03:00
|
|
|
def with_pipe
|
|
|
|
r, w = IO.pipe
|
|
|
|
yield r, w
|
|
|
|
ensure
|
2018-06-17 18:42:35 +03:00
|
|
|
r.close
|
|
|
|
w.close
|
2008-12-02 13:23:48 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def with_reopen(io, arg)
|
|
|
|
old = io.dup
|
|
|
|
io.reopen(arg)
|
|
|
|
yield old
|
|
|
|
ensure
|
|
|
|
io.reopen(old)
|
2018-06-17 18:42:35 +03:00
|
|
|
old.close
|
2008-12-02 13:23:48 +03:00
|
|
|
end
|
|
|
|
|
2008-12-04 13:58:32 +03:00
|
|
|
def test_popen2
|
2008-12-02 13:23:48 +03:00
|
|
|
with_pipe {|r, w|
|
2008-12-04 13:58:32 +03:00
|
|
|
with_reopen(STDERR, w) {|old|
|
2008-12-02 13:23:48 +03:00
|
|
|
w.close
|
2008-12-04 13:58:32 +03:00
|
|
|
Open3.popen2(RUBY, '-e', 's=STDIN.read; STDOUT.print s+"o"; STDERR.print s+"e"') {|i,o,t|
|
2008-12-02 13:23:48 +03:00
|
|
|
assert_kind_of(Thread, t)
|
2008-12-04 13:58:32 +03:00
|
|
|
i.print "z"
|
2008-12-02 13:23:48 +03:00
|
|
|
i.close
|
2008-12-04 13:58:32 +03:00
|
|
|
STDERR.reopen(old)
|
|
|
|
assert_equal("zo", o.read)
|
2021-09-29 20:40:14 +03:00
|
|
|
if defined?(JITSupport)
|
|
|
|
assert_equal("ze", JITSupport.remove_mjit_logs(r.read))
|
|
|
|
else
|
|
|
|
assert_equal("ze", r.read)
|
|
|
|
end
|
2008-12-02 13:23:48 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2008-12-04 13:58:32 +03:00
|
|
|
def test_popen2e
|
2008-12-02 13:23:48 +03:00
|
|
|
with_pipe {|r, w|
|
|
|
|
with_reopen(STDERR, w) {|old|
|
|
|
|
w.close
|
2008-12-04 13:58:32 +03:00
|
|
|
Open3.popen2e(RUBY, '-e', 's=STDIN.read; STDOUT.print s+"o"; STDOUT.flush; STDERR.print s+"e"') {|i,o,t|
|
2008-12-02 13:23:48 +03:00
|
|
|
assert_kind_of(Thread, t)
|
|
|
|
i.print "y"
|
|
|
|
i.close
|
|
|
|
STDERR.reopen(old)
|
2008-12-04 13:58:32 +03:00
|
|
|
assert_equal("yoye", o.read)
|
|
|
|
assert_equal("", r.read)
|
2008-12-02 13:23:48 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2020-06-18 17:01:36 +03:00
|
|
|
def test_popen2e_noblock
|
|
|
|
i, o, t = Open3.popen2e(RUBY, '-e', 'STDOUT.print STDIN.read')
|
|
|
|
i.print "baz"
|
|
|
|
i.close
|
|
|
|
assert_equal("baz", o.read)
|
|
|
|
ensure
|
|
|
|
i.close
|
|
|
|
o.close
|
|
|
|
t.join
|
|
|
|
end
|
|
|
|
|
2008-12-07 11:45:31 +03:00
|
|
|
def test_capture3
|
|
|
|
o, e, s = Open3.capture3(RUBY, '-e', 'i=STDIN.read; print i+"o"; STDOUT.flush; STDERR.print i+"e"', :stdin_data=>"i")
|
2008-12-04 17:24:54 +03:00
|
|
|
assert_equal("io", o)
|
|
|
|
assert_equal("ie", e)
|
|
|
|
assert(s.success?)
|
|
|
|
end
|
|
|
|
|
2017-10-21 10:00:58 +03:00
|
|
|
def test_capture3_stdin_data_io
|
|
|
|
IO.pipe {|r, w|
|
|
|
|
w.write "i"
|
|
|
|
w.close
|
|
|
|
o, e, s = Open3.capture3(RUBY, '-e', 'i=STDIN.read; print i+"o"; STDOUT.flush; STDERR.print i+"e"', :stdin_data=>r)
|
|
|
|
assert_equal("io", o)
|
|
|
|
assert_equal("ie", e)
|
|
|
|
assert(s.success?)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2008-12-07 11:45:31 +03:00
|
|
|
def test_capture3_flip
|
|
|
|
o, e, s = Open3.capture3(RUBY, '-e', 'STDOUT.sync=true; 1000.times { print "o"*1000; STDERR.print "e"*1000 }')
|
2008-12-04 17:24:54 +03:00
|
|
|
assert_equal("o"*1000000, o)
|
|
|
|
assert_equal("e"*1000000, e)
|
|
|
|
assert(s.success?)
|
|
|
|
end
|
|
|
|
|
2008-12-07 11:45:31 +03:00
|
|
|
def test_capture2
|
|
|
|
o, s = Open3.capture2(RUBY, '-e', 'i=STDIN.read; print i+"o"', :stdin_data=>"i")
|
2008-12-04 17:24:54 +03:00
|
|
|
assert_equal("io", o)
|
|
|
|
assert(s.success?)
|
|
|
|
end
|
|
|
|
|
2017-10-21 10:00:58 +03:00
|
|
|
def test_capture2_stdin_data_io
|
|
|
|
IO.pipe {|r, w|
|
|
|
|
w.write "i"
|
|
|
|
w.close
|
|
|
|
o, s = Open3.capture2(RUBY, '-e', 'i=STDIN.read; print i+"o"', :stdin_data=>r)
|
|
|
|
assert_equal("io", o)
|
|
|
|
assert(s.success?)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2008-12-07 11:45:31 +03:00
|
|
|
def test_capture2e
|
|
|
|
oe, s = Open3.capture2e(RUBY, '-e', 'i=STDIN.read; print i+"o"; STDOUT.flush; STDERR.print i+"e"', :stdin_data=>"i")
|
2008-12-04 17:24:54 +03:00
|
|
|
assert_equal("ioie", oe)
|
|
|
|
assert(s.success?)
|
|
|
|
end
|
|
|
|
|
2017-10-21 10:00:58 +03:00
|
|
|
def test_capture2e_stdin_data_io
|
|
|
|
IO.pipe {|r, w|
|
|
|
|
w.write "i"
|
|
|
|
w.close
|
|
|
|
oe, s = Open3.capture2e(RUBY, '-e', 'i=STDIN.read; print i+"o"; STDOUT.flush; STDERR.print i+"e"', :stdin_data=>r)
|
|
|
|
assert_equal("ioie", oe)
|
|
|
|
assert(s.success?)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2014-03-01 14:56:39 +04:00
|
|
|
def test_capture3_stdin_data
|
|
|
|
o, e, s = Open3.capture3(RUBY, '-e', '', :stdin_data=>"z"*(1024*1024))
|
|
|
|
assert_equal("", o)
|
|
|
|
assert_equal("", e)
|
|
|
|
assert(s.success?)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_capture2_stdin_data
|
|
|
|
o, s = Open3.capture2(RUBY, '-e', '', :stdin_data=>"z"*(1024*1024))
|
|
|
|
assert_equal("", o)
|
|
|
|
assert(s.success?)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_capture2e_stdin_data
|
|
|
|
oe, s = Open3.capture2e(RUBY, '-e', '', :stdin_data=>"z"*(1024*1024))
|
|
|
|
assert_equal("", oe)
|
|
|
|
assert(s.success?)
|
|
|
|
end
|
|
|
|
|
2008-12-04 13:58:32 +03:00
|
|
|
def test_pipeline_rw
|
|
|
|
Open3.pipeline_rw([RUBY, '-e', 'print STDIN.read + "1"'],
|
|
|
|
[RUBY, '-e', 'print STDIN.read + "2"']) {|i,o,ts|
|
|
|
|
assert_kind_of(IO, i)
|
|
|
|
assert_kind_of(IO, o)
|
|
|
|
assert_kind_of(Array, ts)
|
|
|
|
assert_equal(2, ts.length)
|
|
|
|
ts.each {|t| assert_kind_of(Thread, t) }
|
|
|
|
i.print "0"
|
|
|
|
i.close
|
|
|
|
assert_equal("012", o.read)
|
|
|
|
ts.each {|t|
|
|
|
|
assert(t.value.success?)
|
2008-12-02 13:23:48 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2008-12-04 13:58:32 +03:00
|
|
|
def test_pipeline_r
|
|
|
|
Open3.pipeline_r([RUBY, '-e', 'print "1"'],
|
|
|
|
[RUBY, '-e', 'print STDIN.read + "2"']) {|o,ts|
|
|
|
|
assert_kind_of(IO, o)
|
|
|
|
assert_kind_of(Array, ts)
|
|
|
|
assert_equal(2, ts.length)
|
|
|
|
ts.each {|t| assert_kind_of(Thread, t) }
|
|
|
|
assert_equal("12", o.read)
|
|
|
|
ts.each {|t|
|
|
|
|
assert(t.value.success?)
|
|
|
|
}
|
|
|
|
}
|
2008-12-02 13:23:48 +03:00
|
|
|
end
|
2008-12-04 13:58:32 +03:00
|
|
|
|
|
|
|
def test_pipeline_w
|
|
|
|
command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
|
|
|
|
str = 'ttftff'
|
|
|
|
Open3.pipeline_w(*[command]*str.length) {|i,ts|
|
|
|
|
assert_kind_of(IO, i)
|
|
|
|
assert_kind_of(Array, ts)
|
|
|
|
assert_equal(str.length, ts.length)
|
|
|
|
ts.each {|t| assert_kind_of(Thread, t) }
|
|
|
|
i.print str
|
|
|
|
i.close
|
2010-01-26 02:12:50 +03:00
|
|
|
ts.each_with_index {|t, ii|
|
|
|
|
assert_equal(str[ii] == ?t, t.value.success?)
|
2008-12-04 13:58:32 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2008-12-05 13:07:13 +03:00
|
|
|
def test_pipeline_start
|
|
|
|
command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
|
|
|
|
str = 'ttftff'
|
|
|
|
Open3.pipeline_start([RUBY, '-e', 'print ARGV[0]', str],
|
|
|
|
*([command]*str.length)) {|ts|
|
|
|
|
assert_kind_of(Array, ts)
|
|
|
|
assert_equal(str.length+1, ts.length)
|
|
|
|
ts.each {|t| assert_kind_of(Thread, t) }
|
|
|
|
ts.each_with_index {|t, i|
|
|
|
|
if i == 0
|
|
|
|
assert(t.value.success?)
|
|
|
|
else
|
|
|
|
assert_equal(str[i-1] == ?t, t.value.success?)
|
|
|
|
end
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2008-12-10 20:24:42 +03:00
|
|
|
def test_pipeline_start_noblock
|
|
|
|
ts = Open3.pipeline_start([RUBY, '-e', ''])
|
|
|
|
assert_kind_of(Array, ts)
|
|
|
|
assert_equal(1, ts.length)
|
|
|
|
ts.each {|t| assert_kind_of(Thread, t) }
|
|
|
|
t = ts[0]
|
|
|
|
assert(t.value.success?)
|
|
|
|
end
|
|
|
|
|
2008-12-05 13:07:13 +03:00
|
|
|
def test_pipeline
|
|
|
|
command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
|
|
|
|
str = 'ttftff'
|
|
|
|
ss = Open3.pipeline([RUBY, '-e', 'print ARGV[0]', str],
|
|
|
|
*([command]*str.length))
|
|
|
|
assert_kind_of(Array, ss)
|
|
|
|
assert_equal(str.length+1, ss.length)
|
|
|
|
ss.each {|s| assert_kind_of(Process::Status, s) }
|
|
|
|
ss.each_with_index {|s, i|
|
|
|
|
if i == 0
|
|
|
|
assert(s.success?)
|
|
|
|
else
|
|
|
|
assert_equal(str[i-1] == ?t, s.success?)
|
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2018-12-12 09:48:46 +03:00
|
|
|
def test_integer_and_symbol_key
|
|
|
|
command = [RUBY, '-e', 'puts "test_integer_and_symbol_key"']
|
2018-12-13 11:53:15 +03:00
|
|
|
out, status = Open3.capture2(*command, :chdir => '.', 2 => IO::NULL)
|
2018-12-12 09:48:46 +03:00
|
|
|
assert_equal("test_integer_and_symbol_key\n", out)
|
2019-06-30 03:34:41 +03:00
|
|
|
assert_predicate(status, :success?)
|
2018-12-12 09:48:46 +03:00
|
|
|
end
|
2008-12-02 13:23:48 +03:00
|
|
|
end
|