right_popen 1.0.7-x86-mswin32-60 → 1.0.9-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
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