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 12import glob 13import multiprocessing 14import os 15import sys 16import traceback 17import unittest 18 19# Bring in the patman and dtoc libraries 20our_path = os.path.dirname(os.path.realpath(__file__)) 21for dirname in ['../patman', '../dtoc', '..', '../concurrencytest']: 22 sys.path.insert(0, os.path.join(our_path, dirname)) 23 24# Bring in the libfdt module 25sys.path.insert(0, 'scripts/dtc/pylibfdt') 26sys.path.insert(0, os.path.join(our_path, 27 '../../build-sandbox_spl/scripts/dtc/pylibfdt')) 28 29import cmdline 30import command 31use_concurrent = True 32try: 33 from concurrencytest import ConcurrentTestSuite, fork_for_tests 34except: 35 use_concurrent = False 36import control 37import test_util 38 39def RunTests(debug, processes, args): 40 """Run the functional tests and any embedded doctests 41 42 Args: 43 debug: True to enable debugging, which shows a full stack trace on error 44 args: List of positional args provided to binman. This can hold a test 45 name to execute (as in 'binman -t testSections', for example) 46 processes: Number of processes to use to run tests (None=same as #CPUs) 47 """ 48 import elf_test 49 import entry_test 50 import fdt_test 51 import ftest 52 import image_test 53 import test 54 import doctest 55 56 result = unittest.TestResult() 57 for module in []: 58 suite = doctest.DocTestSuite(module) 59 suite.run(result) 60 61 sys.argv = [sys.argv[0]] 62 if debug: 63 sys.argv.append('-D') 64 if debug: 65 sys.argv.append('-D') 66 67 # Run the entry tests first ,since these need to be the first to import the 68 # 'entry' module. 69 test_name = args and args[0] or None 70 suite = unittest.TestSuite() 71 loader = unittest.TestLoader() 72 for module in (entry_test.TestEntry, ftest.TestFunctional, fdt_test.TestFdt, 73 elf_test.TestElf, image_test.TestImage): 74 if test_name: 75 try: 76 suite.addTests(loader.loadTestsFromName(test_name, module)) 77 except AttributeError: 78 continue 79 else: 80 suite.addTests(loader.loadTestsFromTestCase(module)) 81 if use_concurrent and processes != 1: 82 concurrent_suite = ConcurrentTestSuite(suite, 83 fork_for_tests(processes or multiprocessing.cpu_count())) 84 concurrent_suite.run(result) 85 else: 86 suite.run(result) 87 88 print result 89 for test, err in result.errors: 90 print test.id(), err 91 for test, err in result.failures: 92 print err, result.failures 93 if result.errors or result.failures: 94 print 'binman tests FAILED' 95 return 1 96 return 0 97 98def GetEntryModules(include_testing=True): 99 """Get a set of entry class implementations 100 101 Returns: 102 Set of paths to entry class filenames 103 """ 104 glob_list = glob.glob(os.path.join(our_path, 'etype/*.py')) 105 return set([os.path.splitext(os.path.basename(item))[0] 106 for item in glob_list 107 if include_testing or '_testing' not in item]) 108 109def RunTestCoverage(): 110 """Run the tests and check that we get 100% coverage""" 111 glob_list = GetEntryModules(False) 112 all_set = set([os.path.splitext(os.path.basename(item))[0] 113 for item in glob_list if '_testing' not in item]) 114 test_util.RunTestCoverage('tools/binman/binman.py', None, 115 ['*test*', '*binman.py', 'tools/patman/*', 'tools/dtoc/*'], 116 options.build_dir, all_set) 117 118def RunBinman(options, args): 119 """Main entry point to binman once arguments are parsed 120 121 Args: 122 options: Command-line options 123 args: Non-option arguments 124 """ 125 ret_code = 0 126 127 # For testing: This enables full exception traces. 128 #options.debug = True 129 130 if not options.debug: 131 sys.tracebacklimit = 0 132 133 if options.test: 134 ret_code = RunTests(options.debug, options.processes, args[1:]) 135 136 elif options.test_coverage: 137 RunTestCoverage() 138 139 elif options.entry_docs: 140 control.WriteEntryDocs(GetEntryModules()) 141 142 else: 143 try: 144 ret_code = control.Binman(options, args) 145 except Exception as e: 146 print 'binman: %s' % e 147 if options.debug: 148 print 149 traceback.print_exc() 150 ret_code = 1 151 return ret_code 152 153 154if __name__ == "__main__": 155 (options, args) = cmdline.ParseArgs(sys.argv) 156 ret_code = RunBinman(options, args) 157 sys.exit(ret_code) 158