398 lines
15 KiB
Python
398 lines
15 KiB
Python
|
#!/usr/bin/python
|
||
|
|
||
|
# Copyright 2008, 2012 Jurko Gospodnetic
|
||
|
# Distributed under the Boost Software License, Version 1.0.
|
||
|
# (See accompanying file LICENSE.txt or copy at
|
||
|
# https://www.bfgroup.xyz/b2/LICENSE.txt)
|
||
|
|
||
|
# Test Boost Build configuration file handling.
|
||
|
|
||
|
import BoostBuild
|
||
|
import TestCmd
|
||
|
|
||
|
import os
|
||
|
import os.path
|
||
|
import re
|
||
|
|
||
|
|
||
|
###############################################################################
|
||
|
#
|
||
|
# test_user_configuration()
|
||
|
# -------------------------
|
||
|
#
|
||
|
###############################################################################
|
||
|
|
||
|
def test_user_configuration():
|
||
|
"""
|
||
|
Test Boost Build user configuration handling. Both relative and absolute
|
||
|
path handling is tested.
|
||
|
|
||
|
"""
|
||
|
|
||
|
implicitConfigLoadMessage = \
|
||
|
"notice: Loading user-config configuration file: *"
|
||
|
explicitConfigLoadMessage = \
|
||
|
"notice: Loading explicitly specified user configuration file:"
|
||
|
disabledConfigLoadMessage = \
|
||
|
"notice: User configuration file loading explicitly disabled."
|
||
|
testMessage = "_!_!_!_!_!_!_!_!_ %s _!_!_!_!_!_!_!_!_"
|
||
|
toolsetName = "__myDummyToolset__"
|
||
|
subdirName = "ASubDirectory"
|
||
|
configFileNames = ["ups_lala_1.jam", "ups_lala_2.jam",
|
||
|
os.path.join(subdirName, "ups_lala_3.jam")]
|
||
|
|
||
|
t = BoostBuild.Tester(["toolset=%s" % toolsetName,
|
||
|
"--debug-configuration"], pass_toolset=False, use_test_config=False)
|
||
|
|
||
|
for configFileName in configFileNames:
|
||
|
message = "ECHO \"%s\" ;" % testMessage % configFileName
|
||
|
# We need to double any backslashes in the message or Jam will
|
||
|
# interpret them as escape characters.
|
||
|
t.write(configFileName, message.replace("\\", "\\\\"))
|
||
|
|
||
|
# Prepare a dummy toolset so we do not get errors in case the default one
|
||
|
# is not found.
|
||
|
t.write(toolsetName + ".jam", """\
|
||
|
import feature ;
|
||
|
feature.extend toolset : %s ;
|
||
|
rule init ( ) { }
|
||
|
""" % toolsetName)
|
||
|
|
||
|
# Python version of the same dummy toolset.
|
||
|
t.write(toolsetName + ".py", """\
|
||
|
from b2.build import feature
|
||
|
feature.extend('toolset', ['%s'])
|
||
|
def init(): pass
|
||
|
""" % toolsetName)
|
||
|
|
||
|
t.write("jamroot.jam", """\
|
||
|
local test-index = [ MATCH ---test-id---=(.*) : [ modules.peek : ARGV ] ] ;
|
||
|
ECHO test-index: $(test-index:E=(unknown)) ;
|
||
|
""")
|
||
|
|
||
|
class LocalTester:
|
||
|
def __init__(self, tester):
|
||
|
self.__tester = tester
|
||
|
self.__test_ids = []
|
||
|
|
||
|
def __assertionFailure(self, message):
|
||
|
BoostBuild.annotation("failure", "Internal test assertion failure "
|
||
|
"- %s" % message)
|
||
|
self.__tester.fail_test(1)
|
||
|
|
||
|
def __call__(self, test_id, env, extra_args=None, *args, **kwargs):
|
||
|
if env == "" and not canSetEmptyEnvironmentVariable:
|
||
|
self.__assertionFailure("Can not set empty environment "
|
||
|
"variables on this platform.")
|
||
|
self.__registerTestId(str(test_id))
|
||
|
if extra_args is None:
|
||
|
extra_args = []
|
||
|
extra_args.append("---test-id---=%s" % test_id)
|
||
|
env_name = "BOOST_BUILD_USER_CONFIG"
|
||
|
previous_env = os.environ.get(env_name)
|
||
|
_env_set(env_name, env)
|
||
|
try:
|
||
|
self.__tester.run_build_system(extra_args, *args, **kwargs)
|
||
|
finally:
|
||
|
_env_set(env_name, previous_env)
|
||
|
|
||
|
def __registerTestId(self, test_id):
|
||
|
if test_id in self.__test_ids:
|
||
|
self.__assertionFailure("Multiple test cases encountered "
|
||
|
"using the same test id '%s'." % test_id)
|
||
|
self.__test_ids.append(test_id)
|
||
|
|
||
|
test = LocalTester(t)
|
||
|
|
||
|
test(1, None)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(2, None, ["--user-config="])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(3, None, ['--user-config=""'])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(4, None, ['--user-config="%s"' % configFileNames[0]])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0])
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(5, None, ['--user-config="%s"' % configFileNames[2]])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2])
|
||
|
|
||
|
test(6, None, ['--user-config="%s"' % os.path.abspath(configFileNames[1])])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[1])
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(7, None, ['--user-config="%s"' % os.path.abspath(configFileNames[2])])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2])
|
||
|
|
||
|
if canSetEmptyEnvironmentVariable:
|
||
|
test(8, "")
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, True)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(9, '""')
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(10, configFileNames[1])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[1])
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(11, configFileNames[1], ['--user-config=""'])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(12, configFileNames[1], ['--user-config="%s"' % configFileNames[0]])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0])
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
if canSetEmptyEnvironmentVariable:
|
||
|
test(13, "", ['--user-config="%s"' % configFileNames[0]])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0])
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(14, '""', ['--user-config="%s"' % configFileNames[0]])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0])
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
test(15, "invalid", ['--user-config="%s"' % configFileNames[0]])
|
||
|
t.expect_output_lines(implicitConfigLoadMessage, False)
|
||
|
t.expect_output_lines(explicitConfigLoadMessage)
|
||
|
t.expect_output_lines(disabledConfigLoadMessage, False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[0])
|
||
|
t.expect_output_lines(testMessage % configFileNames[1], False)
|
||
|
t.expect_output_lines(testMessage % configFileNames[2], False)
|
||
|
|
||
|
t.cleanup()
|
||
|
|
||
|
|
||
|
###############################################################################
|
||
|
#
|
||
|
# Private interface.
|
||
|
#
|
||
|
###############################################################################
|
||
|
|
||
|
def _canSetEmptyEnvironmentVariable():
|
||
|
"""
|
||
|
Unfortunately different OSs (and possibly Python implementations as well)
|
||
|
have different interpretations of what it means to set an environment
|
||
|
variable to an empty string. Some (e.g. Windows) interpret it as unsetting
|
||
|
the variable and some (e.g. AIX or Darwin) actually set it to an empty
|
||
|
string.
|
||
|
|
||
|
"""
|
||
|
dummyName = "UGNABUNGA_FOO_BAR_BAZ_FEE_FAE_FOU_FAM"
|
||
|
original = os.environ.get(dummyName)
|
||
|
_env_set(dummyName, "")
|
||
|
result = _getExternalEnv(dummyName) == ""
|
||
|
_env_set(dummyName, original)
|
||
|
return result
|
||
|
|
||
|
|
||
|
def _env_del(name):
|
||
|
"""
|
||
|
Unsets the given environment variable if it is currently set.
|
||
|
|
||
|
Note that we can not use os.environ.pop() or os.environ.clear() here
|
||
|
since prior to Python 2.6 these functions did not remove the actual
|
||
|
environment variable by calling os.unsetenv().
|
||
|
|
||
|
"""
|
||
|
try:
|
||
|
del os.environ[name]
|
||
|
except KeyError:
|
||
|
pass
|
||
|
|
||
|
|
||
|
def _env_set(name, value):
|
||
|
"""
|
||
|
Sets the given environment variable value or unsets it, if the value is
|
||
|
None.
|
||
|
|
||
|
"""
|
||
|
if value is None:
|
||
|
_env_del(name)
|
||
|
else:
|
||
|
os.environ[name] = value
|
||
|
|
||
|
|
||
|
def _getExternalEnv(name):
|
||
|
toolsetName = "__myDummyToolset__"
|
||
|
|
||
|
t = BoostBuild.Tester(["toolset=%s" % toolsetName], pass_toolset=False,
|
||
|
use_test_config=False)
|
||
|
try:
|
||
|
# Prepare a dummy toolset so we do not get errors in case the default
|
||
|
# one is not found.
|
||
|
t.write(toolsetName + ".jam", """\
|
||
|
import feature ;
|
||
|
feature.extend toolset : %s ;
|
||
|
rule init ( ) { }
|
||
|
""" % toolsetName)
|
||
|
|
||
|
# Python version of the same dummy toolset.
|
||
|
t.write(toolsetName + ".py", """\
|
||
|
from b2.build import feature
|
||
|
feature.extend('toolset', ['%s'])
|
||
|
def init(): pass
|
||
|
""" % toolsetName)
|
||
|
|
||
|
t.write("jamroot.jam", """\
|
||
|
import os ;
|
||
|
local names = [ MATCH ^---var-name---=(.*) : [ modules.peek : ARGV ] ] ;
|
||
|
for x in $(names)
|
||
|
{
|
||
|
value = [ os.environ $(x) ] ;
|
||
|
ECHO "###" $(x): '$(value)' "###" ;
|
||
|
}
|
||
|
""")
|
||
|
|
||
|
t.run_build_system(["---var-name---=%s" % name])
|
||
|
m = re.search("^### %s: '(.*)' ###$" % name, t.stdout(), re.MULTILINE)
|
||
|
if m:
|
||
|
return m.group(1)
|
||
|
finally:
|
||
|
t.cleanup()
|
||
|
|
||
|
|
||
|
def test_site_config():
|
||
|
# Ignore user-config, just in case it depends on the user's site-config.jam
|
||
|
t = BoostBuild.Tester(["--user-config="], use_test_config=False,
|
||
|
pass_toolset=0)
|
||
|
# We can immediately exit after we finish loading the config files
|
||
|
t.write("Jamroot", "EXIT Done : 0 ;")
|
||
|
t.write("my-site-config.jam", "ECHO Loaded my-site-config ;")
|
||
|
|
||
|
t.run_build_system(["--site-config=my-site-config.jam"],
|
||
|
stdout="Loaded my-site-config\nDone\n")
|
||
|
|
||
|
t.run_build_system(["--ignore-site-config", "--debug-configuration"])
|
||
|
t.expect_output_lines("""\
|
||
|
notice: Site configuration files will be ignored due to the
|
||
|
notice: --ignore-site-config command-line option.""")
|
||
|
|
||
|
t.run_build_system(["--site-config=", "--debug-configuration"])
|
||
|
t.expect_output_lines("""\
|
||
|
notice: Site configuration file loading explicitly disabled.""")
|
||
|
|
||
|
t.cleanup()
|
||
|
|
||
|
def test_global_config():
|
||
|
t = BoostBuild.Tester(use_test_config=False, pass_toolset=0)
|
||
|
t.write("my-config.jam", "ECHO Loading my-config ;")
|
||
|
t.write("Jamroot", "EXIT Done : 0 ;")
|
||
|
t.write("project-config.jam", "ECHO bad ;")
|
||
|
t.run_build_system(["--config=my-config.jam", "--debug-configuration"],
|
||
|
match=TestCmd.match_re, stdout=
|
||
|
r"""notice: found boost-build\.jam at .*
|
||
|
notice: loading B2 from .*
|
||
|
notice: Searching '.*' for all-config configuration file 'my-config\.jam'\.
|
||
|
notice: Loading all-config configuration file 'my-config\.jam' from '.*'\.
|
||
|
Loading my-config
|
||
|
notice: Regular configuration files will be ignored due
|
||
|
notice: to the global configuration being loaded\.
|
||
|
Done
|
||
|
""")
|
||
|
t.run_build_system(["--config=", "--debug-configuration"],
|
||
|
match=TestCmd.match_re, stdout=
|
||
|
r"""notice: found boost-build\.jam at .*
|
||
|
notice: loading B2 from .*
|
||
|
notice: Configuration file loading explicitly disabled.
|
||
|
Done
|
||
|
""")
|
||
|
t.cleanup()
|
||
|
|
||
|
def test_project_config():
|
||
|
t = BoostBuild.Tester(["--user-config=", "--site-config="],
|
||
|
use_test_config=False, pass_toolset=False)
|
||
|
t.write("Jamroot", "EXIT Done : 0 ;")
|
||
|
t.write("project-config.jam", "ECHO Loading Root ;")
|
||
|
t.write("my-project-config.jam", "ECHO Loading explicit ;")
|
||
|
t.write("sub/project-config.jam", "ECHO Loading subdir ;")
|
||
|
t.write("sub/Jamfile", "")
|
||
|
|
||
|
t.run_build_system(stdout="Loading Root\nDone\n")
|
||
|
t.run_build_system(subdir="sub", stdout="Loading subdir\nDone\n")
|
||
|
t.rm("sub/project-config.jam")
|
||
|
t.run_build_system(subdir="sub", stdout="Loading Root\nDone\n")
|
||
|
t.run_build_system(["--project-config=my-project-config.jam"],
|
||
|
stdout="Loading explicit\nDone\n")
|
||
|
|
||
|
t.cleanup()
|
||
|
|
||
|
###############################################################################
|
||
|
#
|
||
|
# main()
|
||
|
# ------
|
||
|
#
|
||
|
###############################################################################
|
||
|
|
||
|
canSetEmptyEnvironmentVariable = _canSetEmptyEnvironmentVariable()
|
||
|
|
||
|
test_user_configuration()
|
||
|
test_site_config()
|
||
|
test_global_config()
|
||
|
test_project_config()
|