diff options
| author | William Deegan <bill@baddogconsulting.com> | 2015-09-21 17:03:12 (GMT) |
|---|---|---|
| committer | William Deegan <bill@baddogconsulting.com> | 2015-09-21 17:03:12 (GMT) |
| commit | 0941093e0e5a030faa49968457638a3a6aee7ad8 (patch) | |
| tree | 6d33513c14eb6eac0531dd050de0ecca4c39bd79 /test/option | |
| download | SCons-2.4.0.zip SCons-2.4.0.tar.gz SCons-2.4.0.tar.bz2 | |
release 2.4.02.4.0
Diffstat (limited to 'test/option')
32 files changed, 3665 insertions, 0 deletions
diff --git a/test/option/d.py b/test/option/d.py new file mode 100644 index 0000000..055769a --- /dev/null +++ b/test/option/d.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that the -d option is ignored. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', "") + +test.run(arguments = '-d .', + stderr = "Warning: ignoring -d option\n") + +test.pass_test() + +# + +test.subdir('subdir') + +test.write('SConstruct', """ +env = Environment() +env.Program(target = 'aaa', source = 'aaa.c') +env.Program(target = 'bbb', source = 'bbb.c') +SConscript('subdir/SConscript') +""") + +test.write(['subdir', 'SConscript'], """ +env = Environment() +env.Program(target = 'ccc', source = 'ccc.c') +env.Program(target = 'ddd', source = 'ddd.c') +""") + +test.write('aaa.c', """ +int +main(int argc, char *argv) +{ + argv[argc++] = "--"; + printf("aaa.c\n"); + exit (0); +} +""") + +test.write('bbb.c', """ +int +main(int argc, char *argv) +{ + argv[argc++] = "--"; + printf("bbb.c\n"); + exit (0); +} +""") + +test.write(['subdir', 'ccc.c'], """ +int +main(int argc, char *argv) +{ + argv[argc++] = "--"; + printf("subdir/ccc.c\n"); + exit (0); +} +""") + +test.write(['subdir', 'ddd.c'], """ +int +main(int argc, char *argv) +{ + argv[argc++] = "--"; + printf("subdir/ddd.c\n"); + exit (0); +} +""") + +test.run(arguments = '-d .', stdout = """ +Target aaa: aaa.o +Checking aaa + Checking aaa.o + Checking aaa.c + Rebuilding aaa.o: out of date. +cc -c -o aaa.o aaa.c +Rebuilding aaa: out of date. +cc -o aaa aaa.o +Target aaa.o: aaa.c +Target bbb: bbb.o +Checking bbb + Checking bbb.o + Checking bbb.c + Rebuilding bbb.o: out of date. +cc -c -o bbb.o bbb.c +Rebuilding bbb: out of date. +cc -o bbb bbb.o +Target bbb.o: bbb.c +Target subdir/ccc/g: subdir/ccc.o +Checking subdir/ccc/g + Checking subdir/ccc/g.o + Checking subdir/ccc/g.c + Rebuilding subdir/ccc/g.o: out of date. +cc -c -o subdir/ccc/g.o subdir/ccc.c +Rebuilding subdir/ccc/g: out of date. +cc -o subdir/ccc/g subdir/ccc.o +Target subdir/ccc/g.o: subdir/ccc.c +Target subdir/ddd/g: subdir/ddd.o +Checking subdir/ddd/g + Checking subdir/ddd/g.o + Checking subdir/ddd/g.c + Rebuilding subdir/ddd/g.o: out of date. +cc -c -o subdir/ddd/g.o subdir/ddd.c +Rebuilding subdir/ddd/g: out of date. +cc -o subdir/ddd/g subdir/ddd.o +Target subdir/ddd/g.o: subdir/ddd.c +""") + +test.run(program = test.workpath('aaa'), stdout = "aaa.c\n") +test.run(program = test.workpath('bbb'), stdout = "bbb.c\n") +test.run(program = test.workpath('subdir/ccc'), stdout = "subdir/ccc.c\n") +test.run(program = test.workpath('subdir/ddd'), stdout = "subdir/ddd.c\n") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-count.py b/test/option/debug-count.py new file mode 100644 index 0000000..39c1222 --- /dev/null +++ b/test/option/debug-count.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that the --debug=count option works. +""" + +import re +import sys + +import TestSCons + +test = TestSCons.TestSCons() + +try: + import weakref +except ImportError: + x = "Python version has no 'weakref' module; skipping tests.\n" + test.skip_test(x) + + + +test.write('SConstruct', """ +def cat(target, source, env): + open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read()) +env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))}) +env.Cat('file.out', 'file.in') +""") + +test.write('file.in', "file.in\n") + +# Just check that object counts for some representative classes +# show up in the output. + +def find_object_count(s, stdout): + re_string = '\d+ +\d+ %s' % re.escape(s) + return re.search(re_string, stdout) + +objects = [ + 'Action.CommandAction', + 'Builder.BuilderBase', + 'Environment.Base', + 'Executor.Executor', + 'Node.FS', + 'Node.FS.Base', + 'Node.Node', +] + +for args in ['-h --debug=count', '--debug=count']: + test.run(arguments = args) + stdout = test.stdout() + + missing = [o for o in objects if find_object_count(o, stdout) is None] + + if missing: + print "Missing the following object lines from '%s' output:" % args + print "\t", ' '.join(missing) + print "STDOUT ==========" + print stdout + test.fail_test(1) + +expect_warning = """ +scons: warning: --debug=count is not supported when running SCons +\twith the python -O option or optimized \\(.pyo\\) modules. +""" + TestSCons.file_expr + +test.run( + arguments = '--debug=count -h', + # Test against current interpreter vs default path option. + interpreter = [ sys.executable, '-O' ], + stderr = expect_warning, + match = TestSCons.match_re +) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-duplicate.py b/test/option/debug-duplicate.py new file mode 100644 index 0000000..df2723e --- /dev/null +++ b/test/option/debug-duplicate.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.subdir('sub1') + +test.write('SConstruct', """\ +env=Environment() +Export('env') +env.SConscript('SConscript', variant_dir='Build') +""") + +test.write('SConscript', """\ +Import('env') +env.Command('foo.out', 'SConscript', Copy('$TARGET', '$SOURCE')) +""") + +test.run(arguments = "--debug=duplicate -Q", + stdout='.*relinking variant.*', match=TestSCons.match_re_dotall) + +test.must_exist('Build/foo.out') + +test.write('SConscript', """\ +# different this time! +Import('env') +env.Command('foo.out', 'SConscript', Copy('$TARGET', '$SOURCE')) +""") + +test.run(arguments = "--debug=duplicate -Q", + stdout='.*relinking variant.*removing existing target.*', + match=TestSCons.match_re_dotall) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-findlibs.py b/test/option/debug-findlibs.py new file mode 100644 index 0000000..ce97199 --- /dev/null +++ b/test/option/debug-findlibs.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.subdir('sub1', 'sub2') + +test.write('cat.py', """\ +import sys +ofp = open(sys.argv[1], 'wb') +for f in sys.argv[2:]: + ifp = open(f, 'rb') + ofp.write(ifp.read()) +ofp.close() +""") + +test.write('SConstruct', """\ +env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx', + LIBPATH = ['sub1', 'sub2', '.'], + LIBS = ['iii', 'jjj', 'kkk', 'lll', 'mmm'], + LIBPREFIXES = ['a-', 'b-', 'c-'], + LIBSUFFIXES = ['.aaa', '.bbb', '.ccc'], + LINKCOM = '%(_python_)s cat.py $TARGET $SOURCES') +env.Program('foo', 'a.ooo',) +""" % locals()) + +test.write('a.ooo', "a.ooo\n") + +test.write('a-iii.aaa', "a-iii.aaa\n") +test.write(['sub1', 'b-jjj.bbb'], "b-jjj.bbb\n") +test.write(['sub2', 'c-kkk.ccc'], "c-kkk.ccc\n") +test.write('a-lll.ccc', "a-lll.ccc\n") + +test.run(arguments = "--debug=findlibs foo.xxx", + stdout = test.wrap_stdout("""\ + findlibs: looking for 'a-iii.aaa' in 'sub1' ... + findlibs: looking for 'a-iii.aaa' in 'sub2' ... + findlibs: looking for 'a-iii.aaa' in '.' ... + findlibs: ... FOUND 'a-iii.aaa' in '.' + findlibs: looking for 'b-iii.aaa' in 'sub1' ... + findlibs: looking for 'b-iii.aaa' in 'sub2' ... + findlibs: looking for 'b-iii.aaa' in '.' ... + findlibs: looking for 'c-iii.aaa' in 'sub1' ... + findlibs: looking for 'c-iii.aaa' in 'sub2' ... + findlibs: looking for 'c-iii.aaa' in '.' ... + findlibs: looking for 'a-iii.bbb' in 'sub1' ... + findlibs: looking for 'a-iii.bbb' in 'sub2' ... + findlibs: looking for 'a-iii.bbb' in '.' ... + findlibs: looking for 'b-iii.bbb' in 'sub1' ... + findlibs: looking for 'b-iii.bbb' in 'sub2' ... + findlibs: looking for 'b-iii.bbb' in '.' ... + findlibs: looking for 'c-iii.bbb' in 'sub1' ... + findlibs: looking for 'c-iii.bbb' in 'sub2' ... + findlibs: looking for 'c-iii.bbb' in '.' ... + findlibs: looking for 'a-iii.ccc' in 'sub1' ... + findlibs: looking for 'a-iii.ccc' in 'sub2' ... + findlibs: looking for 'a-iii.ccc' in '.' ... + findlibs: looking for 'b-iii.ccc' in 'sub1' ... + findlibs: looking for 'b-iii.ccc' in 'sub2' ... + findlibs: looking for 'b-iii.ccc' in '.' ... + findlibs: looking for 'c-iii.ccc' in 'sub1' ... + findlibs: looking for 'c-iii.ccc' in 'sub2' ... + findlibs: looking for 'c-iii.ccc' in '.' ... + findlibs: looking for 'a-jjj.aaa' in 'sub1' ... + findlibs: looking for 'a-jjj.aaa' in 'sub2' ... + findlibs: looking for 'a-jjj.aaa' in '.' ... + findlibs: looking for 'b-jjj.aaa' in 'sub1' ... + findlibs: looking for 'b-jjj.aaa' in 'sub2' ... + findlibs: looking for 'b-jjj.aaa' in '.' ... + findlibs: looking for 'c-jjj.aaa' in 'sub1' ... + findlibs: looking for 'c-jjj.aaa' in 'sub2' ... + findlibs: looking for 'c-jjj.aaa' in '.' ... + findlibs: looking for 'a-jjj.bbb' in 'sub1' ... + findlibs: looking for 'a-jjj.bbb' in 'sub2' ... + findlibs: looking for 'a-jjj.bbb' in '.' ... + findlibs: looking for 'b-jjj.bbb' in 'sub1' ... + findlibs: ... FOUND 'b-jjj.bbb' in 'sub1' + findlibs: looking for 'c-jjj.bbb' in 'sub1' ... + findlibs: looking for 'c-jjj.bbb' in 'sub2' ... + findlibs: looking for 'c-jjj.bbb' in '.' ... + findlibs: looking for 'a-jjj.ccc' in 'sub1' ... + findlibs: looking for 'a-jjj.ccc' in 'sub2' ... + findlibs: looking for 'a-jjj.ccc' in '.' ... + findlibs: looking for 'b-jjj.ccc' in 'sub1' ... + findlibs: looking for 'b-jjj.ccc' in 'sub2' ... + findlibs: looking for 'b-jjj.ccc' in '.' ... + findlibs: looking for 'c-jjj.ccc' in 'sub1' ... + findlibs: looking for 'c-jjj.ccc' in 'sub2' ... + findlibs: looking for 'c-jjj.ccc' in '.' ... + findlibs: looking for 'a-kkk.aaa' in 'sub1' ... + findlibs: looking for 'a-kkk.aaa' in 'sub2' ... + findlibs: looking for 'a-kkk.aaa' in '.' ... + findlibs: looking for 'b-kkk.aaa' in 'sub1' ... + findlibs: looking for 'b-kkk.aaa' in 'sub2' ... + findlibs: looking for 'b-kkk.aaa' in '.' ... + findlibs: looking for 'c-kkk.aaa' in 'sub1' ... + findlibs: looking for 'c-kkk.aaa' in 'sub2' ... + findlibs: looking for 'c-kkk.aaa' in '.' ... + findlibs: looking for 'a-kkk.bbb' in 'sub1' ... + findlibs: looking for 'a-kkk.bbb' in 'sub2' ... + findlibs: looking for 'a-kkk.bbb' in '.' ... + findlibs: looking for 'b-kkk.bbb' in 'sub1' ... + findlibs: looking for 'b-kkk.bbb' in 'sub2' ... + findlibs: looking for 'b-kkk.bbb' in '.' ... + findlibs: looking for 'c-kkk.bbb' in 'sub1' ... + findlibs: looking for 'c-kkk.bbb' in 'sub2' ... + findlibs: looking for 'c-kkk.bbb' in '.' ... + findlibs: looking for 'a-kkk.ccc' in 'sub1' ... + findlibs: looking for 'a-kkk.ccc' in 'sub2' ... + findlibs: looking for 'a-kkk.ccc' in '.' ... + findlibs: looking for 'b-kkk.ccc' in 'sub1' ... + findlibs: looking for 'b-kkk.ccc' in 'sub2' ... + findlibs: looking for 'b-kkk.ccc' in '.' ... + findlibs: looking for 'c-kkk.ccc' in 'sub1' ... + findlibs: looking for 'c-kkk.ccc' in 'sub2' ... + findlibs: ... FOUND 'c-kkk.ccc' in 'sub2' + findlibs: looking for 'a-lll.aaa' in 'sub1' ... + findlibs: looking for 'a-lll.aaa' in 'sub2' ... + findlibs: looking for 'a-lll.aaa' in '.' ... + findlibs: looking for 'b-lll.aaa' in 'sub1' ... + findlibs: looking for 'b-lll.aaa' in 'sub2' ... + findlibs: looking for 'b-lll.aaa' in '.' ... + findlibs: looking for 'c-lll.aaa' in 'sub1' ... + findlibs: looking for 'c-lll.aaa' in 'sub2' ... + findlibs: looking for 'c-lll.aaa' in '.' ... + findlibs: looking for 'a-lll.bbb' in 'sub1' ... + findlibs: looking for 'a-lll.bbb' in 'sub2' ... + findlibs: looking for 'a-lll.bbb' in '.' ... + findlibs: looking for 'b-lll.bbb' in 'sub1' ... + findlibs: looking for 'b-lll.bbb' in 'sub2' ... + findlibs: looking for 'b-lll.bbb' in '.' ... + findlibs: looking for 'c-lll.bbb' in 'sub1' ... + findlibs: looking for 'c-lll.bbb' in 'sub2' ... + findlibs: looking for 'c-lll.bbb' in '.' ... + findlibs: looking for 'a-lll.ccc' in 'sub1' ... + findlibs: looking for 'a-lll.ccc' in 'sub2' ... + findlibs: looking for 'a-lll.ccc' in '.' ... + findlibs: ... FOUND 'a-lll.ccc' in '.' + findlibs: looking for 'b-lll.ccc' in 'sub1' ... + findlibs: looking for 'b-lll.ccc' in 'sub2' ... + findlibs: looking for 'b-lll.ccc' in '.' ... + findlibs: looking for 'c-lll.ccc' in 'sub1' ... + findlibs: looking for 'c-lll.ccc' in 'sub2' ... + findlibs: looking for 'c-lll.ccc' in '.' ... + findlibs: looking for 'a-mmm.aaa' in 'sub1' ... + findlibs: looking for 'a-mmm.aaa' in 'sub2' ... + findlibs: looking for 'a-mmm.aaa' in '.' ... + findlibs: looking for 'b-mmm.aaa' in 'sub1' ... + findlibs: looking for 'b-mmm.aaa' in 'sub2' ... + findlibs: looking for 'b-mmm.aaa' in '.' ... + findlibs: looking for 'c-mmm.aaa' in 'sub1' ... + findlibs: looking for 'c-mmm.aaa' in 'sub2' ... + findlibs: looking for 'c-mmm.aaa' in '.' ... + findlibs: looking for 'a-mmm.bbb' in 'sub1' ... + findlibs: looking for 'a-mmm.bbb' in 'sub2' ... + findlibs: looking for 'a-mmm.bbb' in '.' ... + findlibs: looking for 'b-mmm.bbb' in 'sub1' ... + findlibs: looking for 'b-mmm.bbb' in 'sub2' ... + findlibs: looking for 'b-mmm.bbb' in '.' ... + findlibs: looking for 'c-mmm.bbb' in 'sub1' ... + findlibs: looking for 'c-mmm.bbb' in 'sub2' ... + findlibs: looking for 'c-mmm.bbb' in '.' ... + findlibs: looking for 'a-mmm.ccc' in 'sub1' ... + findlibs: looking for 'a-mmm.ccc' in 'sub2' ... + findlibs: looking for 'a-mmm.ccc' in '.' ... + findlibs: looking for 'b-mmm.ccc' in 'sub1' ... + findlibs: looking for 'b-mmm.ccc' in 'sub2' ... + findlibs: looking for 'b-mmm.ccc' in '.' ... + findlibs: looking for 'c-mmm.ccc' in 'sub1' ... + findlibs: looking for 'c-mmm.ccc' in 'sub2' ... + findlibs: looking for 'c-mmm.ccc' in '.' ... +%(_python_)s cat.py foo.xxx a.ooo +""" % locals())) + +test.must_match('foo.xxx', "a.ooo\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-includes.py b/test/option/debug-includes.py new file mode 100644 index 0000000..0982a20 --- /dev/null +++ b/test/option/debug-includes.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that the --debug=includes option prints the implicit +dependencies of a target. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +env = Environment(OBJSUFFIX = '.obj', + SHOBJSUFFIX = '.shobj', + LIBPREFIX = '', + LIBSUFFIX = '.lib', + SHLIBPREFIX = '', + SHLIBSUFFIX = '.shlib', + ) +env.Program('foo.exe', ['foo.c', 'bar.c']) +env.StaticLibrary('foo', ['foo.c', 'bar.c']) +env.SharedLibrary('foo', ['foo.c', 'bar.c'], no_import_lib=True) +""") + +test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> +#include "foo.h" +int main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("f1.c\n"); + exit (0); +} +""") + +test.write('bar.c', """ +#include "bar.h" +int local = 1; +""") + +test.write('foo.h', """ +#ifndef FOO_H +#define FOO_H +#include "bar.h" +#endif +""") + +test.write('bar.h', """ +#ifndef BAR_H +#define BAR_H +#include "foo.h" +#endif +""") + +includes = """ ++-foo.c + +-foo.h + +-bar.h +""" +test.run(arguments = "--debug=includes foo.obj") + +test.must_contain_all_lines(test.stdout(), [includes]) + + + +# In an ideal world, --debug=includes would also work when there's a build +# failure, but this would require even more complicated logic to scan +# all of the intermediate nodes that get skipped when the build failure +# occurs. On the YAGNI theory, we're just not going to worry about this +# until it becomes an issue that someone actually cares enough about. + +#test.write('bar.h', """ +##ifndef BAR_H +##define BAR_H +##include "foo.h" +##endif +#THIS SHOULD CAUSE A BUILD FAILURE +#""") + +#test.run(arguments = "--debug=includes foo.exe", +# status = 2, +# stderr = None) +#test.must_contain_all_lines(test.stdout(), [includes]) + + + +# These shouldn't print out anything in particular, but +# they shouldn't crash either: +test.run(arguments = "--debug=includes .") +test.run(arguments = "--debug=includes foo.c") +test.run(arguments = "--debug=includes foo.lib") +test.run(arguments = "--debug=includes foo.shlib") + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-memoizer.py b/test/option/debug-memoizer.py new file mode 100644 index 0000000..222ba67 --- /dev/null +++ b/test/option/debug-memoizer.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test calling the --debug=memoizer option. +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) + + +test.write('SConstruct', """ +def cat(target, source, env): + open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read()) +env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))}) +env.Cat('file.out', 'file.in') +""") + +test.write('file.in', "file.in\n") + +# The banner, and a list of representative method names that we expect +# to show up in the output. Of course, this depends on keeping those +# names in the implementation, so if we change them, we'll have to +# change this test... +expect = [ + "Memoizer (memory cache) hits and misses", + "Base.stat()", + "Dir.srcdir_list()", + "File.exists()", + "Node._children_get()", +] + + +for args in ['-h --debug=memoizer', '--debug=memoizer']: + test.run(arguments = args) + test.must_contain_any_line(test.stdout(), expect) + +test.must_match('file.out', "file.in\n") + + + +test.unlink("file.out") + + + +os.environ['SCONSFLAGS'] = '--debug=memoizer' + +test.run(arguments = '') + +test.must_contain_any_line(test.stdout(), expect) + +test.must_match('file.out', "file.in\n") + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-memory.py b/test/option/debug-memory.py new file mode 100644 index 0000000..c9165ed --- /dev/null +++ b/test/option/debug-memory.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that the --debug=memory option works. +""" + +import re + +import TestSCons + +test = TestSCons.TestSCons() + +try: + import resource +except ImportError: + try: + import win32process + import win32api + except ImportError: + x = "Python version has no 'resource' or 'win32api/win32process' module; skipping tests.\n" + test.skip_test(x) + + + +test.write('SConstruct', """ +def cat(target, source, env): + open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read()) +env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))}) +env.Cat('file.out', 'file.in') +""") + +test.write('file.in', "file.in\n") + + + +test.run(arguments = '--debug=memory') + +lines = test.stdout().split('\n') + +test.fail_test(re.match(r'Memory before reading SConscript files: +\d+', lines[-5]) is None) +test.fail_test(re.match(r'Memory after reading SConscript files: +\d+', lines[-4]) is None) +test.fail_test(re.match(r'Memory before building targets: +\d+', lines[-3]) is None) +test.fail_test(re.match(r'Memory after building targets: +\d+', lines[-2]) is None) + + + +test.run(arguments = '-h --debug=memory') + +lines = test.stdout().split('\n') + +test.fail_test(re.match(r'Memory before reading SConscript files: +\d+', lines[-3]) is None) +test.fail_test(re.match(r'Memory after reading SConscript files: +\d+', lines[-2]) is None) + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-multiple.py b/test/option/debug-multiple.py new file mode 100644 index 0000000..f5bbdf0 --- /dev/null +++ b/test/option/debug-multiple.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that --debug can take multiple options +""" + +import re + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +def cat(target, source, env): + open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read()) +env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))}) +env.Cat('file.out', 'file.in') +""") + +test.write('file.in', "file.in\n") + +# Just check that object counts for some representative classes +# show up in the output. + +def find_object_count(s, stdout): + re_string = '\d+ +\d+ %s' % re.escape(s) + return re.search(re_string, stdout) + +objects = [ + 'Action.CommandAction', + 'Builder.BuilderBase', + 'Environment.Base', + 'Executor.Executor', + 'Node.FS', + 'Node.FS.Base', + 'Node.Node', +] + +for args in ['--debug=prepare,count', '--debug=count,prepare']: + test.run(arguments = args) + stdout = test.stdout() + missing = [o for o in objects if find_object_count(o, stdout) is None] + + if missing: + print "Missing the following object lines from '%s' output:" % args + print "\t", ' '.join(missing) + print "STDOUT ==========" + print stdout + test.fail_test(1) + + if 'Preparing target file.out...' not in stdout: + print "Missing 'Preparing' lines from '%s' output:" % args + print "STDOUT ==========" + print stdout + test.fail_test(1) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-objects.py b/test/option/debug-objects.py new file mode 100644 index 0000000..6a919a4 --- /dev/null +++ b/test/option/debug-objects.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that the --debug=objects option works. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +try: + import weakref +except ImportError: + x = "Python version has no 'weakref' module; skipping tests.\n" + test.skip_test(x) + + + +test.write('SConstruct', """ +def cat(target, source, env): + open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read()) +env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))}) +env.Cat('file.out', 'file.in') +""") + +test.write('file.in', "file.in\n") + +# Just check that it runs, we're not overly concerned about the actual +# output at this point. +test.run(arguments = "--debug=objects") + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-pdb.py b/test/option/debug-pdb.py new file mode 100644 index 0000000..d4d285c --- /dev/null +++ b/test/option/debug-pdb.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +env = Environment() +""") + +test.run(arguments = "--debug=pdb", stdin = "n\ns\nq\n") +test.must_contain_all_lines(test.stdout(), ["(Pdb)", "SCons"]) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-prepare.py b/test/option/debug-prepare.py new file mode 100644 index 0000000..350c352 --- /dev/null +++ b/test/option/debug-prepare.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +env=Environment() +dest=env.Command('foo.out', 'SConstruct', + [Copy('$TARGET', '$SOURCE'), + Copy('${TARGET}.extra', '$SOURCE')]) +env.SideEffect('foo.out.extra', dest) +""") + +expect = """\ +Preparing target foo.out... +...with side-effect foo.out.extra... +...Preparing side-effect foo.out.extra... +Copy("foo.out", "SConstruct") +Copy("foo.out.extra", "SConstruct") +Preparing target .... +""" + +test.run(arguments = "--debug=prepare", stdout=test.wrap_stdout(expect)) + +test.must_exist('foo.out') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-presub.py b/test/option/debug-presub.py new file mode 100644 index 0000000..28eeb83 --- /dev/null +++ b/test/option/debug-presub.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.write('cat.py', """\ +import sys +open(sys.argv[2], "wb").write(open(sys.argv[1], "rb").read()) +sys.exit(0) +""") + +test.write('SConstruct', """\ +def cat(env, source, target): + target = str(target[0]) + f = open(target, "wb") + for src in source: + f.write(open(str(src), "rb").read()) + f.close() +FILE = Builder(action="$FILECOM") +TEMP = Builder(action="$TEMPCOM") +LIST = Builder(action="$LISTCOM") +FUNC = Builder(action=cat) +env = Environment(PYTHON=r'%(_python_)s', + BUILDERS = {'FILE':FILE, 'TEMP':TEMP, 'LIST':LIST, 'FUNC':FUNC}, + FILECOM="$PYTHON cat.py $SOURCES $TARGET", + TEMPCOM="$PYTHON cat.py $SOURCES temp\\n$PYTHON cat.py temp $TARGET", + LISTCOM=["$PYTHON cat.py $SOURCES temp", "$PYTHON cat.py temp $TARGET"], + FUNCCOM=cat) +env.Command('file01.out', 'file01.in', "$FILECOM") +env.Command('file02.out', 'file02.in', ["$FILECOM"]) +env.Command('file03.out', 'file03.in', "$TEMPCOM") +env.Command('file04.out', 'file04.in', ["$TEMPCOM"]) +env.Command('file05.out', 'file05.in', "$LISTCOM") +env.Command('file06.out', 'file06.in', ["$LISTCOM"]) +env.Command('file07.out', 'file07.in', cat) +env.Command('file08.out', 'file08.in', "$FUNCCOM") +env.Command('file09.out', 'file09.in', ["$FUNCCOM"]) +env.FILE('file11.out', 'file11.in') +env.FILE('file12.out', 'file12.in') +env.TEMP('file13.out', 'file13.in') +env.TEMP('file14.out', 'file14.in') +env.LIST('file15.out', 'file15.in') +env.LIST('file16.out', 'file16.in') +env.FUNC('file17.out', 'file17.in') +env.FUNC('file18.out', 'file18.in') + +env2 = Environment(PYTHON=r'%(_python_)s', + CCCOM="$PYTHON cat.py $SOURCES $TARGET") +env2.Object('file20.obj', 'file20.c') +""" % locals()) + +test.write('file01.in', "file01.in\n") +test.write('file02.in', "file02.in\n") +test.write('file03.in', "file03.in\n") +test.write('file04.in', "file04.in\n") +test.write('file05.in', "file05.in\n") +test.write('file06.in', "file06.in\n") +test.write('file07.in', "file07.in\n") +test.write('file08.in', "file08.in\n") +test.write('file09.in', "file09.in\n") +test.write('file11.in', "file11.in\n") +test.write('file12.in', "file12.in\n") +test.write('file13.in', "file13.in\n") +test.write('file14.in', "file14.in\n") +test.write('file15.in', "file15.in\n") +test.write('file16.in', "file16.in\n") +test.write('file17.in', "file17.in\n") +test.write('file18.in', "file18.in\n") + +test.write('file20.c', "file20.c\n") + +expect = """\ +Building file01.out with action: + $PYTHON cat.py $SOURCES $TARGET +%(_python_)s cat.py file01.in file01.out +Building file02.out with action: + $PYTHON cat.py $SOURCES $TARGET +%(_python_)s cat.py file02.in file02.out +Building file03.out with action: + $PYTHON cat.py $SOURCES temp +%(_python_)s cat.py file03.in temp +Building file03.out with action: + $PYTHON cat.py temp $TARGET +%(_python_)s cat.py temp file03.out +Building file04.out with action: + $PYTHON cat.py $SOURCES temp +%(_python_)s cat.py file04.in temp +Building file04.out with action: + $PYTHON cat.py temp $TARGET +%(_python_)s cat.py temp file04.out +Building file05.out with action: + $PYTHON cat.py $SOURCES temp +%(_python_)s cat.py file05.in temp +Building file05.out with action: + $PYTHON cat.py temp $TARGET +%(_python_)s cat.py temp file05.out +Building file06.out with action: + $PYTHON cat.py $SOURCES temp +%(_python_)s cat.py file06.in temp +Building file06.out with action: + $PYTHON cat.py temp $TARGET +%(_python_)s cat.py temp file06.out +Building file07.out with action: + cat(target, source, env) +cat(["file07.out"], ["file07.in"]) +Building file08.out with action: + cat(target, source, env) +cat(["file08.out"], ["file08.in"]) +Building file09.out with action: + cat(target, source, env) +cat(["file09.out"], ["file09.in"]) +Building file11.out with action: + $PYTHON cat.py $SOURCES $TARGET +%(_python_)s cat.py file11.in file11.out +Building file12.out with action: + $PYTHON cat.py $SOURCES $TARGET +%(_python_)s cat.py file12.in file12.out +Building file13.out with action: + $PYTHON cat.py $SOURCES temp +%(_python_)s cat.py file13.in temp +Building file13.out with action: + $PYTHON cat.py temp $TARGET +%(_python_)s cat.py temp file13.out +Building file14.out with action: + $PYTHON cat.py $SOURCES temp +%(_python_)s cat.py file14.in temp +Building file14.out with action: + $PYTHON cat.py temp $TARGET +%(_python_)s cat.py temp file14.out +Building file15.out with action: + $PYTHON cat.py $SOURCES temp +%(_python_)s cat.py file15.in temp +Building file15.out with action: + $PYTHON cat.py temp $TARGET +%(_python_)s cat.py temp file15.out +Building file16.out with action: + $PYTHON cat.py $SOURCES temp +%(_python_)s cat.py file16.in temp +Building file16.out with action: + $PYTHON cat.py temp $TARGET +%(_python_)s cat.py temp file16.out +Building file17.out with action: + cat(target, source, env) +cat(["file17.out"], ["file17.in"]) +Building file18.out with action: + cat(target, source, env) +cat(["file18.out"], ["file18.in"]) +Building file20.obj with action: + $PYTHON cat.py $SOURCES $TARGET +%(_python_)s cat.py file20.c file20.obj +""" % locals() + +test.run(arguments = "--debug=presub .", stdout=test.wrap_stdout(expect)) + +test.must_match('file01.out', "file01.in\n") +test.must_match('file02.out', "file02.in\n") +test.must_match('file03.out', "file03.in\n") +test.must_match('file04.out', "file04.in\n") +test.must_match('file05.out', "file05.in\n") +test.must_match('file06.out', "file06.in\n") +test.must_match('file07.out', "file07.in\n") +test.must_match('file08.out', "file08.in\n") +test.must_match('file09.out', "file09.in\n") +test.must_match('file11.out', "file11.in\n") +test.must_match('file12.out', "file12.in\n") +test.must_match('file13.out', "file13.in\n") +test.must_match('file14.out', "file14.in\n") +test.must_match('file15.out', "file15.in\n") +test.must_match('file16.out', "file16.in\n") +test.must_match('file17.out', "file17.in\n") +test.must_match('file18.out', "file18.in\n") + +test.must_match('file20.obj', "file20.c\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-stacktrace.py b/test/option/debug-stacktrace.py new file mode 100644 index 0000000..fcc4c1b --- /dev/null +++ b/test/option/debug-stacktrace.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test the --debug=stacktrace option. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +def kfile_scan(node, env, target): + raise Exception("kfile_scan error") + +kscan = Scanner(name = 'kfile', + function = kfile_scan, + skeys = ['.k']) + +env = Environment() +env.Append(SCANNERS = [kscan]) + +env.Command('foo', 'foo.k', Copy('$TARGET', '$SOURCE')) +""") + +test.write('foo.k', "foo.k\n") + +test.run(status = 2, stderr = "scons: *** [foo] Exception : kfile_scan error\n") + +test.run(arguments = "--debug=stacktrace", + status = 2, + stderr = None) + +lines = [ + "scons: *** [foo] Exception : kfile_scan error", + "scons: internal stack trace:", + 'raise Exception("kfile_scan error")', +] + +test.must_contain_all_lines(test.stderr(), lines) + + + +# Test that --debug=stacktrace works for UserError exceptions, +# which are handled by different code than other exceptions. + +test.write('SConstruct', """\ +import SCons.Errors +raise SCons.Errors.UserError("explicit UserError!") +""") + +test.run(arguments = '--debug=stacktrace', + status = 2, + stderr = None) + +user_error_lines = [ + 'UserError: explicit UserError!', + 'scons: *** explicit UserError!', +] + +# The "(most recent call last)" message is used by more recent Python +# versions than the "(innermost last)" message, so that's the one +# we report if neither matches. +traceback_lines = [ + "Traceback (most recent call last)", + "Traceback (innermost last)", +] + +test.must_contain_all_lines(test.stderr(), user_error_lines) +test.must_contain_any_line(test.stderr(), traceback_lines) + +# Test that full path names to SConscript files show up in stack traces. + +test.write('SConstruct', """\ +1/0 +""") + +test.run(arguments = '--debug=stacktrace', + status = 2, + stderr = None) + +lines = [ + ' File "%s", line 1:' % test.workpath('SConstruct'), +] + +test.must_contain_all_lines(test.stderr(), lines) + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-time.py b/test/option/debug-time.py new file mode 100644 index 0000000..198d71d --- /dev/null +++ b/test/option/debug-time.py @@ -0,0 +1,221 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +from __future__ import division + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons +import re +import time + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.write('sleep_cat.py', """\ +import sys +import time +time.sleep(int(sys.argv[1])) +fp = open(sys.argv[2], 'wb') +for arg in sys.argv[3:]: + fp.write(open(arg, 'rb').read()) +fp.close() +sys.exit(0) +""") + +test.write('SConstruct', """ +env = Environment(PYTHON = r'%(_python_)s', + SLEEP_CAT = r'sleep_cat.py', + CATCOM = '$PYTHON $SLEEP_CAT $SECONDS $TARGET $SOURCES', + SECONDS = ARGUMENTS.get('SLEEP', '0')) +f1 = env.Command('f1.out', 'f1.in', '$CATCOM') +f2 = env.Command('f2.out', 'f2.in', '$CATCOM') +f3 = env.Command('f3.out', 'f3.in', '$CATCOM') +f4 = env.Command('f4.out', 'f4.in', '$CATCOM') +env.Command('output', [f1, f2, f3, f4], '$CATCOM') +""" % locals()) + +test.write('f1.in', "f1.in\n") +test.write('f2.in', "f2.in\n") +test.write('f3.in', "f3.in\n") +test.write('f4.in', "f4.in\n") + +expected_targets = ['f1.out', 'f2.out', 'f3.out', 'f4.out', 'output', '.'] + +# Before anything else, make sure we get valid --debug=time results +# when just running the help option. +test.run(arguments = "-h --debug=time") + + + +def num(s, match): + return float(re.search(match, s).group(1)) + +def within_tolerance(expected, actual, tolerance): + return abs((expected-actual)/actual) <= tolerance + +def get_total_time(stdout): + return num(stdout, r'Total build time: (\d+\.\d+) seconds') + +def get_sconscript_time(stdout): + return num(stdout, r'Total SConscript file execution time: (\d+\.\d+) seconds') + +def get_scons_time(stdout): + return num(stdout, r'Total SCons execution time: (\d+\.\d+) seconds') + +def get_command_time(stdout): + return num(stdout, r'Total command execution time: (\d+\.\d+) seconds') + + + +# Try to make our results a little more accurate and repeatable by +# measuring Python overhead executing a minimal file, and reading the +# scons.py script itself from disk so that it's already been cached. +test.write('pass.py', "pass\n") +test.read(test.program) + +start_time = time.time() +test.run(program=TestSCons.python, arguments=test.workpath('pass.py')) +overhead = time.time() - start_time + + + +start_time = time.time() +test.run(arguments = "-j1 --debug=time . SLEEP=0") +complete_time = time.time() - start_time + + + +expected_total_time = complete_time - overhead + +pattern = r'Command execution time: (.*): (\d+\.\d+) seconds' +targets = [] +times = [] +for target,time in re.findall(pattern, test.stdout()): + targets.append(target) + times.append(float(time)) +expected_command_time = 0.0 +for t in times: + expected_command_time += t + + +stdout = test.stdout() + +total_time = get_total_time(stdout) +sconscript_time = get_sconscript_time(stdout) +scons_time = get_scons_time(stdout) +command_time = get_command_time(stdout) + +failures = [] +warnings = [] + +if targets != expected_targets: + failures.append("""\ +Scons reported the targets of timing information as %(targets)s, +but the actual targets should have been %(expected_targets)s. +""" %locals()) + +if not within_tolerance(expected_command_time, command_time, 0.01): + failures.append("""\ +SCons -j1 reported a total command execution time of %(command_time)s, +but command execution times really totalled %(expected_command_time)s, +outside of the 1%% tolerance. +""" % locals()) + +added_times = sconscript_time+scons_time+command_time +if not within_tolerance(total_time, added_times, 0.01): + failures.append("""\ +SCons -j1 reported a total build time of %(total_time)s, +but the various execution times actually totalled %(added_times)s, +outside of the 1%% tolerance. +""" % locals()) + +if not within_tolerance(total_time, expected_total_time, 0.20): + # This tolerance check seems empirically to work fine if there's + # a light load on the system, but on a heavily loaded system the + # timings get screwy and it can fail frequently. Some obvious + # attempts to work around the problem didn't, so just treat it as + # a warning for now. + warnings.append("""\ +Warning: SCons -j1 reported total build time of %(total_time)s, +but the actual measured build time was %(expected_total_time)s +(end-to-end time of %(complete_time)s less Python overhead of %(overhead)s), +outside of the 15%% tolerance. +""" % locals()) + +if failures or warnings: + print '\n'.join([test.stdout()] + failures + warnings) +if failures: + test.fail_test(1) + +test.run(arguments = "--debug=time . SLEEP=0") + +command_time = get_command_time(test.stdout()) +if command_time != 0.0: + print "Up-to-date run received non-zero command time of %s" % command_time + test.fail_test() + + + +test.run(arguments = "-c") + +test.run(arguments = "-j4 --debug=time . SLEEP=1") + + + +stdout = test.stdout() + +total_time = get_total_time(stdout) +sconscript_time = get_sconscript_time(stdout) +scons_time = get_scons_time(stdout) +command_time = get_command_time(stdout) + +failures = [] + +added_times = sconscript_time+scons_time+command_time +if not within_tolerance(total_time, added_times, 0.01): + failures.append("""\ +SCons -j4 reported a total build time of %(total_time)s, +but the various execution times actually totalled %(added_times)s, +outside of the 1%% tolerance. +""" % locals()) + +if failures: + print '\n'.join([test.stdout()] + failures) + test.fail_test(1) + +test.run(arguments = "-j4 --debug=time . SLEEP=1") + +command_time = get_command_time(test.stdout()) +if command_time != 0.0: + print "Up-to-date run received non-zero command time of %s" % command_time + test.fail_test() + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/environment-overrides.py b/test/option/environment-overrides.py new file mode 100644 index 0000000..8680e2c --- /dev/null +++ b/test/option/environment-overrides.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that the -e and --environment-overrides options are ignored. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', "") + +test.run(arguments = '-e .', + stderr = "Warning: ignoring -e option\n") + +test.run(arguments = '--environment-overrides .', + stderr = "Warning: ignoring --environment-overrides option\n") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/h.py b/test/option/h.py new file mode 100644 index 0000000..adcec3a --- /dev/null +++ b/test/option/h.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +test = TestSCons.TestSCons() + +test.run(arguments = '-h') +test.must_contain_all_lines(test.stdout(), ['-h, --help']) + +test.run(arguments = '-u -h') +test.must_contain_all_lines(test.stdout(), ['-h, --help']) + +test.run(arguments = '-U -h') +test.must_contain_all_lines(test.stdout(), ['-h, --help']) + +test.run(arguments = '-D -h') +test.must_contain_all_lines(test.stdout(), ['-h, --help']) + +test.write('SConstruct', "") + +test.run(arguments = '-h') +test.must_contain_all_lines(test.stdout(), ['-h, --help']) + +test.run(arguments = '-u -h') +test.must_contain_all_lines(test.stdout(), ['-h, --help']) + +test.run(arguments = '-U -h') +test.must_contain_all_lines(test.stdout(), ['-h, --help']) + +test.run(arguments = '-D -h') +test.must_contain_all_lines(test.stdout(), ['-h, --help']) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/help-options.py b/test/option/help-options.py new file mode 100644 index 0000000..45bbfa0 --- /dev/null +++ b/test/option/help-options.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify behavior of the -H and --help-options options. +""" + +import re + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', "") + +test.run(arguments = '-H') + +expect = [ + '-H, --help-options', + '--debug=TYPE', +] +test.must_contain_all_lines(test.stdout(), expect) + +# Validate that the help output lists the options in case-insensitive +# alphabetical order. + +# Don't include in the sorted comparison the options that are ignored +# for compatibility. They're all printed at the top of the list. +ignored_re = re.compile('.*Ignored for compatibility\\.\n', re.S) +stdout = ignored_re.sub('', test.stdout()) + +lines = stdout.split('\n') +lines = [x for x in lines if x[:3] == ' -'] +lines = [x[3:] for x in lines] +lines = [x[0] == '-' and x[1:] or x for x in lines] +options = [x.split()[0] for x in lines] +options = [x[-1] == ',' and x[:-1] or x for x in options] +lowered = [x.lower() for x in options] +ordered = sorted(lowered) +if lowered != ordered: + print "lowered =", lowered + print "sorted =", ordered + test.fail_test() + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/md5-chunksize.py b/test/option/md5-chunksize.py new file mode 100644 index 0000000..dbb2615 --- /dev/null +++ b/test/option/md5-chunksize.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.write('build.py', r""" +import sys +contents = open(sys.argv[2], 'rb').read() +file = open(sys.argv[1], 'wb') +file.write(contents) +file.close() +""") + +test.write('SConstruct', """ +SetOption('md5_chunksize', 128) +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) +f1 = env.B(target = 'f1.out', source = 'f1.in') +f2 = env.B(target = 'f2.out', source = 'f2.in') +Requires(f2, f1) +""" % locals()) + +test.write('f1.in', str(list(range(10)))) +test.write('f2.in', str(list(range(100000)))) + +expected_stdout = test.wrap_stdout("""\ +%(_python_)s build.py f1.out f1.in +%(_python_)s build.py f2.out f2.in +""" % locals()) + +# +# Test with SetOption('md5_chunksize') +# +test.run(arguments = '.', + stdout=expected_stdout, + stderr='') +test.must_exist('f1.out') +test.must_exist('f2.out') + +test.run(arguments = '-c .') +test.must_not_exist('f1.out') +test.must_not_exist('f2.out') + +# +# Test with --md5-chunksize +# +test.run(arguments = '--md5-chunksize=128 .', + stdout=expected_stdout, + stderr='') +test.must_exist('f1.out') +test.must_exist('f2.out') + +test.run(arguments = '--md5-chunksize=128 -c .') +test.must_not_exist('f1.out') +test.must_not_exist('f2.out') + +test.pass_test() + +# +# Big-file test +# +test2 = TestSCons.TestSCons() + +if sys.platform.find('linux') == -1: + test2.skip_test("skipping test on non-Linux platform '%s'\n" % sys.platform) + +dd = test2.where_is('dd') + +if not dd: + test2.skip_test('dd not found; skipping test\n') + +expected_stdout = test2.wrap_stdout("""\ +dd if=/dev/zero of=test.big seek=100 bs=1M count=0 2>/dev/null +get_stat(["test.stat"], ["test.big"]) +""") + +test2.write('SConstruct', """ +import os +def get_stat(target, source, env): + stat = os.stat(source[0].get_abspath()) + dest = open(target[0].get_abspath(),'w') + dest.write(str(stat)) + dest.close() +env = Environment() +env.Command('test.big', 'SConstruct', 'dd if=/dev/zero of=test.big seek=100 bs=1M count=0 2>/dev/null') +env.AlwaysBuild('test.big') +env.Command('test.stat', 'test.big', Action(get_stat)) +""") + +test2.run(arguments='--md5-chunksize=128', stdout=expected_stdout, stderr='') +test2.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/no-print-directory.py b/test/option/no-print-directory.py new file mode 100644 index 0000000..850a484 --- /dev/null +++ b/test/option/no-print-directory.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that the --no-print-directory option is ignored. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', "") + +test.run(arguments = '--no-print-directory .', + stderr = "Warning: ignoring --no-print-directory option\n") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/print-directory.py b/test/option/print-directory.py new file mode 100644 index 0000000..96d9d7b --- /dev/null +++ b/test/option/print-directory.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that the -w and --print-directory options are ignored. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', "") + +test.run(arguments = '-w .', + stderr = "Warning: ignoring -w option\n") + +test.run(arguments = '--print-directory .', + stderr = "Warning: ignoring --print-directory option\n") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/profile.py b/test/option/profile.py new file mode 100644 index 0000000..d53c690 --- /dev/null +++ b/test/option/profile.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import sys +try: + import io + _StringIO = io.StringIO +except (ImportError, AttributeError): + # Pre-2.6 Python has no "io" module. + exec('from cStringIO import StringIO') +else: + # TODO(2.6): In 2.6 and beyond, the io.StringIO.write() method + # requires unicode strings. This subclass can probably be removed + # when we drop support for Python 2.6. + class StringIO(_StringIO): + def write(self, s): + _StringIO.write(self, unicode(s)) + +import TestSCons + +test = TestSCons.TestSCons() + +try: + import pstats +except ImportError: + test.skip_test('No pstats module, skipping test.\n') + +test.write('SConstruct', """\ +Command('file.out', 'file.in', Copy("$TARGET", "$SOURCE")) +""") + +test.write('file.in', "file.in\n") + +scons_prof = test.workpath('scons.prof') + +test.run(arguments = "--profile=%s -h" % scons_prof) +test.must_contain_all_lines(test.stdout(), ['usage: scons [OPTION]']) + +try: + save_stdout = sys.stdout + sys.stdout = StringIO() + + stats = pstats.Stats(scons_prof) + stats.sort_stats('time') + + stats.strip_dirs().print_stats() + + s = sys.stdout.getvalue() +finally: + sys.stdout = save_stdout + +test.must_contain_all_lines(s, ['Main.py', '_main']) + + + +scons_prof = test.workpath('scons2.prof') + +test.run(arguments = "--profile %s" % scons_prof) + +try: + save_stdout = sys.stdout + sys.stdout = StringIO() + + stats = pstats.Stats(scons_prof) + stats.sort_stats('time') + + stats.strip_dirs().print_stats() + + s = sys.stdout.getvalue() +finally: + sys.stdout = save_stdout + +test.must_contain_all_lines(s, ['Main.py', '_main', 'FS.py']) + + + +scons_prof = test.workpath('scons3.prof') + +test.run(arguments = "--profile %s --debug=memory -h" % scons_prof) +expect = [ + 'usage: scons [OPTION]', + 'Options:' +] +test.must_contain_all_lines(test.stdout(), expect) + +expect = 'Memory before reading SConscript files' +lines = test.stdout().split('\n') +memory_lines = [l for l in lines if l.find(expect) != -1] + +test.fail_test(len(memory_lines) != 1) + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/repository.py b/test/option/repository.py new file mode 100644 index 0000000..a71e71e --- /dev/null +++ b/test/option/repository.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that the --srcdir option works to fetch things from a repository. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('repository', 'work1') + +repository = test.workpath('repository') + +test.write(['repository', 'SConstruct'], """\ +env = Environment() +env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) +""") + +test.write(['repository', 'file.in'], "repository/file.in\n") + +opts = '--repository ' + repository + +# Make the entire repository non-writable, so we'll detect +# if we try to write into it accidentally. +test.writable('repository', 0) + +test.run(chdir = 'work1', options = opts, arguments = '.') + +test.must_match(['work1', 'file.out'], "repository/file.in\n") + +test.up_to_date(chdir = 'work1', options = opts, arguments = '.') + + + +# +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/srcdir.py b/test/option/srcdir.py new file mode 100644 index 0000000..0a92f13 --- /dev/null +++ b/test/option/srcdir.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that the --srcdir option works to fetch things from a repository. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('repository', 'work1') + +repository = test.workpath('repository') + +test.write(['repository', 'SConstruct'], r""" +env = Environment() +env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) +""") + +test.write(['repository', 'file.in'], "repository/file.in\n") + +opts = '--srcdir ' + repository + +# Make the entire repository non-writable, so we'll detect +# if we try to write into it accidentally. +test.writable('repository', 0) + +test.run(chdir = 'work1', options = opts, arguments = '.') + +test.must_match(['work1', 'file.out'], "repository/file.in\n") + +test.up_to_date(chdir = 'work1', options = opts, arguments = '.') + + + +# +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/stack-size.py b/test/option/stack-size.py new file mode 100644 index 0000000..3d7a715 --- /dev/null +++ b/test/option/stack-size.py @@ -0,0 +1,361 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +isStackSizeAvailable = False +try: + import threading + isStackSizeAvailable = hasattr(threading,'stack_size') +except ImportError: + pass + +test.subdir('work1', 'work2') + +test.write('build.py', r""" +import sys +contents = open(sys.argv[2], 'rb').read() +file = open(sys.argv[1], 'wb') +file.write(contents) +file.close() +""") + + +test.write(['work1', 'SConstruct'], """ +B = Builder(action = r'%(_python_)s ../build.py $TARGETS $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) +f1 = env.B(target = 'f1.out', source = 'f1.in') +f2 = env.B(target = 'f2.out', source = 'f2.in') +Requires(f2, f1) +""" % locals()) + +test.write(['work1', 'f1.in'], "f1.in\n") +test.write(['work1', 'f2.in'], "f2.in\n") + + +test.write(['work2', 'SConstruct'], """ +SetOption('stack_size', 128) +B = Builder(action = r'%(_python_)s ../build.py $TARGETS $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) +f1 = env.B(target = 'f1.out', source = 'f1.in') +f2 = env.B(target = 'f2.out', source = 'f2.in') +Requires(f2, f1) +""" % locals()) + +test.write(['work2', 'f1.in'], "f1.in\n") +test.write(['work2', 'f2.in'], "f2.in\n") + + + +expected_stdout = test.wrap_stdout("""\ +%(_python_)s ../build.py f1.out f1.in +%(_python_)s ../build.py f2.out f2.in +""" % locals()) + +re_expected_stdout = expected_stdout.replace('\\', '\\\\') + +expect_unsupported = """ +scons: warning: Setting stack size is unsupported by this version of Python: + (('module' object|'threading' module) has no attribute 'stack_size'|stack_size) +File .* +""" + + +# +# Test without any options +# +test.run(chdir='work1', + arguments = '.', + stdout=expected_stdout, + stderr='') +test.must_exist(['work1', 'f1.out']) +test.must_exist(['work1', 'f2.out']) + +test.run(chdir='work1', + arguments = '-c .') +test.must_not_exist(['work1', 'f1.out']) +test.must_not_exist(['work1', 'f2.out']) + +# +# Test with -j2 +# +test.run(chdir='work1', + arguments = '-j2 .', + stdout=expected_stdout, + stderr='') +test.must_exist(['work1', 'f1.out']) +test.must_exist(['work1', 'f2.out']) + +test.run(chdir='work1', + arguments = '-j2 -c .') +test.must_not_exist(['work1', 'f1.out']) +test.must_not_exist(['work1', 'f2.out']) + + +# +# Test with --stack-size +# +test.run(chdir='work1', + arguments = '--stack-size=128 .', + stdout=expected_stdout, + stderr='') +test.must_exist(['work1', 'f1.out']) +test.must_exist(['work1', 'f2.out']) + +test.run(chdir='work1', + arguments = '--stack-size=128 -c .') +test.must_not_exist(['work1', 'f1.out']) +test.must_not_exist(['work1', 'f2.out']) + +# +# Test with SetOption('stack_size', 128) +# +test.run(chdir='work2', + arguments = '.', + stdout=expected_stdout, + stderr='') +test.must_exist(['work2', 'f1.out']) +test.must_exist(['work2', 'f2.out']) + +test.run(chdir='work2', + arguments = '--stack-size=128 -c .') +test.must_not_exist(['work2', 'f1.out']) +test.must_not_exist(['work2', 'f2.out']) + +if isStackSizeAvailable: + # + # Test with -j2 --stack-size=128 + # + test.run(chdir='work1', + arguments = '-j2 --stack-size=128 .', + stdout=expected_stdout, + stderr='') + test.must_exist(['work1', 'f1.out']) + test.must_exist(['work1', 'f2.out']) + + test.run(chdir='work1', + arguments = '-j2 --stack-size=128 -c .') + test.must_not_exist(['work1', 'f1.out']) + test.must_not_exist(['work1', 'f2.out']) + + # + # Test with -j2 --stack-size=16 + # + test.run(chdir='work1', + arguments = '-j2 --stack-size=16 .', + match=TestSCons.match_re, + stdout=re_expected_stdout, + stderr=""" +scons: warning: Setting stack size failed: + size not valid: 16384 bytes +File .* +""") + test.must_exist(['work1', 'f1.out']) + test.must_exist(['work1', 'f2.out']) + + test.run(chdir='work1', + arguments = '-j2 --stack-size=16 -c .', + match=TestSCons.match_re, + stderr=""" +scons: warning: Setting stack size failed: + size not valid: 16384 bytes +File .* +""") + test.must_not_exist(['work1', 'f1.out']) + test.must_not_exist(['work1', 'f2.out']) + + # + # Test with -j2 SetOption('stack_size', 128) + # + test.run(chdir='work2', + arguments = '-j2 .', + stdout=expected_stdout, + stderr='') + test.must_exist(['work2', 'f1.out']) + test.must_exist(['work2', 'f2.out']) + + test.run(chdir='work2', + arguments = '-j2 -c .') + test.must_not_exist(['work2', 'f1.out']) + test.must_not_exist(['work2', 'f2.out']) + + # + # Test with -j2 --stack-size=128 --warn=no-stack-size + # + test.run(chdir='work1', + arguments = '-j2 --stack-size=128 --warn=no-stack-size .', + stdout=expected_stdout, + stderr='') + test.must_exist(['work1', 'f1.out']) + test.must_exist(['work1', 'f2.out']) + + test.run(chdir='work1', + arguments = '-j2 --stack-size=128 --warn=no-stack-size -c .') + test.must_not_exist(['work1', 'f1.out']) + test.must_not_exist(['work1', 'f2.out']) + + # + # Test with -j2 --stack-size=16 --warn=no-stack-size + # + test.run(chdir='work1', + arguments = '-j2 --stack-size=16 --warn=no-stack-size .', + stdout=expected_stdout, + stderr='') + test.must_exist(['work1', 'f1.out']) + test.must_exist(['work1', 'f2.out']) + + test.run(chdir='work1', + arguments = '-j2 --stack-size=16 --warn=no-stack-size -c .') + test.must_not_exist(['work1', 'f1.out']) + test.must_not_exist(['work1', 'f2.out']) + + # + # Test with -j2 --warn=no-stack-size SetOption('stack_size', 128) + # + test.run(chdir='work2', + arguments = '-j2 --warn=no-stack-size .', + stdout=expected_stdout, + stderr='') + test.must_exist(['work2', 'f1.out']) + test.must_exist(['work2', 'f2.out']) + + test.run(chdir='work2', + arguments = '-j2 --warn=no-stack-size -c .') + test.must_not_exist(['work2', 'f1.out']) + test.must_not_exist(['work2', 'f2.out']) + +else: + + # + # Test with -j2 --stack-size=128 + # + test.run(chdir='work1', + arguments = '-j2 --stack-size=128 .', + match=TestSCons.match_re, + stdout=re_expected_stdout, + stderr=expect_unsupported) + test.must_exist(['work1', 'f1.out']) + test.must_exist(['work1', 'f2.out']) + + test.run(chdir='work1', + arguments = '-j2 --stack-size=128 -c .', + match=TestSCons.match_re, + stderr=expect_unsupported) + test.must_not_exist(['work1', 'f1.out']) + test.must_not_exist(['work1', 'f2.out']) + + # + # Test with -j2 --stack-size=16 + # + test.run(chdir='work1', + arguments = '-j2 --stack-size=16 .', + match=TestSCons.match_re, + stdout=re_expected_stdout, + stderr=expect_unsupported) + test.must_exist(['work1', 'f1.out']) + test.must_exist(['work1', 'f2.out']) + + test.run(chdir='work1', + arguments = '-j2 --stack-size=16 -c .', + match=TestSCons.match_re, + stderr=expect_unsupported) + test.must_not_exist(['work1', 'f1.out']) + test.must_not_exist(['work1', 'f2.out']) + + # + # Test with -j2 SetOption('stack_size', 128) + # + test.run(chdir='work2', + arguments = '-j2 .', + match=TestSCons.match_re, + stdout=re_expected_stdout, + stderr=expect_unsupported) + test.must_exist(['work2', 'f1.out']) + test.must_exist(['work2', 'f2.out']) + + test.run(chdir='work2', + arguments = '-j2 -c .', + match=TestSCons.match_re, + stderr=expect_unsupported) + test.must_not_exist(['work2', 'f1.out']) + test.must_not_exist(['work2', 'f2.out']) + + # + # Test with -j2 --stack-size=128 --warn=no-stack-size + # + test.run(chdir='work1', + arguments = '-j2 --stack-size=128 --warn=no-stack-size .', + stdout=expected_stdout, + stderr='') + test.must_exist(['work1', 'f1.out']) + test.must_exist(['work1', 'f2.out']) + + test.run(chdir='work1', + arguments = '-j2 --stack-size=128 --warn=no-stack-size -c .') + test.must_not_exist(['work1', 'f1.out']) + test.must_not_exist(['work1', 'f2.out']) + + # + # Test with -j2 --stack-size=16 --warn=no-stack-size + # + test.run(chdir='work1', + arguments = '-j2 --stack-size=16 --warn=no-stack-size .', + stdout=expected_stdout, + stderr='') + test.must_exist(['work1', 'f1.out']) + test.must_exist(['work1', 'f2.out']) + + test.run(chdir='work1', + arguments = '-j2 --stack-size=16 --warn=no-stack-size -c .') + test.must_not_exist(['work1', 'f1.out']) + test.must_not_exist(['work1', 'f2.out']) + + # + # Test with -j2 --warn=no-stack-size SetOption('stack_size', 128) + # + test.run(chdir='work2', + arguments = '-j2 --warn=no-stack-size .', + stdout=expected_stdout, + stderr='') + test.must_exist(['work2', 'f1.out']) + test.must_exist(['work2', 'f2.out']) + + test.run(chdir='work2', + arguments = '-j2 --warn=no-stack-size -c .') + test.must_not_exist(['work2', 'f1.out']) + test.must_not_exist(['work2', 'f2.out']) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/taskmastertrace.py b/test/option/taskmastertrace.py new file mode 100644 index 0000000..28f4574 --- /dev/null +++ b/test/option/taskmastertrace.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Simple tests of the --taskmastertrace= option. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +env = Environment() + +# We name the files 'Tfile' so that they will sort after the SConstruct +# file regardless of whether the test is being run on a case-sensitive +# or case-insensitive system. + +env.Command('Tfile.out', 'Tfile.mid', Copy('$TARGET', '$SOURCE')) +env.Command('Tfile.mid', 'Tfile.in', Copy('$TARGET', '$SOURCE')) +""") + +test.write('Tfile.in', "Tfile.in\n") + +expect_stdout = test.wrap_stdout("""\ + +Taskmaster: Looking for a node to evaluate +Taskmaster: Considering node <no_state 0 '.'> and its children: +Taskmaster: <no_state 0 'SConstruct'> +Taskmaster: <no_state 0 'Tfile.in'> +Taskmaster: <no_state 0 'Tfile.mid'> +Taskmaster: <no_state 0 'Tfile.out'> +Taskmaster: adjusted ref count: <pending 1 '.'>, child 'SConstruct' +Taskmaster: adjusted ref count: <pending 2 '.'>, child 'Tfile.in' +Taskmaster: adjusted ref count: <pending 3 '.'>, child 'Tfile.mid' +Taskmaster: adjusted ref count: <pending 4 '.'>, child 'Tfile.out' +Taskmaster: Considering node <no_state 0 'SConstruct'> and its children: +Taskmaster: Evaluating <pending 0 'SConstruct'> + +Task.make_ready_current(): node <pending 0 'SConstruct'> +Task.prepare(): node <up_to_date 0 'SConstruct'> +Task.executed_with_callbacks(): node <up_to_date 0 'SConstruct'> +Task.postprocess(): node <up_to_date 0 'SConstruct'> +Task.postprocess(): removing <up_to_date 0 'SConstruct'> +Task.postprocess(): adjusted parent ref count <pending 3 '.'> + +Taskmaster: Looking for a node to evaluate +Taskmaster: Considering node <no_state 0 'Tfile.in'> and its children: +Taskmaster: Evaluating <pending 0 'Tfile.in'> + +Task.make_ready_current(): node <pending 0 'Tfile.in'> +Task.prepare(): node <up_to_date 0 'Tfile.in'> +Task.executed_with_callbacks(): node <up_to_date 0 'Tfile.in'> +Task.postprocess(): node <up_to_date 0 'Tfile.in'> +Task.postprocess(): removing <up_to_date 0 'Tfile.in'> +Task.postprocess(): adjusted parent ref count <pending 2 '.'> + +Taskmaster: Looking for a node to evaluate +Taskmaster: Considering node <no_state 0 'Tfile.mid'> and its children: +Taskmaster: <up_to_date 0 'Tfile.in'> +Taskmaster: Evaluating <pending 0 'Tfile.mid'> + +Task.make_ready_current(): node <pending 0 'Tfile.mid'> +Task.prepare(): node <executing 0 'Tfile.mid'> +Task.execute(): node <executing 0 'Tfile.mid'> +Copy("Tfile.mid", "Tfile.in") +Task.executed_with_callbacks(): node <executing 0 'Tfile.mid'> +Task.postprocess(): node <executed 0 'Tfile.mid'> +Task.postprocess(): removing <executed 0 'Tfile.mid'> +Task.postprocess(): adjusted parent ref count <pending 1 '.'> + +Taskmaster: Looking for a node to evaluate +Taskmaster: Considering node <no_state 0 'Tfile.out'> and its children: +Taskmaster: <executed 0 'Tfile.mid'> +Taskmaster: Evaluating <pending 0 'Tfile.out'> + +Task.make_ready_current(): node <pending 0 'Tfile.out'> +Task.prepare(): node <executing 0 'Tfile.out'> +Task.execute(): node <executing 0 'Tfile.out'> +Copy("Tfile.out", "Tfile.mid") +Task.executed_with_callbacks(): node <executing 0 'Tfile.out'> +Task.postprocess(): node <executed 0 'Tfile.out'> +Task.postprocess(): removing <executed 0 'Tfile.out'> +Task.postprocess(): adjusted parent ref count <pending 0 '.'> + +Taskmaster: Looking for a node to evaluate +Taskmaster: Considering node <pending 0 '.'> and its children: +Taskmaster: <up_to_date 0 'SConstruct'> +Taskmaster: <up_to_date 0 'Tfile.in'> +Taskmaster: <executed 0 'Tfile.mid'> +Taskmaster: <executed 0 'Tfile.out'> +Taskmaster: Evaluating <pending 0 '.'> + +Task.make_ready_current(): node <pending 0 '.'> +Task.prepare(): node <executing 0 '.'> +Task.execute(): node <executing 0 '.'> +Task.executed_with_callbacks(): node <executing 0 '.'> +Task.postprocess(): node <executed 0 '.'> + +Taskmaster: Looking for a node to evaluate +Taskmaster: No candidate anymore. + +""") + +test.run(arguments='--taskmastertrace=- .', stdout=expect_stdout) + + + +test.run(arguments='-c .') + + + +expect_stdout = test.wrap_stdout("""\ +Copy("Tfile.mid", "Tfile.in") +Copy("Tfile.out", "Tfile.mid") +""") + +test.run(arguments='--taskmastertrace=trace.out .', stdout=expect_stdout) + +expect_trace = """\ + +Taskmaster: Looking for a node to evaluate +Taskmaster: Considering node <no_state 0 '.'> and its children: +Taskmaster: <no_state 0 'SConstruct'> +Taskmaster: <no_state 0 'Tfile.in'> +Taskmaster: <no_state 0 'Tfile.mid'> +Taskmaster: <no_state 0 'Tfile.out'> +Taskmaster: adjusted ref count: <pending 1 '.'>, child 'SConstruct' +Taskmaster: adjusted ref count: <pending 2 '.'>, child 'Tfile.in' +Taskmaster: adjusted ref count: <pending 3 '.'>, child 'Tfile.mid' +Taskmaster: adjusted ref count: <pending 4 '.'>, child 'Tfile.out' +Taskmaster: Considering node <no_state 0 'SConstruct'> and its children: +Taskmaster: Evaluating <pending 0 'SConstruct'> + +Task.make_ready_current(): node <pending 0 'SConstruct'> +Task.prepare(): node <up_to_date 0 'SConstruct'> +Task.executed_with_callbacks(): node <up_to_date 0 'SConstruct'> +Task.postprocess(): node <up_to_date 0 'SConstruct'> +Task.postprocess(): removing <up_to_date 0 'SConstruct'> +Task.postprocess(): adjusted parent ref count <pending 3 '.'> + +Taskmaster: Looking for a node to evaluate +Taskmaster: Considering node <no_state 0 'Tfile.in'> and its children: +Taskmaster: Evaluating <pending 0 'Tfile.in'> + +Task.make_ready_current(): node <pending 0 'Tfile.in'> +Task.prepare(): node <up_to_date 0 'Tfile.in'> +Task.executed_with_callbacks(): node <up_to_date 0 'Tfile.in'> +Task.postprocess(): node <up_to_date 0 'Tfile.in'> +Task.postprocess(): removing <up_to_date 0 'Tfile.in'> +Task.postprocess(): adjusted parent ref count <pending 2 '.'> + +Taskmaster: Looking for a node to evaluate +Taskmaster: Considering node <no_state 0 'Tfile.mid'> and its children: +Taskmaster: <up_to_date 0 'Tfile.in'> +Taskmaster: Evaluating <pending 0 'Tfile.mid'> + +Task.make_ready_current(): node <pending 0 'Tfile.mid'> +Task.prepare(): node <executing 0 'Tfile.mid'> +Task.execute(): node <executing 0 'Tfile.mid'> +Task.executed_with_callbacks(): node <executing 0 'Tfile.mid'> +Task.postprocess(): node <executed 0 'Tfile.mid'> +Task.postprocess(): removing <executed 0 'Tfile.mid'> +Task.postprocess(): adjusted parent ref count <pending 1 '.'> + +Taskmaster: Looking for a node to evaluate +Taskmaster: Considering node <no_state 0 'Tfile.out'> and its children: +Taskmaster: <executed 0 'Tfile.mid'> +Taskmaster: Evaluating <pending 0 'Tfile.out'> + +Task.make_ready_current(): node <pending 0 'Tfile.out'> +Task.prepare(): node <executing 0 'Tfile.out'> +Task.execute(): node <executing 0 'Tfile.out'> +Task.executed_with_callbacks(): node <executing 0 'Tfile.out'> +Task.postprocess(): node <executed 0 'Tfile.out'> +Task.postprocess(): removing <executed 0 'Tfile.out'> +Task.postprocess(): adjusted parent ref count <pending 0 '.'> + +Taskmaster: Looking for a node to evaluate +Taskmaster: Considering node <pending 0 '.'> and its children: +Taskmaster: <up_to_date 0 'SConstruct'> +Taskmaster: <up_to_date 0 'Tfile.in'> +Taskmaster: <executed 0 'Tfile.mid'> +Taskmaster: <executed 0 'Tfile.out'> +Taskmaster: Evaluating <pending 0 '.'> + +Task.make_ready_current(): node <pending 0 '.'> +Task.prepare(): node <executing 0 '.'> +Task.execute(): node <executing 0 '.'> +Task.executed_with_callbacks(): node <executing 0 '.'> +Task.postprocess(): node <executed 0 '.'> + +Taskmaster: Looking for a node to evaluate +Taskmaster: No candidate anymore. + +""" + +test.must_match('trace.out', expect_trace) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/tree-all.py b/test/option/tree-all.py new file mode 100644 index 0000000..fc0f689 --- /dev/null +++ b/test/option/tree-all.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that the --tree=all option prints a tree representation of the +complete dependencies of a target. +""" + +import TestSCons +import sys + +test = TestSCons.TestSCons() + +CC = test.detect('CC') +LINK = test.detect('LINK') +if LINK is None: LINK = CC + +test.write('SConstruct', """ +env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx') +env.Program('Foo', Split('Foo.c Bar.c')) +""") + +# N.B.: We use upper-case file names (Foo* and Bar*) so that the sorting +# order with our upper-case SConstruct file is the same on case-sensitive +# (UNIX/Linux) and case-insensitive (Windows) systems. + +test.write('Foo.c', r""" +#include <stdio.h> +#include <stdlib.h> +#include "Foo.h" +int main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("f1.c\n"); + exit (0); +} +""") + +test.write('Bar.c', """ +#include "Bar.h" +int local = 1; +""") + +test.write('Foo.h', """ +#ifndef FOO_H +#define FOO_H +#include "Bar.h" +#endif +""") + +test.write('Bar.h', """ +#ifndef BAR_H +#define BAR_H +#include "Foo.h" +#endif +""") + +tree1 = """ ++-Foo.xxx + +-Foo.ooo + | +-Foo.c + | +-Foo.h + | +-Bar.h + | +-%(CC)s + +-Bar.ooo + | +-Bar.c + | +-Bar.h + | +-Foo.h + | +-%(CC)s + +-%(LINK)s +""" % locals() + +test.run(arguments = "--tree=all Foo.xxx") +if test.stdout().count(tree1) != 1: + sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n') + sys.stdout.write(test.stdout()) + test.fail_test() + +tree2 = """ ++-. + +-Bar.c + +-Bar.h + +-Bar.ooo + | +-Bar.c + | +-Bar.h + | +-Foo.h + | +-%(CC)s + +-Foo.c + +-Foo.h + +-Foo.ooo + | +-Foo.c + | +-Foo.h + | +-Bar.h + | +-%(CC)s + +-Foo.xxx + | +-Foo.ooo + | | +-Foo.c + | | +-Foo.h + | | +-Bar.h + | | +-%(CC)s + | +-Bar.ooo + | | +-Bar.c + | | +-Bar.h + | | +-Foo.h + | | +-%(CC)s + | +-%(LINK)s + +-SConstruct +""" % locals() + +test.run(arguments = "--tree=all .") +test.must_contain_all_lines(test.stdout(), [tree2]) + +tree3 = """ ++-. + +-Bar.c + +-Bar.h + +-Bar.ooo + | +-Bar.c + | +-Bar.h + | +-Foo.h + | +-%(CC)s + +-Foo.c + +-Foo.h + +-Foo.ooo + | +-Foo.c + | +-Foo.h + | +-Bar.h + | +-%(CC)s + +-Foo.xxx + | +-[Foo.ooo] + | +-[Bar.ooo] + | +-%(LINK)s + +-SConstruct +""" % locals() + +test.run(arguments = "--tree=all,prune .") +if test.stdout().count(tree3) != 1: + sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n') + sys.stdout.write(test.stdout()) + test.fail_test() + +test.run(arguments = "--tree=prune .") +if test.stdout().count(tree3) != 1: + sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n') + sys.stdout.write(test.stdout()) + test.fail_test() + +tree4 = """ + E = exists + R = exists in repository only + b = implicit builder + B = explicit builder + S = side effect + P = precious + A = always build + C = current + N = no clean + H = no cache + +[ B ]+-Foo.xxx +[ B ] +-Foo.ooo +[E C ] | +-Foo.c +[E C ] | +-Foo.h +[E C ] | +-Bar.h +[E C ] | +-%(CC)s +[ B ] +-Bar.ooo +[E C ] | +-Bar.c +[E C ] | +-Bar.h +[E C ] | +-Foo.h +[E C ] | +-%(CC)s +[E C ] +-%(LINK)s +""" % locals() + +test.run(arguments = '-c Foo.xxx') + +test.run(arguments = "--no-exec --tree=all,status Foo.xxx") +if test.stdout().count(tree4) != 1: + sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n') + sys.stdout.write(test.stdout()) + test.fail_test() + +test.run(arguments = "--no-exec --tree=status Foo.xxx") +if test.stdout().count(tree4) != 1: + sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n') + sys.stdout.write(test.stdout()) + test.fail_test() + +# Make sure we print the debug stuff even if there's a build failure. +test.write('Bar.h', """ +#ifndef BAR_H +#define BAR_H +#include "Foo.h" +#endif +THIS SHOULD CAUSE A BUILD FAILURE +""") + +test.run(arguments = "--tree=all Foo.xxx", + status = 2, + stderr = None) +if test.stdout().count(tree1) != 1: + sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n') + sys.stdout.write(test.stdout()) + test.fail_test() + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/tree-derived.py b/test/option/tree-derived.py new file mode 100644 index 0000000..8490612 --- /dev/null +++ b/test/option/tree-derived.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that the --debug=dtree option correctly prints just the explicit +dependencies (sources or Depends()) of a target. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx') +env.Program('foo', Split('foo.c bar.c')) +""") + +test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> +#include "foo.h" +int main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("f1.c\n"); + exit (0); +} +""") + +test.write('bar.c', """ +#include "bar.h" +int local = 1; +""") + +test.write('foo.h', """ +#ifndef FOO_H +#define FOO_H +#include "bar.h" +#endif +""") + +test.write('bar.h', """ +#ifndef BAR_H +#define BAR_H +#include "foo.h" +#endif +""") + +dtree1 = """ ++-foo.xxx + +-foo.ooo + +-bar.ooo +""" + +test.run(arguments = "--tree=derived foo.xxx") +test.must_contain_all_lines(test.stdout(), [dtree1]) + +dtree2 = """ ++-. + +-bar.ooo + +-foo.ooo + +-foo.xxx + +-foo.ooo + +-bar.ooo +""" + +test.run(arguments = "--tree=derived .") +test.must_contain_all_lines(test.stdout(), [dtree2]) + +dtree3 = """ ++-. + +-bar.ooo + +-foo.ooo + +-foo.xxx + +-foo.ooo + +-bar.ooo +""" + +test.run(arguments = "--tree=derived,prune .") +test.must_contain_all_lines(test.stdout(), [dtree3]) + +dtree4 = """ + E = exists + R = exists in repository only + b = implicit builder + B = explicit builder + S = side effect + P = precious + A = always build + C = current + N = no clean + H = no cache + +[ B ]+-foo.xxx +[ B ] +-foo.ooo +[ B ] +-bar.ooo +""" + +test.run(arguments = '-c foo.xxx') + +test.run(arguments = "--no-exec --tree=derived,status foo.xxx") +test.must_contain_all_lines(test.stdout(), [dtree4]) + +# Make sure we print the debug stuff even if there's a build failure. +test.write('bar.h', """ +#ifndef BAR_H +#define BAR_H +#include "foo.h" +#endif +THIS SHOULD CAUSE A BUILD FAILURE +""") + +test.run(arguments = "--tree=derived foo.xxx", + status = 2, + stderr = None) +test.must_contain_all_lines(test.stdout(), [dtree1]) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/tree-lib.py b/test/option/tree-lib.py new file mode 100644 index 0000000..2dc5fb0 --- /dev/null +++ b/test/option/tree-lib.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure that --tree=derived output with a library dependency shows +the dependency on the library. (On earlier versions of the Microsoft +toolchain this wouldn't show up unless the library already existed +on disk.) + +Issue 1363: http://scons.tigris.org/issues/show_bug.cgi?id=1363 +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +env = Environment(LIBPREFIX='', + LIBSUFFIX='.lib', + OBJSUFFIX='.obj', + EXESUFFIX='.exe') +env.AppendENVPath('PATH', '.') +l = env.Library( 'util.lib', 'util.c' ) +p = env.Program( 'test_tree_lib.exe', 'main.c', LIBS=l ) +env.Command( 'foo.h', p, '$SOURCE > $TARGET') +""") + +test.write('main.c', """\ +#include <stdlib.h> +#include <stdio.h> +int +main(int argc, char **argv) +{ + printf("#define FOO_H \\"foo.h\\"\\n"); + return (0); +} +""") + +test.write('util.c', """\ +void +util(void) +{ + ; +} +""") + +expect = """ + +-test_tree_lib.exe + +-main.obj + +-util.lib + +-util.obj +""" + +test.run(arguments = '--tree=derived foo.h') +test.must_contain_all_lines(test.stdout(), [expect]) + +test.up_to_date(arguments = 'foo.h') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/warn-dependency.py b/test/option/warn-dependency.py new file mode 100644 index 0000000..ca0c2aa --- /dev/null +++ b/test/option/warn-dependency.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify use of the --warn=dependency option. +""" + +import TestSCons + +test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) + + +test.write("SConstruct", """\ +import SCons.Defaults + +def build(target, source, env): + pass + +env=Environment() +env['BUILDERS']['test'] = Builder(action=build, + source_scanner=SCons.Defaults.ObjSourceScan) +env.test(target='foo', source='foo.c') +env.Pseudo('foo') +""") + +test.write("foo.c",""" +#include "not_there.h" +""") + + +expect = r""" +scons: warning: No dependency generated for file: not_there\.h \(included from: foo\.c\) \-\- file not found +""" + TestSCons.file_expr + +test.run(arguments='--warn=dependency .', + stderr=expect) + +test.run(arguments='--warn=dependency .', + stderr=expect) + +test.run(arguments='--warn=all --warn=no-dependency .', + stderr=TestSCons.deprecated_python_expr) + +test.run(arguments='--warn=no-dependency --warn=all .', + stderr=TestSCons.deprecated_python_expr + expect) + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/warn-duplicate-environment.py b/test/option/warn-duplicate-environment.py new file mode 100644 index 0000000..09ced2d --- /dev/null +++ b/test/option/warn-duplicate-environment.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify use of the --warn=duplicate-environment option. +""" + +import TestSCons + +test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) + + +test.write('SConstruct', """ +def build(env, target, source): + file = open(str(target[0]), 'wb') + for s in source: + file.write(open(str(s), 'rb').read()) + +WARN = ARGUMENTS.get('WARN') +if WARN: + SetOption('warn', WARN) + +B = Builder(action=build, multi=1) +env = Environment(BUILDERS = { 'B' : B }) +env2 = env.Clone(DIFFERENT_VARIABLE = 'true') +env.B(target = 'file1.out', source = 'file1a.in') +env2.B(target = 'file1.out', source = 'file1b.in') +""") + +test.write('file1a.in', 'file1a.in\n') +test.write('file1b.in', 'file1b.in\n') + +expect = r""" +scons: warning: Two different environments were specified for target file1.out, +\tbut they appear to have the same action: build\(target, source, env\) +""" + TestSCons.file_expr + +test.run(arguments='file1.out', stderr=expect) + +test.must_match('file1.out', "file1a.in\nfile1b.in\n") + +test.run(arguments='--warn=duplicate-environment file1.out', stderr=expect) + +test.run(arguments='--warn=no-duplicate-environment file1.out') + +test.run(arguments='WARN=duplicate-environment file1.out', stderr=expect) + +test.run(arguments='WARN=no-duplicate-environment file1.out') + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/warn-misleading-keywords.py b/test/option/warn-misleading-keywords.py new file mode 100644 index 0000000..67bc965 --- /dev/null +++ b/test/option/warn-misleading-keywords.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify use of the --warn=misleading-keywords option. +""" + +import TestSCons + +test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) + + +test.write('SConstruct', """ +def build(env, target, source): + file = open(str(target[0]), 'wb') + for s in source: + file.write(open(str(s), 'rb').read()) + +WARN = ARGUMENTS.get('WARN') +if WARN: + SetOption('warn', WARN) + +B = Builder(action=build, multi=1) +env = Environment(BUILDERS = { 'B' : B }) +env.B(targets = 'file3a.out', source = 'file3a.in') +env.B(target = 'file3b.out', sources = 'file3b.in') +""") + +test.write('file3a.in', 'file3a.in\n') +test.write('file3b.out', 'file3b.out\n') + +expect = r""" +scons: warning: Did you mean to use `(target|source)' instead of `(targets|sources)'\? +""" + TestSCons.file_expr + +test.run(arguments='.', + stderr=expect + expect) + +test.must_match(['file3a'], 'file3a.in\n') +test.must_match(['file3b'], 'file3b.out\n') + +test.run(arguments='--warn=misleading-keywords .', stderr=expect + expect) + +test.run(arguments='--warn=no-misleading-keywords .') + +test.run(arguments='WARN=misleading-keywords .', stderr=expect + expect) + +test.run(arguments='WARN=no-misleading-keywords .') + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/warn-missing-sconscript.py b/test/option/warn-missing-sconscript.py new file mode 100644 index 0000000..4f1f8bd --- /dev/null +++ b/test/option/warn-missing-sconscript.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify use of the --warn=missing-sconscript option. +""" + +import TestSCons + +test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) + + +test.write("SConstruct", """\ +def build(target, source, env): + pass + +env=Environment() +env['BUILDERS']['test'] = Builder(action=build) +env.test(target='foo', source='foo.c') +WARN = ARGUMENTS.get('WARN') +if WARN: + SetOption('warn', WARN) +SConscript('no_such_file') +""") + +test.write("foo.c",""" +#include "not_there.h" +""") + +expect = r""" +scons: warning: Ignoring missing SConscript 'no_such_file' +""" + TestSCons.file_expr + +test.run(arguments = '--warn=missing-sconscript .', stderr = expect) + +test.run(arguments = '--warn=no-missing-sconscript .', stderr = "") + +test.run(arguments = 'WARN=missing-sconscript .', stderr = expect) + +test.run(arguments = 'WARN=no-missing-sconscript .') + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: |
