From 45cb9d80ae274fe46ed64c76cc87a36fc994a182 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:33 -0600 Subject: binman: Detect skipped tests If tests are skipped we should ideally exit with an error, since there may be a missing dependency. However at present this is not desirable since it breaks travis tests. For now, just report the skips. Signed-off-by: Simon Glass --- tools/binman/binman.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tools/binman/binman.py') diff --git a/tools/binman/binman.py b/tools/binman/binman.py index aad2e9c8bc4..9f8c5c99b79 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -104,9 +104,14 @@ def RunTests(debug, processes, args): print(test.id(), err) for test, err in result.failures: print(err, result.failures) + if result.skipped: + print('%d binman test%s SKIPPED:' % + (len(result.skipped), 's' if len(result.skipped) > 1 else '')) + for skip_info in result.skipped: + print('%s: %s' % (skip_info[0], skip_info[1])) if result.errors or result.failures: - print('binman tests FAILED') - return 1 + print('binman tests FAILED') + return 1 return 0 def GetEntryModules(include_testing=True): -- cgit v1.2.3 From 86679cefe5fd3d24ccc4dc117c9e1b107f60c937 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:36 -0600 Subject: binman: Ensure that coverage has access to site packages Code coverage tests fail on binman due to dist-packages being dropped from the python path on Ubuntu 16.04. Add them in so that we can find the elffile module, which is required by binman. Signed-off-by: Simon Glass --- tools/binman/binman.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools/binman/binman.py') diff --git a/tools/binman/binman.py b/tools/binman/binman.py index 9f8c5c99b79..05aeaecd8f3 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -11,9 +11,11 @@ from __future__ import print_function +from distutils.sysconfig import get_python_lib import glob import multiprocessing import os +import site import sys import traceback import unittest @@ -28,6 +30,12 @@ sys.path.insert(0, 'scripts/dtc/pylibfdt') sys.path.insert(0, os.path.join(our_path, '../../build-sandbox_spl/scripts/dtc/pylibfdt')) +# When running under python-coverage on Ubuntu 16.04, the dist-packages +# directories are dropped from the python path. Add them in so that we can find +# the elffile module. We could use site.getsitepackages() here but unfortunately +# that is not available in a virtualenv. +sys.path.append(get_python_lib()) + import cmdline import command use_concurrent = True -- cgit v1.2.3 From 9382bb873b627e5ce660ab3e8385a90460a0df2c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:43 -0600 Subject: binman: Drop unnecessary debug handling The -D option enables debug mode, but we only need to add -D to the command line once. Drop the duplicate code. Also drop the comment about enabling debugging since this can be done with -D. Signed-off-by: Simon Glass --- tools/binman/binman.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'tools/binman/binman.py') diff --git a/tools/binman/binman.py b/tools/binman/binman.py index 05aeaecd8f3..bab98826dc6 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -71,8 +71,6 @@ def RunTests(debug, processes, args): sys.argv = [sys.argv[0]] if debug: sys.argv.append('-D') - if debug: - sys.argv.append('-D') # Run the entry tests first ,since these need to be the first to import the # 'entry' module. @@ -151,9 +149,6 @@ def RunBinman(options, args): """ ret_code = 0 - # For testing: This enables full exception traces. - #options.debug = True - if not options.debug: sys.tracebacklimit = 0 -- cgit v1.2.3 From ee0c9a739f219c80b8a1f1abc217338c8c2087cc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:48 -0600 Subject: binman: Allow verbosity control when running tests At present the -v flag is ignored with tests, so that (for example) -v2 does not have any effect. Update binman to pass this flag through to tests so that they work just like running binman normally, except in a few special cases where we are actually testing behaviour with different levels of verbosity. Signed-off-by: Simon Glass --- tools/binman/binman.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tools/binman/binman.py') diff --git a/tools/binman/binman.py b/tools/binman/binman.py index bab98826dc6..7c1dcfb65fc 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -46,11 +46,12 @@ except: import control import test_util -def RunTests(debug, processes, args): +def RunTests(debug, verbosity, processes, args): """Run the functional tests and any embedded doctests Args: debug: True to enable debugging, which shows a full stack trace on error + verbosity: Verbosity level to use args: List of positional args provided to binman. This can hold a test name to execute (as in 'binman -t testSections', for example) processes: Number of processes to use to run tests (None=same as #CPUs) @@ -71,6 +72,8 @@ def RunTests(debug, processes, args): sys.argv = [sys.argv[0]] if debug: sys.argv.append('-D') + if verbosity: + sys.argv.append('-v%d' % verbosity) # Run the entry tests first ,since these need to be the first to import the # 'entry' module. @@ -153,7 +156,8 @@ def RunBinman(options, args): sys.tracebacklimit = 0 if options.test: - ret_code = RunTests(options.debug, options.processes, args[1:]) + ret_code = RunTests(options.debug, options.verbosity, options.processes, + args[1:]) elif options.test_coverage: RunTestCoverage() -- cgit v1.2.3 From d5164a79703df76254d8c0ac67037d629d113518 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:49 -0600 Subject: binman: Allow preserving test directories Sometimes when debugging tests it is useful to keep the input and output directories so they can be examined later. Add an option for this and update the binman tests to support it. This affects both the test class and the tearDown() function called after each test. Signed-off-by: Simon Glass --- tools/binman/binman.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'tools/binman/binman.py') diff --git a/tools/binman/binman.py b/tools/binman/binman.py index 7c1dcfb65fc..9878eb86d4f 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -46,15 +46,20 @@ except: import control import test_util -def RunTests(debug, verbosity, processes, args): +def RunTests(debug, verbosity, processes, test_preserve_dirs, args): """Run the functional tests and any embedded doctests Args: debug: True to enable debugging, which shows a full stack trace on error verbosity: Verbosity level to use + test_preserve_dirs: True to preserve the input directory used by tests + so that it can be examined afterwards (only useful for debugging + tests). If a single test is selected (in args[0]) it also preserves + the output directory for this test. Both directories are displayed + on the command line. + processes: Number of processes to use to run tests (None=same as #CPUs) args: List of positional args provided to binman. This can hold a test name to execute (as in 'binman -t testSections', for example) - processes: Number of processes to use to run tests (None=same as #CPUs) """ import elf_test import entry_test @@ -82,6 +87,11 @@ def RunTests(debug, verbosity, processes, args): loader = unittest.TestLoader() for module in (entry_test.TestEntry, ftest.TestFunctional, fdt_test.TestFdt, elf_test.TestElf, image_test.TestImage): + # Test the test module about our arguments, if it is interested + if hasattr(module, 'setup_test_args'): + setup_test_args = getattr(module, 'setup_test_args') + setup_test_args(preserve_indir=test_preserve_dirs, + preserve_outdirs=test_preserve_dirs and test_name is not None) if test_name: try: suite.addTests(loader.loadTestsFromName(test_name, module)) @@ -157,7 +167,7 @@ def RunBinman(options, args): if options.test: ret_code = RunTests(options.debug, options.verbosity, options.processes, - args[1:]) + options.test_preserve_dirs, args[1:]) elif options.test_coverage: RunTestCoverage() -- cgit v1.2.3 From 8acce60b10f2d60945b71f527fd29ee62242b175 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:50 -0600 Subject: binman: Pass the toolpath to tests Tools like ifwitool may not be available in the PATH, but are available in the build. These tools may be needed by tests, so allow tests to use the --toolpath flag. Also use this flag with travis. Signed-off-by: Simon Glass --- tools/binman/binman.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'tools/binman/binman.py') diff --git a/tools/binman/binman.py b/tools/binman/binman.py index 9878eb86d4f..52c03f68c6d 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -46,7 +46,7 @@ except: import control import test_util -def RunTests(debug, verbosity, processes, test_preserve_dirs, args): +def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath): """Run the functional tests and any embedded doctests Args: @@ -60,6 +60,7 @@ def RunTests(debug, verbosity, processes, test_preserve_dirs, args): processes: Number of processes to use to run tests (None=same as #CPUs) args: List of positional args provided to binman. This can hold a test name to execute (as in 'binman -t testSections', for example) + toolpath: List of paths to use for tools """ import elf_test import entry_test @@ -79,6 +80,9 @@ def RunTests(debug, verbosity, processes, test_preserve_dirs, args): sys.argv.append('-D') if verbosity: sys.argv.append('-v%d' % verbosity) + if toolpath: + for path in toolpath: + sys.argv += ['--toolpath', path] # Run the entry tests first ,since these need to be the first to import the # 'entry' module. @@ -91,7 +95,8 @@ def RunTests(debug, verbosity, processes, test_preserve_dirs, args): if hasattr(module, 'setup_test_args'): setup_test_args = getattr(module, 'setup_test_args') setup_test_args(preserve_indir=test_preserve_dirs, - preserve_outdirs=test_preserve_dirs and test_name is not None) + preserve_outdirs=test_preserve_dirs and test_name is not None, + toolpath=toolpath) if test_name: try: suite.addTests(loader.loadTestsFromName(test_name, module)) @@ -167,7 +172,8 @@ def RunBinman(options, args): if options.test: ret_code = RunTests(options.debug, options.verbosity, options.processes, - options.test_preserve_dirs, args[1:]) + options.test_preserve_dirs, args[1:], + options.toolpath) elif options.test_coverage: RunTestCoverage() -- cgit v1.2.3 From 4997a7ed05bf109b34ea0d072a33bb29209ae4ff Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:52 -0600 Subject: binman: Add a utility library for coreboot CBFS Coreboot uses a simple flash-based filesystem called Coreboot Filesystem (CBFS) to organise files used during boot. This allows files to be named and their position in the flash to be set. It has special features for dealing with x86 devices which typically memory-map their SPI flash to the top of 32-bit address space and need a 'boot block' ending there. Create a library to help create and read CBFS files. This includes a writer class, a reader class and associated other helpers. Only a subset of features are currently supported. Signed-off-by: Simon Glass --- tools/binman/binman.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/binman/binman.py') diff --git a/tools/binman/binman.py b/tools/binman/binman.py index 52c03f68c6d..613aad5c451 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -62,6 +62,7 @@ def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath): name to execute (as in 'binman -t testSections', for example) toolpath: List of paths to use for tools """ + import cbfs_util_test import elf_test import entry_test import fdt_test @@ -90,7 +91,8 @@ def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath): suite = unittest.TestSuite() loader = unittest.TestLoader() for module in (entry_test.TestEntry, ftest.TestFunctional, fdt_test.TestFdt, - elf_test.TestElf, image_test.TestImage): + elf_test.TestElf, image_test.TestImage, + cbfs_util_test.TestCbfs): # Test the test module about our arguments, if it is interested if hasattr(module, 'setup_test_args'): setup_test_args = getattr(module, 'setup_test_args') -- cgit v1.2.3 From 53cd5d921dd76d4651f2c99681a3c050743b6ba1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 14:25:29 -0600 Subject: binman: Convert to use ArgumentParser This class is the new way to handle arguments in Python. Convert binman over to use it. At the same time, introduce commands so that we can separate out the different parts of binman functionality. Signed-off-by: Simon Glass --- tools/binman/binman.py | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'tools/binman/binman.py') diff --git a/tools/binman/binman.py b/tools/binman/binman.py index 613aad5c451..8bd5868df26 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -20,14 +20,15 @@ import sys import traceback import unittest -# Bring in the patman and dtoc libraries +# Bring in the patman and dtoc libraries (but don't override the first path +# in PYTHONPATH) our_path = os.path.dirname(os.path.realpath(__file__)) for dirname in ['../patman', '../dtoc', '..', '../concurrencytest']: - sys.path.insert(0, os.path.join(our_path, dirname)) + sys.path.insert(2, os.path.join(our_path, dirname)) # Bring in the libfdt module -sys.path.insert(0, 'scripts/dtc/pylibfdt') -sys.path.insert(0, os.path.join(our_path, +sys.path.insert(2, 'scripts/dtc/pylibfdt') +sys.path.insert(2, os.path.join(our_path, '../../build-sandbox_spl/scripts/dtc/pylibfdt')) # When running under python-coverage on Ubuntu 16.04, the dist-packages @@ -59,7 +60,7 @@ def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath): on the command line. processes: Number of processes to use to run tests (None=same as #CPUs) args: List of positional args provided to binman. This can hold a test - name to execute (as in 'binman -t testSections', for example) + name to execute (as in 'binman test testSections', for example) toolpath: List of paths to use for tools """ import cbfs_util_test @@ -98,7 +99,7 @@ def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath): setup_test_args = getattr(module, 'setup_test_args') setup_test_args(preserve_indir=test_preserve_dirs, preserve_outdirs=test_preserve_dirs and test_name is not None, - toolpath=toolpath) + toolpath=toolpath, verbosity=verbosity) if test_name: try: suite.addTests(loader.loadTestsFromName(test_name, module)) @@ -158,37 +159,36 @@ def RunTestCoverage(): for item in glob_list if '_testing' not in item]) test_util.RunTestCoverage('tools/binman/binman.py', None, ['*test*', '*binman.py', 'tools/patman/*', 'tools/dtoc/*'], - options.build_dir, all_set) + args.build_dir, all_set) -def RunBinman(options, args): +def RunBinman(args): """Main entry point to binman once arguments are parsed Args: - options: Command-line options - args: Non-option arguments + args: Command line arguments Namespace object """ ret_code = 0 - if not options.debug: + if not args.debug: sys.tracebacklimit = 0 - if options.test: - ret_code = RunTests(options.debug, options.verbosity, options.processes, - options.test_preserve_dirs, args[1:], - options.toolpath) - - elif options.test_coverage: - RunTestCoverage() + if args.cmd == 'test': + if args.test_coverage: + RunTestCoverage() + else: + ret_code = RunTests(args.debug, args.verbosity, args.processes, + args.test_preserve_dirs, args.tests, + args.toolpath) - elif options.entry_docs: + elif args.cmd == 'entry-docs': control.WriteEntryDocs(GetEntryModules()) else: try: - ret_code = control.Binman(options, args) + ret_code = control.Binman(args) except Exception as e: print('binman: %s' % e) - if options.debug: + if args.debug: print() traceback.print_exc() ret_code = 1 @@ -196,6 +196,7 @@ def RunBinman(options, args): if __name__ == "__main__": - (options, args) = cmdline.ParseArgs(sys.argv) - ret_code = RunBinman(options, args) + args = cmdline.ParseArgs(sys.argv[1:]) + + ret_code = RunBinman(args) sys.exit(ret_code) -- cgit v1.2.3