ProcessPilot 0.0.1.20120118
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +1 -0
- data/ChangeLog +5 -0
- data/Credits +18 -0
- data/LICENSE +31 -0
- data/README +18 -0
- data/ReleaseInfo +8 -0
- data/lib/processpilot/processpilot.rb +197 -0
- data/lib/processpilot/wrapper.rb +16 -0
- data/test/ProcessPilotTest/Common.rb +241 -0
- data/test/ProcessPilotTest/NonRuby.rb +114 -0
- data/test/ProcessPilotTest/Ruby.rb +38 -0
- data/test/Programs/Bash/Interactive.sh +5 -0
- data/test/Programs/Bash/InteractivePrompt.sh +6 -0
- data/test/Programs/Bash/InteractivePromptSTDERR.sh +6 -0
- data/test/Programs/Bash/InteractiveSTDERR.sh +5 -0
- data/test/Programs/Bash/InteractiveSeveralPrompts.sh +11 -0
- data/test/Programs/Bash/NotInteractive.sh +3 -0
- data/test/Programs/Bash/NotInteractiveSTDERR.sh +3 -0
- data/test/Programs/Ruby/NormalSTDOUT.rb +8 -0
- data/test/Programs/Ruby/Scenario.rb +25 -0
- data/test/Programs/Ruby/SyncedSTDOUT.rb +10 -0
- data/test/Programs/Windows/Interactive.bat +4 -0
- data/test/Programs/Windows/InteractivePrompt.bat +4 -0
- data/test/Programs/Windows/InteractivePromptSTDERR.bat +5 -0
- data/test/Programs/Windows/InteractiveSTDERR.bat +4 -0
- data/test/Programs/Windows/InteractiveSeveralPrompts.bat +9 -0
- data/test/Programs/Windows/NotInteractive.bat +2 -0
- data/test/Programs/Windows/NotInteractiveSTDERR.bat +2 -0
- data/test/run.rb +30 -0
- metadata +121 -0
data/AUTHORS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
= Muriel Salvan (murielsalvan@users.sourceforge.net)
|
data/ChangeLog
ADDED
data/Credits
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
= Projects used by Process Pilot
|
2
|
+
|
3
|
+
== ChildProcess
|
4
|
+
* Jari Bakken (http://github.com/jarib)
|
5
|
+
* http://github.com/jarib/childprocess
|
6
|
+
* Used to internally pilot stdin in real time
|
7
|
+
|
8
|
+
== Ruby
|
9
|
+
* Yukihiro « matz » Matsumoto (http://www.rubyist.net/~matz/)
|
10
|
+
* http://www.ruby-lang.org/
|
11
|
+
* Thanks a lot Matz for this truly wonderful language !
|
12
|
+
|
13
|
+
== rUtilAnts
|
14
|
+
* Muriel Salvan (http://murielsalvan.users.sourceforge.net)
|
15
|
+
* http://rutilants.sourceforge.net
|
16
|
+
* Used for logging.
|
17
|
+
|
18
|
+
= People that helped a lot in developing Process Pilot
|
data/LICENSE
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
The license stated herein is a copy of the BSD License (modified on July 1999).
|
3
|
+
The AUTHOR mentionned below refers to the list of people involved in the
|
4
|
+
creation and modification of any file included in the delivered package.
|
5
|
+
This list is found in the file named AUTHORS.
|
6
|
+
The AUTHORS and LICENSE files have to be included in any release of software
|
7
|
+
embedding source code of this package, or using it as a derivative software.
|
8
|
+
|
9
|
+
Copyright (c) 2010 - 2012 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
10
|
+
|
11
|
+
Redistribution and use in source and binary forms, with or without
|
12
|
+
modification, are permitted provided that the following conditions are met:
|
13
|
+
|
14
|
+
1. Redistributions of source code must retain the above copyright notice,
|
15
|
+
this list of conditions and the following disclaimer.
|
16
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
17
|
+
this list of conditions and the following disclaimer in the documentation
|
18
|
+
and/or other materials provided with the distribution.
|
19
|
+
3. The name of the author may not be used to endorse or promote products
|
20
|
+
derived from this software without specific prior written permission.
|
21
|
+
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
23
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
24
|
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
25
|
+
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
26
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
27
|
+
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
28
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
29
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
30
|
+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
31
|
+
OF SUCH DAMAGE.
|
data/README
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
-- This file is best viewed when processed by rdoc.
|
2
|
+
++
|
3
|
+
|
4
|
+
= Process Pilot
|
5
|
+
|
6
|
+
Ruby library to pilot interactive command line processes in real time.
|
7
|
+
|
8
|
+
== Where is the documentation ?
|
9
|
+
|
10
|
+
Check the website at http://processpilot.sourceforge.net
|
11
|
+
|
12
|
+
== Who wrote it ?
|
13
|
+
|
14
|
+
Check the AUTHORS[link:files/AUTHORS.html] file.
|
15
|
+
|
16
|
+
== What is the license ?
|
17
|
+
|
18
|
+
You can find out in the LICENSE[link:files/LICENSE.html] file.
|
data/ReleaseInfo
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
require 'childprocess'
|
7
|
+
require 'tempfile'
|
8
|
+
|
9
|
+
module ProcessPilot
|
10
|
+
|
11
|
+
# Pilot a process.
|
12
|
+
# This will create a new thread for the process to be run.
|
13
|
+
# If the process is a Ruby process, you can force STDOUT sync by specifying it in options. In this case the command line should begin with the Ruby file name to be executed (don't use ruby executable, and specifiy ruby options in iOptions[:RubyCmdLine]).
|
14
|
+
#
|
15
|
+
# Parameters:
|
16
|
+
# * *iCmdLine* (<em>list<String></em>): The process' command line
|
17
|
+
# * *iOptions* (<em>map<Symbol,Object></em>): Optional arguments [optional = nil]:
|
18
|
+
# ** *:ForceRubyProcessSync* (_Boolean_): If the command line is a Ruby process, force setting STDOUT to be synced. [optional = false]
|
19
|
+
# ** *:RubyCmdLine* (<em>list<String></em>): Command line of Ruby interpreter with options (used only if :ForceRubyProcessSync is true) [optional = ['ruby']]
|
20
|
+
# ** *:Debug* (_Boolean_): Do we activate some debugging traces ? (need rUtilAnts gem if activated) [optional = false]
|
21
|
+
# * _CodeBlock_: The code called for process piloting:
|
22
|
+
# ** Parameters:
|
23
|
+
# ** *oStdIN* (_IO_): The process' STDIN
|
24
|
+
# ** *iStdOUT* (_IO_): The process' STDOUT
|
25
|
+
# ** *iStdERR* (_IO_): The process' STDERR
|
26
|
+
# ** *iChildProcess* (_ChildProcess_): The corresponding child process. Don't use it to pilot std* IO objects.
|
27
|
+
# ** Return:
|
28
|
+
# ** _Boolean_: Do we have to wait until the process' completion ?
|
29
|
+
def self.pilot(*iArgs)
|
30
|
+
iCmdLine = iArgs
|
31
|
+
iOptions = (iArgs[-1].is_a?(Hash)) ? iArgs.pop : {}
|
32
|
+
iForceRubyProcessSync = (iOptions[:ForceRubyProcessSync] || false)
|
33
|
+
iRubyCmdLine = (iOptions[:RubyCmdLine] || ['ruby'])
|
34
|
+
iDebug = (iOptions[:Debug] || false)
|
35
|
+
|
36
|
+
if ((iDebug) and (require 'rUtilAnts/Logging'))
|
37
|
+
# First time it was required: set it up
|
38
|
+
RUtilAnts::Logging::initializeLogging('', '')
|
39
|
+
activateLogDebug(true)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Wrap eventually Ruby command line
|
43
|
+
lRealCmdLine = (iForceRubyProcessSync) ? iRubyCmdLine + [ "#{File.dirname(__FILE__)}/wrapper.rb" ] + iCmdLine : iCmdLine
|
44
|
+
|
45
|
+
logDebug "[ProcessPilot] Command line: #{lRealCmdLine.inspect}" if iDebug
|
46
|
+
lProcess = ChildProcess.build(*lRealCmdLine)
|
47
|
+
|
48
|
+
# Indication of stdin usage
|
49
|
+
lProcess.duplex = true
|
50
|
+
|
51
|
+
# Specify files for stdout/stderr
|
52
|
+
# ! Use w+ mode to make it possible for our monitoring thread to reopen the file in r mode
|
53
|
+
Tempfile.open('processpilot.stdout') do |oStdOUT|
|
54
|
+
logDebug "[ProcessPilot] STDOUT file: #{oStdOUT.path}" if iDebug
|
55
|
+
lProcess.io.stdout = oStdOUT
|
56
|
+
Tempfile.open('processpilot.stderr') do |oStdERR|
|
57
|
+
logDebug "[ProcessPilot] STDERR file: #{oStdERR.path}" if iDebug
|
58
|
+
lProcess.io.stderr = oStdERR
|
59
|
+
|
60
|
+
# Start the process: this creates the background thread running our command
|
61
|
+
lProcess.start
|
62
|
+
|
63
|
+
# In our main thread: open the STDOUT/ERR files
|
64
|
+
lStdOUT = File.open(oStdOUT.path, 'r')
|
65
|
+
lStdERR = File.open(oStdERR.path, 'r')
|
66
|
+
lStdIN = lProcess.io.stdin
|
67
|
+
|
68
|
+
# Call client code
|
69
|
+
lWaitUntilCompletion = yield(lStdIN, lStdOUT, lStdERR, lProcess)
|
70
|
+
|
71
|
+
# Wait for the process termination in case it is late
|
72
|
+
if (lWaitUntilCompletion)
|
73
|
+
while (!lProcess.exited?)
|
74
|
+
sleep 1
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
# Define some helpers that can be handy in case of process piloting from IO
|
85
|
+
class IO
|
86
|
+
|
87
|
+
# Exception thrown when timeout has been reached
|
88
|
+
class TimeOutError < RuntimeError
|
89
|
+
end
|
90
|
+
|
91
|
+
# Implement a blocking read of a new string ending with newline.
|
92
|
+
# Make sure we wait for the end of a string before returning.
|
93
|
+
# This is done to ensure we will get the new string we are expecting.
|
94
|
+
# If the timeout is reached, an exception is thrown.
|
95
|
+
#
|
96
|
+
# Parameters:
|
97
|
+
# * *iOptions* (<em>map<Symbol,Object></em>): Optional arguments [optional = {}]:
|
98
|
+
# ** *:TimeOutSecs* (_Integer_): Time out in seconds (nil = no timeout) [optional = nil]
|
99
|
+
# ** *:PollingIntervalSecs* (_Float_): Polling interval in seconds [optional = 0.1]
|
100
|
+
# ** *:ChildProcess* (_ChildProcess_): Corresponding child process linked to this IO. Can be used to detect the end of IO. [optional = nil]
|
101
|
+
# Return:
|
102
|
+
# * _String_: The next string from IO (separator is $/). Can be empty if the corresponding child process has exited already.
|
103
|
+
def gets_blocking(iOptions = {})
|
104
|
+
return get_data_blocking(
|
105
|
+
Proc.new { |iStr| iStr[-1..-1] == $/ },
|
106
|
+
iOptions
|
107
|
+
) do |iStr|
|
108
|
+
next self.gets
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Implement a blocking read of a given size.
|
113
|
+
# Make sure we wait for the end of a string before returning.
|
114
|
+
# This is done to ensure we will get the new string we are expecting.
|
115
|
+
# If the timeout is reached, an exception is thrown.
|
116
|
+
#
|
117
|
+
# Parameters:
|
118
|
+
# * *iSize* (_Integer_): Size of the data to read
|
119
|
+
# * *iOptions* (<em>map<Symbol,Object></em>): Optional arguments [optional = {}]:
|
120
|
+
# ** *:TimeOutSecs* (_Integer_): Time out in seconds (nil = no timeout) [optional = nil]
|
121
|
+
# ** *:PollingIntervalSecs* (_Float_): Polling interval in seconds [optional = 0.1]
|
122
|
+
# ** *:ChildProcess* (_ChildProcess_): Corresponding child process linked to this IO. Can be used to detect the end of IO. [optional = nil]
|
123
|
+
# Return:
|
124
|
+
# * _String_: The next string from IO (separator is $/). Can be empty if the corresponding child process has exited already.
|
125
|
+
def read_blocking(iSize, iOptions = {})
|
126
|
+
return get_data_blocking(
|
127
|
+
Proc.new { |iStr| iStr.size == iSize },
|
128
|
+
iOptions
|
129
|
+
) do |iStr|
|
130
|
+
next self.read(iSize-iStr.size)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Send a synchronized input to an IO.
|
135
|
+
# Make sure it will be flushed.
|
136
|
+
#
|
137
|
+
# Parameters:
|
138
|
+
# * *iStr* (_String_): The string to send
|
139
|
+
def write_flushed(iStr)
|
140
|
+
self.write iStr
|
141
|
+
self.flush
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
# Implement a blocking read of a data unless the data read conforms to a given validation code.
|
147
|
+
# Take a validation proc to know if the data was read correctly, and yields code to read effectively data.
|
148
|
+
# Proper implementation should have a more efficient algo.
|
149
|
+
# If the timeout is reached, an exception is thrown.
|
150
|
+
#
|
151
|
+
# Parameters:
|
152
|
+
# * *iProcValidation* (_Proc_): The validation proc:
|
153
|
+
# ** Parameters:
|
154
|
+
# ** *iData* (_String_): The data to validate
|
155
|
+
# ** Return:
|
156
|
+
# ** _Boolean_: Is the data valid ?
|
157
|
+
# * *iOptions* (<em>map<Symbol,Object></em>): Optional arguments [optional = {}]:
|
158
|
+
# ** *:TimeOutSecs* (_Integer_): Time out in seconds (nil = no timeout) [optional = nil]
|
159
|
+
# ** *:PollingIntervalSecs* (_Float_): Polling interval in seconds [optional = 0.1]
|
160
|
+
# ** *:ChildProcess* (_ChildProcess_): Corresponding child process linked to this IO. Can be used to detect the end of IO. [optional = nil]
|
161
|
+
# * _CodeBlock_: Code called to read data effectively:
|
162
|
+
# ** Parameters:
|
163
|
+
# ** *iStr* (_String_): The data already read
|
164
|
+
# ** Return:
|
165
|
+
# ** _String_: String of data read (can be nil if no data was read)
|
166
|
+
# Return:
|
167
|
+
# * _String_: The next string from IO (separator is $/). Can be empty if the corresponding child process has exited already.
|
168
|
+
def get_data_blocking(iProcValidation, iOptions = {})
|
169
|
+
rStr = ''
|
170
|
+
iPollingInterval = (iOptions[:PollingIntervalSecs] || 0.1)
|
171
|
+
iTimeOutSecs = iOptions[:TimeOutSecs]
|
172
|
+
iChildProcess = iOptions[:ChildProcess]
|
173
|
+
|
174
|
+
require 'time' if (iTimeOutSecs != nil)
|
175
|
+
|
176
|
+
# Concatenate chunks unless we have the separator.
|
177
|
+
# As we deal with stdin flow, it is possible to have a line without ending already written in the file and already flushed by the IO.
|
178
|
+
lTimeOut = (iTimeOutSecs == nil) ? nil : Time.now + iTimeOutSecs
|
179
|
+
while (!iProcValidation.call(rStr))
|
180
|
+
lNewChunk = nil
|
181
|
+
while (lNewChunk == nil)
|
182
|
+
lNewChunk = yield(rStr)
|
183
|
+
#$stdout.puts "===== Read #{lNewChunk.inspect}"
|
184
|
+
break if ((iChildProcess != nil) and (iChildProcess.exited?))
|
185
|
+
if (lNewChunk == nil)
|
186
|
+
sleep iPollingInterval
|
187
|
+
raise TimeOutError.new("Timeout of #{iTimeOutSecs} secs reached while waiting for data.") if ((lTimeOut != nil) and (Time.now > lTimeOut))
|
188
|
+
end
|
189
|
+
end
|
190
|
+
rStr.concat(lNewChunk) if (lNewChunk != nil)
|
191
|
+
break if ((iChildProcess != nil) and (iChildProcess.exited?))
|
192
|
+
end
|
193
|
+
|
194
|
+
return rStr
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
# Disable STDOUT caching
|
7
|
+
$stdout.sync = true
|
8
|
+
|
9
|
+
# Get the rb file to execute
|
10
|
+
iRBFileName = ARGV[0]
|
11
|
+
|
12
|
+
# Adapt ARGV for this rb file to get its arguments correctly
|
13
|
+
# TODO: Maybe adapt other variables ...
|
14
|
+
ARGV.replace(ARGV[1..-1])
|
15
|
+
|
16
|
+
load iRBFileName
|
@@ -0,0 +1,241 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module ProcessPilotTest
|
7
|
+
|
8
|
+
module Common
|
9
|
+
|
10
|
+
# Get the OS dependant command line for testing non interactive processes
|
11
|
+
#
|
12
|
+
# Return:
|
13
|
+
# * <em>list<String></em>: Command line
|
14
|
+
def getNotInteractiveCmdLine
|
15
|
+
rCmdLine = nil
|
16
|
+
|
17
|
+
case $rUtilAnts_Platform_Info.os
|
18
|
+
when RUtilAnts::Platform::OS_WINDOWS
|
19
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Windows/NotInteractive.bat"]
|
20
|
+
when RUtilAnts::Platform::OS_LINUX
|
21
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/NotInteractive.sh"]
|
22
|
+
when RUtilAnts::Platform::OS_CYGWIN
|
23
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/NotInteractive.sh"]
|
24
|
+
else
|
25
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/NotInteractive.sh"]
|
26
|
+
end
|
27
|
+
rCmdLine << { :Debug => true } if ($ProcessPilotTest_Debug)
|
28
|
+
|
29
|
+
return rCmdLine
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get the OS dependant command line for testing non interactive processes on STDERR
|
33
|
+
#
|
34
|
+
# Return:
|
35
|
+
# * <em>list<String></em>: Command line
|
36
|
+
def getNotInteractiveCmdLineSTDERR
|
37
|
+
rCmdLine = nil
|
38
|
+
|
39
|
+
case $rUtilAnts_Platform_Info.os
|
40
|
+
when RUtilAnts::Platform::OS_WINDOWS
|
41
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Windows/NotInteractiveSTDERR.bat"]
|
42
|
+
when RUtilAnts::Platform::OS_LINUX
|
43
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/NotInteractiveSTDERR.sh"]
|
44
|
+
when RUtilAnts::Platform::OS_CYGWIN
|
45
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/NotInteractiveSTDERR.sh"]
|
46
|
+
else
|
47
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/NotInteractiveSTDERR.sh"]
|
48
|
+
end
|
49
|
+
rCmdLine << { :Debug => true } if ($ProcessPilotTest_Debug)
|
50
|
+
|
51
|
+
return rCmdLine
|
52
|
+
end
|
53
|
+
|
54
|
+
# Get the OS dependant command line for testing interactive processes
|
55
|
+
#
|
56
|
+
# Return:
|
57
|
+
# * <em>list<String></em>: Command line
|
58
|
+
def getInteractiveCmdLine
|
59
|
+
rCmdLine = nil
|
60
|
+
|
61
|
+
case $rUtilAnts_Platform_Info.os
|
62
|
+
when RUtilAnts::Platform::OS_WINDOWS
|
63
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Windows/Interactive.bat"]
|
64
|
+
when RUtilAnts::Platform::OS_LINUX
|
65
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/Interactive.sh"]
|
66
|
+
when RUtilAnts::Platform::OS_CYGWIN
|
67
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/Interactive.sh"]
|
68
|
+
else
|
69
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/Interactive.sh"]
|
70
|
+
end
|
71
|
+
rCmdLine << { :Debug => true } if ($ProcessPilotTest_Debug)
|
72
|
+
|
73
|
+
return rCmdLine
|
74
|
+
end
|
75
|
+
|
76
|
+
# Get the OS dependant command line for testing interactive processes on STDERR
|
77
|
+
#
|
78
|
+
# Return:
|
79
|
+
# * <em>list<String></em>: Command line
|
80
|
+
def getInteractiveCmdLineSTDERR
|
81
|
+
rCmdLine = nil
|
82
|
+
|
83
|
+
case $rUtilAnts_Platform_Info.os
|
84
|
+
when RUtilAnts::Platform::OS_WINDOWS
|
85
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Windows/InteractiveSTDERR.bat"]
|
86
|
+
when RUtilAnts::Platform::OS_LINUX
|
87
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractiveSTDERR.sh"]
|
88
|
+
when RUtilAnts::Platform::OS_CYGWIN
|
89
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractiveSTDERR.sh"]
|
90
|
+
else
|
91
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractiveSTDERR.sh"]
|
92
|
+
end
|
93
|
+
rCmdLine << { :Debug => true } if ($ProcessPilotTest_Debug)
|
94
|
+
|
95
|
+
return rCmdLine
|
96
|
+
end
|
97
|
+
|
98
|
+
# Get the OS dependant command line for testing interactive processes with a prompt
|
99
|
+
#
|
100
|
+
# Return:
|
101
|
+
# * <em>list<String></em>: Command line
|
102
|
+
def getInteractivePromptCmdLine
|
103
|
+
rCmdLine = nil
|
104
|
+
|
105
|
+
case $rUtilAnts_Platform_Info.os
|
106
|
+
when RUtilAnts::Platform::OS_WINDOWS
|
107
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Windows/InteractivePrompt.bat"]
|
108
|
+
when RUtilAnts::Platform::OS_LINUX
|
109
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractivePrompt.sh"]
|
110
|
+
when RUtilAnts::Platform::OS_CYGWIN
|
111
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractivePrompt.sh"]
|
112
|
+
else
|
113
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractivePrompt.sh"]
|
114
|
+
end
|
115
|
+
rCmdLine << { :Debug => true } if ($ProcessPilotTest_Debug)
|
116
|
+
|
117
|
+
return rCmdLine
|
118
|
+
end
|
119
|
+
|
120
|
+
# Get the OS dependant command line for testing interactive processes with a prompt on STDERR
|
121
|
+
#
|
122
|
+
# Return:
|
123
|
+
# * <em>list<String></em>: Command line
|
124
|
+
def getInteractivePromptCmdLineSTDERR
|
125
|
+
rCmdLine = nil
|
126
|
+
|
127
|
+
case $rUtilAnts_Platform_Info.os
|
128
|
+
when RUtilAnts::Platform::OS_WINDOWS
|
129
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Windows/InteractivePromptSTDERR.bat"]
|
130
|
+
when RUtilAnts::Platform::OS_LINUX
|
131
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractivePromptSTDERR.sh"]
|
132
|
+
when RUtilAnts::Platform::OS_CYGWIN
|
133
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractivePromptSTDERR.sh"]
|
134
|
+
else
|
135
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractivePromptSTDERR.sh"]
|
136
|
+
end
|
137
|
+
rCmdLine << { :Debug => true } if ($ProcessPilotTest_Debug)
|
138
|
+
|
139
|
+
return rCmdLine
|
140
|
+
end
|
141
|
+
|
142
|
+
# Get the OS dependant command line for testing interactive processes with several prompts
|
143
|
+
#
|
144
|
+
# Return:
|
145
|
+
# * <em>list<String></em>: Command line
|
146
|
+
def getInteractiveSeveralPrompts
|
147
|
+
rCmdLine = nil
|
148
|
+
|
149
|
+
case $rUtilAnts_Platform_Info.os
|
150
|
+
when RUtilAnts::Platform::OS_WINDOWS
|
151
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Windows/InteractiveSeveralPrompts.bat"]
|
152
|
+
when RUtilAnts::Platform::OS_LINUX
|
153
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractiveSeveralPrompts.sh"]
|
154
|
+
when RUtilAnts::Platform::OS_CYGWIN
|
155
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractiveSeveralPrompts.sh"]
|
156
|
+
else
|
157
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Bash/InteractiveSeveralPrompts.sh"]
|
158
|
+
end
|
159
|
+
rCmdLine << { :Debug => true } if ($ProcessPilotTest_Debug)
|
160
|
+
|
161
|
+
return rCmdLine
|
162
|
+
end
|
163
|
+
|
164
|
+
# Get the command line for testing synced Ruby programs
|
165
|
+
#
|
166
|
+
# Return:
|
167
|
+
# * <em>list<String></em>: Command line
|
168
|
+
def getSyncedRubyCmdLine
|
169
|
+
rCmdLine = ['ruby', "#{$ProcessPilotTest_RootPath}/test/Programs/Ruby/SyncedSTDOUT.rb"]
|
170
|
+
|
171
|
+
rCmdLine << { :Debug => true } if ($ProcessPilotTest_Debug)
|
172
|
+
|
173
|
+
return rCmdLine
|
174
|
+
end
|
175
|
+
|
176
|
+
# Get the command line for testing normal Ruby programs
|
177
|
+
#
|
178
|
+
# Return:
|
179
|
+
# * <em>list<String></em>: Command line
|
180
|
+
def getNormalRubyCmdLine
|
181
|
+
rCmdLine = ['ruby', "#{$ProcessPilotTest_RootPath}/test/Programs/Ruby/NormalSTDOUT.rb"]
|
182
|
+
|
183
|
+
rCmdLine << { :Debug => true } if ($ProcessPilotTest_Debug)
|
184
|
+
|
185
|
+
return rCmdLine
|
186
|
+
end
|
187
|
+
|
188
|
+
# Get the command line for testing normal Ruby programs and forcing them to sync
|
189
|
+
#
|
190
|
+
# Return:
|
191
|
+
# * <em>list<String></em>: Command line
|
192
|
+
def getNormalRubyWithSyncCmdLine
|
193
|
+
rCmdLine = ["#{$ProcessPilotTest_RootPath}/test/Programs/Ruby/NormalSTDOUT.rb"]
|
194
|
+
|
195
|
+
lOptions = {
|
196
|
+
:ForceRubyProcessSync => true
|
197
|
+
}
|
198
|
+
lOptions[:Debug] = true if ($ProcessPilotTest_Debug)
|
199
|
+
rCmdLine << lOptions
|
200
|
+
|
201
|
+
return rCmdLine
|
202
|
+
end
|
203
|
+
|
204
|
+
# Assert a common given scenario.
|
205
|
+
# This has been put in such a method as the same scenario is used in different scripts.
|
206
|
+
#
|
207
|
+
# Parameters:
|
208
|
+
# * *oStdIN* (_IO_): STDIN
|
209
|
+
# * *iStdOUT* (_IO_): STDOUT
|
210
|
+
# * *iStdERR* (_IO_): STDERR
|
211
|
+
# * *iChildProcess* (_ChildProcess_): Corresponding ChildProcess
|
212
|
+
def assert_testing_scenario(oStdIN, iStdOUT, iStdERR, iChildProcess)
|
213
|
+
assert_equal "STDOUT Line 1\n", iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
214
|
+
assert_equal 'Enter string 1 from STDOUT: ', iStdOUT.read_blocking(28, :ChildProcess => iChildProcess)
|
215
|
+
assert_raise IO::TimeOutError do
|
216
|
+
iStdERR.read_blocking(1, :TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
217
|
+
end
|
218
|
+
assert_raise IO::TimeOutError do
|
219
|
+
iStdOUT.read_blocking(1, :TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
220
|
+
end
|
221
|
+
oStdIN.write_flushed "Test String 1\n"
|
222
|
+
assert_equal "STDOUT Line 2 Test String 1\n", iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
223
|
+
assert_equal "STDERR Line 1\n", iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
224
|
+
assert_equal 'Enter string 2 from STDERR: ', iStdERR.read_blocking(28, :ChildProcess => iChildProcess)
|
225
|
+
assert_raise IO::TimeOutError do
|
226
|
+
iStdERR.read_blocking(1, :TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
227
|
+
end
|
228
|
+
assert_raise IO::TimeOutError do
|
229
|
+
iStdOUT.read_blocking(1, :TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
230
|
+
end
|
231
|
+
oStdIN.write_flushed "Test String 2\n"
|
232
|
+
assert_equal "STDOUT Line 3 Test String 2\n", iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
233
|
+
assert_equal "STDERR Line 2\n", iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
234
|
+
assert_equal '', iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
235
|
+
assert_equal '', iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
236
|
+
assert iChildProcess.exited?
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module ProcessPilotTest
|
7
|
+
|
8
|
+
class NonRuby < ::Test::Unit::TestCase
|
9
|
+
|
10
|
+
include ProcessPilotTest::Common
|
11
|
+
|
12
|
+
def testNotInteractiveSTDOUT
|
13
|
+
ProcessPilot::pilot(*getNotInteractiveCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
14
|
+
assert_equal "Hello World\n", iStdOUT.gets_blocking(:TimeOutSecs => 1)
|
15
|
+
assert_raise IO::TimeOutError do
|
16
|
+
iStdERR.gets_blocking(:TimeOutSecs => 1)
|
17
|
+
end
|
18
|
+
assert iChildProcess.exited?
|
19
|
+
next true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def testNotInteractiveSTDOUTEndOfProcess
|
24
|
+
ProcessPilot::pilot(*getNotInteractiveCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
25
|
+
assert_equal "Hello World\n", iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
26
|
+
assert_equal '', iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
27
|
+
assert_equal '', iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
28
|
+
assert iChildProcess.exited?
|
29
|
+
next true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def testNotInteractiveSTDERR
|
34
|
+
ProcessPilot::pilot(*getNotInteractiveCmdLineSTDERR) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
35
|
+
assert_equal '', iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
36
|
+
assert_equal "Hello World\n", iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
37
|
+
assert_equal '', iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
38
|
+
assert iChildProcess.exited?
|
39
|
+
next true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def testInteractiveSTDOUT
|
44
|
+
ProcessPilot::pilot(*getInteractiveCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
45
|
+
assert_equal "Hello World\n", iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
46
|
+
assert_raise IO::TimeOutError do
|
47
|
+
iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
48
|
+
end
|
49
|
+
oStdIN.write_flushed "Test String\n"
|
50
|
+
assert_equal "Hello Test String\n", iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
51
|
+
assert_equal '', iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
52
|
+
assert iChildProcess.exited?
|
53
|
+
next true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def testInteractiveSTDERR
|
58
|
+
ProcessPilot::pilot(*getInteractiveCmdLineSTDERR) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
59
|
+
assert_raise IO::TimeOutError do
|
60
|
+
iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
61
|
+
end
|
62
|
+
assert_equal "Hello World\n", iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
63
|
+
assert_raise IO::TimeOutError do
|
64
|
+
iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
65
|
+
end
|
66
|
+
oStdIN.write_flushed "Test String\n"
|
67
|
+
assert_equal '', iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
68
|
+
assert_equal "Hello Test String\n", iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
69
|
+
assert_equal '', iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
70
|
+
assert iChildProcess.exited?
|
71
|
+
next true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def testInteractiveWithPromptSTDOUT
|
76
|
+
ProcessPilot::pilot(*getInteractivePromptCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
77
|
+
assert_equal "Hello World\n", iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
78
|
+
assert_equal 'Enter string: ', iStdOUT.read_blocking(14, :ChildProcess => iChildProcess)
|
79
|
+
assert_raise IO::TimeOutError do
|
80
|
+
iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
81
|
+
end
|
82
|
+
oStdIN.write_flushed "Test String\n"
|
83
|
+
assert_equal "Hello Test String\n", iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
84
|
+
assert_equal '', iStdOUT.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
85
|
+
assert iChildProcess.exited?
|
86
|
+
next true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def testInteractiveWithPromptSTDERR
|
91
|
+
ProcessPilot::pilot(*getInteractivePromptCmdLineSTDERR) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
92
|
+
assert_equal "Hello World\n", iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
93
|
+
assert_equal 'Enter string: ', iStdERR.read_blocking(14, :ChildProcess => iChildProcess)
|
94
|
+
assert_raise IO::TimeOutError do
|
95
|
+
iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
96
|
+
end
|
97
|
+
oStdIN.write_flushed "Test String\n"
|
98
|
+
assert_equal "Hello Test String\n", iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
99
|
+
assert_equal '', iStdERR.gets_blocking(:TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
100
|
+
assert iChildProcess.exited?
|
101
|
+
next true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def testSeveralPrompts
|
106
|
+
ProcessPilot::pilot(*getInteractiveSeveralPrompts) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
107
|
+
assert_testing_scenario(oStdIN, iStdOUT, iStdERR, iChildProcess)
|
108
|
+
next true
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module ProcessPilotTest
|
7
|
+
|
8
|
+
class Ruby < ::Test::Unit::TestCase
|
9
|
+
|
10
|
+
include ProcessPilotTest::Common
|
11
|
+
|
12
|
+
def testSyncedSTDOUT
|
13
|
+
ProcessPilot::pilot(*getSyncedRubyCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
14
|
+
assert_testing_scenario(oStdIN, iStdOUT, iStdERR, iChildProcess)
|
15
|
+
next true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def testNormalSTDOUT
|
20
|
+
ProcessPilot::pilot(*getNormalRubyCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
21
|
+
assert_raise IO::TimeOutError do
|
22
|
+
iStdOUT.read_blocking(1, :TimeOutSecs => 1, :ChildProcess => iChildProcess)
|
23
|
+
end
|
24
|
+
iChildProcess.stop
|
25
|
+
next true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def testNormalSTDOUTWithForceSync
|
30
|
+
ProcessPilot::pilot(*getNormalRubyWithSyncCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
31
|
+
assert_testing_scenario(oStdIN, iStdOUT, iStdERR, iChildProcess)
|
32
|
+
next true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module ProcessPilotTest
|
7
|
+
|
8
|
+
module Scenario
|
9
|
+
|
10
|
+
# Execute the testing scenario
|
11
|
+
def self.run
|
12
|
+
$stdout.puts 'STDOUT Line 1'
|
13
|
+
$stdout.write 'Enter string 1 from STDOUT: '
|
14
|
+
lVar = $stdin.gets
|
15
|
+
$stdout.puts "STDOUT Line 2 #{lVar}"
|
16
|
+
$stderr.puts 'STDERR Line 1'
|
17
|
+
$stderr.write 'Enter string 2 from STDERR: '
|
18
|
+
lVar = $stdin.gets
|
19
|
+
$stdout.puts "STDOUT Line 3 #{lVar}"
|
20
|
+
$stderr.puts 'STDERR Line 2'
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
$stdout.sync = true
|
7
|
+
|
8
|
+
require "#{File.dirname(__FILE__)}/Scenario.rb"
|
9
|
+
|
10
|
+
ProcessPilotTest::Scenario::run
|
data/test/run.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2012 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
$ProcessPilotTest_Debug = true
|
7
|
+
|
8
|
+
require 'test/unit'
|
9
|
+
require 'rUtilAnts/Logging'
|
10
|
+
RUtilAnts::Logging::initializeLogging('', '')
|
11
|
+
activateLogDebug($ProcessPilotTest_Debug)
|
12
|
+
require 'rUtilAnts/Misc'
|
13
|
+
RUtilAnts::Misc::initializeMisc
|
14
|
+
require 'rUtilAnts/Platform'
|
15
|
+
RUtilAnts::Platform::initializePlatform
|
16
|
+
|
17
|
+
$ProcessPilotTest_RootPath = File.expand_path("#{File.dirname(__FILE__)}/..")
|
18
|
+
|
19
|
+
# Add the test directory to the current load path
|
20
|
+
$: << "#{$ProcessPilotTest_RootPath}/test"
|
21
|
+
# And the lib one too
|
22
|
+
$: << "#{$ProcessPilotTest_RootPath}/lib"
|
23
|
+
|
24
|
+
# Require the main library
|
25
|
+
require 'processpilot/processpilot'
|
26
|
+
|
27
|
+
# Load test files to execute
|
28
|
+
require 'ProcessPilotTest/Common'
|
29
|
+
require 'ProcessPilotTest/NonRuby'
|
30
|
+
require 'ProcessPilotTest/Ruby'
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ProcessPilot
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 20120118
|
10
|
+
version: 0.0.1.20120118
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Muriel Salvan
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-01-18 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rUtilAnts
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 3
|
32
|
+
version: "0.3"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: childprocess
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
- 2
|
46
|
+
- 3
|
47
|
+
version: 0.2.3
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
description: Ruby library giving a simple way to pilot an external process' stdin, stdout and stderr in real time. Very useful for interactive processes testing or automation.
|
51
|
+
email: muriel@x-aeon.com
|
52
|
+
executables: []
|
53
|
+
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
extra_rdoc_files: []
|
57
|
+
|
58
|
+
files:
|
59
|
+
- AUTHORS
|
60
|
+
- ChangeLog
|
61
|
+
- Credits
|
62
|
+
- lib/processpilot/processpilot.rb
|
63
|
+
- lib/processpilot/wrapper.rb
|
64
|
+
- LICENSE
|
65
|
+
- README
|
66
|
+
- ReleaseInfo
|
67
|
+
- test/ProcessPilotTest/Common.rb
|
68
|
+
- test/ProcessPilotTest/NonRuby.rb
|
69
|
+
- test/ProcessPilotTest/Ruby.rb
|
70
|
+
- test/Programs/Bash/Interactive.sh
|
71
|
+
- test/Programs/Bash/InteractivePrompt.sh
|
72
|
+
- test/Programs/Bash/InteractivePromptSTDERR.sh
|
73
|
+
- test/Programs/Bash/InteractiveSeveralPrompts.sh
|
74
|
+
- test/Programs/Bash/InteractiveSTDERR.sh
|
75
|
+
- test/Programs/Bash/NotInteractive.sh
|
76
|
+
- test/Programs/Bash/NotInteractiveSTDERR.sh
|
77
|
+
- test/Programs/Ruby/NormalSTDOUT.rb
|
78
|
+
- test/Programs/Ruby/Scenario.rb
|
79
|
+
- test/Programs/Ruby/SyncedSTDOUT.rb
|
80
|
+
- test/Programs/Windows/Interactive.bat
|
81
|
+
- test/Programs/Windows/InteractivePrompt.bat
|
82
|
+
- test/Programs/Windows/InteractivePromptSTDERR.bat
|
83
|
+
- test/Programs/Windows/InteractiveSeveralPrompts.bat
|
84
|
+
- test/Programs/Windows/InteractiveSTDERR.bat
|
85
|
+
- test/Programs/Windows/NotInteractive.bat
|
86
|
+
- test/Programs/Windows/NotInteractiveSTDERR.bat
|
87
|
+
- test/run.rb
|
88
|
+
has_rdoc: true
|
89
|
+
homepage: http://processpilot.sourceforge.net/
|
90
|
+
licenses: []
|
91
|
+
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
version: "0"
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
version: "0"
|
113
|
+
requirements: []
|
114
|
+
|
115
|
+
rubyforge_project: processpilot
|
116
|
+
rubygems_version: 1.3.7
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: Ruby library to pilot interactive command line processes in real time.
|
120
|
+
test_files:
|
121
|
+
- test/run.rb
|