summaryrefslogtreecommitdiff
path: root/status
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:41:18 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:43:11 +0900
commitf763a99a501650eff2c60288aa6f10ef916d769e (patch)
tree02af7e13f9a38c888ebf340fe764cbe7dae99da9 /status
parent5cde13f21d36c7224b0e13d11c4b49379ae5210d (diff)
downloadboost-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.v2303
-rw-r--r--status/boost_check_library.py299
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)
+