-
Notifications
You must be signed in to change notification settings - Fork 79
/
Copy pathio_spec.rb
217 lines (165 loc) · 4.26 KB
/
io_spec.rb
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
require File.expand_path('../spec_helper', __FILE__)
describe ChildProcess do
it "can redirect stdout, stderr" do
process = ruby(<<-CODE)
[STDOUT, STDERR].each_with_index do |io, idx|
io.sync = true
io.puts idx
end
CODE
out = Tempfile.new("stdout-spec")
err = Tempfile.new("stderr-spec")
begin
process.io.stdout = out
process.io.stderr = err
process.start
process.io.stdin.should be_nil
process.wait
out.rewind
err.rewind
out.read.should == "0\n"
err.read.should == "1\n"
ensure
out.close
err.close
end
end
it "can redirect stdout only" do
process = ruby(<<-CODE)
[STDOUT, STDERR].each_with_index do |io, idx|
io.sync = true
io.puts idx
end
CODE
out = Tempfile.new("stdout-spec")
begin
process.io.stdout = out
process.start
process.wait
out.rewind
out.read.should == "0\n"
ensure
out.close
end
end
it "pumps all output" do
10.times do |i|
process = echo
out = Tempfile.new("duplex")
begin
process.io.stdout = out
process.start
process.poll_for_exit(exit_timeout)
out.rewind
out.read.should == "hello\n"
ensure
out.close
end
end
end
it "can write to stdin if duplex = true" do
process = cat
out = Tempfile.new("duplex")
out.sync = true
begin
process.io.stdout = out
process.io.stderr = out
process.duplex = true
process.start
process.io.stdin.puts "hello world"
process.io.stdin.close
process.poll_for_exit(exit_timeout)
out.rewind
out.read.should == "hello world\n"
ensure
out.close
end
end
it "can write to stdin interactively if duplex = true" do
process = cat
out = Tempfile.new("duplex")
out.sync = true
out_receiver = File.open(out.path, "rb")
begin
process.io.stdout = out
process.io.stderr = out
process.duplex = true
process.start
stdin = process.io.stdin
lf = ChildProcess.windows? ? "\r\n" : "\n"
stdin.puts "hello"
stdin.flush
wait_until { rewind_and_read(out_receiver).should == "hello#{lf}" }
stdin.putc "n"
stdin.flush
wait_until { rewind_and_read(out_receiver).should == "hello#{lf}n" }
stdin.print "e"
stdin.flush
wait_until { rewind_and_read(out_receiver).should == "hello#{lf}ne" }
stdin.printf "w"
stdin.flush
wait_until { rewind_and_read(out_receiver).should == "hello#{lf}new" }
stdin.write "\nworld\n"
stdin.flush
wait_until { rewind_and_read(out_receiver).should == "hello#{lf}new#{lf}world#{lf}" }
stdin.close
process.poll_for_exit(exit_timeout)
ensure
out_receiver.close
out.close
end
end
#
# this works on JRuby 1.6.5 on my Mac, but for some reason
# hangs on Travis (running 1.6.5.1 + OpenJDK).
#
# http://travis-ci.org/#!/jarib/childprocess/jobs/487331
#
it "works with pipes", :process_builder => false do
process = ruby(<<-CODE)
STDOUT.print "stdout"
STDERR.print "stderr"
CODE
stdout, stdout_w = IO.pipe
stderr, stderr_w = IO.pipe
process.io.stdout = stdout_w
process.io.stderr = stderr_w
process.duplex = true
process.start
process.wait
# write streams are closed *after* the process
# has exited - otherwise it won't work on JRuby
# with the current Process implementation
stdout_w.close
stderr_w.close
out = stdout.read
err = stderr.read
[out, err].should == %w[stdout stderr]
end
it "can set close-on-exec when IO is inherited" do
port = random_free_port
server = TCPServer.new("127.0.0.1", port)
ChildProcess.close_on_exec server
process = sleeping_ruby
process.io.inherit!
process.start
server.close
wait_until { can_bind? "127.0.0.1", port }
end
it "handles long output" do
process = ruby <<-CODE
print 'a'*3000
CODE
out = Tempfile.new("long-output")
out.sync = true
begin
process.io.stdout = out
process.start
process.wait
out.rewind
out.read.size.should == 3000
ensure
out.close
end
end
end