]> git.sur5r.net Git - u-boot/blob - tools/binman/binman.py
binman: Tidy up execution of tests
[u-boot] / tools / binman / binman.py
1 #!/usr/bin/env python2
2 # SPDX-License-Identifier: GPL-2.0+
3
4 # Copyright (c) 2016 Google, Inc
5 # Written by Simon Glass <sjg@chromium.org>
6 #
7 # Creates binary images from input files controlled by a description
8 #
9
10 """See README for more information"""
11
12 import glob
13 import os
14 import sys
15 import traceback
16 import unittest
17
18 # Bring in the patman and dtoc libraries
19 our_path = os.path.dirname(os.path.realpath(__file__))
20 for dirname in ['../patman', '../dtoc', '..']:
21     sys.path.insert(0, os.path.join(our_path, dirname))
22
23 # Bring in the libfdt module
24 sys.path.insert(0, 'scripts/dtc/pylibfdt')
25
26 import cmdline
27 import command
28 import control
29
30 def RunTests(debug, args):
31     """Run the functional tests and any embedded doctests
32
33     Args:
34         debug: True to enable debugging, which shows a full stack trace on error
35         args: List of positional args provided to binman. This can hold a test
36             name to execute (as in 'binman -t testSections', for example)
37     """
38     import elf_test
39     import entry_test
40     import fdt_test
41     import ftest
42     import image_test
43     import test
44     import doctest
45
46     result = unittest.TestResult()
47     for module in []:
48         suite = doctest.DocTestSuite(module)
49         suite.run(result)
50
51     sys.argv = [sys.argv[0]]
52     if debug:
53         sys.argv.append('-D')
54
55     # Run the entry tests first ,since these need to be the first to import the
56     # 'entry' module.
57     test_name = args and args[0] or None
58     for module in (entry_test.TestEntry, ftest.TestFunctional, fdt_test.TestFdt,
59                    elf_test.TestElf, image_test.TestImage):
60         if test_name:
61             try:
62                 suite = unittest.TestLoader().loadTestsFromName(test_name, module)
63             except AttributeError:
64                 continue
65         else:
66             suite = unittest.TestLoader().loadTestsFromTestCase(module)
67         suite.run(result)
68
69     print result
70     for test, err in result.errors:
71         print test.id(), err
72     for test, err in result.failures:
73         print err, result.failures
74     if result.errors or result.failures:
75       print 'binman tests FAILED'
76       return 1
77     return 0
78
79 def RunTestCoverage():
80     """Run the tests and check that we get 100% coverage"""
81     # This uses the build output from sandbox_spl to get _libfdt.so
82     cmd = ('PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools python-coverage run '
83             '--include "tools/binman/*.py" --omit "*test*,*binman.py" '
84             'tools/binman/binman.py -t' % options.build_dir)
85     os.system(cmd)
86     stdout = command.Output('python-coverage', 'report')
87     lines = stdout.splitlines()
88
89     test_set= set([os.path.basename(line.split()[0])
90                      for line in lines if '/etype/' in line])
91     glob_list = glob.glob(os.path.join(our_path, 'etype/*.py'))
92     all_set = set([os.path.splitext(os.path.basename(item))[0]
93                    for item in glob_list if '_testing' not in item])
94     missing_list = all_set
95     missing_list.difference_update(test_set)
96     coverage = lines[-1].split(' ')[-1]
97     ok = True
98     if missing_list:
99         print 'Missing tests for %s' % (', '.join(missing_list))
100         print stdout
101         ok = False
102     if coverage != '100%':
103         print stdout
104         print "Type 'coverage html' to get a report in htmlcov/index.html"
105         print 'Coverage error: %s, but should be 100%%' % coverage
106         ok = False
107     if not ok:
108       raise ValueError('Test coverage failure')
109
110 def RunBinman(options, args):
111     """Main entry point to binman once arguments are parsed
112
113     Args:
114         options: Command-line options
115         args: Non-option arguments
116     """
117     ret_code = 0
118
119     # For testing: This enables full exception traces.
120     #options.debug = True
121
122     if not options.debug:
123         sys.tracebacklimit = 0
124
125     if options.test:
126         ret_code = RunTests(options.debug, args[1:])
127
128     elif options.test_coverage:
129         RunTestCoverage()
130
131     elif options.full_help:
132         pager = os.getenv('PAGER')
133         if not pager:
134             pager = 'more'
135         fname = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])),
136                             'README')
137         command.Run(pager, fname)
138
139     else:
140         try:
141             ret_code = control.Binman(options, args)
142         except Exception as e:
143             print 'binman: %s' % e
144             if options.debug:
145                 print
146                 traceback.print_exc()
147             ret_code = 1
148     return ret_code
149
150
151 if __name__ == "__main__":
152     (options, args) = cmdline.ParseArgs(sys.argv)
153     ret_code = RunBinman(options, args)
154     sys.exit(ret_code)