summaryrefslogtreecommitdiff
path: root/test/GetBuildFailures
diff options
context:
space:
mode:
authorGary Oberbrunner <garyo@oberbrunner.com>2008-10-29 03:01:00 +0000
committerGary Oberbrunner <garyo@oberbrunner.com>2008-10-29 03:01:00 +0000
commit2556cb598478ec1961543d72941545ead5a9a339 (patch)
tree93f780a267396d95f9bfeba9c48da963a81abf05 /test/GetBuildFailures
parentefd8c15b182b80f7151f1a180c95bcfabfe792b4 (diff)
downloadscons-2556cb598478ec1961543d72941545ead5a9a339.tar.gz
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.py160
1 files changed, 142 insertions, 18 deletions
diff --git a/test/GetBuildFailures/serial.py b/test/GetBuildFailures/serial.py
index c8205ed1..b5d8e44b 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()