2 # Copyright 2008, Google Inc.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 """Simple testing harness for running commands and checking expected output.
34 This harness is used instead of shell scripts to ensure windows compatibility
54 def DifferentFromGolden(actual
, golden
, output_type
, fail_msg
):
55 """Compares actual output against golden output.
57 If there are any differences, output an error message (to stdout) with
61 actual: actual output from the program under test, as a single
64 golden: expected output from the program under test, as a single
67 output_type: the name / title for the output type being compared.
68 Used in banner output.
70 fail_msg: additional failure output message, printed at the end.
73 True when there is a difference, False otherwise.
76 diff
= list(test_lib
.DiffStringsIgnoringWhiteSpace(actual
, golden
))
77 diff
= '\n'.join(diff
)
79 Banner('Error %s diff found' % output_type
)
81 Banner('Potential New Golden Output')
97 'stdout_golden': None,
98 'stderr_golden': None,
101 'stdout_filter': None,
102 'stderr_filter': None,
107 def ProcessOptions(argv
):
108 """Process command line options and return the unprocessed left overs."""
110 opts
, args
= getopt
.getopt(argv
, '', [x
+ '=' for x
in GlobalSettings
])
111 except getopt
.GetoptError
, err
:
112 print str(err
) # will print something like 'option -a not recognized'
116 # strip the leading '--'
118 assert option
in GlobalSettings
119 if type(GlobalSettings
[option
]) == int:
120 GlobalSettings
[option
] = int(a
)
122 GlobalSettings
[option
] = a
123 # return the unprocessed options, i.e. the command
127 def FailureMessage():
128 return 'FAILED %s' % GlobalSettings
['name']
131 def SuccessMessage():
132 return 'PASSED %s' % GlobalSettings
['name']
136 command
= ProcessOptions(argv
)
138 if not GlobalSettings
['name']:
139 GlobalSettings
['name'] = command
[0]
141 if GlobalSettings
['osenv']:
142 env
= GlobalSettings
['osenv'].split(',')
144 key
, val
= e
.split('=')
147 if GlobalSettings
['logout']:
149 os
.unlink(GlobalSettings
['logout']) # might not pre-exist
154 if GlobalSettings
['stdin']:
155 stdin_data
= open(GlobalSettings
['stdin']).read()
157 Banner('running %s' % str(command
))
158 _
, exit_status
, failed
, stdout
, stderr
= test_lib
.RunTestWithInputOutput(
161 if exit_status
!= GlobalSettings
['exit_status'] or failed
:
163 print 'command failed'
165 print 'command returned unexpected exit status ', exit_status
170 print FailureMessage()
173 if GlobalSettings
['stdout_golden']:
174 stdout_golden
= open(GlobalSettings
['stdout_golden']).read()
175 if GlobalSettings
['stdout_filter']:
176 stdout
= test_lib
.RegexpFilterLines(GlobalSettings
['stdout_filter'],
178 if DifferentFromGolden(stdout
, stdout_golden
, 'Stdout', FailureMessage()):
181 if GlobalSettings
['stderr_golden']:
182 stderr_golden
= open(GlobalSettings
['stderr_golden']).read()
183 if GlobalSettings
['stderr_filter']:
184 stderr
= test_lib
.RegexpFilterLines(GlobalSettings
['stderr_filter'],
186 if DifferentFromGolden(stderr
, stderr_golden
, 'Stderr', FailureMessage()):
189 if GlobalSettings
['log_golden']:
190 log_golden
= open(GlobalSettings
['log_golden']).read()
191 if GlobalSettings
['log_filter']:
192 log
= open(GlobalSettings
['logout']).read()
193 log
= test_lib
.RegexpFilterLines(GlobalSettings
['log_filter'],
195 if DifferentFromGolden(log
, log_golden
, 'Log', FailureMessage()):
198 print SuccessMessage()
202 if __name__
== '__main__':
203 sys
.exit(main(sys
.argv
[1:]))