right_popen 1.0.7-x86-mswin32-60 → 1.0.9-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Binary file
data/right_popen.gemspec CHANGED
@@ -1,64 +1,61 @@
1
- require 'rubygems'
2
-
3
- def is_windows?
4
- return RUBY_PLATFORM =~ /mswin/
5
- end
6
-
7
- spec = Gem::Specification.new do |spec|
8
- spec.name = 'right_popen'
9
- spec.version = '1.0.7'
10
- spec.authors = ['Scott Messier', 'Raphael Simon']
11
- spec.email = 'scott@rightscale.com'
12
- spec.homepage = 'https://github.com/rightscale/right_popen'
13
- if is_windows?
14
- spec.platform = 'x86-mswin32-60'
15
- else
16
- spec.platform = Gem::Platform::RUBY
17
- end
18
- spec.summary = 'Provides a platform-independent popen implementation'
19
- spec.has_rdoc = true
20
- spec.rdoc_options = ["--main", "README.rdoc", "--title", "RightPopen"]
21
- spec.extra_rdoc_files = ["README.rdoc"]
22
- spec.required_ruby_version = '>= 1.8.6'
23
- spec.rubyforge_project = %q{right_popen}
24
-
25
- spec.description = <<-EOF
26
- RightPopen allows running external processes aynchronously while still
27
- capturing their standard and error outputs. It relies on EventMachine for most
28
- of its internal mechanisms. The Linux implementation is valid for any Linux
29
- platform but there is also a native implementation for Windows platforms.
30
- EOF
31
-
32
- if is_windows?
33
- extension_dir = "ext,"
34
- else
35
- extension_dir = ""
36
- end
37
- candidates = Dir.glob("{#{extension_dir}lib,spec}/**/*") +
38
- ["LICENSE", "README.rdoc", "Rakefile", "right_popen.gemspec"]
39
- candidates = candidates.delete_if do |item|
40
- item.include?("Makefile") || item.include?(".obj") || item.include?(".pdb") || item.include?(".def") || item.include?(".exp") || item.include?(".lib")
41
- end
42
- candidates = candidates.delete_if do |item|
43
- if is_windows?
44
- item.include?("/linux/")
45
- else
46
- item.include?("/win32/")
47
- end
48
- end
49
- spec.files = candidates.sort!
50
-
51
- # Current implementation supports >= 0.12.10
52
- spec.add_runtime_dependency(%q<eventmachine>, [">= 0.12.10"])
53
- if is_windows?
54
- # Windows implementation currently depends on deprecated behavior from
55
- # 0.12.8, but we also need to support the 0.12.8.1 patch version. the Linux
56
- # side is free to use 0.12.10+
57
- spec.add_runtime_dependency(%q<win32-process>, [">= 0.6.1"])
58
- end
59
- end
60
-
61
- if $PROGRAM_NAME == __FILE__
62
- Gem.manage_gems if Gem::RubyGemsVersion.to_f < 1.0
63
- Gem::Builder.new(spec).build
64
- end
1
+ require 'rubygems'
2
+
3
+ def is_windows?
4
+ return RUBY_PLATFORM =~ /mswin/
5
+ end
6
+
7
+ spec = Gem::Specification.new do |spec|
8
+ spec.name = 'right_popen'
9
+ spec.version = '1.0.9'
10
+ spec.authors = ['Scott Messier', 'Raphael Simon']
11
+ spec.email = 'scott@rightscale.com'
12
+ spec.homepage = 'https://github.com/rightscale/right_popen'
13
+ if is_windows?
14
+ spec.platform = 'x86-mswin32-60'
15
+ else
16
+ spec.platform = Gem::Platform::RUBY
17
+ end
18
+ spec.summary = 'Provides a platform-independent popen implementation'
19
+ spec.has_rdoc = true
20
+ spec.rdoc_options = ["--main", "README.rdoc", "--title", "RightPopen"]
21
+ spec.extra_rdoc_files = ["README.rdoc"]
22
+ spec.required_ruby_version = '>= 1.8.6'
23
+ spec.rubyforge_project = %q{right_popen}
24
+
25
+ spec.description = <<-EOF
26
+ RightPopen allows running external processes aynchronously while still
27
+ capturing their standard and error outputs. It relies on EventMachine for most
28
+ of its internal mechanisms. The Linux implementation is valid for any Linux
29
+ platform but there is also a native implementation for Windows platforms.
30
+ EOF
31
+
32
+ if is_windows?
33
+ extension_dir = "ext,"
34
+ else
35
+ extension_dir = ""
36
+ end
37
+ candidates = Dir.glob("{#{extension_dir}lib,spec}/**/*") +
38
+ ["LICENSE", "README.rdoc", "Rakefile", "right_popen.gemspec"]
39
+ candidates = candidates.delete_if do |item|
40
+ item.include?("Makefile") || item.include?(".obj") || item.include?(".pdb") || item.include?(".def") || item.include?(".exp") || item.include?(".lib")
41
+ end
42
+ candidates = candidates.delete_if do |item|
43
+ if is_windows?
44
+ item.include?("/linux/")
45
+ else
46
+ item.include?("/win32/")
47
+ end
48
+ end
49
+ spec.files = candidates.sort!
50
+
51
+ # Current implementation supports >= 0.12.10
52
+ spec.add_runtime_dependency(%q<eventmachine>, [">= 0.12.10"])
53
+ if is_windows?
54
+ spec.add_runtime_dependency(%q<win32-process>, [">= 0.6.1"])
55
+ end
56
+ end
57
+
58
+ if $PROGRAM_NAME == __FILE__
59
+ Gem.manage_gems if Gem::RubyGemsVersion.to_f < 1.0
60
+ Gem::Builder.new(spec).build
61
+ end
data/spec/increment.rb ADDED
@@ -0,0 +1,2 @@
1
+ input = gets.to_i
2
+ $stdout.puts input + 1
@@ -1 +1 @@
1
- exit ARGV[0].to_i
1
+ exit ARGV[0].to_i
@@ -1,210 +1,221 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
2
-
3
- RUBY_CMD = 'ruby'
4
- STANDARD_MESSAGE = 'Standard message'
5
- ERROR_MESSAGE = 'Error message'
6
- EXIT_STATUS = 146
7
-
8
- # manually bump count up for more aggressive multi-processor testing, lessen
9
- # for a quick smoke test
10
- LARGE_OUTPUT_COUNTER = 1000
11
-
12
- # bump up count for most exhaustive leak detection.
13
- REPEAT_TEST_COUNTER = 256
14
-
15
- def is_windows?
16
- return RUBY_PLATFORM =~ /mswin/
17
- end
18
-
19
- describe 'RightScale::popen3' do
20
-
21
- module RightPopenSpec
22
-
23
- class Runner
24
- def initialize
25
- @done = false
26
- @output_text = nil
27
- @error_text = nil
28
- @status = nil
29
- @last_exception = nil
30
- @last_iteration = 0
31
- end
32
-
33
- attr_reader :output_text, :error_text, :status
34
-
35
- def do_right_popen(command, env=nil)
36
- @timeout = EM::Timer.new(10) { puts "** Failed: Timeout"; EM.stop }
37
- @output_text = ''
38
- @error_text = ''
39
- @status = nil
40
- RightScale.popen3(:command => command,
41
- :target => self,
42
- :environment => env,
43
- :stdout_handler => :on_read_stdout,
44
- :stderr_handler => :on_read_stderr,
45
- :exit_handler => :on_exit)
46
- end
47
-
48
- def run_right_popen(command, env=nil, count = 1)
49
- begin
50
- @command = command
51
- @env = env
52
- @last_iteration = 0
53
- @count = count
54
- puts "#{count}>" if count > 1
55
- EM.run { EM.next_tick { do_right_popen(command, env) } }
56
- rescue Exception => e
57
- puts "** Failed: #{e.message} FROM\n#{e.backtrace.join("\n")}"
58
- raise e
59
- end
60
- end
61
-
62
- def on_read_stdout(data)
63
- @output_text << data
64
- end
65
-
66
- def on_read_stderr(data)
67
- @error_text << data
68
- end
69
-
70
- def on_exit(status)
71
- @last_iteration += 1
72
- @timeout.cancel if @timeout
73
- if @last_iteration < @count
74
- EM.next_tick do
75
- print '+'
76
- STDOUT.flush
77
- do_right_popen(@command, @env)
78
- end
79
- else
80
- puts "<" if @count > 1
81
- EM.stop
82
- end
83
- @status = status
84
- end
85
- end
86
-
87
- end
88
-
89
- it 'should redirect output' do
90
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_output.rb'))}\" \"#{STANDARD_MESSAGE}\" \"#{ERROR_MESSAGE}\""
91
- runner = RightPopenSpec::Runner.new
92
- runner.run_right_popen(command)
93
- runner.status.exitstatus.should == 0
94
- runner.output_text.should == STANDARD_MESSAGE + "\n"
95
- runner.error_text.should == ERROR_MESSAGE + "\n"
96
- end
97
-
98
- it 'should return the right status' do
99
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_status.rb'))}\" #{EXIT_STATUS}"
100
- runner = RightPopenSpec::Runner.new
101
- runner.run_right_popen(command)
102
- runner.status.exitstatus.should == EXIT_STATUS
103
- runner.output_text.should == ''
104
- runner.error_text.should == ''
105
- end
106
-
107
- it 'should preserve the integrity of stdout when stderr is unavailable' do
108
- count = LARGE_OUTPUT_COUNTER
109
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_stdout_only.rb'))}\" #{count}"
110
- runner = RightPopenSpec::Runner.new
111
- runner.run_right_popen(command)
112
- runner.status.exitstatus.should == 0
113
-
114
- results = ''
115
- count.times do |i|
116
- results << "stdout #{i}\n"
117
- end
118
- runner.output_text.should == results
119
- runner.error_text.should == ''
120
- end
121
-
122
- it 'should preserve the integrity of stderr when stdout is unavailable' do
123
- count = LARGE_OUTPUT_COUNTER
124
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_stderr_only.rb'))}\" #{count}"
125
- runner = RightPopenSpec::Runner.new
126
- runner.run_right_popen(command)
127
- runner.status.exitstatus.should == 0
128
-
129
- results = ''
130
- count.times do |i|
131
- results << "stderr #{i}\n"
132
- end
133
- runner.error_text.should == results
134
- runner.output_text.should == ''
135
- end
136
-
137
- it 'should preserve the integrity of stdout and stderr despite interleaving' do
138
- count = LARGE_OUTPUT_COUNTER
139
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_mixed_output.rb'))}\" #{count}"
140
- runner = RightPopenSpec::Runner.new
141
- runner.run_right_popen(command)
142
- runner.status.exitstatus.should == 99
143
-
144
- results = ''
145
- count.times do |i|
146
- results << "stdout #{i}\n"
147
- end
148
- runner.output_text.should == results
149
-
150
- results = ''
151
- count.times do |i|
152
- (results << "stderr #{i}\n") if 0 == i % 10
153
- end
154
- runner.error_text.should == results
155
- end
156
-
157
- it 'should setup environment variables' do
158
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
159
- runner = RightPopenSpec::Runner.new
160
- runner.run_right_popen(command)
161
- runner.status.exitstatus.should == 0
162
- runner.output_text.should_not include('_test_')
163
- runner.run_right_popen(command, :__test__ => '42')
164
- runner.status.exitstatus.should == 0
165
- runner.output_text.should match(/^__test__=42$/)
166
- end
167
-
168
- it 'should restore environment variables' do
169
- ENV['__test__'] = '41'
170
- old_envs = {}
171
- ENV.each { |k, v| old_envs[k] = v }
172
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
173
- runner = RightPopenSpec::Runner.new
174
- runner.run_right_popen(command, :__test__ => '42')
175
- runner.status.exitstatus.should == 0
176
- runner.output_text.should match(/^__test__=42$/)
177
- ENV.each { |k, v| old_envs[k].should == v }
178
- old_envs.each { |k, v| ENV[k].should == v }
179
- end
180
-
181
- if is_windows?
182
- # FIX: this behavior is currently specific to Windows but should probably be
183
- # implemented for Linux.
184
- it 'should merge the PATH variable instead of overriding it' do
185
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
186
- runner = RightPopenSpec::Runner.new
187
- runner.run_right_popen(command, 'PATH' => "c:/bogus\\bin")
188
- runner.status.exitstatus.should == 0
189
- runner.output_text.should include('PATH=c:\\bogus\\bin;')
190
- end
191
- else
192
- it 'should allow running bash command lines starting with a built-in command' do
193
- command = "for i in 1 2 3 4 5; do echo $i;done"
194
- runner = RightPopenSpec::Runner.new
195
- runner.run_right_popen(command)
196
- runner.status.exitstatus.should == 0
197
- runner.output_text.should == "1\n2\n3\n4\n5\n"
198
- end
199
- end
200
-
201
- it 'should run repeatedly without leaking resources' do
202
- command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_output.rb'))}\" \"#{STANDARD_MESSAGE}\" \"#{ERROR_MESSAGE}\""
203
- runner = RightPopenSpec::Runner.new
204
- runner.run_right_popen(command, nil, REPEAT_TEST_COUNTER)
205
- runner.status.exitstatus.should == 0
206
- runner.output_text.should == STANDARD_MESSAGE + "\n"
207
- runner.error_text.should == ERROR_MESSAGE + "\n"
208
- end
209
-
210
- end
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ RUBY_CMD = 'ruby'
4
+ STANDARD_MESSAGE = 'Standard message'
5
+ ERROR_MESSAGE = 'Error message'
6
+ EXIT_STATUS = 146
7
+
8
+ # manually bump count up for more aggressive multi-processor testing, lessen
9
+ # for a quick smoke test
10
+ LARGE_OUTPUT_COUNTER = 1000
11
+
12
+ # bump up count for most exhaustive leak detection.
13
+ REPEAT_TEST_COUNTER = 256
14
+
15
+ def is_windows?
16
+ return RUBY_PLATFORM =~ /mswin/
17
+ end
18
+
19
+ describe 'RightScale::popen3' do
20
+
21
+ module RightPopenSpec
22
+
23
+ class Runner
24
+ def initialize
25
+ @done = false
26
+ @output_text = nil
27
+ @error_text = nil
28
+ @status = nil
29
+ @last_exception = nil
30
+ @last_iteration = 0
31
+ end
32
+
33
+ attr_reader :output_text, :error_text, :status
34
+
35
+ def do_right_popen(command, env=nil, input=nil)
36
+ @timeout = EM::Timer.new(2) { puts "\n** Failed to run #{command.inspect}: Timeout"; EM.stop }
37
+ @output_text = ''
38
+ @error_text = ''
39
+ @status = nil
40
+ RightScale.popen3(:command => command,
41
+ :input => input,
42
+ :target => self,
43
+ :environment => env,
44
+ :stdout_handler => :on_read_stdout,
45
+ :stderr_handler => :on_read_stderr,
46
+ :exit_handler => :on_exit)
47
+ end
48
+
49
+ def run_right_popen(command, env=nil, input=nil, count=1)
50
+ begin
51
+ @command = command
52
+ @env = env
53
+ @last_iteration = 0
54
+ @count = count
55
+ puts "#{count}>" if count > 1
56
+ EM.run { EM.next_tick { do_right_popen(command, env, input) } }
57
+ rescue Exception => e
58
+ puts "\n** Failed: #{e.message} FROM\n#{e.backtrace.join("\n")}"
59
+ raise e
60
+ end
61
+ end
62
+
63
+ def on_read_stdout(data)
64
+ @output_text << data
65
+ end
66
+
67
+ def on_read_stderr(data)
68
+ @error_text << data
69
+ end
70
+
71
+ def on_exit(status)
72
+ @last_iteration += 1
73
+ @timeout.cancel if @timeout
74
+ if @last_iteration < @count
75
+ EM.next_tick do
76
+ print '+'
77
+ STDOUT.flush
78
+ do_right_popen(@command, @env)
79
+ end
80
+ else
81
+ puts "<" if @count > 1
82
+ EM.stop
83
+ end
84
+ @status = status
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ it 'should redirect output' do
91
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_output.rb'))}\" \"#{STANDARD_MESSAGE}\" \"#{ERROR_MESSAGE}\""
92
+ runner = RightPopenSpec::Runner.new
93
+ runner.run_right_popen(command)
94
+ runner.status.exitstatus.should == 0
95
+ runner.output_text.should == STANDARD_MESSAGE + "\n"
96
+ runner.error_text.should == ERROR_MESSAGE + "\n"
97
+ end
98
+
99
+ it 'should return the right status' do
100
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_status.rb'))}\" #{EXIT_STATUS}"
101
+ runner = RightPopenSpec::Runner.new
102
+ runner.run_right_popen(command)
103
+ runner.status.exitstatus.should == EXIT_STATUS
104
+ runner.output_text.should == ''
105
+ runner.error_text.should == ''
106
+ end
107
+
108
+ it 'should preserve the integrity of stdout when stderr is unavailable' do
109
+ count = LARGE_OUTPUT_COUNTER
110
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_stdout_only.rb'))}\" #{count}"
111
+ runner = RightPopenSpec::Runner.new
112
+ runner.run_right_popen(command)
113
+ runner.status.exitstatus.should == 0
114
+
115
+ results = ''
116
+ count.times do |i|
117
+ results << "stdout #{i}\n"
118
+ end
119
+ runner.output_text.should == results
120
+ runner.error_text.should == ''
121
+ end
122
+
123
+ it 'should preserve the integrity of stderr when stdout is unavailable' do
124
+ count = LARGE_OUTPUT_COUNTER
125
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_stderr_only.rb'))}\" #{count}"
126
+ runner = RightPopenSpec::Runner.new
127
+ runner.run_right_popen(command)
128
+ runner.status.exitstatus.should == 0
129
+
130
+ results = ''
131
+ count.times do |i|
132
+ results << "stderr #{i}\n"
133
+ end
134
+ runner.error_text.should == results
135
+ runner.output_text.should == ''
136
+ end
137
+
138
+ it 'should preserve the integrity of stdout and stderr despite interleaving' do
139
+ count = LARGE_OUTPUT_COUNTER
140
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_mixed_output.rb'))}\" #{count}"
141
+ runner = RightPopenSpec::Runner.new
142
+ runner.run_right_popen(command)
143
+ runner.status.exitstatus.should == 99
144
+
145
+ results = ''
146
+ count.times do |i|
147
+ results << "stdout #{i}\n"
148
+ end
149
+ runner.output_text.should == results
150
+
151
+ results = ''
152
+ count.times do |i|
153
+ (results << "stderr #{i}\n") if 0 == i % 10
154
+ end
155
+ runner.error_text.should == results
156
+ end
157
+
158
+ it 'should setup environment variables' do
159
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
160
+ runner = RightPopenSpec::Runner.new
161
+ runner.run_right_popen(command)
162
+ runner.status.exitstatus.should == 0
163
+ runner.output_text.should_not include('_test_')
164
+ runner.run_right_popen(command, :__test__ => '42')
165
+ runner.status.exitstatus.should == 0
166
+ runner.output_text.should match(/^__test__=42$/)
167
+ end
168
+
169
+ it 'should restore environment variables' do
170
+ ENV['__test__'] = '41'
171
+ old_envs = {}
172
+ ENV.each { |k, v| old_envs[k] = v }
173
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
174
+ runner = RightPopenSpec::Runner.new
175
+ runner.run_right_popen(command, :__test__ => '42')
176
+ runner.status.exitstatus.should == 0
177
+ runner.output_text.should match(/^__test__=42$/)
178
+ ENV.each { |k, v| old_envs[k].should == v }
179
+ old_envs.each { |k, v| ENV[k].should == v }
180
+ end
181
+
182
+ if is_windows?
183
+ # FIX: this behavior is currently specific to Windows but should probably be
184
+ # implemented for Linux.
185
+ it 'should merge the PATH variable instead of overriding it' do
186
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'print_env.rb'))}\""
187
+ runner = RightPopenSpec::Runner.new
188
+ runner.run_right_popen(command, 'PATH' => "c:/bogus\\bin")
189
+ runner.status.exitstatus.should == 0
190
+ runner.output_text.should include('PATH=c:\\bogus\\bin;')
191
+ end
192
+ else
193
+ it 'should allow running bash command lines starting with a built-in command' do
194
+ command = "for i in 1 2 3 4 5; do echo $i;done"
195
+ runner = RightPopenSpec::Runner.new
196
+ runner.run_right_popen(command)
197
+ runner.status.exitstatus.should == 0
198
+ runner.output_text.should == "1\n2\n3\n4\n5\n"
199
+ end
200
+ end
201
+
202
+ it 'should run repeatedly without leaking resources' do
203
+ pending 'Set environment variable TEST_LEAK to enable' unless ENV['TEST_LEAK']
204
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'produce_output.rb'))}\" \"#{STANDARD_MESSAGE}\" \"#{ERROR_MESSAGE}\""
205
+ runner = RightPopenSpec::Runner.new
206
+ runner.run_right_popen(command, nil, nil, REPEAT_TEST_COUNTER)
207
+ runner.status.exitstatus.should == 0
208
+ runner.output_text.should == STANDARD_MESSAGE + "\n"
209
+ runner.error_text.should == ERROR_MESSAGE + "\n"
210
+ end
211
+
212
+ it 'should pass input to child process' do
213
+ command = "\"#{RUBY_CMD}\" \"#{File.expand_path(File.join(File.dirname(__FILE__), 'increment.rb'))}\""
214
+ runner = RightPopenSpec::Runner.new
215
+ runner.run_right_popen(command, nil, "42\n")
216
+ runner.status.exitstatus.should == 0
217
+ runner.output_text.should == "43\n"
218
+ runner.error_text.should be_empty
219
+ end
220
+
221
+ end