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.
Binary file
@@ -47,8 +47,8 @@ EOF
47
47
  end
48
48
  spec.files = candidates.sort!
49
49
 
50
- # Current implementation supports >= 0.12.11
51
- spec.add_runtime_dependency(%q<eventmachine>, [">= 0.12.11"])
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
@@ -1,6 +1,9 @@
1
1
  count = ARGV[0] ? ARGV[0].to_i : 1
2
2
  exit_code = ARGV[1] ? ARGV[1].to_i : 0
3
3
 
4
+ STDOUT.sync=true
5
+ STDERR.sync=true
6
+
4
7
  count.times do |i|
5
8
  $stderr.puts "stderr #{i}" if 0 == i % 10
6
9
  $stdout.puts "stdout #{i}"
@@ -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
@@ -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
- module RightScale
6
- describe 'popen3' do
7
- def is_windows?
8
- return !!(RUBY_PLATFORM =~ /mswin/)
9
- end
7
+ describe 'RightScale::RightPopen' do
8
+ def is_windows?
9
+ return !!(RUBY_PLATFORM =~ /mswin|mingw/)
10
+ end
10
11
 
11
- it 'should redirect output' do
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
- it 'should return the right status' do
22
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_status.rb'))}\" #{EXIT_STATUS}"
23
- runner = Runner.new
24
- status = runner.run_right_popen(command)
25
- status.status.exitstatus.should == EXIT_STATUS
26
- status.output_text.should == ''
27
- status.error_text.should == ''
28
- status.pid.should > 0
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
- it 'should correctly handle many small processes' do
32
- pending 'Set environment variable TEST_STRESS to enable' unless ENV['TEST_STRESS']
33
- TO_RUN = 100
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
- EM.run do
52
- EM.next_tick { run_cmd.call }
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
- EM::PeriodicTimer.new(1) do
55
- if @completed >= TO_RUN
56
- EM.stop
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
- it 'should close all IO handlers, except STDIN, STDOUT and STDERR' do
63
- GC.start
64
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_status.rb'))}\" #{EXIT_STATUS}"
65
- runner = Runner.new
66
- status = runner.run_right_popen(command)
67
- status.status.exitstatus.should == EXIT_STATUS
68
- useless_handlers = 0
69
- ObjectSpace.each_object(IO) do |io|
70
- if ![STDIN, STDOUT, STDERR].include?(io)
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
- it 'should preserve the integrity of stdout when stderr is unavailable' do
78
- count = LARGE_OUTPUT_COUNTER
79
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_stdout_only.rb'))}\" #{count}"
80
- runner = Runner.new
81
- status = runner.run_right_popen(command)
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
- results = ''
85
- count.times do |i|
86
- results << "stdout #{i}\n"
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
- it 'should preserve the integrity of stderr when stdout is unavailable' do
94
- count = LARGE_OUTPUT_COUNTER
95
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_stderr_only.rb'))}\" #{count}"
96
- runner = Runner.new
97
- status = runner.run_right_popen(command)
98
- status.status.exitstatus.should == 0
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
- results = ''
101
- count.times do |i|
102
- results << "stderr #{i}\n"
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
- it 'should preserve interleaved output when yielding CPU on consumer thread' do
110
- lines = 11
111
- exit_code = 42
112
- repeats = 5
113
- force_yield = 0.1
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
- expected_output = StringIO.new
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
- end
135
- actual_output.string.should == expected_output.string
167
+ status.output_text.should == expected_output.string
136
168
 
