right_popen 1.0.11 → 1.0.16

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/spec/runner.rb ADDED
@@ -0,0 +1,112 @@
1
+ #-- -*- mode: ruby; encoding: utf-8 -*-
2
+ # Copyright: Copyright (c) 2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ module RightScale
25
+ class Runner
26
+ class RunnerStatus
27
+ def initialize(command, block)
28
+ @output_text = ""
29
+ @error_text = ""
30
+ @status = nil
31
+ @did_timeout = false
32
+ @callback = block
33
+ @pid = nil
34
+ EM.next_tick do
35
+ @timeout = EM::Timer.new(2) do
36
+ puts "\n** Failed to run #{command.inspect}: Timeout"
37
+ @did_timeout = true
38
+ @callback.call(self)
39
+ end
40
+ end
41
+ end
42
+
43
+ attr_accessor :output_text, :error_text, :status, :did_timeout, :pid
44
+
45
+ def on_read_stdout(data)
46
+ @output_text << data
47
+ end
48
+
49
+ def on_read_stderr(data)
50
+ @error_text << data
51
+ end
52
+
53
+ def on_pid(pid)
54
+ raise "PID already set!" unless @pid.nil?
55
+ @pid = pid
56
+ end
57
+
58
+ def on_exit(status)
59
+ @timeout.cancel if @timeout
60
+ @status = status
61
+ @callback.call(self)
62
+ end
63
+ end
64
+
65
+ def initialize
66
+ @count = 0
67
+ @done = false
68
+ @last_exception = nil
69
+ @last_iteration = 0
70
+ end
71
+
72
+ def do_right_popen(command, env=nil, input=nil, &callback)
73
+ status = RunnerStatus.new(command, callback)
74
+ RightScale.popen3(:command => command,
75
+ :input => input,
76
+ :target => status,
77
+ :environment => env,
78
+ :stdout_handler => :on_read_stdout,
79
+ :stderr_handler => :on_read_stderr,
80
+ :pid_handler => :on_pid,
81
+ :exit_handler => :on_exit)
82
+ status
83
+ end
84
+
85
+ def run_right_popen(command, env=nil, input=nil, count=1)
86
+ begin
87
+ @iterations = 0
88
+ EM.run do
89
+ EM.next_tick do
90
+ do_right_popen(command, env, input) do |status|
91
+ maybe_continue(status)
92
+ end
93
+ end
94
+ end
95
+ @status
96
+ rescue Exception => e
97
+ puts "\n** Failed: #{e.message} FROM\n#{e.backtrace.join("\n")}"
98
+ raise e
99
+ end
100
+ end
101
+
102
+ def maybe_continue(status)
103
+ @iterations += 1
104
+ if @iterations < @count
105
+ do_right_popen(command, env, input) {|status| maybe_continue(status)}
106
+ else
107
+ @status = status
108
+ EM.stop
109
+ end
110
+ end
111
+ end
112
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'rubygems'
2
+ require 'bundler/setup'
2
3
  require 'spec'
3
4
  require 'eventmachine'
5
+ require 'flexmock'
4
6
  require File.join(File.dirname(__FILE__), '..', 'lib', 'right_popen')
5
7
 
6
8
  RUBY_CMD = 'ruby'
@@ -18,3 +20,7 @@ REPEAT_TEST_COUNTER = 256
18
20
  def is_windows?
19
21
  return RUBY_PLATFORM =~ /mswin/
20
22
  end
23
+
24
+ Spec::Runner.configure do |config|
25
+ config.mock_with :flexmock
26
+ end
data/spec/stdout.rb ADDED
@@ -0,0 +1,28 @@
1
+ #-- -*- mode: ruby; encoding: utf-8 -*-
2
+ # Copyright: Copyright (c) 2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ $stderr.puts "Closing stdout"
25
+ STDOUT.close
26
+ sleep 3
27
+ $stderr.puts "Exiting"
28
+ exit 0
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: right_popen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.11
4
+ hash: 55
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 16
10
+ version: 1.0.16
5
11
  platform: ruby
6
12
  authors:
7
13
  - Scott Messier
@@ -11,19 +17,69 @@ autorequire:
11
17
  bindir: bin
12
18
  cert_chain: []
13
19
 
14
- date: 2010-09-08 00:00:00 -07:00
15
- default_executable:
20
+ date: 2012-05-15 00:00:00 Z
16
21
  dependencies:
17
22
  - !ruby/object:Gem::Dependency
18
23
  name: eventmachine
19
- type: :runtime
20
- version_requirement:
21
- version_requirements: !ruby/object:Gem::Requirement
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ none: false
22
26
  requirements:
23
27
  - - ">="
24
28
  - !ruby/object:Gem::Version
29
+ hash: 59
30
+ segments:
31
+ - 0
32
+ - 12
33
+ - 10
25
34
  version: 0.12.10
26
- version:
35
+ type: :runtime
36
+ requirement: *id001
37
+ prerelease: false
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec
40
+ version_requirements: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 9
46
+ segments:
47
+ - 1
48
+ - 3
49
+ version: "1.3"
50
+ type: :development
51
+ requirement: *id002
52
+ prerelease: false
53
+ - !ruby/object:Gem::Dependency
54
+ name: rake
55
+ version_requirements: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 49
61
+ segments:
62
+ - 0
63
+ - 8
64
+ - 7
65
+ version: 0.8.7
66
+ type: :development
67
+ requirement: *id003
68
+ prerelease: false
69
+ - !ruby/object:Gem::Dependency
70
+ name: flexmock
71
+ version_requirements: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 3
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ type: :development
81
+ requirement: *id004
82
+ prerelease: false
27
83
  description: |
