5 class ChildError(Exception):
6 "Raised when the child process reports an error."
10 """Return text with \ and ' escaped"""
11 return text
.replace("\\", "\\\\").replace("'", "\\'")
14 "Create a Temporary file with a random name."
16 name
= `random
.randint(1, 1000000)`
+ '-archive'
18 return tempfile
.TemporaryFile(suffix
= name
)
20 def pipe_through_command(command
, src
, dst
):
21 """Execute 'command' with src as stdin (if any) and writing to
22 stream dst. src must be a fileno() stream, but dst need not be.
23 Either stream may be None if input or output is not required.
24 Raises an Exception with a suitable message if the command
25 writes to stderr or returns a non-zero exit status."""
27 assert src
is None or hasattr(src
, 'fileno')
29 # Output to 'dst' directly if it's a fileno stream. Otherwise,
30 # send output to a temporary file.
32 if hasattr(dst
, 'fileno'):
37 fd
= tmp_stream
.fileno()
41 # Create a pipe to collect stderr from child
42 stderr_r
, stderr_w
= os
.pipe()
51 # This is the child process
56 os
.dup2(src
.fileno(), 0)
59 if os
.system(command
) == 0:
60 os
._exit
(0) # No error code or signal
65 # This is the parent process
68 # Read until child closes stderr (by quitting)
71 got
= os
.read(stderr_r
, 100)
75 errors
= errors
.strip()
78 pid
, status
= os
.waitpid(child
, 0)
81 raise ChildError("Errors from command '%s':\n%s" % (command
, errors
))
83 raise ChildError("Command '%s' returned an error code!" % command
)
85 # If dst wasn't a fileno stream, copy from the temp file to it
86 if dst
and tmp_stream
is not dst
:
88 dst
.write(tmp_stream
.read())
91 "Check that this module works."
94 error
= sys
.exc_info()[1]
95 print "(error reported was '%s')" % error
97 print "Test escape()..."
99 assert escape(''' a test ''') == ' a test '
100 assert escape(''' "a's test" ''') == ''' "a\\'s test" '''
101 assert escape(''' "a\\'s test" ''') == ''' "a\\\\\\'s test" '''
103 print "Test Tmp()..."
109 os
.write(file.fileno(), 'World')
112 assert file.read() == 'Hello World'
114 print "Test pipe_through_command():"
116 print "Try an invalid command..."
118 pipe_through_command('bad_command_1234', None, None)
125 print "Try a valid command..."
126 pipe_through_command('exit 0', None, None)
128 print "Writing to a non-fileno stream..."
129 from cStringIO
import StringIO
131 pipe_through_command('echo Hello', None, a
)
132 assert a
.getvalue() == 'Hello\n'
134 print "Reading from a stream to a StringIO..."
136 pipe_through_command('cat', file, a
)
137 assert a
.getvalue() == 'Hello\nello World'
139 print "Writing to a fileno stream..."
142 pipe_through_command('echo Foo', None, file)
144 assert file.read() == 'Foo\n'
146 print "Read and write fileno streams..."
152 pipe_through_command('cat', src
, file)
154 assert file.read() == '123'
156 print "Detect non-zero exit value..."
158 pipe_through_command('exit 1', None, None)
164 print "Detect writes to stderr..."
166 pipe_through_command('echo one >&2; sleep 2; echo two >&2', None, None)
172 print "All tests passed!"
174 if __name__
== '__main__':