ProcessPilot 0.0.1.20120118 → 1.0.0.20120124
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +8 -0
- data/Credits +0 -5
- data/README +2 -2
- data/ReleaseInfo +1 -1
- data/lib/processpilot/processpilot.rb +60 -140
- data/test/ProcessPilotTest/Common.rb +19 -19
- data/test/ProcessPilotTest/NonRuby.rb +37 -47
- data/test/ProcessPilotTest/Ruby.rb +2 -5
- data/test/Programs/Bash/InteractiveSeveralPrompts.sh +5 -5
- data/test/Programs/Ruby/Scenario.rb +5 -5
- data/test/Programs/Windows/InteractiveSTDERR.bat +2 -2
- data/test/Programs/Windows/InteractiveSeveralPrompts.bat +6 -5
- metadata +4 -19
data/ChangeLog
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
= Process Pilot Release History
|
2
2
|
|
3
|
+
== 1.0.0.20120124 (Beta)
|
4
|
+
|
5
|
+
* Removed dependency on ChildProcess: now uses Open3
|
6
|
+
* Client code does not need to return the value to wait for the process
|
7
|
+
* Client code now receives a ChildProcessInfo parameter in 4th position that might be nil on some platforms
|
8
|
+
* Replaced IO::gets_blocking and IO::read_blocking with IO::gets and IO::read taking an optional :TimeOutSecs option
|
9
|
+
* Regression: Added some dots and removed some quotes at the end of echoed lines for Windows compatibility
|
10
|
+
|
3
11
|
== 0.0.1.20120118 (Beta)
|
4
12
|
|
5
13
|
* Initial public release.
|
data/Credits
CHANGED
@@ -1,10 +1,5 @@
|
|
1
1
|
= Projects used by Process Pilot
|
2
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
3
|
== Ruby
|
9
4
|
* Yukihiro « matz » Matsumoto (http://www.rubyist.net/~matz/)
|
10
5
|
* http://www.ruby-lang.org/
|
data/README
CHANGED
@@ -11,8 +11,8 @@ Check the website at http://processpilot.sourceforge.net
|
|
11
11
|
|
12
12
|
== Who wrote it ?
|
13
13
|
|
14
|
-
Check the AUTHORS[link:
|
14
|
+
Check the AUTHORS[link:AUTHORS.html] file.
|
15
15
|
|
16
16
|
== What is the license ?
|
17
17
|
|
18
|
-
You can find out in the LICENSE[link:
|
18
|
+
You can find out in the LICENSE[link:LICENSE.html] file.
|
data/ReleaseInfo
CHANGED
@@ -3,11 +3,36 @@
|
|
3
3
|
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
4
|
#++
|
5
5
|
|
6
|
-
require '
|
7
|
-
require '
|
6
|
+
require 'open3'
|
7
|
+
require 'timeout'
|
8
8
|
|
9
9
|
module ProcessPilot
|
10
10
|
|
11
|
+
class ChildProcessInfo
|
12
|
+
|
13
|
+
# Constructor
|
14
|
+
#
|
15
|
+
# Parameters:
|
16
|
+
# * *iWaitThread* (_Thread_): The waiting thread, can be nil if already stopped or dead
|
17
|
+
def initialize(iWaitThread)
|
18
|
+
@WaitThread = iWaitThread
|
19
|
+
end
|
20
|
+
|
21
|
+
# Has the waiting process exited already ?
|
22
|
+
#
|
23
|
+
# Return:
|
24
|
+
# * _Boolean_: Has the waiting process exited already ?
|
25
|
+
def exited?
|
26
|
+
return ((@WaitThread == nil) or (@WaitThread.stop?))
|
27
|
+
end
|
28
|
+
|
29
|
+
# Stop the process' execution
|
30
|
+
def stop
|
31
|
+
@WaitThread.kill if @WaitThread
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
11
36
|
# Pilot a process.
|
12
37
|
# This will create a new thread for the process to be run.
|
13
38
|
# 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]).
|
@@ -23,9 +48,7 @@ module ProcessPilot
|
|
23
48
|
# ** *oStdIN* (_IO_): The process' STDIN
|
24
49
|
# ** *iStdOUT* (_IO_): The process' STDOUT
|
25
50
|
# ** *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 ?
|
51
|
+
# ** *iChildProcess* (_ChildProcess_): The corresponding child process. Don't use it to pilot std* IO objects. Depending on the platforms, this might be nil.
|
29
52
|
def self.pilot(*iArgs)
|
30
53
|
iCmdLine = iArgs
|
31
54
|
iOptions = (iArgs[-1].is_a?(Hash)) ? iArgs.pop : {}
|
@@ -43,40 +66,9 @@ module ProcessPilot
|
|
43
66
|
lRealCmdLine = (iForceRubyProcessSync) ? iRubyCmdLine + [ "#{File.dirname(__FILE__)}/wrapper.rb" ] + iCmdLine : iCmdLine
|
44
67
|
|
45
68
|
logDebug "[ProcessPilot] Command line: #{lRealCmdLine.inspect}" if iDebug
|
46
|
-
|
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
|
69
|
+
Open3::popen3(*lRealCmdLine) do |oStdIN, iStdOUT, iStdERR, iWaitThread|
|
70
|
+
yield(oStdIN, iStdOUT, iStdERR, ChildProcessInfo.new(iWaitThread))
|
78
71
|
end
|
79
|
-
|
80
72
|
end
|
81
73
|
|
82
74
|
end
|
@@ -84,114 +76,42 @@ end
|
|
84
76
|
# Define some helpers that can be handy in case of process piloting from IO
|
85
77
|
class IO
|
86
78
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
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)
|
79
|
+
alias :gets_ORG_ProcessPilot :gets
|
80
|
+
# Add the possibility to gets to take an optional Hash:
|
81
|
+
# *:TimeOutSecs* (_Integer_): Timeout in seconds to read data. nil means no timeout (regular gets) [optional = nil].
|
82
|
+
def gets(*iArgs)
|
83
|
+
if (iArgs[-1].is_a?(Hash))
|
84
|
+
lOptions = iArgs[-1]
|
85
|
+
lTimeOutSecs = lOptions[:TimeOutSecs]
|
86
|
+
if (lTimeOutSecs == nil)
|
87
|
+
return gets_ORG_ProcessPilot(*iArgs[0..-2])
|
88
|
+
else
|
89
|
+
return Timeout::timeout(lTimeOutSecs) do
|
90
|
+
next gets_ORG_ProcessPilot(*iArgs[0..-2])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
else
|
94
|
+
return gets_ORG_ProcessPilot(*iArgs)
|
131
95
|
end
|
132
96
|
end
|
133
97
|
|
134
|
-
|
135
|
-
#
|
136
|
-
#
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
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))
|
98
|
+
alias :read_ORG_ProcessPilot :read
|
99
|
+
# Add the possibility to gets to take an optional Hash:
|
100
|
+
# *:TimeOutSecs* (_Integer_): Timeout in seconds to read data. nil means no timeout (regular gets) [optional = nil].
|
101
|
+
def read(*iArgs)
|
102
|
+
if (iArgs[-1].is_a?(Hash))
|
103
|
+
lOptions = iArgs[-1]
|
104
|
+
lTimeOutSecs = lOptions[:TimeOutSecs]
|
105
|
+
if (lTimeOutSecs == nil)
|
106
|
+
return read_ORG_ProcessPilot(*iArgs[0..-2])
|
107
|
+
else
|
108
|
+
return Timeout::timeout(lTimeOutSecs) do
|
109
|
+
next read_ORG_ProcessPilot(*iArgs[0..-2])
|
188
110
|
end
|
189
111
|
end
|
190
|
-
|
191
|
-
|
112
|
+
else
|
113
|
+
return read_ORG_ProcessPilot(*iArgs)
|
192
114
|
end
|
193
|
-
|
194
|
-
return rStr
|
195
115
|
end
|
196
116
|
|
197
117
|
end
|
@@ -210,29 +210,29 @@ module ProcessPilotTest
|
|
210
210
|
# * *iStdERR* (_IO_): STDERR
|
211
211
|
# * *iChildProcess* (_ChildProcess_): Corresponding ChildProcess
|
212
212
|
def assert_testing_scenario(oStdIN, iStdOUT, iStdERR, iChildProcess)
|
213
|
-
assert_equal "STDOUT Line 1
|
214
|
-
assert_equal 'Enter string 1 from STDOUT: ', iStdOUT.
|
215
|
-
assert_raise
|
216
|
-
iStdERR.
|
213
|
+
assert_equal "STDOUT Line 1.\n", iStdOUT.gets(:TimeOutSecs => 1)
|
214
|
+
assert_equal 'Enter string 1 from STDOUT: ', iStdOUT.read(28)
|
215
|
+
assert_raise Timeout::Error do
|
216
|
+
iStdERR.read(1, :TimeOutSecs => 1)
|
217
217
|
end
|
218
|
-
assert_raise
|
219
|
-
iStdOUT.
|
218
|
+
assert_raise Timeout::Error do
|
219
|
+
iStdOUT.read(1, :TimeOutSecs => 1)
|
220
220
|
end
|
221
|
-
oStdIN.
|
222
|
-
assert_equal "STDOUT Line 2 Test String 1\n", iStdOUT.
|
223
|
-
assert_equal "STDERR Line 1
|
224
|
-
assert_equal 'Enter string 2 from STDERR: ', iStdERR.
|
225
|
-
assert_raise
|
226
|
-
iStdERR.
|
221
|
+
oStdIN.write "Test String 1\n"
|
222
|
+
assert_equal "STDOUT Line 2: Test String 1\n", iStdOUT.gets(:TimeOutSecs => 1)
|
223
|
+
assert_equal "STDERR Line 1.\n", iStdERR.gets(:TimeOutSecs => 1)
|
224
|
+
assert_equal 'Enter string 2 from STDERR: ', iStdERR.read(28)
|
225
|
+
assert_raise Timeout::Error do
|
226
|
+
iStdERR.read(1, :TimeOutSecs => 1)
|
227
227
|
end
|
228
|
-
assert_raise
|
229
|
-
iStdOUT.
|
228
|
+
assert_raise Timeout::Error do
|
229
|
+
iStdOUT.read(1, :TimeOutSecs => 1)
|
230
230
|
end
|
231
|
-
oStdIN.
|
232
|
-
assert_equal "STDOUT Line 3 Test String 2\n", iStdOUT.
|
233
|
-
assert_equal "STDERR Line 2
|
234
|
-
assert_equal
|
235
|
-
assert_equal
|
231
|
+
oStdIN.write "Test String 2\n"
|
232
|
+
assert_equal "STDOUT Line 3: Test String 2\n", iStdOUT.gets(:TimeOutSecs => 1)
|
233
|
+
assert_equal "STDERR Line 2.\n", iStdERR.gets(:TimeOutSecs => 1)
|
234
|
+
assert_equal nil, iStdOUT.gets(:TimeOutSecs => 1)
|
235
|
+
assert_equal nil, iStdERR.gets(:TimeOutSecs => 1)
|
236
236
|
assert iChildProcess.exited?
|
237
237
|
end
|
238
238
|
|
@@ -11,101 +11,91 @@ module ProcessPilotTest
|
|
11
11
|
|
12
12
|
def testNotInteractiveSTDOUT
|
13
13
|
ProcessPilot::pilot(*getNotInteractiveCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
14
|
-
assert_equal "Hello World\n", iStdOUT.
|
15
|
-
|
16
|
-
iStdERR.gets_blocking(:TimeOutSecs => 1)
|
17
|
-
end
|
14
|
+
assert_equal "Hello World\n", iStdOUT.gets(:TimeOutSecs => 1)
|
15
|
+
assert_nil iStdERR.gets
|
18
16
|
assert iChildProcess.exited?
|
19
|
-
next true
|
20
17
|
end
|
21
18
|
end
|
22
19
|
|
23
20
|
def testNotInteractiveSTDOUTEndOfProcess
|
24
21
|
ProcessPilot::pilot(*getNotInteractiveCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
25
|
-
assert_equal "Hello World\n", iStdOUT.
|
26
|
-
assert_equal
|
27
|
-
assert_equal
|
22
|
+
assert_equal "Hello World\n", iStdOUT.gets(:TimeOutSecs => 1)
|
23
|
+
assert_equal nil, iStdOUT.gets(:TimeOutSecs => 1)
|
24
|
+
assert_equal nil, iStdERR.gets(:TimeOutSecs => 1)
|
28
25
|
assert iChildProcess.exited?
|
29
|
-
next true
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
33
29
|
def testNotInteractiveSTDERR
|
34
30
|
ProcessPilot::pilot(*getNotInteractiveCmdLineSTDERR) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
35
|
-
assert_equal
|
36
|
-
assert_equal "Hello World\n", iStdERR.
|
37
|
-
assert_equal
|
31
|
+
assert_equal nil, iStdOUT.gets(:TimeOutSecs => 1)
|
32
|
+
assert_equal "Hello World\n", iStdERR.gets(:TimeOutSecs => 1)
|
33
|
+
assert_equal nil, iStdERR.gets(:TimeOutSecs => 1)
|
38
34
|
assert iChildProcess.exited?
|
39
|
-
next true
|
40
35
|
end
|
41
36
|
end
|
42
37
|
|
43
38
|
def testInteractiveSTDOUT
|
44
39
|
ProcessPilot::pilot(*getInteractiveCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
45
|
-
assert_equal "Hello World\n", iStdOUT.
|
46
|
-
assert_raise
|
47
|
-
iStdOUT.
|
40
|
+
assert_equal "Hello World\n", iStdOUT.gets(:TimeOutSecs => 1)
|
41
|
+
assert_raise Timeout::Error do
|
42
|
+
iStdOUT.gets(:TimeOutSecs => 1)
|
48
43
|
end
|
49
|
-
oStdIN.
|
50
|
-
assert_equal "Hello Test String\n", iStdOUT.
|
51
|
-
assert_equal
|
44
|
+
oStdIN.write "Test String\n"
|
45
|
+
assert_equal "Hello Test String\n", iStdOUT.gets(:TimeOutSecs => 1)
|
46
|
+
assert_equal nil, iStdOUT.gets(:TimeOutSecs => 1)
|
52
47
|
assert iChildProcess.exited?
|
53
|
-
next true
|
54
48
|
end
|
55
49
|
end
|
56
50
|
|
57
51
|
def testInteractiveSTDERR
|
58
52
|
ProcessPilot::pilot(*getInteractiveCmdLineSTDERR) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
59
|
-
assert_raise
|
60
|
-
iStdOUT.
|
53
|
+
assert_raise Timeout::Error do
|
54
|
+
iStdOUT.gets(:TimeOutSecs => 1)
|
61
55
|
end
|
62
|
-
assert_equal "Hello World\n", iStdERR.
|
63
|
-
assert_raise
|
64
|
-
iStdERR.
|
56
|
+
assert_equal "Hello World\n", iStdERR.gets(:TimeOutSecs => 1)
|
57
|
+
assert_raise Timeout::Error do
|
58
|
+
iStdERR.gets(:TimeOutSecs => 1)
|
65
59
|
end
|
66
|
-
oStdIN.
|
67
|
-
assert_equal
|
68
|
-
assert_equal "Hello Test String\n", iStdERR.
|
69
|
-
assert_equal
|
60
|
+
oStdIN.write "Test String\n"
|
61
|
+
assert_equal nil, iStdOUT.gets(:TimeOutSecs => 1)
|
62
|
+
assert_equal "Hello Test String\n", iStdERR.gets(:TimeOutSecs => 1)
|
63
|
+
assert_equal nil, iStdERR.gets(:TimeOutSecs => 1)
|
70
64
|
assert iChildProcess.exited?
|
71
|
-
next true
|
72
65
|
end
|
73
66
|
end
|
74
67
|
|
75
68
|
def testInteractiveWithPromptSTDOUT
|
76
69
|
ProcessPilot::pilot(*getInteractivePromptCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
77
|
-
assert_equal "Hello World\n", iStdOUT.
|
78
|
-
assert_equal 'Enter string: ', iStdOUT.
|
79
|
-
assert_raise
|
80
|
-
iStdOUT.
|
70
|
+
assert_equal "Hello World\n", iStdOUT.gets(:TimeOutSecs => 1)
|
71
|
+
assert_equal 'Enter string: ', iStdOUT.read(14)
|
72
|
+
assert_raise Timeout::Error do
|
73
|
+
iStdOUT.gets(:TimeOutSecs => 1)
|
81
74
|
end
|
82
|
-
oStdIN.
|
83
|
-
assert_equal "Hello Test String\n", iStdOUT.
|
84
|
-
assert_equal
|
75
|
+
oStdIN.write "Test String\n"
|
76
|
+
assert_equal "Hello Test String\n", iStdOUT.gets(:TimeOutSecs => 1)
|
77
|
+
assert_equal nil, iStdOUT.gets(:TimeOutSecs => 1)
|
85
78
|
assert iChildProcess.exited?
|
86
|
-
next true
|
87
79
|
end
|
88
80
|
end
|
89
81
|
|
90
82
|
def testInteractiveWithPromptSTDERR
|
91
83
|
ProcessPilot::pilot(*getInteractivePromptCmdLineSTDERR) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
92
|
-
assert_equal "Hello World\n", iStdERR.
|
93
|
-
assert_equal 'Enter string: ', iStdERR.
|
94
|
-
assert_raise
|
95
|
-
iStdERR.
|
84
|
+
assert_equal "Hello World\n", iStdERR.gets(:TimeOutSecs => 1)
|
85
|
+
assert_equal 'Enter string: ', iStdERR.read(14)
|
86
|
+
assert_raise Timeout::Error do
|
87
|
+
iStdERR.gets(:TimeOutSecs => 1)
|
96
88
|
end
|
97
|
-
oStdIN.
|
98
|
-
assert_equal "Hello Test String\n", iStdERR.
|
99
|
-
assert_equal
|
89
|
+
oStdIN.write "Test String\n"
|
90
|
+
assert_equal "Hello Test String\n", iStdERR.gets(:TimeOutSecs => 1)
|
91
|
+
assert_equal nil, iStdERR.gets(:TimeOutSecs => 1)
|
100
92
|
assert iChildProcess.exited?
|
101
|
-
next true
|
102
93
|
end
|
103
94
|
end
|
104
95
|
|
105
96
|
def testSeveralPrompts
|
106
97
|
ProcessPilot::pilot(*getInteractiveSeveralPrompts) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
107
98
|
assert_testing_scenario(oStdIN, iStdOUT, iStdERR, iChildProcess)
|
108
|
-
next true
|
109
99
|
end
|
110
100
|
end
|
111
101
|
|
@@ -12,24 +12,21 @@ module ProcessPilotTest
|
|
12
12
|
def testSyncedSTDOUT
|
13
13
|
ProcessPilot::pilot(*getSyncedRubyCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
14
14
|
assert_testing_scenario(oStdIN, iStdOUT, iStdERR, iChildProcess)
|
15
|
-
next true
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
19
18
|
def testNormalSTDOUT
|
20
19
|
ProcessPilot::pilot(*getNormalRubyCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
21
|
-
assert_raise
|
22
|
-
iStdOUT.
|
20
|
+
assert_raise Timeout::Error do
|
21
|
+
iStdOUT.read(1, :TimeOutSecs => 1)
|
23
22
|
end
|
24
23
|
iChildProcess.stop
|
25
|
-
next true
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
27
|
def testNormalSTDOUTWithForceSync
|
30
28
|
ProcessPilot::pilot(*getNormalRubyWithSyncCmdLine) do |oStdIN, iStdOUT, iStdERR, iChildProcess|
|
31
29
|
assert_testing_scenario(oStdIN, iStdOUT, iStdERR, iChildProcess)
|
32
|
-
next true
|
33
30
|
end
|
34
31
|
end
|
35
32
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
|
3
|
-
echo "STDOUT Line 1"
|
3
|
+
echo "STDOUT Line 1."
|
4
4
|
echo -n "Enter string 1 from STDOUT: "
|
5
5
|
read VAR
|
6
|
-
echo "STDOUT Line 2 ${VAR}"
|
7
|
-
echo "STDERR Line 1" >&2
|
6
|
+
echo "STDOUT Line 2: ${VAR}"
|
7
|
+
echo "STDERR Line 1." >&2
|
8
8
|
echo -n "Enter string 2 from STDERR: " >&2
|
9
9
|
read VAR
|
10
|
-
echo "STDOUT Line 3 ${VAR}"
|
11
|
-
echo "STDERR Line 2" >&2
|
10
|
+
echo "STDOUT Line 3: ${VAR}"
|
11
|
+
echo "STDERR Line 2." >&2
|
@@ -9,15 +9,15 @@ module ProcessPilotTest
|
|
9
9
|
|
10
10
|
# Execute the testing scenario
|
11
11
|
def self.run
|
12
|
-
$stdout.puts 'STDOUT Line 1'
|
12
|
+
$stdout.puts 'STDOUT Line 1.'
|
13
13
|
$stdout.write 'Enter string 1 from STDOUT: '
|
14
14
|
lVar = $stdin.gets
|
15
|
-
$stdout.puts "STDOUT Line 2 #{lVar}"
|
16
|
-
$stderr.puts 'STDERR Line 1'
|
15
|
+
$stdout.puts "STDOUT Line 2: #{lVar}"
|
16
|
+
$stderr.puts 'STDERR Line 1.'
|
17
17
|
$stderr.write 'Enter string 2 from STDERR: '
|
18
18
|
lVar = $stdin.gets
|
19
|
-
$stdout.puts "STDOUT Line 3 #{lVar}"
|
20
|
-
$stderr.puts 'STDERR Line 2'
|
19
|
+
$stdout.puts "STDOUT Line 3: #{lVar}"
|
20
|
+
$stderr.puts 'STDERR Line 2.'
|
21
21
|
end
|
22
22
|
|
23
23
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
@echo off
|
2
|
-
echo STDOUT Line 1
|
2
|
+
echo STDOUT Line 1.
|
3
3
|
set /p var="Enter string 1 from STDOUT: " %=%
|
4
|
-
echo STDOUT Line 2 %var%
|
5
|
-
|
4
|
+
echo STDOUT Line 2: %var%
|
5
|
+
set line=
|
6
|
+
echo STDERR Line 1.>&2
|
6
7
|
echo/|set /p ="Enter string 2 from STDERR: " >&2
|
7
8
|
set /p var= %=%
|
8
|
-
echo STDOUT Line 3 %var%
|
9
|
-
echo
|
9
|
+
echo STDOUT Line 3: %var%
|
10
|
+
echo STDERR Line 2.>&2
|
metadata
CHANGED
@@ -3,11 +3,11 @@ name: ProcessPilot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
|
+
- 1
|
6
7
|
- 0
|
7
8
|
- 0
|
8
|
-
-
|
9
|
-
|
10
|
-
version: 0.0.1.20120118
|
9
|
+
- 20120124
|
10
|
+
version: 1.0.0.20120124
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Muriel Salvan
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-01-
|
18
|
+
date: 2012-01-24 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -32,21 +32,6 @@ dependencies:
|
|
32
32
|
version: "0.3"
|
33
33
|
type: :runtime
|
34
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
35
|
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
36
|
email: muriel@x-aeon.com
|
52
37
|
executables: []
|