From 8c0690bceff753ce1dea6f5e14cce1a8e0af30f5 Mon Sep 17 00:00:00 2001 From: Greg Noel Date: Sat, 1 May 2010 04:42:33 +0000 Subject: Add test routine to exactly match a set of lines no matter the order --- QMTest/TestCommon.py | 52 +++++++++++++++++++++++++++++++++++++++ test/GetBuildFailures/option-k.py | 10 +++----- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py index fcd3e70..6ee2bd5 100644 --- a/QMTest/TestCommon.py +++ b/QMTest/TestCommon.py @@ -40,6 +40,8 @@ provided by the TestCommon class: test.must_contain_any_line(output, lines, ['title', find]) + test.exactly_contain_all_lines(output, lines, ['title', find]) + test.must_exist('file1', ['file2', ...]) test.must_match('file', "expected contents\n") @@ -304,6 +306,56 @@ class TestCommon(TestCmd): sys.stdout.write(output) self.fail_test() + def exactly_contain_all_lines(self, output, expect, title=None, find=None): + """Ensures that the specified output string (first argument) + contains all of the lines in the expected string (second argument) + with none left over. + + An optional third argument can be used to describe the type + of output being searched, and only shows up in failure output. + + An optional fourth argument can be used to supply a different + function, of the form "find(line, output), to use when searching + for lines in the output. + """ + out = output.splitlines() + exp = expect.splitlines() + if sorted(out) == sorted(exp): + # early out for exact match + return + if find is None: + def find(o, l): + try: + return o.index(l) + except: + return None + missing = [] + for line in exp: + found = find(out, line) + if found is None: + missing.append(line) + else: + out.pop(found) + + if not missing and not out: + # all lines were matched + return + + if title is None: + title = 'output' + if missing: + sys.stdout.write("Missing expected lines from %s:\n" % title) + for line in missing: + sys.stdout.write(' ' + repr(line) + '\n') + sys.stdout.write(self.banner('missing %s ' % title)) + if out: + sys.stdout.write("Extra unexpected lines from %s:\n" % title) + for line in out: + sys.stdout.write(' ' + repr(line) + '\n') + sys.stdout.write(self.banner('extra %s ' % title)) + sys.stdout.flush() + self.fail_test() + def must_contain_lines(self, lines, output, title=None): # Deprecated; retain for backwards compatibility. return self.must_contain_all_lines(output, lines, title) diff --git a/test/GetBuildFailures/option-k.py b/test/GetBuildFailures/option-k.py index a9818a6..142fbf4 100644 --- a/test/GetBuildFailures/option-k.py +++ b/test/GetBuildFailures/option-k.py @@ -23,7 +23,7 @@ # """ -Verify that a failed build action with -j works as expected. +Verify that a failed build action with -k works as expected. """ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -90,10 +90,9 @@ scons: *** [f4] Error 1 scons: *** [f5] Error 1 """ -test.run(arguments = '-k .', - status = 2, - stdout = expect_stdout, - stderr = expect_stderr) +test.run(arguments = '-k .', status = 2, stdout=None, stderr=None) +test.exactly_contain_all_lines(test.stdout(), expect_stdout, title='stdout') +test.exactly_contain_all_lines(test.stderr(), expect_stderr, title='stderr') test.must_match(test.workpath('f3'), 'f3.in\n') test.must_not_exist(test.workpath('f4')) @@ -101,7 +100,6 @@ test.must_not_exist(test.workpath('f5')) test.must_match(test.workpath('f6'), 'f6.in\n') - test.pass_test() # Local Variables: -- cgit v0.12