diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:41:18 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:43:11 +0900 |
commit | f763a99a501650eff2c60288aa6f10ef916d769e (patch) | |
tree | 02af7e13f9a38c888ebf340fe764cbe7dae99da9 /status | |
parent | 5cde13f21d36c7224b0e13d11c4b49379ae5210d (diff) | |
download | boost-f763a99a501650eff2c60288aa6f10ef916d769e.tar.gz boost-f763a99a501650eff2c60288aa6f10ef916d769e.tar.bz2 boost-f763a99a501650eff2c60288aa6f10ef916d769e.zip |
Imported Upstream version 1.62.0upstream/1.62.0
Change-Id: I9d4c1ddb7b7d8f0069217ecc582700f9fda6dd4c
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'status')
-rw-r--r-- | status/Jamfile.v2 | 303 | ||||
-rw-r--r-- | status/boost_check_library.py | 299 |
2 files changed, 447 insertions, 155 deletions
diff --git a/status/Jamfile.v2 b/status/Jamfile.v2 index 85673b699b..6d77de0280 100644 --- a/status/Jamfile.v2 +++ b/status/Jamfile.v2 @@ -1,16 +1,47 @@ -# Boost regression-testing Jamfile -# (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears in -# all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. - -# Status: -# - std::locale-support usage is commented out. -# Two test suite have different names. -# <no-warn> in config test is commented out. -# One of the smart_ptr test is run only from invocation dir in V1, and not -# run in V2 at all. +# Copyright 2002. Dave Abrahams +# Copyright 2016. Rene Rivera +# 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) +# This build project manages running the tests for all of Boost. +# The tests to run are discovered from the structure of the libs tree. +# +# Usage: +# +# > cd boost-root/status +# > b2 [--check-libs-only] [--limit-tests=/lib-name-regex../]* [--exclude-tests=/lib-name-regex../]* +# +# --check-libs-only +# Only runs the library conformance tests. +# +# --limit-tests, or --include-tests +# Only runs the tests for whom the name matches the regex. +# The value for the argument is a comma separated list of simple +# regular expressions to check against the names of all the libraries. +# If any one regex matches the matching library is tested. +# +# --exclude-tests +# Only runs the tests for whom the names does not match the regex. +# The argument is the same as for the limit-tests option except +# that the result is that libraries for whom the name matches +# are not tested. +# +# The test filters are evaluated in the order given in the command +# and can be used to selectively narrow or widen the set of libraries +# tested. +# +# Examples: +# +# > b2 --check-libs-only --include-tests=predef,config +# +# Runs the library conformance tests for the predef and config +# libraries only. +# +# > b2 --include-tests=[n-t] --exclude-tests=rat --limit-tests=[v-w] +# +# Runs all the tests for library names that begin with "n" through "t", +# or "v" through "w", but not libraries that start with "rat". project status : source-location $(BOOST_ROOT) @@ -19,175 +50,137 @@ project status import testing ; import modules ; +import project ; +import regex ; +import modules ; +import path ; +import feature ; +import numbers ; + +local check-libs-only = [ MATCH "^--(check-libs-only)" : [ modules.peek : ARGV ] ] ; +local check-libs-only-targets = ; +local libraries = ; local rule run-tests ( root : tests * ) { - local limit-tests = [ MATCH "^--limit-tests=(.*)" : [ modules.peek : ARGV ] ] ; + local filter-args = [ MATCH "^--(limit|exclude|include)-tests=(.*)" : [ modules.peek : ARGV ] ] ; + local filter-tests ; + while $(filter-args) + { + local type = $(filter-args[1]) ; + for local test in [ regex.split-list $(filter-args[2]) : "[,]" ] + { + filter-tests += $(type) $(test) ; + } + filter-args = $(filter-args[3-]) ; + } + # If any filter is given we make the initial set of tested libraries we: + # (a) make it empty if the first filter is an include. + # (b) make it full otherwise. + local include-default = y ; + if $(filter-tests[1]) && ( $(filter-tests[1]) in limit include ) + { + include-default = n ; + } + local location = [ project.attribute $(__name__) location ] ; + # We only run the check library test when host-os == target-os. + # Hence we need that information. + local host-os-default = [ feature.defaults <host-os> ] ; for local test in $(tests) { - if $(limit-tests) + local library = [ path.parent $(test) ] ; + if $(library) = "." + { + library = $(test) ; + } + local include-test = $(include-default) ; + local t = 1 ; + local f = 2 ; + while $(filter-tests[$(f)]) { - if [ MATCH "^($(limit-tests))" : $(test) ] + if [ MATCH "^($(filter-tests[$(f)]))" : $(test) ] { - build-project ../$(root)/$(test) ; + if $(filter-tests[$(t)]) = exclude { include-test = n ; } + else { include-test = y ; } } - else + t = [ CALC $(t) + 2 ] ; + f = [ CALC $(f) + 2 ] ; + } + use-project /boost/$(test) : ../$(root)/$(test) ; + if $(include-test) = y + { + if $(root) = libs && ( ! ( $(library) in $(libraries) ) ) { - use-project /boost/$(test) : ../$(root)/$(test) ; + libraries += $(library) ; + local test_module = [ project.find ../$(root)/$(test) : $(location) ] ; + modules.poke $(test_module) : __LIBRARY__ : $(root)/$(library) ; + modules.poke $(test_module) : __JAMFILE__ : [ modules.peek project : JAMFILE ] ; + modules.poke $(test_module) : __REQUIRE__ : <target-os>$(host-os-default:G=) ; + project.push-current [ project.target $(test_module) ] ; + module $(test_module) + { + import testing ; + testing.make-test run-pyd : + $(BOOST_ROOT)/status/boost_check_library.py + : + <pythonpath>$(BOOST_ROOT)/status + <testing.arg>--boost-root=\"$(BOOST_ROOT)\" + <testing.arg>--library=$(__LIBRARY__) + <testing.arg>--jamfile=\"$(__JAMFILE__:J=;)\" + <testing.arg>organization + $(__REQUIRE__) + : + __boost_check_library__ ; + } + project.pop-current ; + check-libs-only-targets += ../$(root)/$(test)//__boost_check_library__ ; + } + if ! $(check-libs-only) + { + build-project ../$(root)/$(test) ; } } - else + } +} + +local libs-to-test = ; +for local libdir in [ path.glob $(BOOST_ROOT) : libs/* ] +{ + local jamfile = [ modules.peek project : JAMFILE ] ; + local jamfiles = [ path.glob [ path.join $(libdir) test ] : $(jamfile) ] ; + if $(jamfiles) + { + libs-to-test += $(libdir:B) ; + } + if [ path.glob $(libdir) : sublibs ] + { + jamfiles = [ path.glob $(libdir) : */test/$(jamfile) ] ; + for local sublib_jamfile in $(jamfiles) { - build-project ../$(root)/$(test) ; + local sublibdir = [ path.parent [ path.parent $(sublib_jamfile) ] ] ; + local sublib = $(libdir:B)/$(sublibdir:B) ; + libs-to-test += $(sublib) ; } } } +libs-to-test = [ SORT $(libs-to-test) ] ; + +run-tests libs : $(libs-to-test)/test ; # Tests from Jamfiles in individual library test subdirectories # Please keep these in alphabetic order by test-suite name run-tests libs : - accumulators/test # test-suite accumulators - algorithm/test # test-suite algorithm - algorithm/minmax/test # test-suite algorith/minmax - algorithm/string/test # test-suite algorithm/string - align/test # test-suite align - array/test # test-suite array - asio/test # test-suite asio - assert/test # test-suite assert - assign/test # test-suite assign - atomic/test # test-suite atomic - any/test # test-suite any - bimap/test # test-suite bimap - bind/test # test-suite bind - chrono/test # test-suite chrono - circular_buffer/test # test-suite circular_buffer - compute/test # test-suite compute concept_check # test-suite concept_check - config/test # test-suite config - container/bench # test-suite container benchmarks - container/example # test-suite container_example - container/test # test-suite container_test - context/test # test-suite context - conversion/test # test-suite conversion - convert/test # test-suite convert - core/test # test-suite core - core/test/swap # test-suite core/swap - coroutine/test # test-suite coroutine - coroutine2/test # test-suite coroutine2 - crc/test # test-suite crc - date_time/test # test-suite date_time - detail/test # test-suite detail disjoint_sets # test-suite disjoint_sets - dll/test # test-suite dll dynamic_bitset # test-suite dynamic_bitset - endian/test # test-suite endian - exception/test - filesystem/test # test-suite filesystem - flyweight/test # test-suite flyweight - foreach/test # test-suite foreach - format/test # test-suite format - function/test # test-suite function - functional/test # test-suite functional - functional/factory/test # test-suite functional/factory - functional/forward/test # test-suite functional/forward - functional/hash/test/extra # test-suite functional/hash - functional/overloaded_function/test # test-suite func./overloaded_function - function_types/test # test-suite function_types - fusion/test # test-suite fusion - geometry/test # test-suite geometry - geometry/index/test # test-suite geometry/index - gil/test # test-suite gil - graph/test # test-suite graph - graph_parallel/test # test-suite graph/parallel - hana/test # test-suite hana - heap/test # test-suite heap - icl/test # test-suite icl - integer/test # test-suite integer - interprocess/example # test-suite interprocess_example - interprocess/test # test-suite interprocess_test - intrusive/example # test-suite intrusive_example - intrusive/test # test-suite intrusive_test - io/test # test-suite io - iostreams/test # test-suite iostreams - iterator/test # test-suite iterator - lambda/test # test-suite lambda - lexical_cast/test # test-suite lexical_cast - local_function/test # test-suite local_function - locale/test # test-suite locale - log/test # test-suite log - logic/test # test-suite logic - lockfree/test # test-suite lockfree - math/test # test-suite math - metaparse/test # test-suite metaparse - move/example # test-suite move_example - move/test # test-suite move_test - mpi/test # test-suite mpi - mpl/test # test-suite mpl - msm/test # msm-unit-tests - multi_array/test # test-suite multi_array - multi_index/test # test-suite multi_index - multiprecision/test # test-suite multiprecision - numeric/conversion/test # test-suite numeric/conversion - numeric/interval/test # test-suite numeric/interval - numeric/odeint/test # test-suite numeric/odeint - numeric/ublas/test # test-suite numeirc/uBLAS - optional/test # test-suite optional - parameter/test # test-suite parameter - phoenix/test # test-suite phoenix - polygon/test # test-suite polygon - pool/test # test-suite pool - predef/test # test-suite predef - preprocessor/test # test-suite preprocessor - program_options/test # test-suite program_options - property_map/test # test-suite property_map - property_tree/test # test-suite property_test - proto/test # test-suite proto - ptr_container/test # test-suite ptr_container - python/test # test-suite python - random/test # test-suite random - range/test # test-suite range - ratio/test # test-suite ratio - rational/test # test-suite rational - regex/test # test-suite regex - regex/example # test-suite regex-examples - scope_exit/test # test-suite scope_exit - serialization/test # test-suite serialization - signals/test # test-suite signals - signals2/test # test-suite signals2 - smart_ptr/test # test-suite smart_ptr - sort/test # test-suite sort - spirit/classic/test # test-suite classic spirit - spirit/test # test-suite spirit_v2 - spirit/repository/test # test-suite spirit_v2 repository - statechart/test # test-suite statechart - static_assert # test-suite static_assert - system/test # test-suite system - test/test # test-suite test - thread/test # test-suite thread - throw_exception/test # test-suite throw_exception - timer/test # test-suite timer - tokenizer/test # test-suite tokenizer - tr1/test # test-suite tr1 - tti/test # test-suite tti - tuple/test # test-suite tuple - type_erasure/test # test-suite type_erasure - type_index/test # test-suite type_index - type_traits/test # test-suite type_traits - typeof/test # test-suite typeof - units/test # test-suite units - unordered/test/unordered # test-suite unordered - unordered/test/exception # test-suite unordered-exception - utility/identity_type/test # test-suite utility/identity_type - utility/test # test-suite utility - uuid/test # test-suite uuid - variant/test # test-suite variant - vmd/test # test-suite vmd wave/test/build # test-suite wave - winapi/test # test-suite winapi - xpressive/test # test-suite xpressive ; run-tests tools : bcp/test ; +if $(check-libs-only-targets) +{ + alias check-libs-only : $(check-libs-only-targets) ; +} diff --git a/status/boost_check_library.py b/status/boost_check_library.py new file mode 100644 index 0000000000..e75563936a --- /dev/null +++ b/status/boost_check_library.py @@ -0,0 +1,299 @@ +#!/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 +import inspect +import optparse +import sys +import glob +import fnmatch +import json + +class check_library(): + ''' + This is a collection of checks for a library to test if a library + follows the Boost C++ Libraries requirements and guidelines. It also + checks for possible and likely errors in the library. + ''' + + def __init__(self): + self.main() + + def check_organization(self): + self.run_batch('check_organization_') + + def check_organization_build(self): + if os.path.isdir(os.path.join(self.library_dir, 'build')): + self.assert_file_exists(os.path.join(self.library_dir, 'build'), self.jamfile, + ''' + Did not find a Boost Build file in the [project-root]/build directory. + The library needs to provide a Boost Build project that the user, + and the top level Boost project, can use to build the library if it + has sources to build. + ''', + 'org-build-ok') + if os.path.isdir(os.path.join(self.library_dir, 'src')): + self.assert_dir_exists(os.path.join(self.library_dir,'build'), + ''' + Missing [project-root]/build directory. The [project-root]/build directory + is required for libraries that have a [project-root]/src directory. + ''', + 'org-build-src') + + def check_organization_doc(self): + self.assert_file_exists(self.library_dir, ['index.html'], + ''' + Did not find [project-root]/index.html file. + + The file is required for all libraries. Redirection to HTML documentation. + ''', + 'org-doc-redir') + self.assert_dir_exists(os.path.join(self.library_dir,'doc'), + ''' + Missing [project-root]/doc directory. The [project-root]/doc directory + is required for all libraries. + + Sources to build with and built documentation for the library. If the + library needs to build documentation from non-HTML files this location + must be buildable with Boost Build. + ''', + 'org-doc-dir') + + def check_organization_include(self): + if os.path.isdir(os.path.join(self.library_dir,'include','boost',self.library_name)): + self.warn_file_exists(os.path.join(self.library_dir,'include','boost'), ['*.h*'], + ''' + Found extra files in [project-root]/include/boost directory. + ''', + 'org-inc-extra', + negate = True, + globs_to_exclude = ['%s.h*'%(self.library_name)]) + else: + self.warn_file_exists(os.path.join(self.library_dir,'include','boost'), ['%s.h*'%(self.library_name)], + ''' + Did not find [project-root]/include/boost/[library].h* file. + + A single header for the library is suggested at [project-root]/include/boost/[library].h* + if the library does not have a header directory at [project-root]/include/boost/[library]. + ''', + 'org-inc-one') + + def check_organization_meta(self): + parent_dir = os.path.dirname(self.library_dir) + # If this is a sublibrary it's possible that the library information is the + # parent library's meta/libraries.json. Otherwise it's a regular library + # and structure. + if not self.test_dir_exists(os.path.join(self.library_dir,'meta')) \ + and self.test_file_exists(os.path.join(parent_dir,'meta'),['libraries.json']): + if self.get_library_meta(): + return + self.assert_file_exists(os.path.join(self.library_dir, 'meta'), ['libraries.json'], + ''' + Did not find [project-root]/meta/libraries.json file, nor did + [super-project]/meta/libraries.json contain an entry for the sublibrary. + + The file is required for all libraries. And contains information about + the library used to generate website and documentation for the + Boost C++ Libraries collection. + ''', + 'org-meta-libs') + elif self.assert_dir_exists(os.path.join(self.library_dir,'meta'), + ''' + Missing [project-root]/meta directory. The [project-root]/meta directory + is required for all libraries. + ''', + 'org-meta-dir'): + self.assert_file_exists(os.path.join(self.library_dir, 'meta'), ['libraries.json'], + ''' + Did not find [project-root]/meta/libraries.json file. + + The file is required for all libraries. And contains information about + the library used to generate website and documentation for the + Boost C++ Libraries collection. + ''', + 'org-meta-libs') + + def check_organization_test(self): + if self.assert_dir_exists(os.path.join(self.library_dir,'test'), + ''' + Missing [project-root]/test directory. The [project-root]/test directory + is required for all libraries. + + Regression or other test programs or scripts. This is the only location + considered for automated testing. If you have additional locations that + need to be part of automated testing it is required that this location + refer to the additional test locations. + ''', + 'org-test-dir'): + self.assert_file_exists(os.path.join(self.library_dir, 'test'), self.jamfile, + ''' + Did not find a Boost Build file in the [project-root]/test directory. + ''', + 'org-test-ok') + + def main(self): + commands = []; + for method in inspect.getmembers(self, predicate=inspect.ismethod): + if method[0].startswith('check_'): + commands.append(method[0][6:].replace('_','-')) + commands = "commands: %s" % ', '.join(commands) + + opt = optparse.OptionParser( + usage="%prog [options] [commands]", + description=commands) + opt.add_option('--boost-root') + opt.add_option('--library') + opt.add_option('--jamfile') + opt.add_option('--debug', action='store_true') + self.boost_root = None + self.library = None + self.jamfile = None + self.debug = False + ( _opt_, self.actions ) = opt.parse_args(None,self) + + self.library_dir = os.path.join(self.boost_root, self.library) + self.error_count = 0; + self.jamfile = self.jamfile.split(';') + self.library_name = self.library.split('/',1)[1] #os.path.basename(self.library) + self.library_key = self.library.split('/',1)[1] + + if self.debug: + print ">>> cwd: %s"%(os.getcwd()) + print ">>> actions: %s"%(self.actions) + print ">>> boost_root: %s"%(self.boost_root) + print ">>> library: %s"%(self.library) + print ">>> jamfile: %s"%(self.jamfile) + + for action in self.actions: + action_m = "check_"+action.replace('-','_') + if hasattr(self,action_m): + getattr(self,action_m)() + + def run_batch(self, action_base, *args, **kargs): + for method in inspect.getmembers(self, predicate=inspect.ismethod): + if method[0].startswith(action_base): + getattr(self,method[0])(*args, **kargs) + + def get_library_meta(self): + ''' + Fetches the meta data for the current library. The data could be in + the superlib meta data file. If we can't find the data None is returned. + ''' + parent_dir = os.path.dirname(self.library_dir) + if self.test_file_exists(os.path.join(self.library_dir,'meta'),['libraries.json']): + with open(os.path.join(self.library_dir,'meta','libraries.json'),'r') as f: + meta_data = json.load(f) + if isinstance(meta_data,list): + for lib in meta_data: + if lib['key'] == self.library_key: + return lib + elif 'key' in meta_data and meta_data['key'] == self.library_key: + return meta_data + if not self.test_dir_exists(os.path.join(self.library_dir,'meta')) \ + and self.test_file_exists(os.path.join(parent_dir,'meta'),['libraries.json']): + with open(os.path.join(parent_dir,'meta','libraries.json'),'r') as f: + libraries_json = json.load(f) + if isinstance(libraries_json,list): + for lib in libraries_json: + if lib['key'] == self.library_key: + return lib + return None + + def error(self, reason, message, key): + self.error_count += 1 + print("%s: error: %s; %s <<%s>>"%( + self.library, + self.clean_message(reason), + self.clean_message(message), + key, + )) + + def warn(self, reason, message, key): + print("%s: warning: %s; %s <<%s>>"%( + self.library, + self.clean_message(reason), + self.clean_message(message), + key, + )) + + def info(self, message): + if self.debug: + print("%s: info: %s"%(self.library, self.clean_message(message))) + + def clean_message(self, message): + return " ".join(message.strip().split()) + + def assert_dir_exists(self, dir, message, key, negate = False): + self.info("check directory '%s', negate = %s"%(dir,negate)) + if os.path.isdir(dir): + if negate: + self.error("directory found", message, key) + return False + else: + if not negate: + self.error("directory not found", message, key) + return False + return True + + def warn_dir_exists(self, dir, message, key, negate = False): + self.info("check directory '%s', negate = %s"%(dir,negate)) + if os.path.isdir(dir): + if negate: + self.warn("directory found", message, key) + return False + else: + if not negate: + self.warn("directory not found", message, key) + return False + return True + + def assert_file_exists(self, dir, globs_to_include, message, key, negate = False, globs_to_exclude = []): + found = self.test_file_exists(dir, globs_to_include = globs_to_include, globs_to_exclude = globs_to_exclude) + if negate: + if found: + self.error("file found", message, key) + return False + else: + if not found: + self.error("file not found", message, key) + return False + return True + + def warn_file_exists(self, dir, globs_to_include, message, key, negate = False, globs_to_exclude = []): + found = self.test_file_exists(dir, globs_to_include = globs_to_include, globs_to_exclude = globs_to_exclude) + if negate: + if found: + self.warn("file found", message, key) + return False + else: + if not found: + self.warn("file not found", message, key) + return False + return True + + def test_dir_exists(self, dir): + return os.path.isdir(dir) + + def test_file_exists(self, dir, globs_to_include, globs_to_exclude = []): + self.info("test file(s) in dir '%s', include = '%s', exclude = %s"%(dir,globs_to_include,globs_to_exclude)) + found = False + if os.path.isdir(dir): + for g in globs_to_include: + for f in glob.iglob(os.path.join(dir,g)): + exclude = False + for ge in globs_to_exclude: + if fnmatch.fnmatch(os.path.basename(f),ge): + exclude = True + found = not exclude + if found: + break + return found + +if check_library().error_count > 0: + sys.exit(1) + |