398 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			398 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/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()
 |