diff options
Diffstat (limited to 'test')
42 files changed, 1735 insertions, 978 deletions
diff --git a/test/AS/AS.py b/test/AS/AS.py index 8bfa740..e8a2a59 100644 --- a/test/AS/AS.py +++ b/test/AS/AS.py @@ -24,9 +24,13 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import os -import string +""" +Verify the ability to set the $AS construction variable to a different +assembler (a wrapper we create). +""" + import sys + import TestSCons _python_ = TestSCons._python_ @@ -153,314 +157,17 @@ test.write('test6.SPP', r"""This is a .SPP file. test.run(arguments = '.', stderr = None) -test.fail_test(test.read('test1' + _exe) != "This is a .s file.\n") - -test.fail_test(test.read('test2' + _exe) != "This is a .S file.\n") - -test.fail_test(test.read('test3' + _exe) != "This is a .asm file.\n") - -test.fail_test(test.read('test4' + _exe) != "This is a .ASM file.\n") - -test.fail_test(test.read('test5' + _exe) != "This is a .spp file.\n") - -test.fail_test(test.read('test6' + _exe) != "This is a .SPP file.\n") - - -as = test.detect('AS', 'as') -x86 = (sys.platform == 'win32' or string.find(sys.platform, 'linux') != -1) - -if as and x86: - - test.write("wrapper.py", """\ -import os -import string -import sys -open('%s', 'wb').write("wrapper.py: %%s\\n" %% sys.argv[-1]) -cmd = string.join(sys.argv[1:]) -os.system(cmd) -""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) - - test.write('SConstruct', """\ -aaa = Environment() -bbb = aaa.Clone(AS = r'%(_python_)s wrapper.py ' + WhereIs('as')) -ccc = aaa.Clone(CPPPATH=['.']) -aaa.Program(target = 'aaa', source = ['aaa.s', 'aaa_main.c']) -bbb.Program(target = 'bbb', source = ['bbb.s', 'bbb_main.c']) -ccc.Program(target = 'ccc', source = ['ccc.S', 'ccc_main.c']) -""" % locals()) - - test.write('aaa.s', -""" .file "aaa.s" -.data -.align 4 -.globl name -name: - .ascii "aaa.s" - .byte 0 -""") - - test.write('bbb.s', """\ -.file "bbb.s" -.data -.align 4 -.globl name -name: - .ascii "bbb.s" - .byte 0 -""") - - test.write('ccc.h', """\ -#define STRING "ccc.S" -""") - - test.write('ccc.S', """\ -#include <ccc.h> -.file STRING -.data -.align 4 -.globl name -name: - .ascii STRING - .byte 0 -""") - - test.write('aaa_main.c', r""" -#include <stdlib.h> -#include <stdio.h> - -extern char name[]; - -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("aaa_main.c %s\n", name); - exit (0); -} -""") - - test.write('bbb_main.c', r""" -#include <stdlib.h> -#include <stdio.h> - -extern char name[]; - -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("bbb_main.c %s\n", name); - exit (0); -} -""") - - test.write('ccc_main.c', r""" -#include <stdlib.h> -#include <stdio.h> - -extern char name[]; - -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("ccc_main.c %s\n", name); - exit (0); -} -""") - - test.write('ddd_main.c', r""" -extern char name[]; - -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("ddd_main.c %s\n", name); - exit (0); -} -""") - - test.run() - - test.run(program = test.workpath('aaa'), stdout = "aaa_main.c aaa.s\n") - test.run(program = test.workpath('bbb'), stdout = "bbb_main.c bbb.s\n") - test.run(program = test.workpath('ccc'), stdout = "ccc_main.c ccc.S\n") - - test.fail_test(test.read('wrapper.out') != "wrapper.py: bbb.s\n") - - test.write("ccc.h", """\ -#define STRING "ccc.S 2" -""") - - test.run() - test.run(program = test.workpath('ccc'), stdout = "ccc_main.c ccc.S 2\n") - - test.unlink('wrapper.out') - - - -ml = test.where_is('ml') - -if ml and sys.platform == 'win32': - - test.write("wrapper.py", -"""import os -import string -import sys -open('%s', 'wb').write("wrapper.py\\n") -os.system(string.join(sys.argv[1:], " ")) -""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) - - test.write('SConstruct', """ -import os -ccc = Environment(tools = ['msvc', 'mslink', 'masm'], - ASFLAGS = '/nologo /coff') -ccc['ENV']['PATH'] = ccc['ENV']['PATH'] + os.pathsep + os.environ['PATH'] -ddd = ccc.Clone(AS = r'%(_python_)s wrapper.py ' + ccc['AS']) -ccc.Program(target = 'ccc', source = ['ccc.asm', 'ccc_main.c']) -ddd.Program(target = 'ddd', source = ['ddd.asm', 'ddd_main.c']) -""" % locals()) - - test.write('ccc.asm', -""" -DSEG segment - PUBLIC _name -_name byte "ccc.asm",0 -DSEG ends - end -""") - - test.write('ddd.asm', -""" -DSEG segment - PUBLIC _name -_name byte "ddd.asm",0 -DSEG ends - end -""") - - test.write('ccc_main.c', r""" -extern char name[]; - -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("ccc_main.c %s\n", name); - exit (0); -} -""") - - test.write('ddd_main.c', r""" -extern char name[]; - -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("ddd_main.c %s\n", name); - exit (0); -} -""") - - test.run(arguments = 'ccc' + _exe, stderr = None) - - test.run(program = test.workpath('ccc'), stdout = "ccc_main.c ccc.asm\n") - - test.fail_test(os.path.exists(test.workpath('wrapper.out'))) - - test.run(arguments = 'ddd' + _exe) - - test.run(program = test.workpath('ddd'), stdout = "ddd_main.c ddd.asm\n") - - test.fail_test(test.read('wrapper.out') != "wrapper.py\n") - - - - -nasm = test.where_is('nasm') - -if nasm: - - # Allow flexibility about the type of object/executable format - # needed on different systems. Format_map is a dict that maps - # sys.platform substrings to the correct argument for the nasm -f - # option. The default is "elf," which seems to be a reasonable - # lowest common denominator (works on both Linux and FreeBSD, - # anyway...). - nasm_format = 'elf' - format_map = {} - for k, v in format_map.items(): - if string.find(sys.platform, k) != -1: - nasm_format = v - break - - test.write("wrapper.py", -"""import os -import string -import sys -open('%s', 'wb').write("wrapper.py\\n") -os.system(string.join(sys.argv[1:], " ")) -""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) - - test.write('SConstruct', """ -eee = Environment(tools = ['gcc', 'gnulink', 'nasm'], - ASFLAGS = '-f %(nasm_format)s') -fff = eee.Clone(AS = r'%(_python_)s wrapper.py ' + WhereIs('nasm')) -eee.Program(target = 'eee', source = ['eee.asm', 'eee_main.c']) -fff.Program(target = 'fff', source = ['fff.asm', 'fff_main.c']) -""" % locals()) - - test.write('eee.asm', -""" -global name -name: - db 'eee.asm',0 -""") - - test.write('fff.asm', -""" -global name -name: - db 'fff.asm',0 -""") - - test.write('eee_main.c', r""" -extern char name[]; - -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("eee_main.c %s\n", name); - exit (0); -} -""") - - test.write('fff_main.c', r""" -extern char name[]; - -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("fff_main.c %s\n", name); - exit (0); -} -""") - - test.run(arguments = 'eee' + _exe, stderr = None) +test.must_match('test1' + _exe, "This is a .s file.\n") - test.run(program = test.workpath('eee'), stdout = "eee_main.c eee.asm\n") +test.must_match('test2' + _exe, "This is a .S file.\n") - test.fail_test(os.path.exists(test.workpath('wrapper.out'))) +test.must_match('test3' + _exe, "This is a .asm file.\n") - test.run(arguments = 'fff' + _exe) +test.must_match('test4' + _exe, "This is a .ASM file.\n") - test.run(program = test.workpath('fff'), stdout = "fff_main.c fff.asm\n") +test.must_match('test5' + _exe, "This is a .spp file.\n") - test.fail_test(test.read('wrapper.out') != "wrapper.py\n") +test.must_match('test6' + _exe, "This is a .SPP file.\n") diff --git a/test/AS/as-live.py b/test/AS/as-live.py new file mode 100644 index 0000000..886dc8d --- /dev/null +++ b/test/AS/as-live.py @@ -0,0 +1,184 @@ +#!/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 correct use of the live 'as' assembler. +""" + +import string +import sys + +import TestSCons + +_python_ = TestSCons._python_ +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + + + +as = test.detect('AS', 'as') + +if not as: + test.skip_test("as not found; skipping test\n") + +x86 = (sys.platform == 'win32' or string.find(sys.platform, 'linux') != -1) + +if not x86: + test.skip_test("skipping as test on non-x86 platform '%s'\n" % sys.platform) + + + +test.write("wrapper.py", """\ +import os +import string +import sys +open('%s', 'wb').write("wrapper.py: %%s\\n" %% sys.argv[-1]) +cmd = string.join(sys.argv[1:]) +os.system(cmd) +""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) + +test.write('SConstruct', """\ +aaa = Environment() +bbb = aaa.Clone(AS = r'%(_python_)s wrapper.py ' + WhereIs('as')) +ccc = aaa.Clone(CPPPATH=['.']) +aaa.Program(target = 'aaa', source = ['aaa.s', 'aaa_main.c']) +bbb.Program(target = 'bbb', source = ['bbb.s', 'bbb_main.c']) +ccc.Program(target = 'ccc', source = ['ccc.S', 'ccc_main.c']) +""" % locals()) + +test.write('aaa.s', +""" .file "aaa.s" +.data +.align 4 +.globl name +name: + .ascii "aaa.s" + .byte 0 +""") + +test.write('bbb.s', """\ +.file "bbb.s" +.data +.align 4 +.globl name +name: + .ascii "bbb.s" + .byte 0 +""") + +test.write('ccc.h', """\ +#define STRING "ccc.S" +""") + +test.write('ccc.S', """\ +#include <ccc.h> +.file STRING +.data +.align 4 +.globl name +name: + .ascii STRING + .byte 0 +""") + +test.write('aaa_main.c', r""" +#include <stdlib.h> +#include <stdio.h> + +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("aaa_main.c %s\n", name); + exit (0); +} +""") + +test.write('bbb_main.c', r""" +#include <stdlib.h> +#include <stdio.h> + +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("bbb_main.c %s\n", name); + exit (0); +} +""") + +test.write('ccc_main.c', r""" +#include <stdlib.h> +#include <stdio.h> + +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("ccc_main.c %s\n", name); + exit (0); +} +""") + +test.write('ddd_main.c', r""" +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("ddd_main.c %s\n", name); + exit (0); +} +""") + +test.run() + +test.run(program = test.workpath('aaa'), stdout = "aaa_main.c aaa.s\n") +test.run(program = test.workpath('bbb'), stdout = "bbb_main.c bbb.s\n") +test.run(program = test.workpath('ccc'), stdout = "ccc_main.c ccc.S\n") + +test.must_match('wrapper.out', "wrapper.py: bbb.s\n") + +test.write("ccc.h", """\ +#define STRING "ccc.S 2" +""") + +test.run() +test.run(program = test.workpath('ccc'), stdout = "ccc_main.c ccc.S 2\n") + +test.unlink('wrapper.out') + + + +test.pass_test() diff --git a/test/AS/ml.py b/test/AS/ml.py new file mode 100644 index 0000000..0cb0e9e --- /dev/null +++ b/test/AS/ml.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__" + +""" +Verify correct use of the live 'ml' assembler. +""" + +import os +import string +import sys + +import TestSCons + +_python_ = TestSCons._python_ +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + +if sys.platform == 'win32': + test.skip_test("Skipping ml test on non-win32 platform '%s'\n" % sys.platform) + +ml = test.where_is('ml') + +if not ml: + test.skip_test("ml not found; skipping test\n") + +test.write("wrapper.py", +"""import os +import string +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(string.join(sys.argv[1:], " ")) +""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) + +test.write('SConstruct', """ +import os +ccc = Environment(tools = ['msvc', 'mslink', 'masm'], + ASFLAGS = '/nologo /coff') +ccc['ENV']['PATH'] = ccc['ENV']['PATH'] + os.pathsep + os.environ['PATH'] +ddd = ccc.Clone(AS = r'%(_python_)s wrapper.py ' + ccc['AS']) +ccc.Program(target = 'ccc', source = ['ccc.asm', 'ccc_main.c']) +ddd.Program(target = 'ddd', source = ['ddd.asm', 'ddd_main.c']) +""" % locals()) + +test.write('ccc.asm', +""" +DSEG segment + PUBLIC _name +_name byte "ccc.asm",0 +DSEG ends + end +""") + +test.write('ddd.asm', +""" +DSEG segment + PUBLIC _name +_name byte "ddd.asm",0 +DSEG ends + end +""") + +test.write('ccc_main.c', r""" +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("ccc_main.c %s\n", name); + exit (0); +} +""") + +test.write('ddd_main.c', r""" +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("ddd_main.c %s\n", name); + exit (0); +} +""") + +test.run(arguments = 'ccc' + _exe, stderr = None) + +test.run(program = test.workpath('ccc'), stdout = "ccc_main.c ccc.asm\n") + +test.must_not_exist('wrapper.out') + +test.run(arguments = 'ddd' + _exe) + +test.run(program = test.workpath('ddd'), stdout = "ddd_main.c ddd.asm\n") + +test.must_match('wrapper.out', "wrapper.py\n") + + + +test.pass_test() diff --git a/test/AS/nasm.py b/test/AS/nasm.py new file mode 100644 index 0000000..f96db7e --- /dev/null +++ b/test/AS/nasm.py @@ -0,0 +1,149 @@ +#!/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 correct use of the live 'nasm' assembler. +""" + +import os +import string +import sys + +import TestSCons + +_python_ = TestSCons._python_ +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + +nasm = test.where_is('nasm') + +if not nasm: + test.skip_test('nasm not found; skipping test\n') + +if string.find(sys.platform, 'linux') == -1: + test.skip_test("skipping test on non-Linux platform '%s'\n" % sys.platfrom) + +try: + import popen2 + stdout = popen2.popen2('nasm -v')[0] +except OSError: + test.skip_test('could not determine nasm version; skipping test\n') +else: + version = string.split(stdout.read())[2] + if version[:4] != '0.98': + test.skip_test("skipping test of nasm version %s\n" % version) + + machine = os.uname()[4] + if not machine in ('i386', 'i486', 'i586', 'i686'): + fmt = "skipping test of nasm %s on non-x86 machine '%s'\n" + test.skip_test(fmt % (version, machine)) + +# Allow flexibility about the type of object/executable format +# needed on different systems. Format_map is a dict that maps +# sys.platform substrings to the correct argument for the nasm -f +# option. The default is "elf," which seems to be a reasonable +# lowest common denominator (works on both Linux and FreeBSD, +# anyway...). +nasm_format = 'elf' +format_map = {} +for k, v in format_map.items(): + if string.find(sys.platform, k) != -1: + nasm_format = v + break + +test.write("wrapper.py", +"""import os +import string +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(string.join(sys.argv[1:], " ")) +""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) + +test.write('SConstruct', """ +eee = Environment(tools = ['gcc', 'gnulink', 'nasm'], + ASFLAGS = '-f %(nasm_format)s') +fff = eee.Clone(AS = r'%(_python_)s wrapper.py ' + WhereIs('nasm')) +eee.Program(target = 'eee', source = ['eee.asm', 'eee_main.c']) +fff.Program(target = 'fff', source = ['fff.asm', 'fff_main.c']) +""" % locals()) + +test.write('eee.asm', +""" +global name +name: + db 'eee.asm',0 +""") + +test.write('fff.asm', +""" +global name +name: + db 'fff.asm',0 +""") + +test.write('eee_main.c', r""" +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("eee_main.c %s\n", name); + exit (0); +} +""") + +test.write('fff_main.c', r""" +#include <stdio.h> +#include <stdlib.h> + +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("fff_main.c %s\n", name); + exit (0); +} +""") + +test.run(arguments = 'eee' + _exe, stderr = None) + +test.run(program = test.workpath('eee'), stdout = "eee_main.c eee.asm\n") + +test.must_not_exist('wrapper.out') + +test.run(arguments = 'fff' + _exe) + +test.run(program = test.workpath('fff'), stdout = "fff_main.c fff.asm\n") + +test.must_match('wrapper.out', "wrapper.py\n") + + + +test.pass_test() diff --git a/test/AddOption/basic.py b/test/AddOption/basic.py new file mode 100644 index 0000000..57ee11e --- /dev/null +++ b/test/AddOption/basic.py @@ -0,0 +1,70 @@ +#!/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 the help text when the AddOption() function is used (and when +it's not). +""" + +import string + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +env = Environment() +AddOption('--force', + action="store_true", + help='force installation (overwrite any existing files)') +AddOption('--prefix', + nargs=1, + dest='prefix', + action='store', + type='string', + metavar='DIR', + help='installation prefix') +f = GetOption('force') +if f: + f = "True" +print f +print GetOption('prefix') +""") + +test.run('-Q -q .', + stdout="None\nNone\n") + +test.run('-Q -q . --force', + stdout="True\nNone\n") + +test.run('-Q -q . --prefix=/home/foo', + stdout="None\n/home/foo\n") + +test.run('-Q -q . -- --prefix=/home/foo --force', + status=1, + stdout="None\nNone\n") + +test.pass_test() diff --git a/test/AddOption/help.py b/test/AddOption/help.py new file mode 100644 index 0000000..d7f02f1 --- /dev/null +++ b/test/AddOption/help.py @@ -0,0 +1,82 @@ +#!/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 the help text when the AddOption() function is used (and when +it's not). +""" + +import string + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +env = Environment() +AddOption('--force', + action="store_true", + help='force installation (overwrite existing files)') +AddOption('--prefix', + nargs=1, + dest='prefix', + action='store', + type='string', + metavar='DIR', + help='installation prefix') +""") + +expected_lines = [ + 'Local Options:', + ' --force force installation (overwrite existing files)', + ' --prefix=DIR installation prefix', +] + +test.run(arguments = '-h') +lines = string.split(test.stdout(), '\n') +missing = filter(lambda e, l=lines: not e in l, expected_lines) + +if missing: + print "====== STDOUT:" + print test.stdout() + print "====== Missing the following lines in the above AddOption() help output:" + print string.join(missing, "\n") + test.fail_test() + +test.unlink('SConstruct') + +test.run(arguments = '-h') +lines = string.split(test.stdout(), '\n') +unexpected = filter(lambda e, l=lines: e in l, expected_lines) + +if unexpected: + print "====== STDOUT:" + print test.stdout() + print "====== Unexpected lines in the above non-AddOption() help output:" + print string.join(unexpected, "\n") + test.fail_test() + +test.pass_test() diff --git a/test/Configure/ConfigureDryRunError.py b/test/Configure/ConfigureDryRunError.py index 04fbc75..65c6403 100644 --- a/test/Configure/ConfigureDryRunError.py +++ b/test/Configure/ConfigureDryRunError.py @@ -57,20 +57,24 @@ if not (r1 and not r2): Exit(1) """ % (lib)) -test.run(arguments='-n', status=2, stderr=""" +expect = """ scons: *** Cannot create configure directory ".sconf_temp" within a dry-run. -File "%(SConstruct_path)s", line 5, in ? -""" % locals()) +""" + test.python_file_line(SConstruct_path, 5) + +test.run(arguments='-n', status=2, stderr=expect) test.must_not_exist('config.log') test.subdir('.sconf_temp') conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c") +SConstruct_file_line = test.python_file_line(SConstruct_path, 6)[:-1] -test.run(arguments='-n', status=2, stderr=""" +expect = """ scons: *** Cannot update configure test "%(conftest_0_c)s" within a dry-run. -File "%(SConstruct_path)s", line 6, in ? -""" % locals()) +%(SConstruct_file_line)s +""" % locals() + +test.run(arguments='-n', status=2, stderr=expect) test.run() test.checkLogAndStdout( ["Checking for C library %s... " % lib, diff --git a/test/Configure/option--config.py b/test/Configure/option--config.py index 95a0d3b..807ddb5 100644 --- a/test/Configure/option--config.py +++ b/test/Configure/option--config.py @@ -60,11 +60,14 @@ test.write(['include', 'non_system_header1.h'], """ """) conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c") +SConstruct_file_line = test.python_file_line(SConstruct_path, 6)[:-1] -test.run(arguments='--config=cache', status=2, stderr=""" +expect = """ scons: *** "%(conftest_0_c)s" is not yet built and cache is forced. -File "%(SConstruct_path)s", line 6, in ? -""" % locals()) +%(SConstruct_file_line)s +""" % locals() + +test.run(arguments='--config=cache', status=2, stderr=expect) test.run(arguments='--config=auto') test.checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", diff --git a/test/Java/RMIC.py b/test/Java/RMIC.py index a66f885..2ab1804 100644 --- a/test/Java/RMIC.py +++ b/test/Java/RMIC.py @@ -102,7 +102,7 @@ if not where_javac: test.skip_test("Could not find Java javac, skipping non-simulated test(s).\n") if test.detect_tool('rmic', ENV=ENV): - where_rmic = test.detect('JAVAC', 'rmic', ENV=ENV) + where_rmic = test.detect('RMIC', 'rmic', ENV=ENV) else: where_rmic = test.where_is('rmic') if not where_rmic: diff --git a/test/LIBPATH.py b/test/LIBPATH.py index 1ea7ed8..7fd4f9b 100644 --- a/test/LIBPATH.py +++ b/test/LIBPATH.py @@ -45,7 +45,7 @@ env1 = Environment(LIBS = [ 'foo1' ], LIBPATH = [ '$FOO' ], FOO='./lib1') -f1 = env1.Object('f1', 'f1.c') +f1 = env1.SharedObject('f1', 'f1.c') env1.Program(target = 'prog', source = 'prog.c') env1.Library(target = './lib1/foo1', source = f1) @@ -127,7 +127,7 @@ test.write('SConstruct', """ env1 = Environment(LIBS = [ 'foo1' ], LIBPATH = [ './lib1', './lib2' ]) -f1 = env1.Object('f1', 'f1.c') +f1 = env1.SharedObject('f1', 'f1.c') env1.Program(target = 'prog', source = 'prog.c') env1.Library(target = './lib1/foo1', source = f1) diff --git a/test/NodeOps.py b/test/NodeOps.py index 17a0f02..3869228 100644 --- a/test/NodeOps.py +++ b/test/NodeOps.py @@ -149,10 +149,10 @@ def exists_test(node): node.is_derived() node.is_pseudo_derived() import SCons.Script - if SCons.Script.Main.options.noexec: + if GetOption('no_exec'): if (before,via_node,after) != (False,False,False): import sys - sys.stderr.write('BuildDir exits() populated during dryrun!\n') + sys.stderr.write('BuildDir exists() populated during dryrun!\n') sys.exit(-2) else: if (before,via_node,after) != (False,True,True): diff --git a/test/Options/BoolOption.py b/test/Options/BoolOption.py index aab2b20..38b30d5 100644 --- a/test/Options/BoolOption.py +++ b/test/Options/BoolOption.py @@ -78,8 +78,7 @@ check([str(False), str(True)]) expect_stderr = """ scons: *** Error converting option: warnings Invalid value for boolean option: irgendwas -File "%(SConstruct_path)s", line 9, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 9) test.run(arguments='warnings=irgendwas', stderr = expect_stderr, status=2) diff --git a/test/Options/EnumOption.py b/test/Options/EnumOption.py index 5e29477..610a485 100644 --- a/test/Options/EnumOption.py +++ b/test/Options/EnumOption.py @@ -82,22 +82,19 @@ check(['full', 'KdE', 'eins']) expect_stderr = """ scons: *** Invalid value for option debug: FULL -File "%(SConstruct_path)s", line 18, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 18) test.run(arguments='debug=FULL', stderr=expect_stderr, status=2) expect_stderr = """ scons: *** Invalid value for option guilib: irgendwas -File "%(SConstruct_path)s", line 18, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 18) test.run(arguments='guilib=IrGeNdwas', stderr=expect_stderr, status=2) expect_stderr = """ scons: *** Invalid value for option some: irgendwas -File "%(SConstruct_path)s", line 18, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 18) test.run(arguments='some=IrGeNdwas', stderr=expect_stderr, status=2) diff --git a/test/Options/ListOption.py b/test/Options/ListOption.py index fddfc5f..b6ba306 100644 --- a/test/Options/ListOption.py +++ b/test/Options/ListOption.py @@ -96,8 +96,7 @@ check(['gl,qt', '0', 'gl qt', 'gl qt']) expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "%(SConstruct_path)s", line 14, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 14) test.run(arguments='shared=foo', stderr=expect_stderr, status=2) @@ -106,32 +105,28 @@ test.run(arguments='shared=foo', stderr=expect_stderr, status=2) expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "%(SConstruct_path)s", line 14, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 14) test.run(arguments='shared=foo,ical', stderr=expect_stderr, status=2) expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "%(SConstruct_path)s", line 14, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 14) test.run(arguments='shared=ical,foo', stderr=expect_stderr, status=2) expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "%(SConstruct_path)s", line 14, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 14) test.run(arguments='shared=ical,foo,x11', stderr=expect_stderr, status=2) expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo,bar -File "%(SConstruct_path)s", line 14, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 14) test.run(arguments='shared=foo,x11,,,bar', stderr=expect_stderr, status=2) diff --git a/test/Options/PackageOption.py b/test/Options/PackageOption.py index d285338..79d4dda 100644 --- a/test/Options/PackageOption.py +++ b/test/Options/PackageOption.py @@ -80,8 +80,7 @@ check([test.workpath()]) expect_stderr = """ scons: *** Path does not exist for option x11: /non/existing/path/ -File "%(SConstruct_path)s", line 10, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 10) test.run(arguments='x11=/non/existing/path/', stderr=expect_stderr, status=2) diff --git a/test/Options/PathOption.py b/test/Options/PathOption.py index d22071e..23fec6e 100644 --- a/test/Options/PathOption.py +++ b/test/Options/PathOption.py @@ -90,17 +90,18 @@ test.run(arguments=['qtdir=%s' % qtpath, 'qt_libraries=%s' % libpath]) check([qtpath, libpath, libpath]) qtpath = os.path.join(workpath, 'non', 'existing', 'path') +SConstruct_file_line = test.python_file_line(test.workpath('SConstruct'), 11)[:-1] expect_stderr = """ scons: *** Path for option qtdir does not exist: %(qtpath)s -File "%(SConstruct_path)s", line 11, in ? +%(SConstruct_file_line)s """ % locals() test.run(arguments=['qtdir=%s' % qtpath], stderr=expect_stderr, status=2) expect_stderr = """ scons: *** Path for option qt_libraries does not exist: %(qtpath)s -File "%(SConstruct_path)s", line 11, in ? +%(SConstruct_file_line)s """ % locals() test.run(arguments=['qt_libraries=%s' % qtpath], stderr=expect_stderr, status=2) @@ -167,9 +168,11 @@ print env['X'] Default(env.Alias('dummy', None)) """ % default_file) +SConstruct_file_line = test.python_file_line(test.workpath('SConstruct'), 6)[:-1] + expect_stderr = """ scons: *** File path for option X does not exist: %(default_file)s -File "%(SConstruct_path)s", line 6, in ? +%(SConstruct_file_line)s """ % locals() test.run(status=2, stderr=expect_stderr) @@ -181,7 +184,7 @@ check([default_file]) expect_stderr = """ scons: *** File path for option X is a directory: %(existing_subdir)s -File "%(SConstruct_path)s", line 6, in ? +%(SConstruct_file_line)s """ % locals() test.run(arguments=['X=%s' % existing_subdir], status=2, stderr=expect_stderr) @@ -191,7 +194,7 @@ check([existing_file]) expect_stderr = """ scons: *** File path for option X does not exist: %(non_existing_file)s -File "%(SConstruct_path)s", line 6, in ? +%(SConstruct_file_line)s """ % locals() test.run(arguments=['X=%s' % non_existing_file], status=2, stderr=expect_stderr) @@ -213,7 +216,7 @@ Default(env.Alias('dummy', None)) expect_stderr = """ scons: *** Directory path for option X does not exist: %(default_subdir)s -File "%(SConstruct_path)s", line 6, in ? +%(SConstruct_file_line)s """ % locals() test.run(status=2, stderr=expect_stderr) @@ -225,7 +228,7 @@ check([default_subdir]) expect_stderr = """ scons: *** Directory path for option X is a file: %(existing_file)s -File "%(SConstruct_path)s", line 6, in ? +%(SConstruct_file_line)s """ % locals() test.run(arguments=['X=%s' % existing_file], @@ -237,7 +240,7 @@ check([existing_subdir]) expect_stderr = """ scons: *** Directory path for option X does not exist: %(non_existing_subdir)s -File "%(SConstruct_path)s", line 6, in ? +%(SConstruct_file_line)s """ % locals() test.run(arguments=['X=%s' % non_existing_subdir], @@ -264,7 +267,7 @@ check([default_subdir]) expect_stderr = """ scons: *** Path for option X is a file, not a directory: %(existing_file)s -File "%(SConstruct_path)s", line 6, in ? +%(SConstruct_file_line)s """ % locals() test.run(arguments=['X=%s' % existing_file], status=2, stderr=expect_stderr) diff --git a/test/Perforce/Perforce.py b/test/Perforce/Perforce.py index a24c65d..b409210 100644 --- a/test/Perforce/Perforce.py +++ b/test/Perforce/Perforce.py @@ -40,6 +40,8 @@ class TestPerforce(TestSCons.TestSCons): def __init__(self, *args, **kw): apply(TestSCons.TestSCons.__init__, (self,)+args, kw) + self.p4d = None + self.p4path = self.where_is('p4') if not self.p4path: self.skip_test("Could not find 'p4'; skipping test(s).\n") diff --git a/test/QT/Tool.py b/test/QT/Tool.py index 9079225..3ccabf7 100644 --- a/test/QT/Tool.py +++ b/test/QT/Tool.py @@ -30,14 +30,20 @@ works properly. This was broken in 0.96.95. The configuration here is a moderately stripped-down version of the real-world configuration for lprof (lprof.sourceforge.net). It's probably -not completely minimal, but we're leaving it as since it represents a +not completely minimal, but we're leaving it as-is since it represents a good real-world sanity check on the interaction of some key subsystems. """ +import os + import TestSCons test = TestSCons.TestSCons() +if not os.environ.get('QTDIR', None): + x ="External environment variable $QTDIR not set; skipping test(s).\n" + test.skip_test(x) + test.write('SConstruct', """ import os import os.path diff --git a/test/QT/warnings.py b/test/QT/warnings.py index 0fd3f66..baa1e6f 100644 --- a/test/QT/warnings.py +++ b/test/QT/warnings.py @@ -85,13 +85,13 @@ if moc: expect = """ scons: warning: Could not detect qt, using moc executable as a hint \(QTDIR=%s\) -File "%s", line \d+, in \? +File "%s", line \d+, in (\?|<module>) """ % (qtdir, re.escape(SConstruct_path)) else: - expect = """ + expect = r""" scons: warning: Could not detect qt, using empty QTDIR -File "%s", line \d+, in \? +File "%s", line \d+, in (\?|<module>) """ % re.escape(SConstruct_path) test.fail_test(not test.match_re(test.stderr(), expect)) diff --git a/test/RCS/diskcheck.py b/test/RCS/diskcheck.py index 78120f6..07cb170 100644 --- a/test/RCS/diskcheck.py +++ b/test/RCS/diskcheck.py @@ -115,13 +115,15 @@ test.write('bbb.in', "checked-out bbb.in\n") test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n") +sub_SConscript = os.path.join('sub', 'SConscript') +SConstruct_file_line = test.python_file_line(test.workpath('SConstruct'), 23)[:-1] expect = """\ -scons: warning: Ignoring missing SConscript '%s' -File "%s", line 23, in ? +scons: warning: Ignoring missing SConscript '%(sub_SConscript)s' +%(SConstruct_file_line)s scons: *** Source `aaa.in' not found, needed by target `aaa.out'. Stop. -""" % (os.path.join('sub', 'SConscript'), test.workpath('SConstruct')) +""" % locals() test.run(status=2, stderr=expect) diff --git a/test/Repository/RMIC.py b/test/Repository/RMIC.py index e4a4459..ebe6a83 100644 --- a/test/Repository/RMIC.py +++ b/test/Repository/RMIC.py @@ -47,7 +47,7 @@ if not where_javac: test.skip_test("Could not find Java javac, skipping test(s).\n") if test.detect_tool('rmic', ENV=ENV): - where_rmic = test.detect('JAVAC', 'rmic', ENV=ENV) + where_rmic = test.detect('RMIC', 'rmic', ENV=ENV) else: where_rmic = test.where_is('rmic') if not where_rmic: diff --git a/test/SCCS/diskcheck.py b/test/SCCS/diskcheck.py index 66566fa..a9df89b 100644 --- a/test/SCCS/diskcheck.py +++ b/test/SCCS/diskcheck.py @@ -93,17 +93,18 @@ test.write(['bbb.in'], "checked-out bbb.in\n") test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n") +sub_SConscript = os.path.join('sub', 'SConscript') +SConstruct_file_line = test.python_file_line(test.workpath('SConstruct'), 17)[:-1] + expect = """\ -scons: warning: Ignoring missing SConscript '%s' -File "%s", line 17, in ? +scons: warning: Ignoring missing SConscript '%(sub_SConscript)s' +%(SConstruct_file_line)s scons: *** Source `aaa.in' not found, needed by target `aaa.out'. Stop. -""" % (os.path.join('sub', 'SConscript'), test.workpath('SConstruct')) +""" % locals() test.run(status=2, stderr=expect) -test.run(arguments = '--diskcheck=none', status=2, stderr=expect) - test.run(arguments = '--diskcheck=sccs', stderr = None) lines = string.split(""" diff --git a/test/SWIG/live.py b/test/SWIG/live.py index c6b45d2..93336ca 100644 --- a/test/SWIG/live.py +++ b/test/SWIG/live.py @@ -28,6 +28,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Test SWIG behavior with a live, installed SWIG. """ +import os.path import string import sys @@ -73,6 +74,14 @@ if sys.platform == 'darwin': # (see top of file for further explanation) frameworks = '-framework Python' platform_sys_prefix = '/System/Library/Frameworks/Python.framework/Versions/%s/' % version + +python_include_dir = os.path.join(platform_sys_prefix, + 'include', + 'python' + version) +Python_h = os.path.join(python_include_dir, 'Python.h') + +if not os.path.exists(Python_h): + test.skip_test('Can not find %s, skipping test.\n' % Python_h) test.write("wrapper.py", """import os @@ -84,7 +93,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(SWIGFLAGS='-python', - CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/', + CPPPATH='%(python_include_dir)s/', LDMODULEPREFIX='%(ldmodule_prefix)s', LDMODULESUFFIX='%(_dll)s', FRAMEWORKSFLAGS='%(frameworks)s', @@ -108,6 +117,12 @@ test.write("foo.i", """\ %module foo %{ /* Put header files here (optional) */ +/* + * This duplication shouldn't be necessary, I guess, but it seems + * to suppress "cast to pointer from integer of different size" + * warning messages on some systems. + */ +extern char *foo_string(); %} extern char *foo_string(); @@ -125,6 +140,12 @@ test.write("bar.i", """\ %module \t bar %{ /* Put header files here (optional) */ +/* + * This duplication shouldn't be necessary, I guess, but it seems + * to suppress "cast to pointer from integer of different size" + * warning messages on some systems. + */ +extern char *bar_string(); %} extern char *bar_string(); diff --git a/test/SWIG/remove-modules.py b/test/SWIG/remove-modules.py index cac9677..1a48c9e 100644 --- a/test/SWIG/remove-modules.py +++ b/test/SWIG/remove-modules.py @@ -29,6 +29,7 @@ Verify that swig-generated modules are removed. The %module directive specifies the module name. """ +import os.path import sys import TestSCons @@ -62,6 +63,14 @@ if sys.platform == 'darwin': # (see top of file for further explanation) frameworks = '-framework Python' platform_sys_prefix = '/System/Library/Frameworks/Python.framework/Versions/%s/' % version + +python_include_dir = os.path.join(platform_sys_prefix, + 'include', + 'python' + version) +Python_h = os.path.join(python_include_dir, 'Python.h') + +if not os.path.exists(Python_h): + test.skip_test('Can not find %s, skipping test.\n' % Python_h) test.write("module.i", """\ diff --git a/test/Scanner/exception.py b/test/Scanner/exception.py index 7615888..d8204db 100644 --- a/test/Scanner/exception.py +++ b/test/Scanner/exception.py @@ -49,7 +49,7 @@ def kfile_scan(node, env, target, arg): contents = node.get_contents() exceptions = exception_re.findall(contents) if exceptions: - raise "kfile_scan error: %s" % exceptions[0] + raise Exception, "kfile_scan error: %s" % exceptions[0] includes = include_re.findall(contents) return includes diff --git a/test/Script-import.py b/test/Script-import.py index 544960b..3df980f 100644 --- a/test/Script-import.py +++ b/test/Script-import.py @@ -60,24 +60,33 @@ import SCons.Script SCons.Script.BuildTask SCons.Script.CleanTask SCons.Script.QuestionTask -#SCons.Script.PrintHelp -SCons.Script.OptParser -SCons.Script.SConscriptSettableOptions - -SCons.Script.keep_going_on_error -#SCons.Script.print_dtree -SCons.Script.print_explanations -SCons.Script.print_includes -SCons.Script.print_objects -SCons.Script.print_time -#SCons.Script.print_tree -SCons.Script.memory_stats -SCons.Script.ignore_errors -#SCons.Script.sconscript_time -#SCons.Script.command_time -#SCons.Script.exit_status -#SCons.Script.profiling -SCons.Script.repositories + +old_SCons_Script_variables = [ + 'PrintHelp', + 'OptParser', + 'keep_going_on_error', + 'print_explanations', + 'print_includes', + 'print_objects', + 'print_time', + 'memory_stats', + 'ignore_errors', + 'repositories', + 'print_dtree', + 'print_tree', + 'sconscript_time', + 'command_time', + 'exit_status', + 'profiling', +] + +for var in old_SCons_Script_variables: + try: + getattr(SCons.Script, var) + except AttributeError: + pass + else: + raise Exception, "unexpected variable SCons.Script.%s" % var """) test.write("m4.py", """\ diff --git a/test/TEX/auxiliaries.py b/test/TEX/auxiliaries.py index e34ddaa..39984b3 100644 --- a/test/TEX/auxiliaries.py +++ b/test/TEX/auxiliaries.py @@ -123,9 +123,8 @@ pdf_output_1 = test.read(['build', 'docs', 'test.pdf']) ps_output_1 = test.read(['build', 'docs', 'test.ps']) # Adding blank lines will cause SCons to re-run the builds, but the -# actual contents of the output files shouldn't be any different. -# This assumption won't work if it's ever used with a toolchain that does -# something to the output like put a commented-out timestamp in a header. +# actual contents of the output files should be the same modulo +# the CreationDate header. test.write(['docs', 'test.tex'], tex_input + "\n\n\n") test.run(stderr=None) @@ -133,7 +132,14 @@ test.run(stderr=None) pdf_output_2 = test.read(['build', 'docs', 'test.pdf']) ps_output_2 = test.read(['build', 'docs', 'test.ps']) -test.fail_test(pdf_output_1 != pdf_output_2) -test.fail_test(ps_output_1 != ps_output_2) + + +pdf_output_1 = test.normalize_pdf(pdf_output_1) +pdf_output_2 = test.normalize_pdf(pdf_output_2) + +assert pdf_output_1 == pdf_output_2, test.diff_substr(pdf_output_1, pdf_output_2, 80, 80) +assert ps_output_1 == ps_output_2, test.diff_substr(ps_output_1, ps_output_2, 80, 80) + + test.pass_test() diff --git a/test/TEX/bibtex-latex-rerun.py b/test/TEX/bibtex-latex-rerun.py index 353d9a4..a0ba5c2 100644 --- a/test/TEX/bibtex-latex-rerun.py +++ b/test/TEX/bibtex-latex-rerun.py @@ -95,10 +95,16 @@ test.run() pdf_output_3 = test.read('bibtest.pdf') -# If the PDF file is now different than the second run, then something -# else odd has happened, so fail. (Note that this test will be incorrect -# if the tool does something like insert a timestamp in the PDF file.) -test.fail_test(pdf_output_2 != pdf_output_3) + + +# If the PDF file is now different than the second run, modulo the +# creation timestamp and the ID, then something else odd has happened, +# so fail. + +pdf_output_2 = test.normalize_pdf(pdf_output_2) +pdf_output_3 = test.normalize_pdf(pdf_output_3) + +assert pdf_output_2 == pdf_output_3, test.diff_substr(pdf_output_2, pdf_output_3, 80, 80) diff --git a/test/bad-variables.py b/test/bad-variables.py index cb6b357..0618c5e 100644 --- a/test/bad-variables.py +++ b/test/bad-variables.py @@ -43,8 +43,7 @@ env['foo-bar'] = 1 expect_stderr = """ scons: *** Illegal construction variable `foo-bar' -File "%(SConstruct_path)s", line 2, in ? -""" % locals() +""" + test.python_file_line(SConstruct_path, 2) test.run(arguments='.', status=2, stderr=expect_stderr) @@ -59,10 +58,10 @@ env = Environment() env['foo(bar)'] = 1 """) + expect_stderr = """ scons: *** Illegal construction variable `foo(bar)' -File "%(SConscript_path)s", line 2, in ? -""" % locals() +""" + test.python_file_line(SConscript_path, 2) test.run(arguments='.', status=2, stderr=expect_stderr) diff --git a/test/compat/all.py b/test/compat/all.py new file mode 100644 index 0000000..ee8f9ef --- /dev/null +++ b/test/compat/all.py @@ -0,0 +1,59 @@ +#!/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 we can use the any() function (in any supported Python +version we happen to be testing). + +This test can be retired at some point in the distant future when Python +2.5 becomes the minimum version supported by SCons. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +print all([True, 1]) and "YES" or "NO" +print all([0]) and "YES" or "NO" +SConscript('SConscript') +""") + +test.write('SConscript', """\ +print all([1, False]) and "YES" or "NO" +print all([True, None]) and "YES" or "NO" +""") + +expect = """\ +YES +NO +NO +NO +""" + +test.run(arguments = '-Q -q', stdout = expect) + +test.pass_test() diff --git a/test/compat/any.py b/test/compat/any.py new file mode 100644 index 0000000..cab191c --- /dev/null +++ b/test/compat/any.py @@ -0,0 +1,57 @@ +#!/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 we can use the any() function (in any supported Python +version we happen to be testing). + +This test can be retired at some point in the distant future when Python +2.5 becomes the minimum version supported by SCons. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +print any([True, False]) and "YES" or "NO" +print any([1]) and "YES" or "NO" +SConscript('SConscript') +""") + +test.write('SConscript', """\ +print any([0, False]) and "YES" or "NO" +""") + +expect = """\ +YES +YES +NO +""" + +test.run(arguments = '-Q -q', stdout = expect) + +test.pass_test() diff --git a/test/exceptions.py b/test/exceptions.py index 01a2855..34c24f4 100644 --- a/test/exceptions.py +++ b/test/exceptions.py @@ -39,7 +39,7 @@ SConstruct_path = test.workpath('SConstruct') test.write(SConstruct_path, """\ def func(source = None, target = None, env = None): - raise "func exception" + raise Exception, "func exception" B = Builder(action = func) env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') @@ -55,8 +55,8 @@ Traceback \((most recent call|innermost) last\): )*( File ".+", line \d+, in \S+ [^\n]+ )* File "%s", line 2, in func - raise "func exception" -func exception + raise Exception, "func exception" +Exception: func exception """ % re.escape(SConstruct_path) test.run(arguments = "foo.out", stderr = expected_stderr, status = 2) diff --git a/test/explain.py b/test/explain.py deleted file mode 100644 index 9b721d2..0000000 --- a/test/explain.py +++ /dev/null @@ -1,561 +0,0 @@ -#!/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=explain option. -""" - -import os.path -import string -import sys -import TestSCons - -_python_ = TestSCons._python_ - -test = TestSCons.TestSCons() - -test.subdir('work1', ['work1', 'src'], ['work1', 'src', 'subdir'], - 'work4', ['work4', 'src'], ['work4', 'src', 'subdir'], - 'work5') - -subdir_file7 = os.path.join('subdir', 'file7') -subdir_file7_in = os.path.join('subdir', 'file7.in') -cat_py = test.workpath('cat.py') - -test.write(cat_py, r""" -import sys - -def process(outfp, infp): - for line in infp.readlines(): - if line[:8] == 'include ': - file = line[8:-1] - try: - fp = open(file, 'rb') - except IOError: - import os - print "os.getcwd() =", os.getcwd() - raise - process(outfp, fp) - else: - outfp.write(line) - -outfp = open(sys.argv[1], 'wb') -for f in sys.argv[2:]: - if f != '-': - process(outfp, open(f, 'rb')) - -sys.exit(0) -""") - -SConstruct_contents = """\ -import re - -include_re = re.compile(r'^include\s+(\S+)$', re.M) - -def kfile_scan(node, env, target, arg): - contents = node.get_contents() - includes = include_re.findall(contents) - return includes - -kscan = Scanner(name = 'kfile', - function = kfile_scan, - argument = None, - skeys = ['.k']) - -cat = Builder(action = r'%(_python_)s %(cat_py)s $TARGET $SOURCES') - -env = Environment() -env.Append(BUILDERS = {'Cat':cat}, - SCANNERS = kscan) - -Export("env") -SConscript('SConscript') -env.Install('../inc', 'aaa') -env.InstallAs('../inc/bbb.k', 'bbb.k') -env.Install('../inc', 'ddd') -env.InstallAs('../inc/eee', 'eee.in') -""" % locals() - -args = '--debug=explain .' - -############################################################################# -test.write(['work1', 'src', 'SConstruct'], SConstruct_contents) - -test.write(['work1', 'src', 'SConscript'], """\ -Import("env") -env.Cat('file1', 'file1.in') -env.Cat('file2', 'file2.k') -env.Cat('file3', ['xxx', 'yyy', 'zzz']) -env.Command('file4', 'file4.in', - r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES', - FILE4FLAG='-') -env.Cat('file5', 'file5.k') -file6 = env.Cat('file6', 'file6.in') -AlwaysBuild(file6) -env.Cat('subdir/file7', 'subdir/file7.in') -""" % locals()) - -test.write(['work1', 'src', 'aaa'], "aaa 1\n") -test.write(['work1', 'src', 'bbb.k'], """\ -bbb.k 1 -include ccc -include ../inc/ddd -include ../inc/eee -""") -test.write(['work1', 'src', 'ccc'], "ccc 1\n") -test.write(['work1', 'src', 'ddd'], "ddd 1\n") -test.write(['work1', 'src', 'eee.in'], "eee.in 1\n") - -test.write(['work1', 'src', 'file1.in'], "file1.in 1\n") - -test.write(['work1', 'src', 'file2.k'], """\ -file2.k 1 line 1 -include xxx -include yyy -file2.k 1 line 4 -""") - -test.write(['work1', 'src', 'file4.in'], "file4.in 1\n") - -test.write(['work1', 'src', 'xxx'], "xxx 1\n") -test.write(['work1', 'src', 'yyy'], "yyy 1\n") -test.write(['work1', 'src', 'zzz'], "zzz 1\n") - -test.write(['work1', 'src', 'file5.k'], """\ -file5.k 1 line 1 -include ../inc/aaa -include ../inc/bbb.k -file5.k 1 line 4 -""") - -test.write(['work1', 'src', 'file6.in'], "file6.in 1\n") - -test.write(['work1', 'src', 'subdir', 'file7.in'], "subdir/file7.in 1\n") - -work1_inc_aaa = test.workpath('work1', 'inc', 'aaa') -work1_inc_ddd = test.workpath('work1', 'inc', 'ddd') -work1_inc_eee = test.workpath('work1', 'inc', 'eee') -work1_inc_bbb_k = test.workpath('work1', 'inc', 'bbb.k') - -# -expect = test.wrap_stdout("""\ -scons: building `file1' because it doesn't exist -%(_python_)s %(cat_py)s file1 file1.in -scons: building `file2' because it doesn't exist -%(_python_)s %(cat_py)s file2 file2.k -scons: building `file3' because it doesn't exist -%(_python_)s %(cat_py)s file3 xxx yyy zzz -scons: building `file4' because it doesn't exist -%(_python_)s %(cat_py)s file4 - file4.in -scons: building `%(work1_inc_aaa)s' because it doesn't exist -Install file: "aaa" as "%(work1_inc_aaa)s" -scons: building `%(work1_inc_ddd)s' because it doesn't exist -Install file: "ddd" as "%(work1_inc_ddd)s" -scons: building `%(work1_inc_eee)s' because it doesn't exist -Install file: "eee.in" as "%(work1_inc_eee)s" -scons: building `%(work1_inc_bbb_k)s' because it doesn't exist -Install file: "bbb.k" as "%(work1_inc_bbb_k)s" -scons: building `file5' because it doesn't exist -%(_python_)s %(cat_py)s file5 file5.k -scons: building `file6' because it doesn't exist -%(_python_)s %(cat_py)s file6 file6.in -scons: building `%(subdir_file7)s' because it doesn't exist -%(_python_)s %(cat_py)s %(subdir_file7)s %(subdir_file7_in)s -""" % locals()) - -test.run(chdir='work1/src', arguments=args, stdout=expect) - -test.must_match(['work1', 'src', 'file1'], "file1.in 1\n") -test.must_match(['work1', 'src', 'file2'], """\ -file2.k 1 line 1 -xxx 1 -yyy 1 -file2.k 1 line 4 -""") -test.must_match(['work1', 'src', 'file3'], "xxx 1\nyyy 1\nzzz 1\n") -test.must_match(['work1', 'src', 'file4'], "file4.in 1\n") -test.must_match(['work1', 'src', 'file5'], """\ -file5.k 1 line 1 -aaa 1 -bbb.k 1 -ccc 1 -ddd 1 -eee.in 1 -file5.k 1 line 4 -""") -test.must_match(['work1', 'src', 'file6'], "file6.in 1\n") - -# -test.write(['work1', 'src', 'file1.in'], "file1.in 2\n") -test.write(['work1', 'src', 'yyy'], "yyy 2\n") -test.write(['work1', 'src', 'zzz'], "zzz 2\n") -test.write(['work1', 'src', 'bbb.k'], "bbb.k 2\ninclude ccc\n") - -expect = test.wrap_stdout("""\ -scons: rebuilding `file1' because `file1.in' changed -%(_python_)s %(cat_py)s file1 file1.in -scons: rebuilding `file2' because `yyy' changed -%(_python_)s %(cat_py)s file2 file2.k -scons: rebuilding `file3' because: - `yyy' changed - `zzz' changed -%(_python_)s %(cat_py)s file3 xxx yyy zzz -scons: rebuilding `%(work1_inc_bbb_k)s' because: - `%(work1_inc_ddd)s' is no longer a dependency - `%(work1_inc_eee)s' is no longer a dependency - `bbb.k' changed -Install file: "bbb.k" as "%(work1_inc_bbb_k)s" -scons: rebuilding `file5' because `%(work1_inc_bbb_k)s' changed -%(_python_)s %(cat_py)s file5 file5.k -scons: rebuilding `file6' because AlwaysBuild() is specified -%(_python_)s %(cat_py)s file6 file6.in -""" % locals()) - -test.run(chdir='work1/src', arguments=args, stdout=expect) - -test.must_match(['work1', 'src', 'file1'], "file1.in 2\n") -test.must_match(['work1', 'src', 'file2'], """\ -file2.k 1 line 1 -xxx 1 -yyy 2 -file2.k 1 line 4 -""") -test.must_match(['work1', 'src', 'file3'], "xxx 1\nyyy 2\nzzz 2\n") -test.must_match(['work1', 'src', 'file5'], """\ -file5.k 1 line 1 -aaa 1 -bbb.k 2 -ccc 1 -file5.k 1 line 4 -""") - -# -test.write(['work1', 'src', 'SConscript'], """\ -Import("env") -env.Cat('file3', ['xxx', 'yyy']) -""") - -expect = test.wrap_stdout("""\ -scons: rebuilding `file3' because `zzz' is no longer a dependency -%(_python_)s %(cat_py)s file3 xxx yyy -""" % locals()) - -test.run(chdir='work1/src', arguments=args, stdout=expect) - -test.must_match(['work1', 'src', 'file3'], "xxx 1\nyyy 2\n") - -# -test.write(['work1', 'src', 'SConscript'], """\ -Import("env") -env.Cat('file3', ['xxx', 'yyy', 'zzz']) -""") - -expect = test.wrap_stdout("""\ -scons: rebuilding `file3' because `zzz' is a new dependency -%(_python_)s %(cat_py)s file3 xxx yyy zzz -""" % locals()) - -test.run(chdir='work1/src', arguments=args, stdout=expect) - -test.must_match(['work1', 'src', 'file3'], "xxx 1\nyyy 2\nzzz 2\n") - -# -test.write(['work1', 'src', 'SConscript'], """\ -Import("env") -env.Cat('file3', ['zzz', 'yyy', 'xxx']) -""") - -expect = test.wrap_stdout("""\ -scons: rebuilding `file3' because the dependency order changed: - old: ['xxx', 'yyy', 'zzz'] - new: ['zzz', 'yyy', 'xxx'] -%(_python_)s %(cat_py)s file3 zzz yyy xxx -""" % locals()) - -test.run(chdir='work1/src', arguments=args, stdout=expect) - -test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") - -# -test.write(['work1', 'src', 'SConscript'], """\ -Import("env") -f3 = File('file3') -env.Cat(f3, ['zzz', 'yyy', 'xxx']) -env.AddPostAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy') -env.AddPreAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES') -""" % locals()) - -expect = test.wrap_stdout("""\ -scons: rebuilding `file3' because the build action changed: - old: %(_python_)s %(cat_py)s $TARGET $SOURCES - new: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES - %(_python_)s %(cat_py)s $TARGET $SOURCES - %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy -%(_python_)s %(cat_py)s file3.alt zzz yyy xxx -%(_python_)s %(cat_py)s file3 zzz yyy xxx -%(_python_)s %(cat_py)s file3.yyy zzz yyy xxx yyy -""" % locals()) - -test.run(chdir='work1/src', arguments=args, stdout=expect) - -test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") -test.must_match(['work1', 'src', 'file3.alt'], "zzz 2\nyyy 2\nxxx 1\n") -test.must_match(['work1', 'src', 'file3.yyy'], "zzz 2\nyyy 2\nxxx 1\nyyy 2\n") - -# -test.write(['work1', 'src', 'SConscript'], """\ -Import("env") -f3 = File('file3') -env.Cat(f3, ['zzz', 'yyy', 'xxx']) -env.AddPostAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx') -env.AddPreAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES') -""" % locals()) - -expect = test.wrap_stdout("""\ -scons: rebuilding `file3' because the build action changed: - old: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES - %(_python_)s %(cat_py)s $TARGET $SOURCES - %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy - new: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES - %(_python_)s %(cat_py)s $TARGET $SOURCES - %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx -%(_python_)s %(cat_py)s file3.alt zzz yyy xxx -%(_python_)s %(cat_py)s file3 zzz yyy xxx -%(_python_)s %(cat_py)s file3.yyy zzz yyy xxx xxx -""" % locals()) - -test.run(chdir='work1/src', arguments=args, stdout=expect) - -test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") -test.must_match(['work1', 'src', 'file3.alt'], "zzz 2\nyyy 2\nxxx 1\n") -test.must_match(['work1', 'src', 'file3.yyy'], "zzz 2\nyyy 2\nxxx 1\nxxx 1\n") - -# -test.write(['work1', 'src', 'SConscript'], """\ -Import("env") -env.Command('file4', 'file4.in', - r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES', - FILE4FLAG='') -""" % locals()) - -expect = test.wrap_stdout("""\ -scons: rebuilding `file4' because the contents of the build action changed - action: %(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES -%(_python_)s %(cat_py)s file4 file4.in -""" % locals()) - -test.run(chdir='work1/src',arguments=args, stdout=expect) - -test.must_match(['work1', 'src', 'file4'], "file4.in 1\n") - -test.up_to_date(chdir='work1/src',arguments='.') - -# Test the transition when you turn ON SConsignFile(). -# This will (or might) rebuild things, but we don't care what, -# we just want to make sure we don't blow up. -test.write(['work1', 'src', 'SConstruct'], - "SConsignFile()\n" + SConstruct_contents) - -test.run(chdir='work1/src', arguments=args) - -test.up_to_date(chdir='work1/src',arguments='.') - -############################################################################# -# Test that the --debug=explain information gets saved by default. -test.write(['work4', 'src', 'SConstruct'], SConstruct_contents) - -test.write(['work4', 'src', 'SConscript'], """\ -Import("env") -env.Cat('file1', 'file1.in') -env.Cat('file2', 'file2.k') -env.Cat('file3', ['xxx', 'yyy', 'zzz']) -env.Command('file4', 'file4.in', r'%(_python_)s %(cat_py)s $TARGET - $SOURCES') -env.Cat('file5', 'file5.k') -env.Cat('subdir/file6', 'subdir/file6.in') -""" % locals()) - -test.write(['work4', 'src', 'aaa'], "aaa 1\n") -test.write(['work4', 'src', 'bbb.k'], """\ -bbb.k 1 -include ccc -include ../inc/ddd -include ../inc/eee -""") -test.write(['work4', 'src', 'ccc'], "ccc 1\n") -test.write(['work4', 'src', 'ddd'], "ddd 1\n") -test.write(['work4', 'src', 'eee.in'], "eee.in 1\n") - -test.write(['work4', 'src', 'file1.in'], "file1.in 1\n") - -test.write(['work4', 'src', 'file2.k'], """\ -file2.k 1 line 1 -include xxx -include yyy -file2.k 1 line 4 -""") - -test.write(['work4', 'src', 'file4.in'], "file4.in 1\n") - -test.write(['work4', 'src', 'xxx'], "xxx 1\n") -test.write(['work4', 'src', 'yyy'], "yyy 1\n") -test.write(['work4', 'src', 'zzz'], "zzz 1\n") - -test.write(['work4', 'src', 'file5.k'], """\ -file5.k 1 line 1 -include ../inc/aaa -include ../inc/bbb.k -file5.k 1 line 4 -""") - -test.write(['work4', 'src', 'subdir', 'file6.in'], "subdir/file6.in 1\n") - -# -test.run(chdir='work4/src', arguments='.') - -test.must_match(['work4', 'src', 'file1'], "file1.in 1\n") -test.must_match(['work4', 'src', 'file2'], """\ -file2.k 1 line 1 -xxx 1 -yyy 1 -file2.k 1 line 4 -""") -test.must_match(['work4', 'src', 'file3'], "xxx 1\nyyy 1\nzzz 1\n") -test.must_match(['work4', 'src', 'file4'], "file4.in 1\n") -test.must_match(['work4', 'src', 'file5'], """\ -file5.k 1 line 1 -aaa 1 -bbb.k 1 -ccc 1 -ddd 1 -eee.in 1 -file5.k 1 line 4 -""") - -# -test.write(['work4', 'src', 'file1.in'], "file1.in 2\n") -test.write(['work4', 'src', 'yyy'], "yyy 2\n") -test.write(['work4', 'src', 'zzz'], "zzz 2\n") -test.write(['work4', 'src', 'bbb.k'], "bbb.k 2\ninclude ccc\n") - -work4_inc_bbb_k = test.workpath('work4', 'inc', 'bbb.k') -work4_inc_ddd = test.workpath('work4', 'inc', 'ddd') -work4_inc_eee = test.workpath('work4', 'inc', 'eee') - -test.run(chdir='work4/src', arguments=args, stdout=test.wrap_stdout("""\ -scons: rebuilding `file1' because `file1.in' changed -%(_python_)s %(cat_py)s file1 file1.in -scons: rebuilding `file2' because `yyy' changed -%(_python_)s %(cat_py)s file2 file2.k -scons: rebuilding `file3' because: - `yyy' changed - `zzz' changed -%(_python_)s %(cat_py)s file3 xxx yyy zzz -scons: rebuilding `%(work4_inc_bbb_k)s' because: - `%(work4_inc_ddd)s' is no longer a dependency - `%(work4_inc_eee)s' is no longer a dependency - `bbb.k' changed -Install file: "bbb.k" as "%(work4_inc_bbb_k)s" -scons: rebuilding `file5' because `%(work4_inc_bbb_k)s' changed -%(_python_)s %(cat_py)s file5 file5.k -""" % locals())) - -test.must_match(['work4', 'src', 'file1'], "file1.in 2\n") -test.must_match(['work4', 'src', 'file2'], """\ -file2.k 1 line 1 -xxx 1 -yyy 2 -file2.k 1 line 4 -""") -test.must_match(['work4', 'src', 'file3'], "xxx 1\nyyy 2\nzzz 2\n") -test.must_match(['work4', 'src', 'file5'], """\ -file5.k 1 line 1 -aaa 1 -bbb.k 2 -ccc 1 -file5.k 1 line 4 -""") - - - -test.write(['work5', 'SConstruct'], """\ -import shutil - -env = Environment() -mode = int(ARGUMENTS.get('mode')) -if mode: - def DifferentCopy(target, source, env): - tgt = str(target[0]) - src = str(source[0]) - shutil.copy(src, tgt) - def AltCopyStage2(target, source, env): - pass - MyCopy = Builder(action = [DifferentCopy, AltCopyStage2]) - - def ChangingCopy(target, source, env): - tgt = str(target[0]) - src = str(source[0]) - shutil.copy(src, tgt) - ChangingCopy = Builder(action = ChangingCopy) -else: - MyCopy = Builder(action = Copy('$TARGET', '$SOURCE')) - def ChangingCopy(target, source, env): - tgt = str(target[0].abspath) - src = str(source[0].abspath) - shutil.copy(src, tgt) - ChangingCopy = Builder(action = ChangingCopy) - -env['BUILDERS']['MyCopy'] = MyCopy -env['BUILDERS']['ChangingCopy'] = ChangingCopy - -env.MyCopy('f1.out', 'f1.in') -env.ChangingCopy('f2.out', 'f2.in') -""") - -test.write(['work5', 'f1.in'], "work5/f1.in\n") -test.write(['work5', 'f2.in'], "work5/f2.in\n") - -test.run(chdir = 'work5', arguments = "mode=0 .") - -test.must_match(['work5', 'f1.out'], "work5/f1.in\n") -test.must_match(['work5', 'f2.out'], "work5/f2.in\n") - -test.run(chdir = 'work5', - arguments = "--debug=explain mode=1 .", - stdout = test.wrap_stdout("""\ -scons: rebuilding `f1.out' because the build action changed: - old: Copy("$TARGET", "$SOURCE") - new: DifferentCopy(target, source, env) - AltCopyStage2(target, source, env) -DifferentCopy(["f1.out"], ["f1.in"]) -AltCopyStage2(["f1.out"], ["f1.in"]) -scons: rebuilding `f2.out' because the contents of the build action changed - action: ChangingCopy(target, source, env) -ChangingCopy(["f2.out"], ["f2.in"]) -""")) - - - -test.pass_test() diff --git a/test/explain/alias-order.py b/test/explain/alias-order.py new file mode 100644 index 0000000..78f9642 --- /dev/null +++ b/test/explain/alias-order.py @@ -0,0 +1,81 @@ +#!/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 a lot of the basic operation of the --debug=explain option. +""" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +args = '--debug=explain target2.dat' + +test.subdir('src') +test.write(['src', 'SConstruct'],""" +env = Environment() + +def action( source, target, env ): + f = open( str(target[0]), 'w' ) + f.write( source[0].get_contents()) + f.close() + +builder = env.Builder( action=action ) + +builder( env, target = "target1.dat", source = "source1.dat" ) +alias = env.Alias( "alias", "source2.dat" ) +builder( env, target = "target2.dat", source = ["target1.dat"] ) +env.Depends( "target2.dat", alias ) +""" +) + +test.write(["src", "source1.dat"], "a" ) +test.write(["src", "source2.dat"], "a" ) + +expect = test.wrap_stdout("""\ +scons: building `target1.dat' because it doesn't exist +action(["target1.dat"], ["source1.dat"]) +scons: building `target2.dat' because it doesn't exist +action(["target2.dat"], ["target1.dat"]) +""") + +test.run(chdir='src', arguments=args, stdout=expect) + +test.write(["src", "source1.dat"], "b" ) + +expect = test.wrap_stdout("""\ +scons: rebuilding `target1.dat' because `source1.dat' changed +action(["target1.dat"], ["source1.dat"]) +scons: rebuilding `target2.dat' because `target1.dat' changed +action(["target2.dat"], ["target1.dat"]) +""") + +test.run(chdir='src', arguments=args, stdout=expect) + + +test.pass_test() diff --git a/test/explain/basic.py b/test/explain/basic.py new file mode 100644 index 0000000..3366359 --- /dev/null +++ b/test/explain/basic.py @@ -0,0 +1,399 @@ +#!/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 a lot of the basic operation of the --debug=explain option. +""" + +import os.path +import string +import sys +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.subdir(['src'], ['src', 'subdir']) + +subdir_file7 = os.path.join('subdir', 'file7') +subdir_file7_in = os.path.join('subdir', 'file7.in') + +cat_py = test.workpath('cat.py') +inc_aaa = test.workpath('inc', 'aaa') +inc_ddd = test.workpath('inc', 'ddd') +inc_eee = test.workpath('inc', 'eee') +inc_bbb_k = test.workpath('inc', 'bbb.k') + + + +test.write(cat_py, r""" +import sys + +def process(outfp, infp): + for line in infp.readlines(): + if line[:8] == 'include ': + file = line[8:-1] + try: + fp = open(file, 'rb') + except IOError: + import os + print "os.getcwd() =", os.getcwd() + raise + process(outfp, fp) + else: + outfp.write(line) + +outfp = open(sys.argv[1], 'wb') +for f in sys.argv[2:]: + if f != '-': + process(outfp, open(f, 'rb')) + +sys.exit(0) +""") + +SConstruct_contents = """\ +import re + +include_re = re.compile(r'^include\s+(\S+)$', re.M) + +def kfile_scan(node, env, target, arg): + contents = node.get_contents() + includes = include_re.findall(contents) + return includes + +kscan = Scanner(name = 'kfile', + function = kfile_scan, + argument = None, + skeys = ['.k']) + +cat = Builder(action = r'%(_python_)s %(cat_py)s $TARGET $SOURCES') + +env = Environment() +env.Append(BUILDERS = {'Cat':cat}, + SCANNERS = kscan) + +Export("env") +SConscript('SConscript') +env.Install('../inc', 'aaa') +env.InstallAs('../inc/bbb.k', 'bbb.k') +env.Install('../inc', 'ddd') +env.InstallAs('../inc/eee', 'eee.in') +""" % locals() + +test.write(['src', 'SConstruct'], SConstruct_contents) + +test.write(['src', 'SConscript'], """\ +Import("env") +env.Cat('file1', 'file1.in') +env.Cat('file2', 'file2.k') +env.Cat('file3', ['xxx', 'yyy', 'zzz']) +env.Command('file4', 'file4.in', + r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES', + FILE4FLAG='-') +env.Cat('file5', 'file5.k') +file6 = env.Cat('file6', 'file6.in') +AlwaysBuild(file6) +env.Cat('subdir/file7', 'subdir/file7.in') +""" % locals()) + +test.write(['src', 'aaa'], "aaa 1\n") +test.write(['src', 'bbb.k'], """\ +bbb.k 1 +include ccc +include ../inc/ddd +include ../inc/eee +""") +test.write(['src', 'ccc'], "ccc 1\n") +test.write(['src', 'ddd'], "ddd 1\n") +test.write(['src', 'eee.in'], "eee.in 1\n") + +test.write(['src', 'file1.in'], "file1.in 1\n") + +test.write(['src', 'file2.k'], """\ +file2.k 1 line 1 +include xxx +include yyy +file2.k 1 line 4 +""") + +test.write(['src', 'file4.in'], "file4.in 1\n") + +test.write(['src', 'xxx'], "xxx 1\n") +test.write(['src', 'yyy'], "yyy 1\n") +test.write(['src', 'zzz'], "zzz 1\n") + +test.write(['src', 'file5.k'], """\ +file5.k 1 line 1 +include ../inc/aaa +include ../inc/bbb.k +file5.k 1 line 4 +""") + +test.write(['src', 'file6.in'], "file6.in 1\n") + +test.write(['src', 'subdir', 'file7.in'], "subdir/file7.in 1\n") + + + +args = '--debug=explain .' + + + +expect = test.wrap_stdout("""\ +scons: building `file1' because it doesn't exist +%(_python_)s %(cat_py)s file1 file1.in +scons: building `file2' because it doesn't exist +%(_python_)s %(cat_py)s file2 file2.k +scons: building `file3' because it doesn't exist +%(_python_)s %(cat_py)s file3 xxx yyy zzz +scons: building `file4' because it doesn't exist +%(_python_)s %(cat_py)s file4 - file4.in +scons: building `%(inc_aaa)s' because it doesn't exist +Install file: "aaa" as "%(inc_aaa)s" +scons: building `%(inc_ddd)s' because it doesn't exist +Install file: "ddd" as "%(inc_ddd)s" +scons: building `%(inc_eee)s' because it doesn't exist +Install file: "eee.in" as "%(inc_eee)s" +scons: building `%(inc_bbb_k)s' because it doesn't exist +Install file: "bbb.k" as "%(inc_bbb_k)s" +scons: building `file5' because it doesn't exist +%(_python_)s %(cat_py)s file5 file5.k +scons: building `file6' because it doesn't exist +%(_python_)s %(cat_py)s file6 file6.in +scons: building `%(subdir_file7)s' because it doesn't exist +%(_python_)s %(cat_py)s %(subdir_file7)s %(subdir_file7_in)s +""" % locals()) + +test.run(chdir='src', arguments=args, stdout=expect) + +test.must_match(['src', 'file1'], "file1.in 1\n") +test.must_match(['src', 'file2'], """\ +file2.k 1 line 1 +xxx 1 +yyy 1 +file2.k 1 line 4 +""") +test.must_match(['src', 'file3'], "xxx 1\nyyy 1\nzzz 1\n") +test.must_match(['src', 'file4'], "file4.in 1\n") +test.must_match(['src', 'file5'], """\ +file5.k 1 line 1 +aaa 1 +bbb.k 1 +ccc 1 +ddd 1 +eee.in 1 +file5.k 1 line 4 +""") +test.must_match(['src', 'file6'], "file6.in 1\n") + + + +test.write(['src', 'file1.in'], "file1.in 2\n") +test.write(['src', 'yyy'], "yyy 2\n") +test.write(['src', 'zzz'], "zzz 2\n") +test.write(['src', 'bbb.k'], "bbb.k 2\ninclude ccc\n") + +expect = test.wrap_stdout("""\ +scons: rebuilding `file1' because `file1.in' changed +%(_python_)s %(cat_py)s file1 file1.in +scons: rebuilding `file2' because `yyy' changed +%(_python_)s %(cat_py)s file2 file2.k +scons: rebuilding `file3' because: + `yyy' changed + `zzz' changed +%(_python_)s %(cat_py)s file3 xxx yyy zzz +scons: rebuilding `%(inc_bbb_k)s' because: + `%(inc_ddd)s' is no longer a dependency + `%(inc_eee)s' is no longer a dependency + `bbb.k' changed +Install file: "bbb.k" as "%(inc_bbb_k)s" +scons: rebuilding `file5' because `%(inc_bbb_k)s' changed +%(_python_)s %(cat_py)s file5 file5.k +scons: rebuilding `file6' because AlwaysBuild() is specified +%(_python_)s %(cat_py)s file6 file6.in +""" % locals()) + +test.run(chdir='src', arguments=args, stdout=expect) + +test.must_match(['src', 'file1'], "file1.in 2\n") +test.must_match(['src', 'file2'], """\ +file2.k 1 line 1 +xxx 1 +yyy 2 +file2.k 1 line 4 +""") +test.must_match(['src', 'file3'], "xxx 1\nyyy 2\nzzz 2\n") +test.must_match(['src', 'file5'], """\ +file5.k 1 line 1 +aaa 1 +bbb.k 2 +ccc 1 +file5.k 1 line 4 +""") + + + +test.write(['src', 'SConscript'], """\ +Import("env") +env.Cat('file3', ['xxx', 'yyy']) +""") + +expect = test.wrap_stdout("""\ +scons: rebuilding `file3' because `zzz' is no longer a dependency +%(_python_)s %(cat_py)s file3 xxx yyy +""" % locals()) + +test.run(chdir='src', arguments=args, stdout=expect) + +test.must_match(['src', 'file3'], "xxx 1\nyyy 2\n") + + + +test.write(['src', 'SConscript'], """\ +Import("env") +env.Cat('file3', ['xxx', 'yyy', 'zzz']) +""") + +expect = test.wrap_stdout("""\ +scons: rebuilding `file3' because `zzz' is a new dependency +%(_python_)s %(cat_py)s file3 xxx yyy zzz +""" % locals()) + +test.run(chdir='src', arguments=args, stdout=expect) + +test.must_match(['src', 'file3'], "xxx 1\nyyy 2\nzzz 2\n") + + + +test.write(['src', 'SConscript'], """\ +Import("env") +env.Cat('file3', ['zzz', 'yyy', 'xxx']) +""") + +expect = test.wrap_stdout("""\ +scons: rebuilding `file3' because the dependency order changed: + old: ['xxx', 'yyy', 'zzz'] + new: ['zzz', 'yyy', 'xxx'] +%(_python_)s %(cat_py)s file3 zzz yyy xxx +""" % locals()) + +test.run(chdir='src', arguments=args, stdout=expect) + +test.must_match(['src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") + + + +test.write(['src', 'SConscript'], """\ +Import("env") +f3 = File('file3') +env.Cat(f3, ['zzz', 'yyy', 'xxx']) +env.AddPostAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy') +env.AddPreAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES') +""" % locals()) + +expect = test.wrap_stdout("""\ +scons: rebuilding `file3' because the build action changed: + old: %(_python_)s %(cat_py)s $TARGET $SOURCES + new: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES + %(_python_)s %(cat_py)s $TARGET $SOURCES + %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy +%(_python_)s %(cat_py)s file3.alt zzz yyy xxx +%(_python_)s %(cat_py)s file3 zzz yyy xxx +%(_python_)s %(cat_py)s file3.yyy zzz yyy xxx yyy +""" % locals()) + +test.run(chdir='src', arguments=args, stdout=expect) + +test.must_match(['src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") +test.must_match(['src', 'file3.alt'], "zzz 2\nyyy 2\nxxx 1\n") +test.must_match(['src', 'file3.yyy'], "zzz 2\nyyy 2\nxxx 1\nyyy 2\n") + + + +test.write(['src', 'SConscript'], """\ +Import("env") +f3 = File('file3') +env.Cat(f3, ['zzz', 'yyy', 'xxx']) +env.AddPostAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx') +env.AddPreAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES') +""" % locals()) + +expect = test.wrap_stdout("""\ +scons: rebuilding `file3' because the build action changed: + old: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES + %(_python_)s %(cat_py)s $TARGET $SOURCES + %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy + new: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES + %(_python_)s %(cat_py)s $TARGET $SOURCES + %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx +%(_python_)s %(cat_py)s file3.alt zzz yyy xxx +%(_python_)s %(cat_py)s file3 zzz yyy xxx +%(_python_)s %(cat_py)s file3.yyy zzz yyy xxx xxx +""" % locals()) + +test.run(chdir='src', arguments=args, stdout=expect) + +test.must_match(['src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") +test.must_match(['src', 'file3.alt'], "zzz 2\nyyy 2\nxxx 1\n") +test.must_match(['src', 'file3.yyy'], "zzz 2\nyyy 2\nxxx 1\nxxx 1\n") + + + +test.write(['src', 'SConscript'], """\ +Import("env") +env.Command('file4', 'file4.in', + r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES', + FILE4FLAG='') +""" % locals()) + +expect = test.wrap_stdout("""\ +scons: rebuilding `file4' because the contents of the build action changed + action: %(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES +%(_python_)s %(cat_py)s file4 file4.in +""" % locals()) + +test.run(chdir='src',arguments=args, stdout=expect) + +test.must_match(['src', 'file4'], "file4.in 1\n") + +test.up_to_date(chdir='src',arguments='.') + + + +# Test the transition when you turn ON SConsignFile(). +# This will (or might) rebuild things, but we don't care what, +# we just want to make sure we don't blow up. +test.write(['src', 'SConstruct'], + "SConsignFile()\n" + SConstruct_contents) + +test.run(chdir='src', arguments=args) + +test.up_to_date(chdir='src',arguments='.') + + + +test.pass_test() diff --git a/test/explain/function-actions.py b/test/explain/function-actions.py new file mode 100644 index 0000000..b28747d --- /dev/null +++ b/test/explain/function-actions.py @@ -0,0 +1,100 @@ +#!/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 --debug=explain correctly handles changes to actions +that contain a list of function Actions. +""" + +import os.path +import string +import sys +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + + + +test.write('SConstruct', """\ +import shutil + +env = Environment() +mode = int(ARGUMENTS.get('mode')) +if mode: + def DifferentCopy(target, source, env): + tgt = str(target[0]) + src = str(source[0]) + shutil.copy(src, tgt) + def AltCopyStage2(target, source, env): + pass + MyCopy = Builder(action = [DifferentCopy, AltCopyStage2]) + + def ChangingCopy(target, source, env): + tgt = str(target[0]) + src = str(source[0]) + shutil.copy(src, tgt) + ChangingCopy = Builder(action = ChangingCopy) +else: + MyCopy = Builder(action = Copy('$TARGET', '$SOURCE')) + def ChangingCopy(target, source, env): + tgt = str(target[0].abspath) + src = str(source[0].abspath) + shutil.copy(src, tgt) + ChangingCopy = Builder(action = ChangingCopy) + +env['BUILDERS']['MyCopy'] = MyCopy +env['BUILDERS']['ChangingCopy'] = ChangingCopy + +env.MyCopy('f1.out', 'f1.in') +env.ChangingCopy('f2.out', 'f2.in') +""") + +test.write('f1.in', "f1.in\n") +test.write('f2.in', "f2.in\n") + +test.run(arguments = "mode=0 .") + +test.must_match('f1.out', "f1.in\n") +test.must_match('f2.out', "f2.in\n") + +test.run(arguments = "--debug=explain mode=1 .", + stdout = test.wrap_stdout("""\ +scons: rebuilding `f1.out' because the build action changed: + old: Copy("$TARGET", "$SOURCE") + new: DifferentCopy(target, source, env) + AltCopyStage2(target, source, env) +DifferentCopy(["f1.out"], ["f1.in"]) +AltCopyStage2(["f1.out"], ["f1.in"]) +scons: rebuilding `f2.out' because the contents of the build action changed + action: ChangingCopy(target, source, env) +ChangingCopy(["f2.out"], ["f2.in"]) +""")) + + + +test.pass_test() diff --git a/test/explain/save-info.py b/test/explain/save-info.py new file mode 100644 index 0000000..0d8f5c7 --- /dev/null +++ b/test/explain/save-info.py @@ -0,0 +1,211 @@ +#!/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 --debug=explain information gets saved by default. +""" + +import os.path +import string +import sys +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.subdir( 'src', ['src', 'subdir']) + +cat_py = test.workpath('cat.py') +inc_bbb_k = test.workpath('inc', 'bbb.k') +inc_ddd = test.workpath('inc', 'ddd') +inc_eee = test.workpath('inc', 'eee') + +test.write(cat_py, r""" +import sys + +def process(outfp, infp): + for line in infp.readlines(): + if line[:8] == 'include ': + file = line[8:-1] + try: + fp = open(file, 'rb') + except IOError: + import os + print "os.getcwd() =", os.getcwd() + raise + process(outfp, fp) + else: + outfp.write(line) + +outfp = open(sys.argv[1], 'wb') +for f in sys.argv[2:]: + if f != '-': + process(outfp, open(f, 'rb')) + +sys.exit(0) +""") + +test.write(['src', 'SConstruct'], """\ +import re + +include_re = re.compile(r'^include\s+(\S+)$', re.M) + +def kfile_scan(node, env, target, arg): + contents = node.get_contents() + includes = include_re.findall(contents) + return includes + +kscan = Scanner(name = 'kfile', + function = kfile_scan, + argument = None, + skeys = ['.k']) + +cat = Builder(action = r'%(_python_)s %(cat_py)s $TARGET $SOURCES') + +env = Environment() +env.Append(BUILDERS = {'Cat':cat}, + SCANNERS = kscan) + +Export("env") +SConscript('SConscript') +env.Install('../inc', 'aaa') +env.InstallAs('../inc/bbb.k', 'bbb.k') +env.Install('../inc', 'ddd') +env.InstallAs('../inc/eee', 'eee.in') +""" % locals()) + +test.write(['src', 'SConscript'], """\ +Import("env") +env.Cat('file1', 'file1.in') +env.Cat('file2', 'file2.k') +env.Cat('file3', ['xxx', 'yyy', 'zzz']) +env.Command('file4', 'file4.in', r'%(_python_)s %(cat_py)s $TARGET - $SOURCES') +env.Cat('file5', 'file5.k') +env.Cat('subdir/file6', 'subdir/file6.in') +""" % locals()) + +test.write(['src', 'aaa'], "aaa 1\n") +test.write(['src', 'bbb.k'], """\ +bbb.k 1 +include ccc +include ../inc/ddd +include ../inc/eee +""") +test.write(['src', 'ccc'], "ccc 1\n") +test.write(['src', 'ddd'], "ddd 1\n") +test.write(['src', 'eee.in'], "eee.in 1\n") + +test.write(['src', 'file1.in'], "file1.in 1\n") + +test.write(['src', 'file2.k'], """\ +file2.k 1 line 1 +include xxx +include yyy +file2.k 1 line 4 +""") + +test.write(['src', 'file4.in'], "file4.in 1\n") + +test.write(['src', 'xxx'], "xxx 1\n") +test.write(['src', 'yyy'], "yyy 1\n") +test.write(['src', 'zzz'], "zzz 1\n") + +test.write(['src', 'file5.k'], """\ +file5.k 1 line 1 +include ../inc/aaa +include ../inc/bbb.k +file5.k 1 line 4 +""") + +test.write(['src', 'subdir', 'file6.in'], "subdir/file6.in 1\n") + +# +test.run(chdir='src', arguments='.') + +test.must_match(['src', 'file1'], "file1.in 1\n") +test.must_match(['src', 'file2'], """\ +file2.k 1 line 1 +xxx 1 +yyy 1 +file2.k 1 line 4 +""") +test.must_match(['src', 'file3'], "xxx 1\nyyy 1\nzzz 1\n") +test.must_match(['src', 'file4'], "file4.in 1\n") +test.must_match(['src', 'file5'], """\ +file5.k 1 line 1 +aaa 1 +bbb.k 1 +ccc 1 +ddd 1 +eee.in 1 +file5.k 1 line 4 +""") + +test.write(['src', 'file1.in'], "file1.in 2\n") +test.write(['src', 'yyy'], "yyy 2\n") +test.write(['src', 'zzz'], "zzz 2\n") +test.write(['src', 'bbb.k'], "bbb.k 2\ninclude ccc\n") + +expect = test.wrap_stdout("""\ +scons: rebuilding `file1' because `file1.in' changed +%(_python_)s %(cat_py)s file1 file1.in +scons: rebuilding `file2' because `yyy' changed +%(_python_)s %(cat_py)s file2 file2.k +scons: rebuilding `file3' because: + `yyy' changed + `zzz' changed +%(_python_)s %(cat_py)s file3 xxx yyy zzz +scons: rebuilding `%(inc_bbb_k)s' because: + `%(inc_ddd)s' is no longer a dependency + `%(inc_eee)s' is no longer a dependency + `bbb.k' changed +Install file: "bbb.k" as "%(inc_bbb_k)s" +scons: rebuilding `file5' because `%(inc_bbb_k)s' changed +%(_python_)s %(cat_py)s file5 file5.k +""" % locals()) + +test.run(chdir='src', arguments='--debug=explain .', stdout=expect) + +test.must_match(['src', 'file1'], "file1.in 2\n") +test.must_match(['src', 'file2'], """\ +file2.k 1 line 1 +xxx 1 +yyy 2 +file2.k 1 line 4 +""") +test.must_match(['src', 'file3'], "xxx 1\nyyy 2\nzzz 2\n") +test.must_match(['src', 'file5'], """\ +file5.k 1 line 1 +aaa 1 +bbb.k 2 +ccc 1 +file5.k 1 line 4 +""") + + + +test.pass_test() diff --git a/test/import.py b/test/import.py index 7debffc..a26d745 100644 --- a/test/import.py +++ b/test/import.py @@ -179,8 +179,8 @@ if moc: qtdir = os.path.dirname(os.path.dirname(moc)) - qt_err = """ -scons: warning: Could not detect qt, using moc executable as a hint (QTDIR=%(qtdir)s) + qt_err = r""" +scons: warning: Could not detect qt, using moc executable as a hint \(QTDIR=%(qtdir)s\) """ % locals() else: diff --git a/test/option/debug-count.py b/test/option/debug-count.py index 3a0fbb0..d301312 100644 --- a/test/option/debug-count.py +++ b/test/option/debug-count.py @@ -83,5 +83,15 @@ for args in ['-h --debug=count', '--debug=count']: 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', + interpreter = ['python', '-O'], + stderr = expect_warning, + match = TestSCons.match_re) + test.pass_test() diff --git a/test/option/debug-stacktrace.py b/test/option/debug-stacktrace.py index aff25f2..cf7b81d 100644 --- a/test/option/debug-stacktrace.py +++ b/test/option/debug-stacktrace.py @@ -51,7 +51,7 @@ def must_contain_all_lines(content, lines): test.write('SConstruct', """\ def kfile_scan(node, env, target): - raise "kfile_scan error" + raise Exception, "kfile_scan error" kscan = Scanner(name = 'kfile', function = kfile_scan, @@ -74,7 +74,7 @@ test.run(arguments = "--debug=stacktrace", lines = [ "scons: *** kfile_scan error", "scons: internal stack trace:", - 'raise "kfile_scan error"', + 'raise Exception, "kfile_scan error"', ] err = must_contain_all_lines(test.stderr(), lines) diff --git a/test/option/debug-time.py b/test/option/debug-time.py index 51cfacf..bf18b97 100644 --- a/test/option/debug-time.py +++ b/test/option/debug-time.py @@ -70,6 +70,18 @@ def num(s, match): 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 @@ -99,10 +111,10 @@ expected_command_time = reduce(lambda x, y: x + y, times, 0.0) stdout = test.stdout() -total_time = num(stdout, r'Total build time: (\d+\.\d+) seconds') -sconscript_time = num(stdout, r'Total SConscript file execution time: (\d+\.\d+) seconds') -scons_time = num(stdout, r'Total SCons execution time: (\d+\.\d+) seconds') -command_time = num(stdout, r'Total command execution time: (\d+\.\d+) seconds') +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 = [] @@ -133,6 +145,13 @@ if failures: print string.join([test.stdout()] + failures, '\n') 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") @@ -143,10 +162,10 @@ test.run(arguments = "-j4 --debug=time . SLEEP=1") stdout = test.stdout() -total_time = num(stdout, r'Total build time: (\d+\.\d+) seconds') -sconscript_time = num(stdout, r'Total SConscript file execution time: (\d+\.\d+) seconds') -scons_time = num(stdout, r'Total SCons execution time: (\d+\.\d+) seconds') -command_time = num(stdout, r'Total command execution time: (\d+\.\d+) seconds') +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 = [] @@ -162,5 +181,12 @@ if failures: print string.join([test.stdout()] + failures, '\n') 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() diff --git a/test/option/profile.py b/test/option/profile.py index eb6b394..7adf933 100644 --- a/test/option/profile.py +++ b/test/option/profile.py @@ -49,13 +49,13 @@ test.run(arguments = "--profile=%s -h" % scons_prof) test.fail_test(string.find(test.stdout(), 'usage: scons [OPTION]') == -1) test.fail_test(string.find(test.stdout(), 'usage: scons [OPTION]') == -1) -stats = pstats.Stats(scons_prof) -stats.sort_stats('time') - try: save_stdout = sys.stdout sys.stdout = StringIO.StringIO() + stats = pstats.Stats(scons_prof) + stats.sort_stats('time') + stats.strip_dirs().print_stats() s = sys.stdout.getvalue() @@ -63,9 +63,7 @@ finally: sys.stdout = save_stdout test.fail_test(string.find(s, 'Main.py') == -1) -test.fail_test(string.find(s, 'print_help') == -1) test.fail_test(string.find(s, '_main') == -1) -test.fail_test(string.find(s, 'option_parser.py') == -1) @@ -73,13 +71,13 @@ scons_prof = test.workpath('scons2.prof') test.run(arguments = "--profile %s" % scons_prof) -stats = pstats.Stats(scons_prof) -stats.sort_stats('time') - try: save_stdout = sys.stdout sys.stdout = StringIO.StringIO() + stats = pstats.Stats(scons_prof) + stats.sort_stats('time') + stats.strip_dirs().print_stats() s = sys.stdout.getvalue() |