right_popen 1.0.21-x86-mswin32-60 → 1.1.3-x86-mswin32-60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +10 -8
- data/lib/right_popen.rb +125 -30
- data/lib/right_popen/process_base.rb +339 -0
- data/lib/right_popen/process_status.rb +64 -0
- data/lib/right_popen/safe_output_buffer.rb +79 -0
- data/lib/right_popen/target_proxy.rb +67 -0
- data/lib/right_popen/version.rb +2 -2
- data/lib/right_popen/win32/popen3_async.rb +258 -0
- data/lib/right_popen/win32/popen3_sync.rb +35 -0
- data/lib/right_popen/win32/process.rb +306 -0
- data/lib/right_popen/win32/{right_popen.rb → right_popen_ex.rb} +8 -231
- data/lib/win32/right_popen.so +0 -0
- data/right_popen.gemspec +2 -2
- data/spec/produce_mixed_output.rb +3 -0
- data/spec/right_popen/safe_output_buffer_spec.rb +26 -0
- data/spec/right_popen_spec.rb +272 -227
- data/spec/runner.rb +171 -79
- data/spec/sleeper.rb +35 -0
- data/spec/stdout.rb +1 -1
- data/spec/writer.rb +34 -0
- metadata +23 -15
data/lib/win32/right_popen.so
CHANGED
Binary file
|
data/right_popen.gemspec
CHANGED
@@ -47,8 +47,8 @@ EOF
|
|
47
47
|
end
|
48
48
|
spec.files = candidates.sort!
|
49
49
|
|
50
|
-
# Current implementation supports >= 0.
|
51
|
-
spec.
|
50
|
+
# Current implementation supports >= 1.0.0
|
51
|
+
spec.add_development_dependency(%q<eventmachine>, [">= 1.0.0"])
|
52
52
|
if is_windows
|
53
53
|
spec.add_runtime_dependency(%q<win32-process>, [">= 0.6.1"])
|
54
54
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require ::File.expand_path(::File.join(::File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
require ::File.expand_path(::File.join(::File.dirname(__FILE__), '..', '..', 'lib', 'right_popen', 'safe_output_buffer'))
|
3
|
+
|
4
|
+
describe RightScale::RightPopen::SafeOutputBuffer do
|
5
|
+
|
6
|
+
context 'given a default buffer' do
|
7
|
+
subject { described_class.new }
|
8
|
+
|
9
|
+
it 'should limit line count and length' do
|
10
|
+
(described_class::DEFAULT_MAX_LINE_COUNT * 2).times do |line_index|
|
11
|
+
data = 'x' * rand(described_class::DEFAULT_MAX_LINE_LENGTH * 3)
|
12
|
+
subject.safe_buffer_data(data).should be_true
|
13
|
+
end
|
14
|
+
subject.buffer.size.should == described_class::DEFAULT_MAX_LINE_COUNT
|
15
|
+
subject.buffer.first.should == described_class::ELLIPSIS
|
16
|
+
subject.buffer.last.should_not == described_class::ELLIPSIS
|
17
|
+
subject.buffer.each do |line|
|
18
|
+
(line.length <= described_class::DEFAULT_MAX_LINE_LENGTH).should be_true
|
19
|
+
end
|
20
|
+
text = subject.display_text
|
21
|
+
text.should_not be_empty
|
22
|
+
text.lines.count.should == subject.buffer.size
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/spec/right_popen_spec.rb
CHANGED
@@ -1,286 +1,331 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
2
|
require File.expand_path(File.join(File.dirname(__FILE__), 'runner'))
|
3
|
+
|
3
4
|
require 'stringio'
|
5
|
+
require 'tmpdir'
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
7
|
+
describe 'RightScale::RightPopen' do
|
8
|
+
def is_windows?
|
9
|
+
return !!(RUBY_PLATFORM =~ /mswin|mingw/)
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_output.rb'))}\" \"#{STANDARD_MESSAGE}\" \"#{ERROR_MESSAGE}\""
|
13
|
-
runner = Runner.new
|
14
|
-
status = runner.run_right_popen(command)
|
15
|
-
status.status.exitstatus.should == 0
|
16
|
-
status.output_text.should == STANDARD_MESSAGE + "\n"
|
17
|
-
status.error_text.should == ERROR_MESSAGE + "\n"
|
18
|
-
status.pid.should > 0
|
19
|
-
end
|
12
|
+
let(:runner) { ::RightScale::RightPopen::Runner.new }
|
20
13
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
14
|
+
it "should correctly handle many small processes [async]" do
|
15
|
+
pending 'Set environment variable TEST_STRESS to enable' unless ENV['TEST_STRESS']
|
16
|
+
run_count = 100
|
17
|
+
command = is_windows? ? ['cmd.exe', '/c', 'exit 0'] : ['sh', '-c', 'exit 0']
|
18
|
+
@completed = 0
|
19
|
+
@started = 0
|
20
|
+
run_cmd = Proc.new do
|
21
|
+
runner.do_right_popen3_async(command, runner_options={}, popen3_options={}) do |runner_status|
|
22
|
+
@completed += 1
|
23
|
+
runner_status.status.exitstatus.should == 0
|
24
|
+
runner_status.output_text.should == ''
|
25
|
+
runner_status.error_text.should == ''
|
26
|
+
runner_status.pid.should > 0
|
27
|
+
end
|
28
|
+
@started += 1
|
29
|
+
if @started < run_count
|
30
|
+
EM.next_tick { run_cmd.call }
|
31
|
+
end
|
29
32
|
end
|
33
|
+
EM.run do
|
34
|
+
EM.next_tick { run_cmd.call }
|
30
35
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
command = is_windows? ? "cmd.exe /c exit 0" : "exit 0"
|
35
|
-
runner = Runner.new
|
36
|
-
@completed = 0
|
37
|
-
@started = 0
|
38
|
-
run_cmd = Proc.new do
|
39
|
-
runner.do_right_popen(command) do |status|
|
40
|
-
@completed += 1
|
41
|
-
status.status.exitstatus.should == 0
|
42
|
-
status.output_text.should == ''
|
43
|
-
status.error_text.should == ''
|
44
|
-
status.pid.should > 0
|
45
|
-
end
|
46
|
-
@started += 1
|
47
|
-
if @started < TO_RUN
|
48
|
-
EM.next_tick { run_cmd.call }
|
36
|
+
EM::PeriodicTimer.new(1) do
|
37
|
+
if @completed >= run_count
|
38
|
+
EM.stop
|
49
39
|
end
|
50
40
|
end
|
51
|
-
|
52
|
-
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
[:sync, :async].each do |synchronicity|
|
45
|
+
|
46
|
+
context synchronicity do
|
47
|
+
|
48
|
+
it "should redirect output" do
|
49
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_output.rb'))}\" \"#{STANDARD_MESSAGE}\" \"#{ERROR_MESSAGE}\""
|
50
|
+
runner_status = runner.run_right_popen3(synchronicity, command)
|
51
|
+
runner_status.should_not be_nil
|
52
|
+
runner_status.status.should_not be_nil
|
53
|
+
runner_status.status.exitstatus.should == 0
|
54
|
+
runner_status.output_text.should == STANDARD_MESSAGE + "\n"
|
55
|
+
runner_status.error_text.should == ERROR_MESSAGE + "\n"
|
56
|
+
runner_status.pid.should > 0
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return the right status" do
|
60
|
+
ruby = `which ruby`.chomp # which is assumed to be on the PATH for the Windows case
|
61
|
+
command = [
|
62
|
+
ruby,
|
63
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'produce_status.rb')),
|
64
|
+
EXIT_STATUS
|
65
|
+
]
|
66
|
+
status = runner.run_right_popen3(synchronicity, command)
|
67
|
+
status.status.exitstatus.should == EXIT_STATUS
|
68
|
+
status.output_text.should == ''
|
69
|
+
status.error_text.should == ''
|
70
|
+
status.pid.should > 0
|
71
|
+
end
|
53
72
|
|
54
|
-
|
55
|
-
|
56
|
-
|
73
|
+
it "should close all IO handlers, except STDIN, STDOUT and STDERR" do
|
74
|
+
GC.start
|
75
|
+
command = [
|
76
|
+
RUBY_CMD,
|
77
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'produce_status.rb')),
|
78
|
+
EXIT_STATUS
|
79
|
+
]
|
80
|
+
status = runner.run_right_popen3(synchronicity, command)
|
81
|
+
status.status.exitstatus.should == EXIT_STATUS
|
82
|
+
useless_handlers = 0
|
83
|
+
ObjectSpace.each_object(IO) do |io|
|
84
|
+
if ![STDIN, STDOUT, STDERR].include?(io)
|
85
|
+
useless_handlers += 1 unless io.closed?
|
57
86
|
end
|
58
87
|
end
|
88
|
+
useless_handlers.should == 0
|
59
89
|
end
|
60
|
-
end
|
61
90
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
useless_handlers += 1 unless io.closed?
|
91
|
+
it "should preserve the integrity of stdout when stderr is unavailable" do
|
92
|
+
count = LARGE_OUTPUT_COUNTER
|
93
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_stdout_only.rb'))}\" #{count}"
|
94
|
+
status = runner.run_right_popen3(synchronicity, command)
|
95
|
+
status.status.exitstatus.should == 0
|
96
|
+
|
97
|
+
results = ''
|
98
|
+
count.times do |i|
|
99
|
+
results << "stdout #{i}\n"
|
72
100
|
end
|
101
|
+
status.output_text.should == results
|
102
|
+
status.error_text.should == ''
|
103
|
+
status.pid.should > 0
|
73
104
|
end
|
74
|
-
useless_handlers.should == 0
|
75
|
-
end
|
76
105
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
status.status.exitstatus.should == 0
|
106
|
+
it "should preserve the integrity of stderr when stdout is unavailable" do
|
107
|
+
count = LARGE_OUTPUT_COUNTER
|
108
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_stderr_only.rb'))}\" #{count}"
|
109
|
+
status = runner.run_right_popen3(synchronicity, command)
|
110
|
+
status.status.exitstatus.should == 0
|
83
111
|
|
84
|
-
|
85
|
-
|
86
|
-
|
112
|
+
results = ''
|
113
|
+
count.times do |i|
|
114
|
+
results << "stderr #{i}\n"
|
115
|
+
end
|
116
|
+
status.error_text.should == results
|
117
|
+
status.output_text.should == ''
|
118
|
+
status.pid.should > 0
|
87
119
|
end
|
88
|
-
status.output_text.should == results
|
89
|
-
status.error_text.should == ''
|
90
|
-
status.pid.should > 0
|
91
|
-
end
|
92
120
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
121
|
+
it "should preserve interleaved output when yielding CPU on consumer thread" do
|
122
|
+
lines = 11
|
123
|
+
exit_code = 42
|
124
|
+
repeats = 5
|
125
|
+
force_yield = 0.1
|
126
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_mixed_output.rb'))}\" #{lines} #{exit_code}"
|
127
|
+
actual_output = StringIO.new
|
128
|
+
actual_error = StringIO.new
|
129
|
+
puts
|
130
|
+
stats = runner.run_right_popen3(synchronicity, command, :repeats=>repeats, :force_yield=>force_yield) do |status|
|
131
|
+
status.status.exitstatus.should == exit_code
|
132
|
+
status.pid.should > 0
|
133
|
+
actual_output << status.output_text
|
134
|
+
actual_error << status.error_text
|
135
|
+
end
|
136
|
+
puts
|
137
|
+
stats.size.should == repeats
|
138
|
+
|
139
|
+
expected_output = StringIO.new
|
140
|
+
repeats.times do
|
141
|
+
lines.times do |i|
|
142
|
+
expected_output << "stdout #{i}\n"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
actual_output.string.should == expected_output.string
|
99
146
|
|
100
|
-
|
101
|
-
|
102
|
-
|
147
|
+
expected_error = StringIO.new
|
148
|
+
repeats.times do
|
149
|
+
lines.times do |i|
|
150
|
+
(expected_error << "stderr #{i}\n") if 0 == i % 10
|
151
|
+
end
|
152
|
+
end
|
153
|
+
actual_error.string.should == expected_error.string
|
103
154
|
end
|
104
|
-
status.error_text.should == results
|
105
|
-
status.output_text.should == ''
|
106
|
-
status.pid.should > 0
|
107
|
-
end
|
108
155
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_mixed_output.rb'))}\" #{lines} #{exit_code}"
|
115
|
-
runner = Runner.new
|
116
|
-
actual_output = StringIO.new
|
117
|
-
actual_error = StringIO.new
|
118
|
-
puts
|
119
|
-
stats = runner.run_right_popen(command, :repeats=>repeats, :force_yield=>force_yield) do |status|
|
156
|
+
it "should preserve interleaved output when process is spewing rapidly" do
|
157
|
+
lines = LARGE_OUTPUT_COUNTER
|
158
|
+
exit_code = 99
|
159
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_mixed_output.rb'))}\" #{lines} #{exit_code}"
|
160
|
+
status = runner.run_right_popen3(synchronicity, command, :timeout=>10)
|
120
161
|
status.status.exitstatus.should == exit_code
|
121
|
-
status.pid.should > 0
|
122
|
-
actual_output << status.output_text
|
123
|
-
actual_error << status.error_text
|
124
|
-
print '+'
|
125
|
-
end
|
126
|
-
puts
|
127
|
-
stats.size.should == repeats
|
128
162
|
|
129
|
-
|
130
|
-
repeats.times do
|
163
|
+
expected_output = StringIO.new
|
131
164
|
lines.times do |i|
|
132
165
|
expected_output << "stdout #{i}\n"
|
133
166
|
end
|
134
|
-
|
135
|
-
actual_output.string.should == expected_output.string
|
167
|
+
status.output_text.should == expected_output.string
|
136
168
|
|
137
|
-
|
138
|
-
repeats.times do
|
169
|
+
expected_error = StringIO.new
|
139
170
|
lines.times do |i|
|
140
171
|
(expected_error << "stderr #{i}\n") if 0 == i % 10
|
141
172
|
end
|
173
|
+
status.error_text.should == expected_error.string
|
174
|
+
status.pid.should > 0
|
142
175
|
end
|
143
|
-
actual_error.string.should == expected_error.string
|
144
|
-
end
|
145
176
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
lines.times do |i|
|
156
|
-
expected_output << "stdout #{i}\n"
|
177
|
+
it "should setup environment variables" do
|
178
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
|
179
|
+
status = runner.run_right_popen3(synchronicity, command)
|
180
|
+
status.status.exitstatus.should == 0
|
181
|
+
status.output_text.should_not include('_test_')
|
182
|
+
status = runner.run_right_popen3(synchronicity, command, :env=>{ :__test__ => '42' })
|
183
|
+
status.status.exitstatus.should == 0
|
184
|
+
status.output_text.should match(/^__test__=42$/)
|
185
|
+
status.pid.should > 0
|
157
186
|
end
|
158
|
-
status.output_text.should == expected_output.string
|
159
187
|
|
160
|
-
|
161
|
-
|
162
|
-
|
188
|
+
it "should restore environment variables" do
|
189
|
+
begin
|
190
|
+
ENV['__test__'] = '41'
|
191
|
+
old_envs = {}
|
192
|
+
ENV.each { |k, v| old_envs[k] = v }
|
193
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
|
194
|
+
status = runner.run_right_popen3(synchronicity, command, :env=>{ :__test__ => '42' })
|
195
|
+
status.status.exitstatus.should == 0
|
196
|
+
status.output_text.should match(/^__test__=42$/)
|
197
|
+
ENV.each { |k, v| old_envs[k].should == v }
|
198
|
+
old_envs.each { |k, v| ENV[k].should == v }
|
199
|
+
status.pid.should > 0
|
200
|
+
ensure
|
201
|
+
ENV.delete('__test__')
|
202
|
+
end
|
163
203
|
end
|
164
|
-
status.error_text.should == expected_error.string
|
165
|
-
status.pid.should > 0
|
166
|
-
end
|
167
204
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
205
|
+
if is_windows?
|
206
|
+
# FIX: this behavior is currently specific to Windows but should probably be
|
207
|
+
# implemented for Linux.
|
208
|
+
it "should merge the PATH variable instead of overriding it" do
|
209
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
|
210
|
+
status = runner.run_right_popen3(synchronicity, command, :env=>{ 'PATH' => "c:/bogus\\bin" })
|
211
|
+
status.status.exitstatus.should == 0
|
212
|
+
status.output_text.should include('c:\\bogus\\bin;')
|
213
|
+
status.pid.should > 0
|
214
|
+
end
|
215
|
+
else
|
216
|
+
it "should allow running bash command lines starting with a built-in command" do
|
217
|
+
command = "for i in 1 2 3 4 5; do echo $i;done"
|
218
|
+
status = runner.run_right_popen3(synchronicity, command)
|
219
|
+
status.status.exitstatus.should == 0
|
220
|
+
status.output_text.should == "1\n2\n3\n4\n5\n"
|
221
|
+
status.pid.should > 0
|
222
|
+
end
|
179
223
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
old_envs.each { |k, v| ENV[k].should == v }
|
192
|
-
status.pid.should > 0
|
193
|
-
ensure
|
194
|
-
ENV.delete('__test__')
|
224
|
+
it "should support running background processes" do
|
225
|
+
command = "(sleep 20)&"
|
226
|
+
now = Time.now
|
227
|
+
status = runner.run_right_popen3(synchronicity, command)
|
228
|
+
finished = Time.now
|
229
|
+
(finished - now).should < 20
|
230
|
+
status.did_timeout.should be_false
|
231
|
+
status.status.exitstatus.should == 0
|
232
|
+
status.output_text.should == ""
|
233
|
+
status.pid.should > 0
|
234
|
+
end
|
195
235
|
end
|
196
|
-
end
|
197
236
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
it 'should merge the PATH variable instead of overriding it' do
|
202
|
-
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
|
203
|
-
runner = Runner.new
|
204
|
-
status = runner.run_right_popen(command, :env=>{ 'PATH' => "c:/bogus\\bin" })
|
237
|
+
it "should support raw command arguments" do
|
238
|
+
command = is_windows? ? ["cmd.exe", "/c", "echo", "*"] : ["echo", "*"]
|
239
|
+
status = runner.run_right_popen3(synchronicity, command)
|
205
240
|
status.status.exitstatus.should == 0
|
206
|
-
status.output_text.should
|
241
|
+
status.output_text.should == "*\n"
|
207
242
|
status.pid.should > 0
|
208
243
|
end
|
209
|
-
|
210
|
-
it
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
244
|
+
|
245
|
+
it "should run repeatedly without leaking resources" do
|
246
|
+
pending 'Set environment variable TEST_LEAK to enable' unless ENV['TEST_LEAK']
|
247
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_output.rb'))}\" \"#{STANDARD_MESSAGE}\" \"#{ERROR_MESSAGE}\""
|
248
|
+
stats = runner.run_right_popen3(synchronicity, command, :repeats=>REPEAT_TEST_COUNTER)
|
249
|
+
stats.each do |status|
|
250
|
+
status.status.exitstatus.should == 0
|
251
|
+
status.output_text.should == STANDARD_MESSAGE + "\n"
|
252
|
+
status.error_text.should == ERROR_MESSAGE + "\n"
|
253
|
+
status.pid.should > 0
|
254
|
+
end
|
217
255
|
end
|
218
256
|
|
219
|
-
it
|
220
|
-
command = "(
|
221
|
-
|
222
|
-
runner = Runner.new
|
223
|
-
status = runner.run_right_popen(command)
|
224
|
-
finished = Time.now
|
225
|
-
(finished - now).should < 20
|
226
|
-
status.did_timeout.should be_false
|
257
|
+
it "should pass input to child process" do
|
258
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'increment.rb'))}\""
|
259
|
+
status = runner.run_right_popen3(synchronicity, command, :input=>"42\n")
|
227
260
|
status.status.exitstatus.should == 0
|
228
|
-
status.output_text.should == ""
|
261
|
+
status.output_text.should == "43\n"
|
262
|
+
status.error_text.should be_empty
|
229
263
|
status.pid.should > 0
|
230
264
|
end
|
231
|
-
end
|
232
265
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
266
|
+
it "should run long child process without any watches by default" do
|
267
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'sleeper.rb'))}\""
|
268
|
+
runner_status = runner.run_right_popen3(synchronicity, command, :timeout=>nil)
|
269
|
+
runner_status.status.exitstatus.should == 0
|
270
|
+
runner_status.did_timeout.should be_false
|
271
|
+
runner_status.output_text.should == "To sleep... 0\nTo sleep... 1\nTo sleep... 2\nTo sleep... 3\nThe sleeper must awaken.\n"
|
272
|
+
runner_status.error_text.should == "Perchance to dream... 0\nPerchance to dream... 1\nPerchance to dream... 2\nPerchance to dream... 3\n"
|
273
|
+
end
|
241
274
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
status.output_text.should == STANDARD_MESSAGE + "\n"
|
250
|
-
status.error_text.should == ERROR_MESSAGE + "\n"
|
251
|
-
status.pid.should > 0
|
275
|
+
it "should interrupt watched child process when timeout expires" do
|
276
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'sleeper.rb'))}\" 10"
|
277
|
+
runner_status = runner.run_right_popen3(synchronicity, command, :expect_timeout=>true, :timeout=>0.1)
|
278
|
+
runner_status.status.success?.should be_false
|
279
|
+
runner_status.did_timeout.should be_true
|
280
|
+
runner_status.output_text.should_not be_empty
|
281
|
+
runner_status.error_text.should_not be_empty
|
252
282
|
end
|
253
|
-
end
|
254
283
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
end
|
284
|
+
it "should allow watched child to write files up to size limit" do
|
285
|
+
::Dir.mktmpdir do |watched_dir|
|
286
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'writer.rb'))}\" \"#{watched_dir}\""
|
287
|
+
runner_status = runner.run_right_popen3(synchronicity, command, :size_limit_bytes=>1000, :watch_directory=>watched_dir, :timeout=>10)
|
288
|
+
runner_status.status.success?.should be_true
|
289
|
+
runner_status.did_size_limit.should be_false
|
290
|
+
end
|
291
|
+
end
|
264
292
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
293
|
+
it "should interrupt watched child at size limit" do
|
294
|
+
::Dir.mktmpdir do |watched_dir|
|
295
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'writer.rb'))}\" \"#{watched_dir}\""
|
296
|
+
runner_status = runner.run_right_popen3(synchronicity, command, :expect_size_limit=>true, :size_limit_bytes=>100, :watch_directory=>watched_dir, :timeout=>10)
|
297
|
+
runner_status.status.success?.should be_false
|
298
|
+
runner_status.did_size_limit.should be_true
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
it "should handle child processes that close stdout but keep running" do
|
303
|
+
pending 'not implemented for windows' if is_windows? && :sync != synchronicity
|
304
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'stdout.rb'))}\""
|
305
|
+
runner_status = runner.run_right_popen3(synchronicity, command, :expect_timeout=>true, :timeout=>2)
|
306
|
+
runner_status.output_text.should be_empty
|
307
|
+
runner_status.error_text.should == "Closing stdout\n"
|
308
|
+
runner_status.did_timeout.should be_true
|
309
|
+
end
|
274
310
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
311
|
+
it "should handle child processes that spawn long running background processes" do
|
312
|
+
pending 'not implemented for windows' if is_windows?
|
313
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'background.rb'))}\""
|
314
|
+
status = runner.run_right_popen3(synchronicity, command)
|
315
|
+
status.status.exitstatus.should == 0
|
316
|
+
status.did_timeout.should be_false
|
317
|
+
status.output_text.should be_empty
|
318
|
+
status.error_text.should be_empty
|
319
|
+
end
|
320
|
+
|
321
|
+
it "should run long child process without any watches by default" do
|
322
|
+
command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'sleeper.rb'))}\""
|
323
|
+
runner_status = runner.run_right_popen3(synchronicity, command, :timeout=>nil)
|
324
|
+
runner_status.status.exitstatus.should == 0
|
325
|
+
runner_status.did_timeout.should be_false
|
326
|
+
runner_status.output_text.should == "To sleep... 0\nTo sleep... 1\nTo sleep... 2\nTo sleep... 3\nThe sleeper must awaken.\n"
|
327
|
+
runner_status.error_text.should == "Perchance to dream... 0\nPerchance to dream... 1\nPerchance to dream... 2\nPerchance to dream... 3\n"
|
328
|
+
end
|
284
329
|
end
|
285
330
|
end
|
286
331
|
end
|