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