55
58
Input lines start with '<'.
56
59
Output lines start with nothing.
57
60
Error lines start with '2>'.
62
:return: A sequence of ([args], input, output, errors), where the args are
63
split in to words, and the input, output, and errors are just strings,
64
typically containing newlines.
75
82
input, output, error = None, None, None
76
for line in text.split('\n'):
83
text = textwrap.dedent(text)
84
lines = text.split('\n')
85
# to make use of triple-quoted strings easier, we ignore a blank line
86
# right at the start and right at the end; the rest are meaningful
87
if lines and lines[0] == '':
89
if lines and lines[-1] == '':
78
93
# Keep a copy for error reporting
80
95
comment = line.find('#')
98
# NB: this syntax means comments are allowed inside output, which
83
100
line = line[0:comment]
84
101
line = line.rstrip()
88
104
if line.startswith('$'):
89
105
# Time to output the current command
90
106
add_command(cmd_cur, input, output, error)
207
223
retcode, actual_output, actual_error = method(test_case,
210
self._check_output(output, actual_output, test_case)
211
self._check_output(error, actual_error, test_case)
227
self._check_output(output, actual_output, test_case)
228
except AssertionError, e:
229
raise AssertionError(str(e) + " in stdout of command %s" % cmd)
231
self._check_output(error, actual_error, test_case)
232
except AssertionError, e:
233
raise AssertionError(str(e) +
234
" in stderr of running command %s" % cmd)
212
235
if retcode and not error and actual_error:
213
236
test_case.fail('In \n\t%s\nUnexpected error: %s'
214
237
% (' '.join(cmd), actual_error))
215
238
return retcode, actual_output, actual_error
217
240
def _check_output(self, expected, actual, test_case):
219
# Specifying None means: any output is accepted
222
test_case.fail('We expected output: %r, but found None'
244
elif expected == '...\n':
247
test_case.fail('expected output: %r, but found nothing'
249
expected = expected or ''
224
250
matching = self.output_checker.check_output(
225
251
expected, actual, self.check_options)
230
256
# 'expected' parameter. So we just fallback to our good old
231
257
# assertEqualDiff since we know there *are* differences and the
232
258
# output should be decently readable.
233
test_case.assertEqualDiff(expected, actual)
260
# As a special case, we allow output that's missing a final
261
# newline to match an expected string that does have one, so that
262
# we can match a prompt printed on one line, then input given on
264
if expected == actual + '\n':
267
test_case.assertEqualDiff(expected, actual)
235
269
def _pre_process_args(self, args):
475
509
def run_command(self, cmd, input, output, error):
476
510
return self.script_runner.run_command(self, cmd, input, output, error)
513
def run_script(test_case, script_string):
514
"""Run the given script within a testcase"""
515
return ScriptRunner().run_script(test_case, script_string)
518
class cmd_test_script(commands.Command):
519
"""Run a shell-like test from a file."""
522
takes_args = ['infile']
524
@commands.display_command
525
def run(self, infile):
533
class Test(TestCaseWithTransportAndScript):
535
script = None # Set before running
538
self.run_script(script)
540
runner = tests.TextTestRunner(stream=self.outf)
541
test = Test('test_it')
542
test.path = os.path.realpath(infile)
543
res = runner.run(test)
544
return len(res.errors) + len(res.failures)