diff options
Diffstat (limited to 'test')
28 files changed, 1810 insertions, 972 deletions
diff --git a/test/AddMethod.py b/test/AddMethod.py new file mode 100644 index 0000000..ef4a8d0 --- /dev/null +++ b/test/AddMethod.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify use of the AddMethod() global function (specifically, to add +an unbound method to the Environment class) and its counterpart +construction environment method. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +def foo(self): + return 'foo-' + env['FOO'] + +AddMethod(Environment, foo) +env = Environment(FOO = '111') +print env.foo() + +env = Environment(FOO = '222') +print env.foo() + +env.AddMethod(foo, 'bar') +print env.bar() + +""") + +expect = """\ +foo-111 +foo-222 +foo-222 +""" + +test.run(arguments = '-Q -q', stdout = expect) + +test.pass_test() diff --git a/test/AlwaysBuild.py b/test/AlwaysBuild.py index a107302..d1f07fd 100644 --- a/test/AlwaysBuild.py +++ b/test/AlwaysBuild.py @@ -33,6 +33,9 @@ test = TestSCons.TestSCons() test.subdir('sub') +sub_f3_out = os.path.join('sub', 'f3.out') +_SUBDIR_f3_out = os.path.join('$SUBDIR', 'f3.out') + test.write('SConstruct', """\ def bfunc(target, source, env): import shutil @@ -43,30 +46,37 @@ env = Environment(BUILDERS = { 'B' : B }, SUBDIR='sub') env.B('f1.out', source='f1.in') AlwaysBuild('f1.out') -env.B(r'%s', source='f3.in') -env.AlwaysBuild(r'%s') +env.B(r'%(sub_f3_out)s', source='f3.in') +env.AlwaysBuild(r'%(_SUBDIR_f3_out)s') env.Alias('clean1', [], Delete('clean1-target')) env.AlwaysBuild('clean1') c2 = env.Alias('clean2', [], [Delete('clean2-t1'), Delete('clean2-t2')]) env.AlwaysBuild(c2) -""" % (os.path.join('sub', 'f3.out'), - os.path.join('$SUBDIR', 'f3.out') - )) + +def dir_build(target, source, env): + open('dir_build.txt', 'ab').write('dir_build()\\n') +env.Command(Dir('dir'), None, dir_build) +env.AlwaysBuild('dir') +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "1") test.write('f3.in', "f3.in\n") +test.subdir('dir') + test.run(arguments = ".") -test.fail_test(test.read('f1.out') != '1') -test.fail_test(test.read(['sub', 'f3.out']) != '1') +test.must_match('f1.out', '1') +test.must_match(['sub', 'f3.out'], '1') +test.must_match('dir_build.txt', "dir_build()\n") test.write('f2.in', "2") test.run(arguments = ".") -test.fail_test(test.read('f1.out') != '2') -test.fail_test(test.read(['sub', 'f3.out']) != '2') +test.must_match('f1.out', '2') +test.must_match(['sub', 'f3.out'], '2') +test.must_match('dir_build.txt', "dir_build()\ndir_build()\n") test.run(arguments = 'clean1', stdout=test.wrap_stdout("""\ Delete("clean1-target") @@ -77,4 +87,8 @@ Delete("clean2-t1") Delete("clean2-t2") """)) +test.not_up_to_date(arguments = 'dir') + +test.must_match('dir_build.txt', "dir_build()\ndir_build()\ndir_build()\n") + test.pass_test() diff --git a/test/CFILESUFFIX.py b/test/CFILESUFFIX.py index 1fa615a..08c40c2 100644 --- a/test/CFILESUFFIX.py +++ b/test/CFILESUFFIX.py @@ -24,6 +24,10 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +""" +Verify that we can set CFILESUFFIX to arbitrary values. +""" + import os import os.path import string @@ -49,6 +53,13 @@ test.write('SConstruct', """ env = Environment(LEX = r'%(_python_)s mylex.py', tools = ['lex']) env.CFile(target = 'foo', source = 'foo.l') env.Clone(CFILESUFFIX = '.xyz').CFile(target = 'bar', source = 'bar.l') + +# Make sure that calling a Tool on a construction environment *after* +# we've set CFILESUFFIX doesn't overwrite the value. +env2 = Environment(tools = [], CFILESUFFIX = '.env2') +env2.Tool('lex') +env2['LEX'] = r'%(_python_)s mylex.py' +env2.CFile(target = 'f3', source = 'f3.l') """ % locals()) input = r""" @@ -66,10 +77,14 @@ test.write('foo.l', input % 'foo.l') test.write('bar.l', input % 'bar.l') +test.write('f3.l', input % 'f3.l') + test.run(arguments = '.') -test.fail_test(not os.path.exists(test.workpath('foo.c'))) +test.must_exist(test.workpath('foo.c')) + +test.must_exist(test.workpath('bar.xyz')) -test.fail_test(not os.path.exists(test.workpath('bar.xyz'))) +test.must_exist(test.workpath('f3.env2')) test.pass_test() diff --git a/test/CXX/CXXFILESUFFIX.py b/test/CXX/CXXFILESUFFIX.py index b156f74..fbc34ff 100644 --- a/test/CXX/CXXFILESUFFIX.py +++ b/test/CXX/CXXFILESUFFIX.py @@ -49,6 +49,13 @@ test.write('SConstruct', """ env = Environment(LEX = r'%(_python_)s mylex.py', tools = ['lex']) env.CXXFile(target = 'foo', source = 'foo.ll') env.Clone(CXXFILESUFFIX = '.xyz').CXXFile(target = 'bar', source = 'bar.ll') + +# Make sure that calling a Tool on a construction environment *after* +# we've set CXXFILESUFFIX doesn't overwrite the value. +env2 = Environment(tools = [], CXXFILESUFFIX = '.env2') +env2.Tool('lex') +env2['LEX'] = r'%(_python_)s mylex.py' +env2.CXXFile(target = 'f3', source = 'f3.ll') """ % locals()) input = r""" @@ -66,10 +73,14 @@ test.write('foo.ll', input % 'foo.ll') test.write('bar.ll', input % 'bar.ll') +test.write('f3.ll', input % 'f3.ll') + test.run(arguments = '.') -test.fail_test(not os.path.exists(test.workpath('foo.cc'))) +test.must_exist(test.workpath('foo.cc')) + +test.must_exist(test.workpath('bar.xyz')) -test.fail_test(not os.path.exists(test.workpath('bar.xyz'))) +test.must_exist(test.workpath('f3.env2')) test.pass_test() diff --git a/test/CacheDir/symlink.py b/test/CacheDir/symlink.py new file mode 100644 index 0000000..6dd1f94 --- /dev/null +++ b/test/CacheDir/symlink.py @@ -0,0 +1,68 @@ +#!/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 push and retrieve a built symlink to/from a CacheDir() +as an actualy symlink, not by copying the file contents. +""" + +import os +import os.path + +import TestSCons + +test = TestSCons.TestSCons() + +if not hasattr(os, 'symlink'): + import sys + test.skip_test('%s has no os.symlink() method; skipping test\n' % sys.executable) + +test.write('SConstruct', """\ +CacheDir('cache') +import os +Symlink = Action(lambda target, source, env: + os.symlink(str(source[0]), str(target[0])), + "os.symlink($SOURCE, $TARGET)") +Command('file.symlink', 'file.txt', Symlink) +""") + +test.write('file.txt', "file.txt\n") + +test.run(arguments = '.') + +test.fail_test(not os.path.islink('file.symlink')) +test.must_match('file.symlink', "file.txt\n") + +test.run(arguments = '-c .') + +test.must_not_exist('file.symlink') + +test.run(arguments = '.') + +test.fail_test(not os.path.islink('file.symlink')) +test.must_match('file.symlink', "file.txt\n") + +test.pass_test() diff --git a/test/Configure/Action-error.py b/test/Configure/Action-error.py new file mode 100644 index 0000000..0abcc7c --- /dev/null +++ b/test/Configure/Action-error.py @@ -0,0 +1,48 @@ +#!/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 calling Configure from an Action results in a readable error. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +def ConfigureAction(target, source, env): + env.Configure() + return 0 +env = Environment(BUILDERS = {'MyAction' : + Builder(action=Action(ConfigureAction))}) +env.MyAction('target', []) +""") + +expect = "scons: *** Calling Configure from Builders is not supported.\n" + +test.run(status=2, stderr=expect) + +test.pass_test() diff --git a/test/Configure/BuildDir-SConscript.py b/test/Configure/BuildDir-SConscript.py new file mode 100644 index 0000000..47b7d82 --- /dev/null +++ b/test/Configure/BuildDir-SConscript.py @@ -0,0 +1,159 @@ +#!/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 Configure calls in SConscript files work when used +with BuildDir. +""" + +import os.path + +import TestSCons + +_obj = TestSCons._obj + +test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) + +test.subdir( 'sub', ['sub', 'local'] ) + +NCR = test.NCR # non-cached rebuild +CR = test.CR # cached rebuild (up to date) +NCF = test.NCF # non-cached build failure +CF = test.CF # cached build failure + +test.write('SConstruct', """\ +opts = Options() +opts.Add('chdir') +env = Environment(options=opts) +if env['chdir'] == 'yes': + SConscriptChdir(1) +else: + SConscriptChdir(0) +BuildDir( 'build', '.' ) +SConscript( 'build/SConscript' ) +""") + +test.write(['sub', 'local', 'local_header.h'], "/* Hello World */" ) + +test.write('SConscript', """\ +SConscript( 'sub/SConscript' ) +""") + +test.write(['sub', 'SConscript'], """\ +def CustomTest(context): + context.Message('Executing Custom Test ... ') + ret = context.TryCompile('#include "local_header.h"', '.c') + context.Result(ret) + return ret + +env = Environment(FOO='fff') +env.Append( CPPPATH='local' ) +import os +env.AppendENVPath('PATH', os.environ['PATH']) +conf = Configure( env, custom_tests = {'CustomTest' : CustomTest, + '$FOO' : CustomTest} ) +if hasattr(conf, 'fff'): + conf.Message('$FOO should not have been expanded!') + Exit(1) +if not conf.CheckCHeader( 'math.h' ): + Exit(1) +if conf.CheckCHeader( 'no_std_c_header.h' ): + Exit(1) +if not conf.CustomTest(): + Exit(1) +env = conf.Finish() +env.Program( 'TestProgram', 'TestProgram.c' ) +""") + +test.write(['sub', 'TestProgram.h'], """\ +/* Just a test header */ +""") + +test.write(['sub', 'TestProgram.c'], """\ +#include "TestProgram.h" +#include <stdio.h> + +int main() { + printf( "Hello\\n" ); +} +""") + +# first with SConscriptChdir(0) +test.run(arguments='chdir=no') +test.checkLogAndStdout( ["Checking for C header file math.h... ", + "Checking for C header file no_std_c_header.h... ", + "Executing Custom Test ... "], + ["yes", "no", "yes"], + [[((".c", NCR), (_obj, NCR))], + [((".c", NCR), (_obj, NCF))], + [((".c", NCR), (_obj, NCR))]], + "config.log", + ".sconf_temp", + os.path.join("build", "sub", "SConscript")) + +test.run(arguments='chdir=no') +test.checkLogAndStdout( ["Checking for C header file math.h... ", + "Checking for C header file no_std_c_header.h... ", + "Executing Custom Test ... "], + ["yes", "no", "yes"], + [[((".c", CR), (_obj, CR))], + [((".c", CR), (_obj, CF))], + [((".c", CR), (_obj, CR))]], + "config.log", + ".sconf_temp", + os.path.join("build", "sub", "SConscript")) + +import shutil +shutil.rmtree(test.workpath(".sconf_temp")) +test.unlink(".sconsign.dblite") + +# now with SConscriptChdir(1) +test.run(arguments='chdir=yes') +test.checkLogAndStdout( ["Checking for C header file math.h... ", + "Checking for C header file no_std_c_header.h... ", + "Executing Custom Test ... "], + ["yes", "no", "yes"], + [[((".c", NCR), (_obj, NCR))], + [((".c", NCR), (_obj, NCF))], + [((".c", NCR), (_obj, NCR))]], + "config.log", + ".sconf_temp", + os.path.join("build", "sub", "SConscript")) + +test.run(arguments='chdir=yes') +test.checkLogAndStdout( ["Checking for C header file math.h... ", + "Checking for C header file no_std_c_header.h... ", + "Executing Custom Test ... "], + ["yes", "no", "yes"], + [[((".c", CR), (_obj, CR))], + [((".c", CR), (_obj, CF))], + [((".c", CR), (_obj, CR))]], + "config.log", + ".sconf_temp", + os.path.join("build", "sub", "SConscript")) + + +test.pass_test() diff --git a/test/Configure/BuildDir.py b/test/Configure/BuildDir.py new file mode 100644 index 0000000..ca3c147 --- /dev/null +++ b/test/Configure/BuildDir.py @@ -0,0 +1,91 @@ +#!/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 Configure contexts work with basic use of BuildDir. +""" + +import os.path + +import TestSCons + +_obj = TestSCons._obj + +test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) + +NCR = test.NCR # non-cached rebuild +CR = test.CR # cached rebuild (up to date) +NCF = test.NCF # non-cached build failure +CF = test.CF # cached build failure + +test.write('SConstruct', """\ +env = Environment(LOGFILE='build/config.log') +import os +env.AppendENVPath('PATH', os.environ['PATH']) +BuildDir( 'build', '.' ) +conf = env.Configure(conf_dir='build/config.tests', log_file='$LOGFILE') +r1 = conf.CheckCHeader( 'math.h' ) +r2 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error +env = conf.Finish() +Export( 'env' ) +# print open( 'build/config.log' ).readlines() +SConscript( 'build/SConscript' ) +""") + +test.write('SConscript', """\ +Import( 'env' ) +env.Program( 'TestProgram', 'TestProgram.c' ) +""") + +test.write('TestProgram.c', """\ +#include <stdio.h> + +int main() { + printf( "Hello\\n" ); +} +""") + +test.run() +test.checkLogAndStdout(["Checking for C header file math.h... ", + "Checking for C header file no_std_c_header.h... "], + ["yes", "no"], + [[((".c", NCR), (_obj, NCR))], + [((".c", NCR), (_obj, NCF))]], + os.path.join("build", "config.log"), + os.path.join("build", "config.tests"), + "SConstruct") + +test.run() +test.checkLogAndStdout(["Checking for C header file math.h... ", + "Checking for C header file no_std_c_header.h... "], + ["yes", "no"], + [[((".c", CR), (_obj, CR))], + [((".c", CR), (_obj, CF))]], + os.path.join("build", "config.log"), + os.path.join("build", "config.tests"), + "SConstruct") + +test.pass_test() diff --git a/test/Configure/Builder-call.py b/test/Configure/Builder-call.py new file mode 100644 index 0000000..a6f2fa5 --- /dev/null +++ b/test/Configure/Builder-call.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 calling normal Builders from an actual Configure +context environment works correctly. +""" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.write('cmd.py', r""" +import sys +sys.stderr.write( 'Hello World on stderr\n' ) +sys.stdout.write( 'Hello World on stdout\n' ) +open(sys.argv[1], 'w').write( 'Hello World\n' ) +""") + +test.write('SConstruct', """\ +env = Environment() +def CustomTest(*args): + return 0 +conf = env.Configure(custom_tests = {'MyTest' : CustomTest}) +if not conf.MyTest(): + env.Command("hello", [], '%(_python_)s cmd.py $TARGET') +env = conf.Finish() +""" % locals()) + +test.run(stderr="Hello World on stderr\n") + +test.pass_test() diff --git a/test/Configure/Configure.py b/test/Configure/Configure.py deleted file mode 100644 index 4063699..0000000 --- a/test/Configure/Configure.py +++ /dev/null @@ -1,939 +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__" - -import os -import re -import shutil -import string -import sys - -import __builtin__ -try: - __builtin__.zip -except AttributeError: - def zip(*lists): - result = [] - for i in xrange(len(lists[0])): - result.append(tuple(map(lambda l, i=i: l[i], lists))) - return result - __builtin__.zip = zip - -import TestCmd -import TestSCons - -if sys.platform == 'win32': - lib = 'msvcrt' -else: - lib = 'm' - -# to use cygwin compilers on cmd.exe -> uncomment following line -#lib = 'm' - -work_cnt = 0 -work_dir = None -python = TestSCons.python -_python_ = TestSCons._python_ -test = TestSCons.TestSCons() -_obj = TestSCons._obj -_exe = TestSCons._exe - -RE = 0 -RE_DOTALL = 1 -EXACT = 2 -def reset(match): - global test, work_dir, work_cnt - work_cnt = work_cnt + 1 - work_dir='test%d' % work_cnt - test.subdir(work_dir) - if match == RE: - test.match_func = TestCmd.match_re - elif match == RE_DOTALL: - test.match_func = TestCmd.match_re_dotall - elif match == EXACT: - test.match_func = TestCmd.match_exact - -def checkFiles(test, files): - global work_dir - for f in files: - test.fail_test( not os.path.isfile( test.workpath(work_dir,f) ) ) - -def checklib(lang, name, up_to_date): - if lang == 'C': - return (".c", _obj, _exe) - elif lang == 'C++': - return (".cc", _obj, _exe) - -class NoMatch: - def __init__(self, p): - self.pos = p - -NCR = 0 # non-cached rebuild -CR = 1 # cached rebuild (up to date) -NCF = 2 # non-cached build failure -CF = 3 # cached build failure - -def checkLogAndStdout(checks, results, cached, - test, logfile, sconf_dir, sconstruct, - doCheckLog=1, doCheckStdout=1): - def matchPart(log, logfile, lastEnd): - m = re.match(log, logfile[lastEnd:]) - if not m: - raise NoMatch, lastEnd - return m.end() + lastEnd - try: - #print len(os.linesep) - ls = os.linesep - nols = "(" - for i in range(len(ls)): - nols = nols + "(" - for j in range(i): - nols = nols + ls[j] - nols = nols + "[^" + ls[i] + "])" - if i < len(ls)-1: - nols = nols + "|" - nols = nols + ")" - lastEnd = 0 - logfile = test.read(test.workpath(work_dir, logfile)) - if (doCheckLog and - string.find( logfile, "scons: warning: The stored build " - "information has an unexpected class." ) >= 0): - test.fail_test() - sconf_dir = sconf_dir - sconstruct = sconstruct - - log = r'file\ \S*%s\,line \d+:' % re.escape(sconstruct) + ls - if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd) - log = "\t" + re.escape("Configure(confdir = %s)" % sconf_dir) + ls - if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd) - rdstr = "" - cnt = 0 - for check,result,cache_desc in zip(checks, results, cached): - log = re.escape("scons: Configure: " + check) + ls - if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd) - log = "" - result_cached = 1 - for bld_desc in cache_desc: # each TryXXX - for ext, flag in bld_desc: # each file in TryBuild - file = os.path.join(sconf_dir,"conftest_%d%s" % (cnt, ext)) - if flag == NCR: - # rebuild will pass - if ext in ['.c', '.cpp']: - log=log + re.escape(file + " <-") + ls - log=log + r"( \|" + nols + "*" + ls + ")+?" - else: - log=log + "(" + nols + "*" + ls +")*?" - result_cached = 0 - if flag == CR: - # up to date - log=log + \ - re.escape("scons: Configure: \"%s\" is up to date." - % file) + ls - log=log+re.escape("scons: Configure: The original builder " - "output was:") + ls - log=log+r"( \|.*"+ls+")+" - if flag == NCF: - # non-cached rebuild failure - log=log + "(" + nols + "*" + ls + ")*?" - result_cached = 0 - if flag == CF: - # cached rebuild failure - log=log + \ - re.escape("scons: Configure: Building \"%s\" failed " - "in a previous run and all its sources are" - " up to date." % file) + ls - log=log+re.escape("scons: Configure: The original builder " - "output was:") + ls - log=log+r"( \|.*"+ls+")+" - cnt = cnt + 1 - if result_cached: - result = "(cached) " + result - rdstr = rdstr + re.escape(check) + re.escape(result) + "\n" - log=log + re.escape("scons: Configure: " + result) + ls + ls - if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd) - log = "" - if doCheckLog: lastEnd = matchPart(ls, logfile, lastEnd) - if doCheckLog and lastEnd != len(logfile): - raise NoMatch, lastEnd - - except NoMatch, m: - print "Cannot match log file against log regexp." - print "log file: " - print "------------------------------------------------------" - print logfile[m.pos:] - print "------------------------------------------------------" - print "log regexp: " - print "------------------------------------------------------" - print log - print "------------------------------------------------------" - test.fail_test() - - if doCheckStdout: - exp_stdout = test.wrap_stdout(".*", rdstr) - if not test.match_re_dotall(test.stdout(), exp_stdout): - print "Unexpected stdout: " - print "-----------------------------------------------------" - print repr(test.stdout()) - print "-----------------------------------------------------" - print repr(exp_stdout) - print "-----------------------------------------------------" - test.fail_test() - -try: - # 1.1 if checks are ok, the cache mechanism should work - - reset(RE) - - test.write([work_dir, 'SConstruct'], """ -if int(ARGUMENTS.get('target_signatures_content', 0)): - TargetSignatures('content') -env = Environment() -import os -env.AppendENVPath('PATH', os.environ['PATH']) -conf = Configure(env) -r1 = conf.CheckLibWithHeader( '%s', 'math.h', 'c' ) -r2 = conf.CheckLibWithHeader( None, 'math.h', 'c' ) -r3 = conf.CheckLib( '%s', autoadd=0 ) -r4 = conf.CheckLib( None, autoadd=0 ) -r5 = conf.CheckCHeader( 'math.h' ) -r6 = conf.CheckCXXHeader( 'vector' ) -env = conf.Finish() -if not (r1 and r2 and r3 and r4 and r5 and r6): - Exit(1) -""" % (lib,lib)) - - test.run(chdir=work_dir) - checkLogAndStdout(["Checking for C library %s... " % lib, - "Checking for C library None... ", - "Checking for C library %s... " % lib, - "Checking for C library None... ", - "Checking for C header file math.h... ", - "Checking for C++ header file vector... "], - ["yes"]*6, - [[((".c", NCR), (_obj, NCR), (_exe, NCR))]]*4 + - [[((".c", NCR), (_obj, NCR))]] + - [[((".cpp", NCR), (_obj, NCR))]], - test, "config.log", ".sconf_temp", "SConstruct") - - - test.run(chdir=work_dir) - checkLogAndStdout(["Checking for C library %s... " % lib, - "Checking for C library None... ", - "Checking for C library %s... " % lib, - "Checking for C library None... ", - "Checking for C header file math.h... ", - "Checking for C++ header file vector... "], - ["yes"]*6, - [[((".c", CR), (_obj, CR), (_exe, CR))]]*4 + - [[((".c", CR), (_obj, CR))]] + - [[((".cpp", CR), (_obj, CR))]], - test, "config.log", ".sconf_temp", "SConstruct") - - # same should be true for TargetSignatures('content') - - test.run(chdir=work_dir, arguments='target_signatures_content=1 --config=force') - checkLogAndStdout(["Checking for C library %s... " % lib, - "Checking for C library None... ", - "Checking for C library %s... " % lib, - "Checking for C library None... ", - "Checking for C header file math.h... ", - "Checking for C++ header file vector... "], - ["yes"]*6, - [[((".c", NCR), (_obj, NCR), (_exe, NCR))]]*4 + - [[((".c", NCR), (_obj, NCR))]] + - [[((".cpp", NCR), (_obj, NCR))]], - test, "config.log", ".sconf_temp", "SConstruct") - - test.run(chdir=work_dir, arguments='target_signatures_content=1') - checkLogAndStdout(["Checking for C library %s... " % lib, - "Checking for C library None... ", - "Checking for C library %s... " % lib, - "Checking for C library None... ", - "Checking for C header file math.h... ", - "Checking for C++ header file vector... "], - ["yes"]*6, - [[((".c", CR), (_obj, CR), (_exe, CR))]]*4 + - [[((".c", CR), (_obj, CR))]] + - [[((".cpp", CR), (_obj, CR))]], - test, "config.log", ".sconf_temp", "SConstruct") - - # 1.2 if checks are not ok, the cache mechanism should work as well - # (via explicit cache) - reset(EXACT) # match exactly, "()" is a regexp thing - - test.write([work_dir, 'SConstruct'], """ -if int(ARGUMENTS.get('target_signatures_content', 0)): - TargetSignatures('content') -env = Environment() -import os -env.AppendENVPath('PATH', os.environ['PATH']) -conf = env.Configure() -r1 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error -r2 = conf.CheckLib( 'no_c_library_SAFFDG' ) # leads to link error -env = conf.Finish() -if not (not r1 and not r2): - print "FAIL: ", r1, r2 - Exit(1) -""") - - test.run(chdir=work_dir) - checkLogAndStdout(["Checking for C header file no_std_c_header.h... ", - "Checking for C library no_c_library_SAFFDG... "], - ["no"]*2, - [[((".c", NCR), (_obj, NCF))], - [((".c", NCR), (_obj, NCR), (_exe, NCF))]], - test, "config.log", ".sconf_temp", "SConstruct") - - test.run(chdir=work_dir) - checkLogAndStdout(["Checking for C header file no_std_c_header.h... ", - "Checking for C library no_c_library_SAFFDG... "], - ["no"]*2, - [[((".c", CR), (_obj, CF))], - [((".c", CR), (_obj, CR), (_exe, CF))]], - test, "config.log", ".sconf_temp", "SConstruct") - - # 1.3 same should be true for TargetSignatures('content') - test.run(chdir=work_dir, arguments='--config=force target_signatures_content=1') - checkLogAndStdout(["Checking for C header file no_std_c_header.h... ", - "Checking for C library no_c_library_SAFFDG... "], - ["no"]*2, - [[((".c", NCR), (_obj, NCF))], - [((".c", NCR), (_obj, NCR), (_exe, NCF))]], - test, "config.log", ".sconf_temp", "SConstruct") - - test.run(chdir=work_dir, arguments='target_signatures_content=1') - checkLogAndStdout(["Checking for C header file no_std_c_header.h... ", - "Checking for C library no_c_library_SAFFDG... "], - ["no"]*2, - [[((".c", CR), (_obj, CF))], - [((".c", CR), (_obj, CR), (_exe, CF))]], - test, "config.log", ".sconf_temp", "SConstruct") - - - - # 2.1 test that normal builds work together with Sconf - reset(RE_DOTALL) - - - test.write([work_dir, 'SConstruct'], """ -env = Environment() -import os -env.AppendENVPath('PATH', os.environ['PATH']) -conf = Configure(env) -r1 = conf.CheckCHeader( 'math.h' ) -r2 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error -env = conf.Finish() -Export( 'env' ) -SConscript( 'SConscript' ) -""") - test.write([work_dir, 'SConscript'], """ -Import( 'env' ) -env.Program( 'TestProgram', 'TestProgram.c' ) -""") - test.write([work_dir, 'TestProgram.c'], """ -#include <stdio.h> - -int main() { - printf( "Hello\\n" ); -} -""") - test.run(chdir=work_dir) - checkLogAndStdout(["Checking for C header file math.h... ", - "Checking for C header file no_std_c_header.h... "], - ["yes", "no"], - [[((".c", NCR), (_obj, NCR))], - [((".c", NCR), (_obj, NCF))]], - test, "config.log", ".sconf_temp", "SConstruct") - - test.run(chdir=work_dir) - checkLogAndStdout(["Checking for C header file math.h... ", - "Checking for C header file no_std_c_header.h... "], - ["yes", "no"], - [[((".c", CR), (_obj, CR))], - [((".c", CR), (_obj, CF))]], - test, "config.log", ".sconf_temp", "SConstruct") - - # 2.2 test that BuildDir builds work together with Sconf - reset(RE_DOTALL) - - - test.write([work_dir, 'SConstruct'], """ -env = Environment(LOGFILE='build/config.log') -import os -env.AppendENVPath('PATH', os.environ['PATH']) -BuildDir( 'build', '.' ) -conf = env.Configure(conf_dir='build/config.tests', log_file='$LOGFILE') -r1 = conf.CheckCHeader( 'math.h' ) -r2 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error -env = conf.Finish() -Export( 'env' ) -# print open( 'build/config.log' ).readlines() -SConscript( 'build/SConscript' ) -""") - test.write([work_dir, 'SConscript'], """ -Import( 'env' ) -env.Program( 'TestProgram', 'TestProgram.c' ) -""") - test.write([work_dir, 'TestProgram.c'], """ -#include <stdio.h> - -int main() { - printf( "Hello\\n" ); -} -""") - - test.run(chdir=work_dir) - checkLogAndStdout(["Checking for C header file math.h... ", - "Checking for C header file no_std_c_header.h... "], - ["yes", "no"], - [[((".c", NCR), (_obj, NCR))], - [((".c", NCR), (_obj, NCF))]], - test, - os.path.join("build", "config.log"), - os.path.join("build", "config.tests"), - "SConstruct") - - test.run(chdir=work_dir) - checkLogAndStdout(["Checking for C header file math.h... ", - "Checking for C header file no_std_c_header.h... "], - ["yes", "no"], - [[((".c", CR), (_obj, CR))], - [((".c", CR), (_obj, CF))]], - test, - os.path.join("build", "config.log"), - os.path.join("build", "config.tests"), - "SConstruct") - - # 2.3 test that Configure calls in SConscript files work - # even if BuildDir is set - reset(RE_DOTALL) - - test.subdir( [work_dir, 'sub'], [work_dir, 'sub', 'local'] ) - test.write([work_dir, 'SConstruct'], """ -opts = Options() -opts.Add('chdir') -env = Environment(options=opts) -if env['chdir'] == 'yes': - SConscriptChdir(1) -else: - SConscriptChdir(0) -BuildDir( 'build', '.' ) -SConscript( 'build/SConscript' ) -""") - test.write([work_dir, 'sub', 'local', 'local_header.h'], - "/* Hello World */" ) - test.write([work_dir, 'SConscript'], """ -SConscript( 'sub/SConscript' ) -""") - test.write([work_dir, 'sub', 'SConscript'], """ -def CustomTest(context): - context.Message('Executing Custom Test ... ') - ret = context.TryCompile('#include "local_header.h"', '.c') - context.Result(ret) - return ret - -env = Environment(FOO='fff') -env.Append( CPPPATH='local' ) -import os -env.AppendENVPath('PATH', os.environ['PATH']) -conf = Configure( env, custom_tests = {'CustomTest' : CustomTest, - '$FOO' : CustomTest} ) -if hasattr(conf, 'fff'): - conf.Message('$FOO should not have been expanded!') - Exit(1) -if not conf.CheckCHeader( 'math.h' ): - Exit(1) -if conf.CheckCHeader( 'no_std_c_header.h' ): - Exit(1) -if not conf.CustomTest(): - Exit(1) -env = conf.Finish() -env.Program( 'TestProgram', 'TestProgram.c' ) -""") - test.write([work_dir, 'sub', 'TestProgram.h'], """ -/* Just a test header */ -""") - test.write([work_dir, 'sub', 'TestProgram.c'], """ -#include "TestProgram.h" -#include <stdio.h> - -int main() { - printf( "Hello\\n" ); -} -""") - - # first with SConscriptChdir(0) - test.run(chdir=work_dir, arguments='chdir=no') - checkLogAndStdout( ["Checking for C header file math.h... ", - "Checking for C header file no_std_c_header.h... ", - "Executing Custom Test ... "], - ["yes", "no", "yes"], - [[((".c", NCR), (_obj, NCR))], - [((".c", NCR), (_obj, NCF))], - [((".c", NCR), (_obj, NCR))]], - test, "config.log", - ".sconf_temp", - os.path.join("build", "sub", "SConscript")) - - test.run(chdir=work_dir, arguments='chdir=no') - checkLogAndStdout( ["Checking for C header file math.h... ", - "Checking for C header file no_std_c_header.h... ", - "Executing Custom Test ... "], - ["yes", "no", "yes"], - [[((".c", CR), (_obj, CR))], - [((".c", CR), (_obj, CF))], - [((".c", CR), (_obj, CR))]], - test, "config.log", - ".sconf_temp", - os.path.join("build", "sub", "SConscript")) - - shutil.rmtree(test.workpath(work_dir, ".sconf_temp")) - os.unlink(test.workpath(work_dir, ".sconsign.dblite")) - - # now with SConscriptChdir(1) - test.run(chdir=work_dir, arguments='chdir=yes') - checkLogAndStdout( ["Checking for C header file math.h... ", - "Checking for C header file no_std_c_header.h... ", - "Executing Custom Test ... "], - ["yes", "no", "yes"], - [[((".c", NCR), (_obj, NCR))], - [((".c", NCR), (_obj, NCF))], - [((".c", NCR), (_obj, NCR))]], - test, "config.log", - ".sconf_temp", - os.path.join("build", "sub", "SConscript")) - - test.run(chdir=work_dir, arguments='chdir=yes') - checkLogAndStdout( ["Checking for C header file math.h... ", - "Checking for C header file no_std_c_header.h... ", - "Executing Custom Test ... "], - ["yes", "no", "yes"], - [[((".c", CR), (_obj, CR))], - [((".c", CR), (_obj, CF))], - [((".c", CR), (_obj, CR))]], - test, "config.log", - ".sconf_temp", - os.path.join("build", "sub", "SConscript")) - - # 3.1 test custom tests - reset(RE_DOTALL) - - compileOK = '#include <stdio.h>\\nint main() {printf("Hello");return 0;}' - compileFAIL = "syntax error" - linkOK = compileOK - linkFAIL = "void myFunc(); int main() { myFunc(); }" - runOK = compileOK - runFAIL = "int main() { return 1; }" - test.write([work_dir, 'pyAct.py'], 'import sys\nprint sys.argv[1]\nsys.exit(int(sys.argv[1]))\n') - test.write([work_dir, 'SConstruct'], """ -def CheckCustom(test): - test.Message( 'Executing MyTest ... ' ) - retCompileOK = test.TryCompile( '%s', '.c' ) - retCompileFAIL = test.TryCompile( '%s', '.c' ) - retLinkOK = test.TryLink( '%s', '.c' ) - retLinkFAIL = test.TryLink( '%s', '.c' ) - (retRunOK, outputRunOK) = test.TryRun( '%s', '.c' ) - (retRunFAIL, outputRunFAIL) = test.TryRun( '%s', '.c' ) - (retActOK, outputActOK) = test.TryAction( '%s pyAct.py 0 > $TARGET' ) - (retActFAIL, outputActFAIL) = test.TryAction( '%s pyAct.py 1 > $TARGET' ) - resOK = retCompileOK and retLinkOK and retRunOK and outputRunOK=="Hello" - resOK = resOK and retActOK and int(outputActOK)==0 - resFAIL = retCompileFAIL or retLinkFAIL or retRunFAIL or outputRunFAIL!="" - resFAIL = resFAIL or retActFAIL or outputActFAIL!="" - test.Result( int(resOK and not resFAIL) ) - return resOK and not resFAIL - -env = Environment() -import os -env.AppendENVPath('PATH', os.environ['PATH']) -conf = Configure( env, custom_tests={'CheckCustom' : CheckCustom} ) -conf.CheckCustom() -env = conf.Finish() -""" % (compileOK, compileFAIL, linkOK, linkFAIL, runOK, runFAIL, - python, python ) ) - test.run(chdir=work_dir) - checkLogAndStdout(["Executing MyTest ... "], - ["yes"], - [[(('.c', NCR), (_obj, NCR)), - (('.c', NCR), (_obj, NCF)), - (('.c', NCR), (_obj, NCR), (_exe, NCR)), - (('.c', NCR), (_obj, NCR), (_exe, NCF)), - (('.c', NCR), (_obj, NCR), (_exe, NCR), (_exe + '.out', NCR)), - (('.c', NCR), (_obj, NCR), (_exe, NCR), (_exe + '.out', NCF)), - (('', NCR),), - (('', NCF),)]], - test, "config.log", ".sconf_temp", "SConstruct") - - test.run(chdir=work_dir) - checkLogAndStdout(["Executing MyTest ... "], - ["yes"], - [[(('.c', CR), (_obj, CR)), - (('.c', CR), (_obj, CF)), - (('.c', CR), (_obj, CR), (_exe, CR)), - (('.c', CR), (_obj, CR), (_exe, CF)), - (('.c', CR), (_obj, CR), (_exe, CR), (_exe + '.out', CR)), - (('.c', CR), (_obj, CR), (_exe, CR), (_exe + '.out', CF)), - (('', CR),), - (('', CF),)]], - test, "config.log", ".sconf_temp", "SConstruct") - - # 4.1 test that calling normal builders from an actual configuring - # environment works - reset(RE_DOTALL) - - test.write([work_dir, 'cmd.py'], r""" -import sys -sys.stderr.write( 'Hello World on stderr\n' ) -sys.stdout.write( 'Hello World on stdout\n' ) -open(sys.argv[1], 'w').write( 'Hello World\n' ) -""") - - test.write([work_dir, 'SConstruct'], """ -env = Environment() -def CustomTest(*args): - return 0 -conf = env.Configure(custom_tests = {'MyTest' : CustomTest}) -if not conf.MyTest(): - env.Command("hello", [], '%(_python_)s cmd.py $TARGET') -env = conf.Finish() -""" % locals()) - test.run(chdir=work_dir, stderr="Hello World on stderr\n") - - # 4.2 test that calling Configure from a builder results in a - # readable Error - reset(EXACT) - - test.write([work_dir, 'SConstruct'], """ -def ConfigureAction(target, source, env): - env.Configure() - return 0 -env = Environment(BUILDERS = {'MyAction' : - Builder(action=Action(ConfigureAction))}) -env.MyAction('target', []) -""") - test.run(chdir=work_dir, status=2, - stderr="scons: *** Calling Configure from Builders is not supported.\n") - - # 4.3 test the calling Configure from multiple subsidiary, - # nested SConscript files does *not* result in an error. - - test.subdir([work_dir, 'dir1'], - [work_dir, 'dir2'], - [work_dir, 'dir2', 'sub1'], - [work_dir, 'dir2', 'sub1', 'sub2']) - test.write([work_dir, 'SConstruct'], """ -env = Environment() -SConscript(dirs=['dir1', 'dir2'], exports="env") -""") - test.write([work_dir, 'dir1', 'SConscript'], """ -Import("env") -conf = env.Configure() -conf.Finish() -""") - test.write([work_dir, 'dir2', 'SConscript'], """ -Import("env") -conf = env.Configure() -conf.Finish() -SConscript(dirs=['sub1'], exports="env") -""") - test.write([work_dir, 'dir2', 'sub1', 'SConscript'], """ -Import("env") -conf = env.Configure() -conf.Finish() -SConscript(dirs=['sub2'], exports="env") -""") - test.write([work_dir, 'dir2', 'sub1', 'sub2', 'SConscript'], """ -Import("env") -conf = env.Configure() -conf.Finish() -""") - test.run(chdir=work_dir) - - # 5.1 test the ConfigureDryRunError - - reset(EXACT) # exact match - - SConstruct_path = test.workpath(work_dir, 'SConstruct') - - test.write(SConstruct_path, """ -env = Environment() -import os -env.AppendENVPath('PATH', os.environ['PATH']) -conf = Configure(env) -r1 = conf.CheckLib('%s') # will pass -r2 = conf.CheckLib('hopefullynolib') # will fail -env = conf.Finish() -if not (r1 and not r2): - Exit(1) -""" % (lib)) - - test.run(chdir=work_dir, arguments='-n', status=2, stderr=""" -scons: *** Cannot create configure directory ".sconf_temp" within a dry-run. -File "%(SConstruct_path)s", line 5, in ? -""" % locals()) - test.must_not_exist([work_dir, 'config.log']) - test.subdir([work_dir, '.sconf_temp']) - - conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c") - - test.run(chdir=work_dir, arguments='-n', status=2, stderr=""" -scons: *** Cannot update configure test "%(conftest_0_c)s" within a dry-run. -File "%(SConstruct_path)s", line 6, in ? -""" % locals()) - - test.run(chdir=work_dir) - checkLogAndStdout( ["Checking for C library %s... " % lib, - "Checking for C library hopefullynolib... "], - ["yes", "no"], - [[((".c", NCR), (_obj, NCR))], - [((".c", NCR), (_obj, NCF))]], - test, "config.log", ".sconf_temp", "SConstruct") - oldLog = test.read(test.workpath(work_dir, 'config.log')) - - test.run(chdir=work_dir, arguments='-n') - checkLogAndStdout( ["Checking for C library %s... " % lib, - "Checking for C library hopefullynolib... "], - ["yes", "no"], - [[((".c", CR), (_obj, CR))], - [((".c", CR), (_obj, CF))]], - test, "config.log", ".sconf_temp", "SConstruct", - doCheckLog=0) - newLog = test.read(test.workpath(work_dir, 'config.log')) - if newLog != oldLog: - print "Unexpected update of log file within a dry run" - test.fail_test() - - # 5.2 test the --config=<auto|force|cache> option - reset(EXACT) # exact match - - SConstruct_path = test.workpath(work_dir, 'SConstruct') - - test.write(SConstruct_path, """ -env = Environment(CPPPATH='#/include') -import os -env.AppendENVPath('PATH', os.environ['PATH']) -conf = Configure(env) -r1 = conf.CheckCHeader('non_system_header1.h') -r2 = conf.CheckCHeader('non_system_header2.h') -env = conf.Finish() -""") - test.subdir([work_dir, 'include']) - test.write([work_dir, 'include', 'non_system_header1.h'], """ -/* A header */ -""") - - conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c") - - test.run(chdir=work_dir, arguments='--config=cache', status=2, stderr=""" -scons: *** "%(conftest_0_c)s" is not yet built and cache is forced. -File "%(SConstruct_path)s", line 6, in ? -""" % locals()) - - test.run(chdir=work_dir, arguments='--config=auto') - checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", - "Checking for C header file non_system_header2.h... "], - ["yes", "no"], - [[((".c", NCR), (_obj, NCR))], - [((".c", NCR), (_obj, NCF))]], - test, "config.log", ".sconf_temp", "SConstruct") - test.run(chdir=work_dir, arguments='--config=auto') - checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", - "Checking for C header file non_system_header2.h... "], - ["yes", "no"], - [[((".c", CR), (_obj, CR))], - [((".c", CR), (_obj, CF))]], - test, "config.log", ".sconf_temp", "SConstruct") - - test.run(chdir=work_dir, arguments='--config=force') - checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", - "Checking for C header file non_system_header2.h... "], - ["yes", "no"], - [[((".c", NCR), (_obj, NCR))], - [((".c", NCR), (_obj, NCF))]], - test, "config.log", ".sconf_temp", "SConstruct") - - test.run(chdir=work_dir, arguments='--config=cache') - checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", - "Checking for C header file non_system_header2.h... "], - ["yes", "no"], - [[((".c", CR), (_obj, CR))], - [((".c", CR), (_obj, CF))]], - test, "config.log", ".sconf_temp", "SConstruct") - - test.write([work_dir, 'include', 'non_system_header2.h'], """ -/* Another header */ -""") - test.unlink([work_dir, 'include', 'non_system_header1.h']) - test.run(chdir=work_dir, arguments='--config=cache') - checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", - "Checking for C header file non_system_header2.h... "], - ["yes", "no"], - [[((".c", CR), (_obj, CR))], - [((".c", CR), (_obj, CF))]], - test, "config.log", ".sconf_temp", "SConstruct") - - test.run(chdir=work_dir, arguments='--config=auto') - checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", - "Checking for C header file non_system_header2.h... "], - ["no", "yes"], - [[((".c", CR), (_obj, NCF))], - [((".c", CR), (_obj, NCR))]], - test, "config.log", ".sconf_temp", "SConstruct") - - # 5.3 test -Q option - reset(EXACT) - test.write([work_dir, 'SConstruct'], """ -env = Environment() -import os -env.AppendENVPath('PATH', os.environ['PATH']) -conf = Configure(env) -r1 = conf.CheckCHeader('stdio.h') -env = conf.Finish() -""") - test.run(chdir=work_dir, arguments='-Q', - stdout="scons: `.' is up to date.\n", stderr="") - - - # 6. check config.h support - reset(EXACT) - test.write([work_dir, 'SConstruct'], """ -env = Environment() -import os -env.AppendENVPath('PATH', os.environ['PATH']) -conf = Configure(env, config_h = 'config.h') -r1 = conf.CheckFunc('printf') -r2 = conf.CheckFunc('noFunctionCall') -r3 = conf.CheckType('int') -r4 = conf.CheckType('noType') -r5 = conf.CheckCHeader('stdio.h', '<>') -r6 = conf.CheckCHeader('hopefullynoc-header.h') -r7 = conf.CheckCXXHeader('vector', '<>') -r8 = conf.CheckCXXHeader('hopefullynocxx-header.h') -env = conf.Finish() -conf = Configure(env, config_h = 'config.h') -r9 = conf.CheckLib('%s', 'sin') -r10 = conf.CheckLib('hopefullynolib', 'sin') -r11 = conf.CheckLibWithHeader('%s', 'math.h', 'c') -r12 = conf.CheckLibWithHeader('%s', 'hopefullynoheader2.h', 'c') -r13 = conf.CheckLibWithHeader('hopefullynolib2', 'math.h', 'c') -env = conf.Finish() -""" % (lib, lib, lib)) - - expected_read_str = """\ -Checking for C function printf()... yes -Checking for C function noFunctionCall()... no -Checking for C type int... yes -Checking for C type noType... no -Checking for C header file stdio.h... yes -Checking for C header file hopefullynoc-header.h... no -Checking for C++ header file vector... yes -Checking for C++ header file hopefullynocxx-header.h... no -Checking for sin() in C library %(lib)s... yes -Checking for sin() in C library hopefullynolib... no -Checking for C library %(lib)s... yes -Checking for C library %(lib)s... no -Checking for C library hopefullynolib2... no -""" % {'lib' : lib} - - expected_build_str = """\ -scons: Configure: creating config.h -""" - - expected_stdout = test.wrap_stdout(build_str=expected_build_str, - read_str=expected_read_str) - - expected_config_h = string.replace("""#ifndef CONFIG_H_SEEN -#define CONFIG_H_SEEN - -#define HAVE_PRINTF -/* #undef HAVE_NOFUNCTIONCALL */ -#define HAVE_INT -/* #undef HAVE_NOTYPE */ -#define HAVE_STDIO_H -/* #undef HAVE_HOPEFULLYNOC_HEADER_H */ -#define HAVE_VECTOR -/* #undef HAVE_HOPEFULLYNOCXX_HEADER_H */ -#define HAVE_%(LIB)s -/* #undef HAVE_LIBHOPEFULLYNOLIB */ -#define HAVE_%(LIB)s -/* #undef HAVE_%(LIB)s */ -/* #undef HAVE_LIBHOPEFULLYNOLIB2 */ - -#endif /* CONFIG_H_SEEN */ -""" % {'LIB' : "LIB" + string.upper(lib) }, "\n", os.linesep) - - test.run(chdir=work_dir, stdout=expected_stdout) - config_h = test.read(test.workpath(work_dir, 'config.h')) - if expected_config_h != config_h: - print "Unexpected config.h" - print "Expected: " - print "---------------------------------------------------------" - print repr(expected_config_h) - print "---------------------------------------------------------" - print "Found: " - print "---------------------------------------------------------" - print repr(config_h) - print "---------------------------------------------------------" - print "Stdio: " - print "---------------------------------------------------------" - print test.stdout() - print "---------------------------------------------------------" - test.fail_test() - - expected_read_str = re.sub(r'\b((yes)|(no))\b', - r'(cached) \1', - expected_read_str) - expected_build_str = "scons: `.' is up to date.\n" - expected_stdout = test.wrap_stdout(build_str=expected_build_str, - read_str=expected_read_str) - #expected_stdout = string.replace(expected_stdout, "\n", os.linesep) - test.run(chdir=work_dir, stdout=expected_stdout) - config_h = test.read(test.workpath(work_dir, 'config.h')) - if expected_config_h != config_h: - print "Unexpected config.h" - print "Expected: " - print "---------------------------------------------------------" - print repr(expected_config_h) - print "---------------------------------------------------------" - print "Found: " - print "---------------------------------------------------------" - print repr(config_h) - print "---------------------------------------------------------" - print "Stdio: " - print "---------------------------------------------------------" - print test.stdout() - print "---------------------------------------------------------" - test.fail_test() - -finally: - pass - #os.system( 'find . -type f -exec ls -l {} \;' ) - #print "-------------config.log------------------" - #print test.read( test.workpath(work_dir, 'config.log')) - #print "-------------build/config.log------------" - #print test.read( test.workpath('build/config.log' )) - - -test.pass_test() diff --git a/test/Configure/ConfigureDryRunError.py b/test/Configure/ConfigureDryRunError.py new file mode 100644 index 0000000..04fbc75 --- /dev/null +++ b/test/Configure/ConfigureDryRunError.py @@ -0,0 +1,99 @@ +#!/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 ConfigureDryRunError. +""" + +import os.path + +import TestSCons + +_obj = TestSCons._obj + +test = TestSCons.TestSCons() + +lib = test.Configure_lib + +NCR = test.NCR # non-cached rebuild +CR = test.CR # cached rebuild (up to date) +NCF = test.NCF # non-cached build failure +CF = test.CF # cached build failure + +SConstruct_path = test.workpath('SConstruct') + +test.write(SConstruct_path, """ +env = Environment() +import os +env.AppendENVPath('PATH', os.environ['PATH']) +conf = Configure(env) +r1 = conf.CheckLib('%s') # will pass +r2 = conf.CheckLib('hopefullynolib') # will fail +env = conf.Finish() +if not (r1 and not r2): + Exit(1) +""" % (lib)) + +test.run(arguments='-n', status=2, stderr=""" +scons: *** Cannot create configure directory ".sconf_temp" within a dry-run. +File "%(SConstruct_path)s", line 5, in ? +""" % locals()) + +test.must_not_exist('config.log') +test.subdir('.sconf_temp') + +conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c") + +test.run(arguments='-n', status=2, stderr=""" +scons: *** Cannot update configure test "%(conftest_0_c)s" within a dry-run. +File "%(SConstruct_path)s", line 6, in ? +""" % locals()) + +test.run() +test.checkLogAndStdout( ["Checking for C library %s... " % lib, + "Checking for C library hopefullynolib... "], + ["yes", "no"], + [[((".c", NCR), (_obj, NCR))], + [((".c", NCR), (_obj, NCF))]], + "config.log", ".sconf_temp", "SConstruct") + +oldLog = test.read(test.workpath('config.log')) + +test.run(arguments='-n') +test.checkLogAndStdout( ["Checking for C library %s... " % lib, + "Checking for C library hopefullynolib... "], + ["yes", "no"], + [[((".c", CR), (_obj, CR))], + [((".c", CR), (_obj, CF))]], + "config.log", ".sconf_temp", "SConstruct", + doCheckLog=0) + +newLog = test.read(test.workpath('config.log')) +if newLog != oldLog: + print "Unexpected update of log file within a dry run" + test.fail_test() + +test.pass_test() diff --git a/test/Configure/SConscript.py b/test/Configure/SConscript.py new file mode 100644 index 0000000..2bfe2f7 --- /dev/null +++ b/test/Configure/SConscript.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that Configure contexts from multiple subsidiary SConscript +files work without error. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir(['dir1'], + ['dir2'], + ['dir2', 'sub1'], + ['dir2', 'sub1', 'sub2']) + +test.write('SConstruct', """\ +env = Environment() +SConscript(dirs=['dir1', 'dir2'], exports="env") +""") + +test.write(['dir1', 'SConscript'], """ +Import("env") +conf = env.Configure() +conf.Finish() +""") + +test.write(['dir2', 'SConscript'], """ +Import("env") +conf = env.Configure() +conf.Finish() +SConscript(dirs=['sub1'], exports="env") +""") + +test.write(['dir2', 'sub1', 'SConscript'], """ +Import("env") +conf = env.Configure() +conf.Finish() +SConscript(dirs=['sub2'], exports="env") +""") + +test.write(['dir2', 'sub1', 'sub2', 'SConscript'], """ +Import("env") +conf = env.Configure() +conf.Finish() +""") + +test.run() + +test.pass_test() diff --git a/test/Configure/basic.py b/test/Configure/basic.py new file mode 100644 index 0000000..677f40f --- /dev/null +++ b/test/Configure/basic.py @@ -0,0 +1,83 @@ +#!/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 basic builds work with Configure contexts. +""" + +import TestSCons + +_obj = TestSCons._obj + +test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) + +NCR = test.NCR # non-cached rebuild +CR = test.CR # cached rebuild (up to date) +NCF = test.NCF # non-cached build failure +CF = test.CF # cached build failure + +test.write('SConstruct', """\ +env = Environment() +import os +env.AppendENVPath('PATH', os.environ['PATH']) +conf = Configure(env) +r1 = conf.CheckCHeader( 'math.h' ) +r2 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error +env = conf.Finish() +Export( 'env' ) +SConscript( 'SConscript' ) +""") + +test.write('SConscript', """\ +Import( 'env' ) +env.Program( 'TestProgram', 'TestProgram.c' ) +""") + +test.write('TestProgram.c', """\ +#include <stdio.h> + +int main() { + printf( "Hello\\n" ); +} +""") + +test.run() +test.checkLogAndStdout(["Checking for C header file math.h... ", + "Checking for C header file no_std_c_header.h... "], + ["yes", "no"], + [[((".c", NCR), (_obj, NCR))], + [((".c", NCR), (_obj, NCF))]], + "config.log", ".sconf_temp", "SConstruct") + +test.run() +test.checkLogAndStdout(["Checking for C header file math.h... ", + "Checking for C header file no_std_c_header.h... "], + ["yes", "no"], + [[((".c", CR), (_obj, CR))], + [((".c", CR), (_obj, CF))]], + "config.log", ".sconf_temp", "SConstruct") + +test.pass_test() diff --git a/test/Configure/cache-not-ok.py b/test/Configure/cache-not-ok.py new file mode 100644 index 0000000..82e32f6 --- /dev/null +++ b/test/Configure/cache-not-ok.py @@ -0,0 +1,96 @@ +#!/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 cache mechanism works when checks are not ok. +""" + +import os.path + +import TestSCons + +_exe = TestSCons._exe +_obj = TestSCons._obj + +test = TestSCons.TestSCons() + +lib = test.Configure_lib + +NCR = test.NCR # non-cached rebuild +CR = test.CR # cached rebuild (up to date) +NCF = test.NCF # non-cached build failure +CF = test.CF # cached build failure + +test.write('SConstruct', """\ +if int(ARGUMENTS.get('target_signatures_content', 0)): + TargetSignatures('content') +env = Environment() +import os +env.AppendENVPath('PATH', os.environ['PATH']) +conf = env.Configure() +r1 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error +r2 = conf.CheckLib( 'no_c_library_SAFFDG' ) # leads to link error +env = conf.Finish() +if not (not r1 and not r2): + print "FAIL: ", r1, r2 + Exit(1) +""") + +test.run() +test.checkLogAndStdout(["Checking for C header file no_std_c_header.h... ", + "Checking for C library no_c_library_SAFFDG... "], + ["no"]*2, + [[((".c", NCR), (_obj, NCF))], + [((".c", NCR), (_obj, NCR), (_exe, NCF))]], + "config.log", ".sconf_temp", "SConstruct") + +test.run() +test.checkLogAndStdout(["Checking for C header file no_std_c_header.h... ", + "Checking for C library no_c_library_SAFFDG... "], + ["no"]*2, + [[((".c", CR), (_obj, CF))], + [((".c", CR), (_obj, CR), (_exe, CF))]], + "config.log", ".sconf_temp", "SConstruct") + +# same should be true for TargetSignatures('content') + +test.run(arguments='--config=force target_signatures_content=1') +test.checkLogAndStdout(["Checking for C header file no_std_c_header.h... ", + "Checking for C library no_c_library_SAFFDG... "], + ["no"]*2, + [[((".c", NCR), (_obj, NCF))], + [((".c", NCR), (_obj, NCR), (_exe, NCF))]], + "config.log", ".sconf_temp", "SConstruct") + +test.run(arguments='target_signatures_content=1') +test.checkLogAndStdout(["Checking for C header file no_std_c_header.h... ", + "Checking for C library no_c_library_SAFFDG... "], + ["no"]*2, + [[((".c", CR), (_obj, CF))], + [((".c", CR), (_obj, CR), (_exe, CF))]], + "config.log", ".sconf_temp", "SConstruct") + +test.pass_test() diff --git a/test/Configure/cache-ok.py b/test/Configure/cache-ok.py new file mode 100644 index 0000000..d8eac77 --- /dev/null +++ b/test/Configure/cache-ok.py @@ -0,0 +1,118 @@ +#!/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 cache mechanism works when checks are ok. +""" + +import TestSCons + +_exe = TestSCons._exe +_obj = TestSCons._obj + +test = TestSCons.TestSCons(match = TestSCons.match_re) + +lib = test.Configure_lib + +NCR = test.NCR # non-cached rebuild +CR = test.CR # cached rebuild (up to date) +NCF = test.NCF # non-cached build failure +CF = test.CF # cached build failure + +test.write('SConstruct', """\ +if int(ARGUMENTS.get('target_signatures_content', 0)): + TargetSignatures('content') +env = Environment() +import os +env.AppendENVPath('PATH', os.environ['PATH']) +conf = Configure(env) +r1 = conf.CheckLibWithHeader( '%(lib)s', 'math.h', 'c' ) +r2 = conf.CheckLibWithHeader( None, 'math.h', 'c' ) +r3 = conf.CheckLib( '%(lib)s', autoadd=0 ) +r4 = conf.CheckLib( None, autoadd=0 ) +r5 = conf.CheckCHeader( 'math.h' ) +r6 = conf.CheckCXXHeader( 'vector' ) +env = conf.Finish() +if not (r1 and r2 and r3 and r4 and r5 and r6): + Exit(1) +""" % locals()) + +test.run() +test.checkLogAndStdout(["Checking for C library %s... " % lib, + "Checking for C library None... ", + "Checking for C library %s... " % lib, + "Checking for C library None... ", + "Checking for C header file math.h... ", + "Checking for C++ header file vector... "], + ["yes"]*6, + [[((".c", NCR), (_obj, NCR), (_exe, NCR))]]*4 + + [[((".c", NCR), (_obj, NCR))]] + + [[((".cpp", NCR), (_obj, NCR))]], + "config.log", ".sconf_temp", "SConstruct") + + +test.run() +test.checkLogAndStdout(["Checking for C library %s... " % lib, + "Checking for C library None... ", + "Checking for C library %s... " % lib, + "Checking for C library None... ", + "Checking for C header file math.h... ", + "Checking for C++ header file vector... "], + ["yes"]*6, + [[((".c", CR), (_obj, CR), (_exe, CR))]]*4 + + [[((".c", CR), (_obj, CR))]] + + [[((".cpp", CR), (_obj, CR))]], + "config.log", ".sconf_temp", "SConstruct") + +# same should be true for TargetSignatures('content') + +test.run(arguments='target_signatures_content=1 --config=force') +test.checkLogAndStdout(["Checking for C library %s... " % lib, + "Checking for C library None... ", + "Checking for C library %s... " % lib, + "Checking for C library None... ", + "Checking for C header file math.h... ", + "Checking for C++ header file vector... "], + ["yes"]*6, + [[((".c", NCR), (_obj, NCR), (_exe, NCR))]]*4 + + [[((".c", NCR), (_obj, NCR))]] + + [[((".cpp", NCR), (_obj, NCR))]], + "config.log", ".sconf_temp", "SConstruct") + +test.run(arguments='target_signatures_content=1') +test.checkLogAndStdout(["Checking for C library %s... " % lib, + "Checking for C library None... ", + "Checking for C library %s... " % lib, + "Checking for C library None... ", + "Checking for C header file math.h... ", + "Checking for C++ header file vector... "], + ["yes"]*6, + [[((".c", CR), (_obj, CR), (_exe, CR))]]*4 + + [[((".c", CR), (_obj, CR))]] + + [[((".cpp", CR), (_obj, CR))]], + "config.log", ".sconf_temp", "SConstruct") + +test.pass_test() diff --git a/test/Configure/config-h.py b/test/Configure/config-h.py new file mode 100644 index 0000000..7bc8645 --- /dev/null +++ b/test/Configure/config-h.py @@ -0,0 +1,155 @@ +#!/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 creation of a config.h file from a Configure context. +""" + +import os +import re +import string + +import TestSCons + +test = TestSCons.TestSCons(match = TestSCons.match_exact) + +lib = test.Configure_lib +LIB = "LIB" + string.upper(lib) + +test.write('SConstruct', """\ +env = Environment() +import os +env.AppendENVPath('PATH', os.environ['PATH']) +conf = Configure(env, config_h = 'config.h') +r1 = conf.CheckFunc('printf') +r2 = conf.CheckFunc('noFunctionCall') +r3 = conf.CheckType('int') +r4 = conf.CheckType('noType') +r5 = conf.CheckCHeader('stdio.h', '<>') +r6 = conf.CheckCHeader('hopefullynoc-header.h') +r7 = conf.CheckCXXHeader('vector', '<>') +r8 = conf.CheckCXXHeader('hopefullynocxx-header.h') +env = conf.Finish() +conf = Configure(env, config_h = 'config.h') +r9 = conf.CheckLib('%(lib)s', 'sin') +r10 = conf.CheckLib('hopefullynolib', 'sin') +r11 = conf.CheckLibWithHeader('%(lib)s', 'math.h', 'c') +r12 = conf.CheckLibWithHeader('%(lib)s', 'hopefullynoheader2.h', 'c') +r13 = conf.CheckLibWithHeader('hopefullynolib2', 'math.h', 'c') +env = conf.Finish() +""" % locals()) + +expected_read_str = """\ +Checking for C function printf()... yes +Checking for C function noFunctionCall()... no +Checking for C type int... yes +Checking for C type noType... no +Checking for C header file stdio.h... yes +Checking for C header file hopefullynoc-header.h... no +Checking for C++ header file vector... yes +Checking for C++ header file hopefullynocxx-header.h... no +Checking for sin() in C library %(lib)s... yes +Checking for sin() in C library hopefullynolib... no +Checking for C library %(lib)s... yes +Checking for C library %(lib)s... no +Checking for C library hopefullynolib2... no +""" % locals() + +expected_build_str = """\ +scons: Configure: creating config.h +""" + +expected_stdout = test.wrap_stdout(build_str=expected_build_str, + read_str=expected_read_str) + +expected_config_h = string.replace("""\ +#ifndef CONFIG_H_SEEN +#define CONFIG_H_SEEN + +#define HAVE_PRINTF 1 +/* #undef HAVE_NOFUNCTIONCALL */ +#define HAVE_INT 1 +/* #undef HAVE_NOTYPE */ +#define HAVE_STDIO_H 1 +/* #undef HAVE_HOPEFULLYNOC_HEADER_H */ +#define HAVE_VECTOR 1 +/* #undef HAVE_HOPEFULLYNOCXX_HEADER_H */ +#define HAVE_%(LIB)s 1 +/* #undef HAVE_LIBHOPEFULLYNOLIB */ +#define HAVE_%(LIB)s 1 +/* #undef HAVE_%(LIB)s */ +/* #undef HAVE_LIBHOPEFULLYNOLIB2 */ + +#endif /* CONFIG_H_SEEN */ +""" % locals(), "\n", os.linesep) + +test.run(stdout=expected_stdout) + +config_h = test.read(test.workpath('config.h')) +if expected_config_h != config_h: + print "Unexpected config.h" + print "Expected: " + print "---------------------------------------------------------" + print repr(expected_config_h) + print "---------------------------------------------------------" + print "Found: " + print "---------------------------------------------------------" + print repr(config_h) + print "---------------------------------------------------------" + print "Stdio: " + print "---------------------------------------------------------" + print test.stdout() + print "---------------------------------------------------------" + test.fail_test() + +expected_read_str = re.sub(r'\b((yes)|(no))\b', + r'(cached) \1', + expected_read_str) +expected_build_str = "scons: `.' is up to date.\n" +expected_stdout = test.wrap_stdout(build_str=expected_build_str, + read_str=expected_read_str) +#expected_stdout = string.replace(expected_stdout, "\n", os.linesep) + +test.run(stdout=expected_stdout) + +config_h = test.read(test.workpath('config.h')) +if expected_config_h != config_h: + print "Unexpected config.h" + print "Expected: " + print "---------------------------------------------------------" + print repr(expected_config_h) + print "---------------------------------------------------------" + print "Found: " + print "---------------------------------------------------------" + print repr(config_h) + print "---------------------------------------------------------" + print "Stdio: " + print "---------------------------------------------------------" + print test.stdout() + print "---------------------------------------------------------" + test.fail_test() + +test.pass_test() diff --git a/test/Configure/custom-tests.py b/test/Configure/custom-tests.py new file mode 100644 index 0000000..7fb0ab7 --- /dev/null +++ b/test/Configure/custom-tests.py @@ -0,0 +1,111 @@ +#!/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 execution of custom test cases. +""" + +import TestSCons + +_exe = TestSCons._exe +_obj = TestSCons._obj +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +NCR = test.NCR # non-cached rebuild +CR = test.CR # cached rebuild (up to date) +NCF = test.NCF # non-cached build failure +CF = test.CF # cached build failure + +compileOK = '#include <stdio.h>\\nint main() {printf("Hello");return 0;}' +compileFAIL = "syntax error" +linkOK = compileOK +linkFAIL = "void myFunc(); int main() { myFunc(); }" +runOK = compileOK +runFAIL = "int main() { return 1; }" + +test.write('pyAct.py', """\ +import sys +print sys.argv[1] +sys.exit(int(sys.argv[1])) +""") + +test.write('SConstruct', """\ +def CheckCustom(test): + test.Message( 'Executing MyTest ... ' ) + retCompileOK = test.TryCompile( '%(compileOK)s', '.c' ) + retCompileFAIL = test.TryCompile( '%(compileFAIL)s', '.c' ) + retLinkOK = test.TryLink( '%(linkOK)s', '.c' ) + retLinkFAIL = test.TryLink( '%(linkFAIL)s', '.c' ) + (retRunOK, outputRunOK) = test.TryRun( '%(runOK)s', '.c' ) + (retRunFAIL, outputRunFAIL) = test.TryRun( '%(runFAIL)s', '.c' ) + (retActOK, outputActOK) = test.TryAction( '%(_python_)s pyAct.py 0 > $TARGET' ) + (retActFAIL, outputActFAIL) = test.TryAction( '%(_python_)s pyAct.py 1 > $TARGET' ) + resOK = retCompileOK and retLinkOK and retRunOK and outputRunOK=="Hello" + resOK = resOK and retActOK and int(outputActOK)==0 + resFAIL = retCompileFAIL or retLinkFAIL or retRunFAIL or outputRunFAIL!="" + resFAIL = resFAIL or retActFAIL or outputActFAIL!="" + test.Result( int(resOK and not resFAIL) ) + return resOK and not resFAIL + +env = Environment() +import os +env.AppendENVPath('PATH', os.environ['PATH']) +conf = Configure( env, custom_tests={'CheckCustom' : CheckCustom} ) +conf.CheckCustom() +env = conf.Finish() +""" % locals()) + +test.run() + +test.checkLogAndStdout(["Executing MyTest ... "], + ["yes"], + [[(('.c', NCR), (_obj, NCR)), + (('.c', NCR), (_obj, NCF)), + (('.c', NCR), (_obj, NCR), (_exe, NCR)), + (('.c', NCR), (_obj, NCR), (_exe, NCF)), + (('.c', NCR), (_obj, NCR), (_exe, NCR), (_exe + '.out', NCR)), + (('.c', NCR), (_obj, NCR), (_exe, NCR), (_exe + '.out', NCF)), + (('', NCR),), + (('', NCF),)]], + "config.log", ".sconf_temp", "SConstruct") + +test.run() + +test.checkLogAndStdout(["Executing MyTest ... "], + ["yes"], + [[(('.c', CR), (_obj, CR)), + (('.c', CR), (_obj, CF)), + (('.c', CR), (_obj, CR), (_exe, CR)), + (('.c', CR), (_obj, CR), (_exe, CF)), + (('.c', CR), (_obj, CR), (_exe, CR), (_exe + '.out', CR)), + (('.c', CR), (_obj, CR), (_exe, CR), (_exe + '.out', CF)), + (('', CR),), + (('', CF),)]], + "config.log", ".sconf_temp", "SConstruct") + +test.pass_test() diff --git a/test/Configure/option--Q.py b/test/Configure/option--Q.py new file mode 100644 index 0000000..ab9d488 --- /dev/null +++ b/test/Configure/option--Q.py @@ -0,0 +1,46 @@ +#!/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 -Q option suppresses Configure context output. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +env = Environment() +import os +env.AppendENVPath('PATH', os.environ['PATH']) +conf = Configure(env) +r1 = conf.CheckCHeader('stdio.h') +env = conf.Finish() +""") + +test.run(arguments='-Q', stdout="scons: `.' is up to date.\n", stderr="") + +test.pass_test() diff --git a/test/Configure/option--config.py b/test/Configure/option--config.py new file mode 100644 index 0000000..95a0d3b --- /dev/null +++ b/test/Configure/option--config.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify use of the --config=<auto|force|cache> option. +""" + +import os.path + +import TestSCons + +_obj = TestSCons._obj + +test = TestSCons.TestSCons() + +test.subdir('include') + +NCR = test.NCR # non-cached rebuild +CR = test.CR # cached rebuild (up to date) +NCF = test.NCF # non-cached build failure +CF = test.CF # cached build failure + +SConstruct_path = test.workpath('SConstruct') + +test.write(SConstruct_path, """ +env = Environment(CPPPATH='#/include') +import os +env.AppendENVPath('PATH', os.environ['PATH']) +conf = Configure(env) +r1 = conf.CheckCHeader('non_system_header1.h') +r2 = conf.CheckCHeader('non_system_header2.h') +env = conf.Finish() +""") + +test.write(['include', 'non_system_header1.h'], """ +/* A header */ +""") + +conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c") + +test.run(arguments='--config=cache', status=2, stderr=""" +scons: *** "%(conftest_0_c)s" is not yet built and cache is forced. +File "%(SConstruct_path)s", line 6, in ? +""" % locals()) + +test.run(arguments='--config=auto') +test.checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", + "Checking for C header file non_system_header2.h... "], + ["yes", "no"], + [[((".c", NCR), (_obj, NCR))], + [((".c", NCR), (_obj, NCF))]], + "config.log", ".sconf_temp", "SConstruct") + +test.run(arguments='--config=auto') +test.checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", + "Checking for C header file non_system_header2.h... "], + ["yes", "no"], + [[((".c", CR), (_obj, CR))], + [((".c", CR), (_obj, CF))]], + "config.log", ".sconf_temp", "SConstruct") + +test.run(arguments='--config=force') +test.checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", + "Checking for C header file non_system_header2.h... "], + ["yes", "no"], + [[((".c", NCR), (_obj, NCR))], + [((".c", NCR), (_obj, NCF))]], + "config.log", ".sconf_temp", "SConstruct") + +test.run(arguments='--config=cache') +test.checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", + "Checking for C header file non_system_header2.h... "], + ["yes", "no"], + [[((".c", CR), (_obj, CR))], + [((".c", CR), (_obj, CF))]], + "config.log", ".sconf_temp", "SConstruct") + +test.write(['include', 'non_system_header2.h'], """ +/* Another header */ +""") +test.unlink(['include', 'non_system_header1.h']) + +test.run(arguments='--config=cache') +test.checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", + "Checking for C header file non_system_header2.h... "], + ["yes", "no"], + [[((".c", CR), (_obj, CR))], + [((".c", CR), (_obj, CF))]], + "config.log", ".sconf_temp", "SConstruct") + +test.run(arguments='--config=auto') +test.checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", + "Checking for C header file non_system_header2.h... "], + ["no", "yes"], + [[((".c", CR), (_obj, NCF))], + [((".c", CR), (_obj, NCR))]], + "config.log", ".sconf_temp", "SConstruct") + +test.pass_test() diff --git a/test/GetOption/help.py b/test/GetOption/help.py new file mode 100644 index 0000000..37f9555 --- /dev/null +++ b/test/GetOption/help.py @@ -0,0 +1,54 @@ +#!/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 use of GetOption('help') to short-circuit work. +""" + +import string + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +if GetOption('help'): + print "GetOption('help') set" +else: + print "no help for you" +""") + +test.run(arguments = '-q -Q', stdout = "no help for you\n") + +expect = "GetOption('help') set" + +test.run(arguments = '-q -Q -h') +test.fail_test(string.split(test.stdout(), '\n')[0] != expect) + +test.run(arguments = '-q -Q --help') +test.fail_test(string.split(test.stdout(), '\n')[0] != expect) + +test.pass_test() diff --git a/test/IDL/MIDLCOM.py b/test/IDL/MIDLCOM.py index 79857d0..b285568 100644 --- a/test/IDL/MIDLCOM.py +++ b/test/IDL/MIDLCOM.py @@ -37,12 +37,18 @@ test = TestSCons.TestSCons() test.write('mymidl.py', """ +import os.path import sys -outfile = open(sys.argv[1], 'wb') +out_tlb = open(sys.argv[1], 'wb') +base = os.path.splitext(sys.argv[1])[0] +out_h = open(base + '.h', 'wb') +out_c = open(base + '_i.c', 'wb') for f in sys.argv[2:]: infile = open(f, 'rb') for l in filter(lambda l: l != '/*midl*/\\n', infile.readlines()): - outfile.write(l) + out_tlb.write(l) + out_h.write(l) + out_c.write(l) sys.exit(0) """) @@ -57,6 +63,10 @@ test.write('aaa.idl', "aaa.idl\n/*midl*/\n") test.run(arguments = '.') test.must_match('aaa.tlb', "aaa.idl\n") +test.must_match('aaa.h', "aaa.idl\n") +test.must_match('aaa_i.c', "aaa.idl\n") + +test.up_to_date(options = '--debug=explain', arguments = 'aaa.tlb') diff --git a/test/MSVC/multiple-pdb.py b/test/MSVC/multiple-pdb.py new file mode 100644 index 0000000..f359fb9 --- /dev/null +++ b/test/MSVC/multiple-pdb.py @@ -0,0 +1,83 @@ +#!/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 setting $PDB to '${TARGET}.pdb allows us to build multiple
+programs with separate .pdb files from the same environment.
+
+Under the covers, this verifies that emitters support expansion of the
+$TARGET variable (and implicitly $SOURCE), using the original specified
+list(s).
+"""
+
+import sys
+
+import TestSCons
+
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+if sys.platform != 'win32':
+ msg = "Skipping Visual C/C++ test on non-Windows platform '%s'\n" % sys.platform
+ test.skip_test(msg)
+
+test.write('SConstruct', """\
+env = Environment(PDB = '${TARGET}.pdb')
+env.Program('test1.cpp')
+env.Program('test2.cpp')
+""")
+
+test.write('test1.cpp', """\
+#include <stdio.h>
+#include <stdlib.h>
+int
+main(int argc, char *argv)
+{
+ printf("test1.cpp\\n");
+ exit (0);
+}
+""")
+
+test.write('test2.cpp', """\
+#include <stdio.h>
+#include <stdlib.h>
+int
+main(int argc, char *argv)
+{
+ printf("test2.cpp\\n");
+ exit (0);
+}
+""")
+
+test.run(arguments = '.')
+
+test.must_exist('test1%s' % _exe)
+test.must_exist('test1%s.pdb' % _exe)
+test.must_exist('test2%s' % _exe)
+test.must_exist('test2%s.pdb' % _exe)
+
+test.pass_test()
diff --git a/test/MSVC/pdb-BuildDir-path.py b/test/MSVC/pdb-BuildDir-path.py new file mode 100644 index 0000000..223e535 --- /dev/null +++ b/test/MSVC/pdb-BuildDir-path.py @@ -0,0 +1,76 @@ +#!/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 .pdb files get put in a build_dir correctly.
+"""
+
+import sys
+
+import TestSCons
+
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+if sys.platform != 'win32':
+ msg = "Skipping Visual C/C++ test on non-Windows platform '%s'\n" % sys.platform
+ test.skip_test(msg)
+
+test.subdir('src')
+
+test.write('SConstruct', """\
+env = Environment()
+env.Append(BINDIR = '#bin')
+
+Export('env')
+SConscript('#src/SConscript', duplicate = 0, build_dir = '#.build')
+""")
+
+test.write(['src', 'SConscript'], """\
+Import('env')
+env['PDB'] = '${TARGET}.pdb'
+p = env.Program('test.exe', 'test.cpp')
+env.Install(env['BINDIR'], p)
+""")
+
+test.write(['src', 'test.cpp'], """\
+#include <stdio.h>
+#include <stdlib.h>
+int
+main(int argc, char *argv)
+{
+ printf("test.cpp\\n");
+ exit (0);
+}
+""")
+
+test.run(arguments = '.')
+
+test.must_exist(['.build', 'test%s' % _exe])
+test.must_exist(['.build', 'test%s.pdb' % _exe])
+
+test.pass_test()
diff --git a/test/MSVS/vs-7.0-files.py b/test/MSVS/vs-7.0-files.py index b9827e7..aaffd7d 100644 --- a/test/MSVS/vs-7.0-files.py +++ b/test/MSVS/vs-7.0-files.py @@ -53,8 +53,8 @@ Global \tGlobalSection(ProjectDependencies) = postSolution \tEndGlobalSection \tGlobalSection(ProjectConfiguration) = postSolution -\t\t{SLNGUID}.Release.ActiveCfg = Release|Win32 -\t\t{SLNGUID}.Release.Build.0 = Release|Win32 +\t\t{E5466E26-0003-F18B-8F8A-BCD76C86388D}.Release.ActiveCfg = Release|Win32 +\t\t{E5466E26-0003-F18B-8F8A-BCD76C86388D}.Release.Build.0 = Release|Win32 \tEndGlobalSection \tGlobalSection(ExtensibilityGlobals) = postSolution \tEndGlobalSection diff --git a/test/MSVS/vs-7.1-files.py b/test/MSVS/vs-7.1-files.py index 057f34f..98bd9da 100644 --- a/test/MSVS/vs-7.1-files.py +++ b/test/MSVS/vs-7.1-files.py @@ -53,8 +53,8 @@ Global \t\tConfigName.0 = Release \tEndGlobalSection \tGlobalSection(ProjectConfiguration) = postSolution -\t\t{SLNGUID}.Release.ActiveCfg = Release|Win32 -\t\t{SLNGUID}.Release.Build.0 = Release|Win32 +\t\t{E5466E26-0003-F18B-8F8A-BCD76C86388D}.Release.ActiveCfg = Release|Win32 +\t\t{E5466E26-0003-F18B-8F8A-BCD76C86388D}.Release.Build.0 = Release|Win32 \tEndGlobalSection \tGlobalSection(ExtensibilityGlobals) = postSolution \tEndGlobalSection diff --git a/test/TEX/usepackage.py b/test/TEX/usepackage.py new file mode 100644 index 0000000..4be7f58 --- /dev/null +++ b/test/TEX/usepackage.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Validate that we can set the LATEX string to our own utility, that +the produced .dvi, .aux and .log files get removed by the -c option, +and that we can use this to wrap calls to the real latex utility. +""" + +import os +import os.path +import string +import sys +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +latex = test.where_is('latex') + +if not latex: + test.skip_test('could not find latex; skipping test\n') + +test.write('SConstruct', """ +import os +ENV = { 'PATH' : os.environ['PATH'], + 'TEXINPUTS' : [ 'subdir', os.environ.get('TEXINPUTS', '') ] } +foo = Environment(ENV = ENV) +foo.DVI(target = 'foo.dvi', source = 'foo.ltx') +""" % locals()) + +test.write('foo.ltx', r""" +\documentclass{letter} +\usepackage{bar} +\begin{document} +This is the foo.ltx file. +\end{document} +""") + +test.write('bar.sty', "\n") + +test.run(arguments = 'foo.dvi', stderr = None) + +test.write('bar.sty', "\n\n\n") + +test.not_up_to_date(arguments = 'foo.dvi', stderr = None) + + + +test.pass_test() diff --git a/test/explain.py b/test/explain.py index f69b00f..9b721d2 100644 --- a/test/explain.py +++ b/test/explain.py @@ -41,8 +41,8 @@ test.subdir('work1', ['work1', 'src'], ['work1', 'src', 'subdir'], 'work4', ['work4', 'src'], ['work4', 'src', 'subdir'], 'work5') -subdir_file6 = os.path.join('subdir', 'file6') -subdir_file6_in = os.path.join('subdir', 'file6.in') +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""" @@ -113,7 +113,9 @@ env.Command('file4', 'file4.in', r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES', FILE4FLAG='-') env.Cat('file5', 'file5.k') -env.Cat('subdir/file6', 'subdir/file6.in') +file6 = env.Cat('file6', 'file6.in') +AlwaysBuild(file6) +env.Cat('subdir/file7', 'subdir/file7.in') """ % locals()) test.write(['work1', 'src', 'aaa'], "aaa 1\n") @@ -149,7 +151,9 @@ include ../inc/bbb.k file5.k 1 line 4 """) -test.write(['work1', 'src', 'subdir', 'file6.in'], "subdir/file6.in 1\n") +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') @@ -176,8 +180,10 @@ 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 `%(subdir_file6)s' because it doesn't exist -%(_python_)s %(cat_py)s %(subdir_file6)s %(subdir_file6_in)s +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) @@ -200,6 +206,7 @@ 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") @@ -223,6 +230,8 @@ scons: rebuilding `%(work1_inc_bbb_k)s' because: 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) diff --git a/test/option--random.py b/test/option--random.py index f806bbe..8c7ef1e 100644 --- a/test/option--random.py +++ b/test/option--random.py @@ -34,7 +34,7 @@ import TestSCons test = TestSCons.TestSCons() -test.write('SConstruct', """ +test.write('SConscript', """\ def cat(env, source, target): target = str(target[0]) source = map(str, source) @@ -53,23 +53,66 @@ test.write('aaa.in', "aaa.in\n") test.write('bbb.in', "bbb.in\n") test.write('ccc.in', "ccc.in\n") -test.run(arguments = '--random .') -test.fail_test(test.read('all') != "aaa.in\nbbb.in\nccc.in\n") + +test.write('SConstruct', """\ +SetOption('random', 1) +SConscript('SConscript') +""") + +test.run(arguments = '-n -Q') +non_random_output = test.stdout() + +tries = 0 +max_tries = 3 +while test.stdout() == non_random_output: + if tries >= max_tries: + print "--random generated the non-random output %s times!" % max_tries + test.fail_test() + tries = tries + 1 + test.run(arguments = '-n -Q --random') + + + +test.write('SConstruct', """\ +SConscript('SConscript') +""") + +test.run(arguments = '-n -Q') +non_random_output = test.stdout() + +tries = 0 +max_tries = 3 +while test.stdout() == non_random_output: + if tries >= max_tries: + print "--random generated the non-random output %s times!" % max_tries + test.fail_test() + tries = tries + 1 + test.run(arguments = '-n -Q --random') + + + +test.run(arguments = '-Q --random') + +test.must_match('all', "aaa.in\nbbb.in\nccc.in\n") test.run(arguments = '-q --random .') test.run(arguments = '-c --random .') -test.fail_test(os.path.exists(test.workpath('aaa.out'))) -test.fail_test(os.path.exists(test.workpath('bbb.out'))) -test.fail_test(os.path.exists(test.workpath('ccc.out'))) -test.fail_test(os.path.exists(test.workpath('all'))) +test.must_not_exist(test.workpath('aaa.out')) +test.must_not_exist(test.workpath('bbb.out')) +test.must_not_exist(test.workpath('ccc.out')) +test.must_not_exist(test.workpath('all')) test.run(arguments = '-q --random .', status = 1) test.run(arguments = '--random .') -test.fail_test(test.read('all') != "aaa.in\nbbb.in\nccc.in\n") +test.must_match('all', "aaa.in\nbbb.in\nccc.in\n") + +test.run(arguments = '-c --random .') + + test.pass_test() |