diff options
author | Gary Oberbrunner <garyo@oberbrunner.com> | 2008-10-29 03:01:00 (GMT) |
---|---|---|
committer | Gary Oberbrunner <garyo@oberbrunner.com> | 2008-10-29 03:01:00 (GMT) |
commit | 652d80b36bf9e80989336bf7a25b54c176ff626c (patch) | |
tree | 93f780a267396d95f9bfeba9c48da963a81abf05 /test/GetBuildFailures | |
parent | d695652a34c6740b3c925a94b45256270027f473 (diff) | |
download | SCons-652d80b36bf9e80989336bf7a25b54c176ff626c.zip SCons-652d80b36bf9e80989336bf7a25b54c176ff626c.tar.gz SCons-652d80b36bf9e80989336bf7a25b54c176ff626c.tar.bz2 |
Applied Benoit Belley's patch in ticket 1957 improve the robustness of
GetBuildFailures(). New function convert_to_buildError, and use it in
several places so all build failures now go through it and are
returned as BuildError exceptions. Had a small effect on output
formatting in many tests but no significant change to behavior. I
reworked the patch a little to keep SCons exit status values the same
as before; this patch could make it simpler to change them in some
cases, e.g. exit with the errno of the failed action if desired. One
nice side effect of this patch is that more scons errors print the
node that caused the error now.
Diffstat (limited to 'test/GetBuildFailures')
-rw-r--r-- | test/GetBuildFailures/serial.py | 160 |
1 files changed, 142 insertions, 18 deletions
diff --git a/test/GetBuildFailures/serial.py b/test/GetBuildFailures/serial.py index c8205ed..b5d8e44 100644 --- a/test/GetBuildFailures/serial.py +++ b/test/GetBuildFailures/serial.py @@ -31,6 +31,7 @@ attributes we expect to be most commonly used. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons +import re _python_ = TestSCons._python_ @@ -59,19 +60,43 @@ test.write('mypass.py', contents) test.write('myfail.py', contents) test.write('SConstruct', """\ -Command('f3', 'f3.in', r'@%(_python_)s mypass.py - f3 $TARGET $SOURCE') -Command('f4', 'f4.in', r'@%(_python_)s myfail.py f3 f4 $TARGET $SOURCE') -Command('f5', 'f5.in', r'@%(_python_)s myfail.py f4 f5 $TARGET $SOURCE') -Command('f6', 'f6.in', r'@%(_python_)s mypass.py f5 - $TARGET $SOURCE') +Command('f03', 'f03.in', r'@%(_python_)s mypass.py - f03 $TARGET $SOURCE') +Command('f04', 'f04.in', r'@%(_python_)s myfail.py f03 f04 $TARGET $SOURCE') +Command('f05', 'f05.in', r'@%(_python_)s myfail.py f04 f05 $TARGET $SOURCE') +Command('f06', 'f06.in', r'@%(_python_)s mypass.py f05 - $TARGET $SOURCE') +Command('f07', 'f07.in', r'@%(_python_)s mypass.py f07 - $TARGET $SOURCE') + +import SCons.Errors +def raiseExcAction(exc): + def action(env, target, source): + raise exc + return action +def returnExcAction(exc): + def action(env, target, source): + return exc + return action +class MyBuildError(SCons.Errors.BuildError): + pass + +Command('f08', 'f08.in', raiseExcAction(SCons.Errors.UserError("My User Error"))) +Command('f09', 'f09.in', returnExcAction(SCons.Errors.UserError("My User Error"))) +Command('f10', 'f10.in', raiseExcAction(MyBuildError(errstr="My Build Error", status=7))) +Command('f11', 'f11.in', returnExcAction(MyBuildError(errstr="My Build Error", status=7))) +Command('f12', 'f12.in', raiseExcAction(EnvironmentError(123, "My EnvironmentError", "f12"))) +Command('f13', 'f13.in', returnExcAction(EnvironmentError(123, "My EnvironmentError", "f13"))) +Command('f14', 'f14.in', raiseExcAction(SCons.Errors.InternalError("My InternalError"))) +Command('f15', 'f15.in', returnExcAction(SCons.Errors.InternalError("My InternalError"))) def print_build_failures(): from SCons.Script import GetBuildFailures import string bf_list = GetBuildFailures() - bf_list.sort(lambda a,b: cmp(a.filename, b.filename)) + bf_list.sort(lambda a,b: cmp(str(a.node), str(b.node))) for bf in bf_list: - print "%%s failed (%%s): %%s" %% (bf.node, bf.status, bf.errstr) - print " %%s" %% string.join(bf.command) + assert( isinstance(bf, SCons.Errors.BuildError) ) + print "BF: %%s failed (%%s): %%s" %% (bf.node, bf.status, bf.errstr) + if bf.command: + print "BF: %%s" %% string.join(Flatten(bf.command)) try: import atexit @@ -82,22 +107,31 @@ else: atexit.register(print_build_failures) """ % locals()) -test.write('f3.in', "f3.in\n") -test.write('f4.in', "f4.in\n") -test.write('f5.in', "f5.in\n") -test.write('f6.in', "f6.in\n") +test.write('f03.in', "f03.in\n") +test.write('f04.in', "f04.in\n") +test.write('f05.in', "f05.in\n") +test.write('f06.in', "f06.in\n") +# f07.in is intentionally missing... +test.write('f08.in', "f08.in\n") +test.write('f09.in', "f09.in\n") +test.write('f10.in', "f10.in\n") +test.write('f11.in', "f11.in\n") +test.write('f12.in', "f12.in\n") +test.write('f13.in', "f13.in\n") +test.write('f14.in', "f14.in\n") +test.write('f15.in', "f15.in\n") expect_stdout = """\ scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... scons: building terminated because of errors. -f4 failed (1): Error 1 - %(_python_)s myfail.py f3 f4 "f4" "f4.in" +BF: f04 failed (1): Error 1 +BF: %(_python_)s myfail.py f03 f04 "f04" "f04.in" """ % locals() expect_stderr = """\ -scons: *** [f4] Error 1 +scons: *** [f04] Error 1 """ test.run(arguments = '.', @@ -105,11 +139,101 @@ test.run(arguments = '.', stdout = expect_stdout, stderr = expect_stderr) -test.must_match(test.workpath('f3'), 'f3.in\n') -test.must_not_exist(test.workpath('f4')) -test.must_not_exist(test.workpath('f5')) -test.must_not_exist(test.workpath('f6')) +test.must_match(test.workpath('f03'), 'f03.in\n') +test.must_not_exist(test.workpath('f04')) +test.must_not_exist(test.workpath('f05')) +test.must_not_exist(test.workpath('f06')) +test.must_not_exist(test.workpath('f07')) +test.must_not_exist(test.workpath('f08')) +test.must_not_exist(test.workpath('f09')) +test.must_not_exist(test.workpath('f10')) +test.must_not_exist(test.workpath('f11')) +test.must_not_exist(test.workpath('f12')) +test.must_not_exist(test.workpath('f13')) +test.must_not_exist(test.workpath('f14')) +test.must_not_exist(test.workpath('f15')) + + +expect_stdout = re.escape("""\ +scons: Reading SConscript files ... +scons: done reading SConscript files. +scons: Building targets ... +action(["f08"], ["f08.in"]) +action(["f09"], ["f09.in"]) +action(["f10"], ["f10.in"]) +action(["f11"], ["f11.in"]) +action(["f12"], ["f12.in"]) +action(["f13"], ["f13.in"]) +action(["f14"], ["f14.in"]) +action(["f15"], ["f15.in"]) +scons: done building targets (errors occurred during build). +BF: f04 failed (1): Error 1 +BF: %(_python_)s myfail.py f03 f04 "f04" "f04.in" +BF: f05 failed (1): Error 1 +BF: %(_python_)s myfail.py f04 f05 "f05" "f05.in" +BF: f07 failed (2): Source `f07.in' not found, needed by target `f07'. +BF: f08 failed (2): My User Error +BF: action(["f08"], ["f08.in"]) +BF: f09 failed (2): My User Error +BF: action(["f09"], ["f09.in"]) +BF: f10 failed (7): My Build Error +BF: action(["f10"], ["f10.in"]) +BF: f11 failed (7): My Build Error +BF: action(["f11"], ["f11.in"]) +BF: f12 failed (123): My EnvironmentError +BF: action(["f12"], ["f12.in"]) +BF: f13 failed (123): My EnvironmentError +BF: action(["f13"], ["f13.in"]) +BF: f14 failed (2): InternalError : My InternalError +BF: action(["f14"], ["f14.in"]) +BF: f15 failed (2): InternalError : My InternalError +BF: action(["f15"], ["f15.in"]) +""" % locals()) +expect_stderr = re.escape("""\ +scons: *** [f04] Error 1 +scons: *** [f05] Error 1 +scons: *** [f07] Source `f07.in' not found, needed by target `f07'. +scons: *** [f08] My User Error +scons: *** [f09] My User Error +scons: *** [f10] My Build Error +scons: *** [f11] My Build Error +scons: *** [f12] f12: My EnvironmentError +scons: *** [f13] f13: My EnvironmentError +scons: *** [f14] InternalError : My InternalError +""") + \ +"""\ +Traceback \((most recent call|innermost) last\): +( File ".+", line \d+, in \S+ + [^\n]+ +)*( File ".+", line \d+, in \S+ +)*( File ".+", line \d+, in \S+ + [^\n]+ +)*\S.+ +""" + \ +re.escape("""\ +scons: *** [f15] InternalError : My InternalError +""") + +test.run(arguments = '-k .', + status = 2, + stdout = expect_stdout, + stderr = expect_stderr, + match = TestSCons.match_re_dotall) + +test.must_match(test.workpath('f03'), 'f03.in\n') +test.must_not_exist(test.workpath('f04')) +test.must_not_exist(test.workpath('f05')) +test.must_match(test.workpath('f06'), 'f06.in\n') +test.must_not_exist(test.workpath('f07')) +test.must_not_exist(test.workpath('f08')) +test.must_not_exist(test.workpath('f09')) +test.must_not_exist(test.workpath('f10')) +test.must_not_exist(test.workpath('f11')) +test.must_not_exist(test.workpath('f12')) +test.must_not_exist(test.workpath('f13')) +test.must_not_exist(test.workpath('f14')) +test.must_not_exist(test.workpath('f15')) test.pass_test() |