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 <sjg@chromium.org>
This commit is contained in:
Simon Glass 2019-07-08 13:18:49 -06:00
parent ee0c9a739f
commit d5164a7970
4 changed files with 50 additions and 6 deletions

View file

@ -731,6 +731,14 @@ Use '-P 1' to disable this. It is automatically disabled when code coverage is
being used (-T) since they are incompatible.
Debugging tests
---------------
Sometimes when debugging tests it is useful to keep the input and output
directories so they can be examined later. Use -X or --test-preserve-dirs for
this.
Advanced Features / Technical docs
----------------------------------

View file

@ -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()

View file

@ -59,6 +59,10 @@ def ParseArgs(argv):
parser.add_option('-v', '--verbosity', default=1,
type='int', help='Control verbosity: 0=silent, 1=progress, 3=full, '
'4=debug')
parser.add_option('-X', '--test-preserve-dirs', action='store_true',
help='Preserve and display test-created input directories; also '
'preserve the output directory if a single test is run (pass test '
'name at the end of the command line')
parser.usage += """

View file

@ -6,6 +6,8 @@
#
# python -m unittest func_test.TestFunctional.testHelp
from __future__ import print_function
import hashlib
from optparse import OptionParser
import os
@ -134,10 +136,27 @@ class TestFunctional(unittest.TestCase):
@classmethod
def tearDownClass(self):
"""Remove the temporary input directory and its contents"""
if self._indir:
shutil.rmtree(self._indir)
if self.preserve_indir:
print('Preserving input dir: %s' % self._indir)
else:
if self._indir:
shutil.rmtree(self._indir)
self._indir = None
@classmethod
def setup_test_args(cls, preserve_indir=False, preserve_outdirs=False):
"""Accept arguments controlling test execution
Args:
preserve_indir: Preserve the shared input directory used by all
tests in this class.
preserve_outdir: Preserve the output directories used by tests. Each
test has its own, so this is normally only useful when running a
single test.
"""
cls.preserve_indir = preserve_indir
cls.preserve_outdirs = preserve_outdirs
def setUp(self):
# Enable this to turn on debugging output
# tout.Init(tout.DEBUG)
@ -145,7 +164,10 @@ class TestFunctional(unittest.TestCase):
def tearDown(self):
"""Remove the temporary output directory"""
tools._FinaliseForTest()
if self.preserve_outdirs:
print('Preserving output dir: %s' % tools.outdir)
else:
tools._FinaliseForTest()
@classmethod
def _ResetDtbs(self):