137
- expected_error = StringIO.new
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
- it 'should preserve interleaved output when process is spewing rapidly' do
147
- lines = LARGE_OUTPUT_COUNTER
148
- exit_code = 99
149
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_mixed_output.rb'))}\" #{lines} #{exit_code}"
150
- runner = Runner.new
151
- status = runner.run_right_popen(command)
152
- status.status.exitstatus.should == exit_code
153
-
154
- expected_output = StringIO.new
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
- expected_error = StringIO.new
161
- lines.times do |i|
162
- (expected_error << "stderr #{i}\n") if 0 == i % 10
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
- it 'should setup environment variables' do
169
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
170
- runner = Runner.new
171
- status = runner.run_right_popen(command)
172
- status.status.exitstatus.should == 0
173
- status.output_text.should_not include('_test_')
174
- status = runner.run_right_popen(command, :env=>{ :__test__ => '42' })
175
- status.status.exitstatus.should == 0
176
- status.output_text.should match(/^__test__=42$/)
177
- status.pid.should > 0
178
- end
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
- it 'should restore environment variables' do
181
- begin
182
- ENV['__test__'] = '41'
183
- old_envs = {}
184
- ENV.each { |k, v| old_envs[k] = v }
185
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
186
- runner = Runner.new
187
- status = runner.run_right_popen(command, :env=>{ :__test__ => '42' })
188
- status.status.exitstatus.should == 0
189
- status.output_text.should match(/^__test__=42$/)
190
- ENV.each { |k, v| old_envs[k].should == v }
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
- if is_windows?
199
- # FIX: this behavior is currently specific to Windows but should probably be
200
- # implemented for Linux.
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 include('c:\\bogus\\bin;')
241
+ status.output_text.should == "*\n"
207
242
  status.pid.should > 0
208
243
  end
209
- else
210
- it 'should allow running bash command lines starting with a built-in command' do
211
- command = "for i in 1 2 3 4 5; do echo $i;done"
212
- runner = Runner.new
213
- status = runner.run_right_popen(command)
214
- status.status.exitstatus.should == 0
215
- status.output_text.should == "1\n2\n3\n4\n5\n"
216
- status.pid.should > 0
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 'should support running background processes' do
220
- command = "(sleep 20)&"
221
- now = Time.now
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
- it 'should support raw command arguments' do
234
- command = is_windows? ? ["cmd.exe", "/c", "echo", "*"] : ["echo", "*"]
235
- runner = Runner.new
236
- status = runner.run_right_popen(command)
237
- status.status.exitstatus.should == 0
238
- status.output_text.should == "*\n"
239
- status.pid.should > 0
240
- end
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
- it 'should run repeatedly without leaking resources' do
243
- pending 'Set environment variable TEST_LEAK to enable' unless ENV['TEST_LEAK']
244
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_output.rb'))}\" \"#{STANDARD_MESSAGE}\" \"#{ERROR_MESSAGE}\""
245
- runner = Runner.new
246
- stats = runner.run_right_popen(command, :repeats=>REPEAT_TEST_COUNTER)
247
- stats.each do |status|
248
- status.status.exitstatus.should == 0
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
- it 'should pass input to child process' do
256
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'increment.rb'))}\""
257
- runner = Runner.new
258
- status = runner.run_right_popen(command, :input=>"42\n")
259
- status.status.exitstatus.should == 0
260
- status.output_text.should == "43\n"
261
- status.error_text.should be_empty
262
- status.pid.should > 0
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
- it 'should handle child processes that close stdout but keep running' do
266
- pending 'not implemented for windows' if is_windows?
267
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'stdout.rb'))}\""
268
- runner = Runner.new
269
- status = runner.run_right_popen(command, :expect_timeout=>true, :timeout=>2)
270
- status.did_timeout.should be_true
271
- status.output_text.should be_empty
272
- status.error_text.should == "Closing stdout\n"
273
- end
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
- it 'should handle child processes that spawn long running background processes' do
276
- pending 'not implemented for windows' if is_windows?
277
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'background.rb'))}\""
278
- runner = Runner.new
279
- status = runner.run_right_popen(command)
280
- status.status.exitstatus.should == 0
281
- status.did_timeout.should be_false
282
- status.output_text.should be_empty
283
- status.error_text.should be_empty
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