binman: Correct the search patch for pylibfdt
[platform/kernel/u-boot.git] / tools / binman / main.py
1 #!/usr/bin/env python3
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 from distutils.sysconfig import get_python_lib
13 import glob
14 import os
15 import site
16 import sys
17 import traceback
18 import unittest
19
20 # Bring in the patman and dtoc libraries (but don't override the first path
21 # in PYTHONPATH)
22 our_path = os.path.dirname(os.path.realpath(__file__))
23 sys.path.insert(2, os.path.join(our_path, '..'))
24
25 from patman import test_util
26
27 # Bring in the libfdt module
28 sys.path.insert(2, 'scripts/dtc/pylibfdt')
29 sys.path.insert(2, os.path.join(our_path, '../../scripts/dtc/pylibfdt'))
30 sys.path.insert(2, os.path.join(our_path,
31                 '../../build-sandbox_spl/scripts/dtc/pylibfdt'))
32
33 # When running under python-coverage on Ubuntu 16.04, the dist-packages
34 # directories are dropped from the python path. Add them in so that we can find
35 # the elffile module. We could use site.getsitepackages() here but unfortunately
36 # that is not available in a virtualenv.
37 sys.path.append(get_python_lib())
38
39 from binman import cmdline
40 from binman import control
41 from patman import test_util
42
43 def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath):
44     """Run the functional tests and any embedded doctests
45
46     Args:
47         debug: True to enable debugging, which shows a full stack trace on error
48         verbosity: Verbosity level to use
49         test_preserve_dirs: True to preserve the input directory used by tests
50             so that it can be examined afterwards (only useful for debugging
51             tests). If a single test is selected (in args[0]) it also preserves
52             the output directory for this test. Both directories are displayed
53             on the command line.
54         processes: Number of processes to use to run tests (None=same as #CPUs)
55         args: List of positional args provided to binman. This can hold a test
56             name to execute (as in 'binman test testSections', for example)
57         toolpath: List of paths to use for tools
58     """
59     from binman import cbfs_util_test
60     from binman import elf_test
61     from binman import entry_test
62     from binman import fdt_test
63     from binman import ftest
64     from binman import image_test
65     from binman import test
66     import doctest
67
68     result = unittest.TestResult()
69     test_name = args and args[0] or None
70
71     # Run the entry tests first ,since these need to be the first to import the
72     # 'entry' module.
73     test_util.RunTestSuites(
74         result, debug, verbosity, test_preserve_dirs, processes, test_name,
75         toolpath,
76         [entry_test.TestEntry, ftest.TestFunctional, fdt_test.TestFdt,
77          elf_test.TestElf, image_test.TestImage, cbfs_util_test.TestCbfs])
78
79     return test_util.ReportResult('binman', test_name, result)
80
81 def GetEntryModules(include_testing=True):
82     """Get a set of entry class implementations
83
84     Returns:
85         Set of paths to entry class filenames
86     """
87     glob_list = glob.glob(os.path.join(our_path, 'etype/*.py'))
88     return set([os.path.splitext(os.path.basename(item))[0]
89                 for item in glob_list
90                 if include_testing or '_testing' not in item])
91
92 def RunTestCoverage():
93     """Run the tests and check that we get 100% coverage"""
94     glob_list = GetEntryModules(False)
95     all_set = set([os.path.splitext(os.path.basename(item))[0]
96                    for item in glob_list if '_testing' not in item])
97     test_util.RunTestCoverage('tools/binman/binman', None,
98             ['*test*', '*main.py', 'tools/patman/*', 'tools/dtoc/*'],
99             args.build_dir, all_set)
100
101 def RunBinman(args):
102     """Main entry point to binman once arguments are parsed
103
104     Args:
105         args: Command line arguments Namespace object
106     """
107     ret_code = 0
108
109     if not args.debug:
110         sys.tracebacklimit = 0
111
112     if args.cmd == 'test':
113         if args.test_coverage:
114             RunTestCoverage()
115         else:
116             ret_code = RunTests(args.debug, args.verbosity, args.processes,
117                                 args.test_preserve_dirs, args.tests,
118                                 args.toolpath)
119
120     elif args.cmd == 'entry-docs':
121         control.WriteEntryDocs(GetEntryModules())
122
123     else:
124         try:
125             ret_code = control.Binman(args)
126         except Exception as e:
127             print('binman: %s' % e, file=sys.stderr)
128             if args.debug:
129                 print()
130                 traceback.print_exc()
131             ret_code = 1
132     return ret_code
133
134
135 if __name__ == "__main__":
136     args = cmdline.ParseArgs(sys.argv[1:])
137
138     ret_code = RunBinman(args)
139     sys.exit(ret_code)