File: pfork4_test.rb

package info (click to toggle)
ruby-open4 1.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 184 kB
  • sloc: ruby: 806; makefile: 2
file content (150 lines) | stat: -rw-r--r-- 3,756 bytes parent folder | download
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