blob: d7b0e87fc3e86196a17102f73b08bc7c7c542778 [file] [log] [blame]
#!/usr/bin/env python
# Copyright Rene Rivera 2016
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
import os.path
import shutil
import sys
from common import toolset_info, main, utils, script_common, ci_cli, set_arg
__dirname__ = os.path.dirname(os.path.realpath(__file__))
class script(script_common):
'''
Main script to test a Boost C++ Library.
'''
def __init__(self, ci_klass, **kargs):
script_common.__init__(self, ci_klass, **kargs)
def init(self, opt, kargs):
opt.add_option( '--toolset',
help="single toolset to test with" )
opt.add_option( '--target',
help="test target to build for testing, defaults to TARGET or 'minimal'")
opt.add_option( '--address-model',
help="address model to test, ie 64 or 32" )
opt.add_option( '--variant',
help="variant to test, ie debug, release" )
set_arg(kargs, 'toolset', os.getenv("TOOLSET"))
set_arg(kargs, 'target', os.getenv('TARGET', 'minimal'))
set_arg(kargs, 'address_model', os.getenv("ADDRESS_MODEL",None))
set_arg(kargs, 'variant', os.getenv("VARIANT","debug"))
set_arg(kargs, 'cxxflags', os.getenv("CXXFLAGS",None))
return kargs
def start(self):
script_common.start(self)
# Some setup we need to redo for each invocation.
self.boost_root = os.path.join(self.ci.work_dir,'boostorg','boost')
@property
def repo_path(self):
if not hasattr(self,'_repo_path'):
# Find the path for the submodule of the repo we are testing.
if self.repo != 'boost':
self._repo_path = None
with open(os.path.join(self.boost_root,'.gitmodules'),"rU") as f:
path = None
url = None
for line in f:
line = line.strip()
if line.startswith("[submodule"):
path = None
url = None
else:
name = line.split("=")[0].strip()
value = line.split("=")[1].strip()
if name == "path":
path = value
elif name == "url":
url = value
if name and url and url.endswith("/%s.git"%(self.repo)):
self._repo_path = path
if not self._repo_path:
self._repo_path = "libs/%s"%(self.repo)
return self._repo_path
def command_install(self):
script_common.command_install(self)
# Fetch & install toolset..
utils.log( "Install toolset: %s"%(self.toolset) )
if self.toolset:
self.command_install_toolset(self.toolset)
def command_before_build(self):
script_common.command_before_build(self)
# Clone boost super-project.
if self.repo != 'boost':
utils.git_clone('boost',self.branch,cwd=self.ci.work_dir,no_submodules=True)
utils.check_call("git","submodule","update","--quiet","--init","tools/build")
utils.check_call("git","submodule","update","--quiet","--init","tools/boostdep")
# The global jamfiles require config as they trigger build config checks.
utils.check_call("git","submodule","update","--quiet","--init","libs/config")
# Find the path for the submodule of the repo we are testing.
if self.repo != 'boost':
self.repo_dir = os.path.join(self.boost_root,self.repo_path)
if self.repo != 'boost':
# Copy in the existing library tree checkout.
shutil.rmtree(self.repo_path)
shutil.copytree(self.root_dir, self.repo_path)
# Fetch the dependencies for the library we are testing.
if self.repo != 'boost':
os.chdir(self.boost_root)
utils.check_call(
sys.executable,
'tools/boostdep/depinst/depinst.py',
self.repo)
# Create config file for toolset.
if not isinstance(self.ci, ci_cli):
cxxflags = None
if self.cxxflags:
cxxflags = self.cxxflags.split()
cxxflags = " <cxxflags>".join(cxxflags)
utils.make_file(os.path.join(self.boost_root, 'project-config.jam'),
"""
using %(toolset)s : %(version)s : %(command)s : %(cxxflags)s ;
using python : %(pyversion)s : "%(python)s" ;
"""%{
'toolset':toolset_info[self.toolset]['toolset'],
'version':toolset_info[self.toolset]['version'],
'command':toolset_info[self.toolset]['command'],
'cxxflags':"<cxxflags>"+cxxflags if cxxflags else "",
'pyversion':"%s.%s"%(sys.version_info[0],sys.version_info[1]),
'python':sys.executable.replace("\\","\\\\")
})
def command_build(self):
script_common.command_build(self)
# Set up tools.
utils.makedirs(os.path.join(self.build_dir,'dist','bin'))
if not isinstance(self.ci, ci_cli) and toolset_info[self.toolset]['command']:
os.environ['PATH'] = os.pathsep.join([
os.path.dirname(toolset_info[self.toolset]['command']),
os.path.join(self.build_dir,'dist','bin'),
os.environ['PATH']])
else:
os.environ['PATH'] = os.pathsep.join([
os.path.join(self.build_dir,'dist','bin'),
os.environ['PATH']])
os.environ['BOOST_BUILD_PATH'] = self.build_dir
# Bootstrap Boost Build engine.
os.chdir(os.path.join(self.boost_root,"tools","build"))
if sys.platform == 'win32':
utils.check_call(".\\bootstrap.bat")
shutil.copy2("b2.exe", os.path.join(self.build_dir,"dist","bin","b2.exe"))
else:
utils.check_call("./bootstrap.sh")
shutil.copy2("b2", os.path.join(self.build_dir,"dist","bin","b2"))
utils.check_call("git","clean","-dfqx")
# Run the limited tests.
if self.repo != 'boost':
print("--- Testing %s ---"%(self.repo_path))
os.chdir(os.path.join(self.boost_root,'status'))
to_test = self.repo_path.split("/")
del to_test[0]
toolset_to_test = ""
if self.toolset:
if not isinstance(self.ci, ci_cli):
toolset_to_test = toolset_info[self.toolset]['toolset']
else:
toolset_to_test = self.toolset
self.b2(
'-d1',
'-p0',
'--include-tests=%s'%("/".join(to_test)),
'preserve-test-targets=off',
'--dump-tests',
'--build-dir=%s'%(self.build_dir),
'--out-xml=%s'%(os.path.join(self.build_dir,'regression.xml')),
'' if not toolset_to_test else 'toolset=%s'%(toolset_to_test),
'' if not self.address_model else 'address-model=%s'%(self.address_model),
'variant=%s'%(self.variant),
'--test-type=%s'%(self.target),
'--verbose-test'
)
# Generate a readable test report.
import build_log
log_main = build_log.Main([
'--output=console',
os.path.join(self.build_dir,'regression.xml')])
# And exit with an error if the report contains failures.
# This lets the CI notice the error and report a failed build.
# And hence trigger the failure machinery, like sending emails.
if log_main.failed:
self.ci.finish(-1)
def command_before_cache(self):
script_common.command_before_cache(self)
os.chdir(self.boost_root)
utils.check_call("git","clean","-dfqx")
utils.check_call("git","submodule","--quiet","foreach","git","clean","-dfqx")
utils.check_call("git","status","-bs")
utils.check_call("git","submodule","foreach","git","status","-bs")
main(script)