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