28
84
  RightPopen allows running external processes aynchronously while still
29
85
  capturing their standard and error outputs. It relies on EventMachine for most
@@ -41,9 +97,14 @@ files:
41
97
  - LICENSE
42
98
  - README.rdoc
43
99
  - Rakefile
44
- - lib/linux/right_popen.rb
45
100
  - lib/right_popen.rb
101
+ - lib/right_popen/linux/accumulator.rb
102
+ - lib/right_popen/linux/process.rb
103
+ - lib/right_popen/linux/right_popen.rb
104
+ - lib/right_popen/linux/utilities.rb
105
+ - lib/right_popen/version.rb
46
106
  - right_popen.gemspec
107
+ - spec/background.rb
47
108
  - spec/increment.rb
48
109
  - spec/print_env.rb
49
110
  - spec/produce_mixed_output.rb
@@ -51,9 +112,12 @@ files:
51
112
  - spec/produce_status.rb
52
113
  - spec/produce_stderr_only.rb
53
114
  - spec/produce_stdout_only.rb
115
+ - spec/right_popen/linux/accumulator_spec.rb
116
+ - spec/right_popen/linux/utilities_spec.rb
54
117
  - spec/right_popen_spec.rb
118
+ - spec/runner.rb
55
119
  - spec/spec_helper.rb
56
- has_rdoc: true
120
+ - spec/stdout.rb
57
121
  homepage: https://github.com/rightscale/right_popen
58
122
  licenses: []
59
123
 
@@ -66,21 +130,29 @@ rdoc_options:
66
130
  require_paths:
67
131
  - lib
68
132
  required_ruby_version: !ruby/object:Gem::Requirement
133
+ none: false
69
134
  requirements:
70
135
  - - ">="
71
136
  - !ruby/object:Gem::Version
137
+ hash: 59
138
+ segments:
139
+ - 1
140
+ - 8
141
+ - 6
72
142
  version: 1.8.6
73
- version:
74
143
  required_rubygems_version: !ruby/object:Gem::Requirement
144
+ none: false
75
145
  requirements:
76
146
  - - ">="
77
147
  - !ruby/object:Gem::Version
148
+ hash: 3
149
+ segments:
150
+ - 0
78
151
  version: "0"
79
- version:
80
152
  requirements: []
81
153
 
82
154
  rubyforge_project: right_popen
83
- rubygems_version: 1.3.5
155
+ rubygems_version: 1.8.24
84
156
  signing_key:
85
157
  specification_version: 3
86
158
  summary: Provides a platform-independent popen implementation
@@ -1,118 +0,0 @@
1
- #--
2
- # Copyright (c) 2009 RightScale Inc
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
-
24
- # RightScale.popen3 allows running external processes aynchronously
25
- # while still capturing their standard and error outputs.
26
- # It relies on EventMachine for most of its internal mechanisms.
27
-
28
- require 'rubygems'
29
- require 'eventmachine'
30
- require 'tempfile'
31
-
32
- module RightScale
33
- module PipeHandler
34
- def initialize(target, handler)
35
- @target = target
36
- @handler = handler
37
- end
38
-
39
- def receive_data(data)
40
- @target.method(@handler).call(data) if @handler
41
- end
42
- end
43
- module InputHandler
44
- def initialize(string)
45
- @string = string
46
- end
47
-
48
- def post_init
49
- send_data(@string) if @string
50
- close_connection_after_writing
51
- end
52
- end
53
-
54
- # Forks process to run given command asynchronously, hooking all three
55
- # standard streams of the child process.
56
- #
57
- # === Parameters
58
- # options[:pid_handler](Symbol):: Token for pid handler method name.
59
- # options[:temp_dir]:: Path to temporary directory where executable files are
60
- # created, default to /tmp if not specified
61
- #
62
- # See RightScale.popen3
63
- def self.popen3_imp(options)
64
- GC.start # To garbage collect open file descriptors from passed executions
65
- EM.next_tick do
66
- inr, inw = IO::pipe
67
- outr, outw = IO::pipe
68
- errr, errw = IO::pipe
69
-
70
- [inr, inw, outr, outw, errr, errw].each {|fdes| fdes.sync = true}
71
-
72
- pid = fork do
73
- options[:environment].each do |k, v|
74
- ENV[k.to_s] = v
75
- end unless options[:environment].nil?
76
-
77
- inw.close
78
- outr.close
79
- errr.close
80
- $stdin.reopen inr
81
- $stdout.reopen outw
82
- $stderr.reopen errw
83
-
84
- if options[:command].instance_of?(String)
85
- exec "sh", "-c", options[:command]
86
- else
87
- exec *options[:command]
88
- end
89
- end
90
-
91
- inr.close
92
- outw.close
93
- errw.close
94
- stderr = EM.attach(errr, PipeHandler, options[:target],
95
- options[:stderr_handler])
96
- stdout = EM.attach(outr, PipeHandler, options[:target],
97
- options[:stdout_handler])
98
- stdin = EM.attach(inw, InputHandler, options[:input])
99
-
100
- options[:target].method(options[:pid_handler]).call(pid) if
101
- options.key? :pid_handler
102
-
103
- wait_timer = EM::PeriodicTimer.new(1) do
104
- value = Process.waitpid2(pid, Process::WNOHANG)
105
- unless value.nil?
106
- ignored, status = value
107
- wait_timer.cancel
108
- stdin.close_connection
109
- stdout.close_connection
110
- stderr.close_connection
111
- options[:target].method(options[:exit_handler]).call(status) if
112
- options[:exit_handler]
113
- end
114
- end
115
- end
116
- true
117
- end
118
- end