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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
require 'test_case'
module Open4
class PFork4Test < TestCase
def test_fun_successful_return
fun = lambda { 'lucky me' }
cid, _ = pfork4 fun
assert_equal 0, wait_status(cid)
end
def test_fun_force_exit
exit_code = 43
fun = lambda { exit! exit_code }
cid, _ = pfork4 fun
assert_equal exit_code, wait_status(cid)
end
def test_fun_normal_exit
exit_code = 43
fun = lambda { exit exit_code }
cid, _ = pfork4 fun
assert_equal exit_code, wait_status(cid)
end
def test_fun_does_not_propagate_exception_without_block
fun = lambda { raise MyError }
cid, _ = pfork4 fun
refute_equal 0, wait_status(cid)
end
def test_fun_propagate_exception_with_block
fun = lambda { raise MyError }
assert_raises(MyError) { pfork4(fun) {} }
end
def test_fun_propagate_exception_with_block_avoids_zombie_child_process
fun = lambda { raise MyError }
assert_raises(MyError) { pfork4(fun) {} }
assert_empty Process.waitall
end
def test_call_block_upon_exception
fun = lambda { raise MyError }
block_called = false
assert_raises(MyError) { pfork4(fun) { block_called = true } }
assert_equal true, block_called
end
def test_passes_child_pid_to_block
fun = lambda { $stdout.write Process.pid }
cid_in_block = nil
cid_in_fun = nil
status = pfork4(fun) do |cid, _, stdout, _|
cid_in_block = cid
cid_in_fun = stdout.read.to_i
end
assert_equal cid_in_fun, cid_in_block
end
def test_io_pipes_without_block
via_msg = 'foo'
err_msg = 'bar'
fun = lambda do
$stdout.write $stdin.read
$stderr.write err_msg
end
out_actual, err_actual = nil, nil
cid, stdin, stdout, stderr = pfork4 fun
stdin.write via_msg
stdin.close
out_actual = stdout.read
err_actual = stderr.read
assert_equal via_msg, out_actual
assert_equal err_msg, err_actual
assert_equal 0, wait_status(cid)
end
def test_io_pipes_with_block
via_msg = 'foo'
err_msg = 'bar'
fun = lambda do
$stdout.write $stdin.read
$stderr.write err_msg
end
out_actual, err_actual = nil, nil
status = pfork4(fun) do |_, stdin, stdout, stderr|
stdin.write via_msg
stdin.close
out_actual = stdout.read
err_actual = stderr.read
end
assert_equal via_msg, out_actual
assert_equal err_msg, err_actual
assert_equal 0, status.exitstatus
end
def test_exec_in_fun
via_msg = 'foo'
fun = lambda { exec %{ruby -e "print '#{via_msg}'"} }
out_actual = nil
status = pfork4(fun) do |_, stdin, stdout, _|
stdin.close
out_actual = stdout.read
end
assert_equal via_msg, out_actual
assert_equal 0, status.exitstatus
end
def test_io_pipes_and_then_exception_propagation_with_block
via_msg = 'foo'
err_msg = 'bar'
fun = lambda do
$stdout.write $stdin.read
$stderr.write err_msg
raise MyError
end
out_actual, err_actual = nil, nil
assert_raises(MyError) do
pfork4(fun) do |_, stdin, stdout, stderr|
stdin.write via_msg
stdin.close
out_actual = stdout.read
err_actual = stderr.read
end
end
assert_equal via_msg, out_actual
assert_equal err_msg, err_actual
end
def test_blocked_on_io_read_and_exception_propagation_with_block
fun = lambda do
$stdin.read
raise MyError
end
out_actual, err_actual = nil, nil
assert_raises(MyError) do
pfork4(fun) do |_, stdin, stdout, stderr|
stdin.write 'foo'
stdin.close
out_actual = stdout.read
err_actual = stderr.read
end
end
assert_equal '', out_actual
assert_equal '', err_actual
end
end
end
|