Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
test.py
00001 #! /usr/bin/env python2 00002 """ 00003 mbed SDK 00004 Copyright (c) 2011-2013 ARM Limited 00005 00006 Licensed under the Apache License, Version 2.0 (the "License"); 00007 you may not use this file except in compliance with the License. 00008 You may obtain a copy of the License at 00009 00010 http://www.apache.org/licenses/LICENSE-2.0 00011 00012 Unless required by applicable law or agreed to in writing, software 00013 distributed under the License is distributed on an "AS IS" BASIS, 00014 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 See the License for the specific language governing permissions and 00016 limitations under the License. 00017 00018 00019 TEST BUILD 00020 """ 00021 from __future__ import print_function, division, absolute_import 00022 import sys 00023 import os 00024 import fnmatch 00025 00026 ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) 00027 sys.path.insert(0, ROOT) 00028 00029 from tools.config import ConfigException, Config 00030 from tools.test_configs import get_default_config 00031 from tools.config import ConfigException 00032 from tools.test_api import find_tests, get_test_config, print_tests, build_tests, test_spec_from_test_builds 00033 import tools.test_configs as TestConfig 00034 from tools.options import get_default_options_parser, extract_profile, extract_mcus 00035 from tools.build_api import build_project, build_library 00036 from tools.build_api import print_build_memory_usage 00037 from tools.build_api import merge_build_data 00038 from tools.targets import TARGET_MAP 00039 from tools.notifier.term import TerminalNotifier 00040 from tools.utils import mkdir, ToolException, NotSupportedException, args_error, write_json_to_file 00041 from tools.test_exporters import ReportExporter, ResultExporterType 00042 from tools.utils import argparse_filestring_type, argparse_lowercase_type, argparse_many 00043 from tools.utils import argparse_dir_not_parent 00044 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS, TOOLCHAIN_CLASSES 00045 from tools.settings import CLI_COLOR_MAP 00046 00047 if __name__ == '__main__': 00048 try: 00049 # Parse Options 00050 parser = get_default_options_parser(add_app_config=True) 00051 00052 parser.add_argument("-D", 00053 action="append", 00054 dest="macros", 00055 help="Add a macro definition") 00056 00057 parser.add_argument("-j", "--jobs", 00058 type=int, 00059 dest="jobs", 00060 default=0, 00061 help="Number of concurrent jobs. Default: 0/auto (based on host machine's number of CPUs)") 00062 00063 parser.add_argument("--source", dest="source_dir", 00064 type=argparse_filestring_type, 00065 default=None, help="The source (input) directory (for sources other than tests). Defaults to current directory.", action="append") 00066 00067 parser.add_argument("--build", dest="build_dir", type=argparse_dir_not_parent(ROOT), 00068 default=None, help="The build (output) directory") 00069 00070 parser.add_argument("-l", "--list", action="store_true", dest="list", 00071 default=False, help="List (recursively) available tests in order and exit") 00072 00073 parser.add_argument("-p", "--paths", dest="paths", 00074 type=argparse_many(argparse_filestring_type), 00075 default=None, help="Limit the tests to those within the specified comma separated list of paths") 00076 00077 format_choices = ["list", "json"] 00078 format_default_choice = "list" 00079 format_help = "Change the format in which tests are listed. Choices include: %s. Default: %s" % (", ".join(format_choices), format_default_choice) 00080 parser.add_argument("-f", "--format", dest="format", 00081 type=argparse_lowercase_type(format_choices, "format"), 00082 default=format_default_choice, help=format_help) 00083 00084 parser.add_argument("--continue-on-build-fail", action="store_true", dest="continue_on_build_fail", 00085 default=None, help="Continue trying to build all tests if a build failure occurs") 00086 00087 #TODO validate the names instead of just passing through str 00088 parser.add_argument("-n", "--names", dest="names", type=argparse_many(str), 00089 default=None, help="Limit the tests to a comma separated list of names") 00090 00091 parser.add_argument("--test-config", dest="test_config", type=str, 00092 default=None, help="Test config for a module") 00093 00094 parser.add_argument("--test-spec", dest="test_spec", 00095 default=None, help="Destination path for a test spec file that can be used by the Greentea automated test tool") 00096 00097 parser.add_argument("--build-report-junit", dest="build_report_junit", 00098 default=None, help="Destination path for a build report in the JUnit xml format") 00099 parser.add_argument("--build-data", 00100 dest="build_data", 00101 default=None, 00102 help="Dump build_data to this file") 00103 00104 parser.add_argument("-v", "--verbose", 00105 action="store_true", 00106 dest="verbose", 00107 default=False, 00108 help="Verbose diagnostic output") 00109 00110 parser.add_argument("--stats-depth", 00111 type=int, 00112 dest="stats_depth", 00113 default=2, 00114 help="Depth level for static memory report") 00115 parser.add_argument("--ignore", dest="ignore", type=argparse_many(str), 00116 default=None, help="Comma separated list of patterns to add to mbedignore (eg. ./main.cpp)") 00117 parser.add_argument("--icetea", 00118 action="store_true", 00119 dest="icetea", 00120 default=False, 00121 help="Only icetea tests") 00122 00123 parser.add_argument("--greentea", 00124 action="store_true", 00125 dest="greentea", 00126 default=False, 00127 help="Only greentea tests") 00128 00129 options = parser.parse_args() 00130 00131 # Filter tests by path if specified 00132 if options.paths: 00133 all_paths = options.paths 00134 else: 00135 all_paths = ["."] 00136 00137 all_tests = {} 00138 tests = {} 00139 00140 # As default both test tools are enabled 00141 if not (options.greentea or options.icetea): 00142 options.greentea = True 00143 options.icetea = True 00144 00145 # Target 00146 if options.mcu is None: 00147 args_error(parser, "argument -m/--mcu is required") 00148 mcu = extract_mcus(parser, options)[0] 00149 00150 # Toolchain 00151 if options.tool is None: 00152 args_error(parser, "argument -t/--tool is required") 00153 toolchain = options.tool[0] 00154 00155 if not TOOLCHAIN_CLASSES[toolchain].check_executable(): 00156 search_path = TOOLCHAIN_PATHS[toolchain] or "No path set" 00157 args_error(parser, "Could not find executable for %s.\n" 00158 "Currently set search path: %s" 00159 % (toolchain, search_path)) 00160 00161 # Assign config file. Precedence: test_config>app_config 00162 # TODO: merge configs if both given 00163 if options.test_config: 00164 config = get_test_config(options.test_config, mcu) 00165 if not config: 00166 args_error(parser, "argument --test-config contains invalid path or identifier") 00167 elif options.app_config: 00168 config = options.app_config 00169 else: 00170 config = Config.find_app_config(options.source_dir) 00171 00172 if not config: 00173 config = get_default_config(options.source_dir or ['.'], mcu) 00174 00175 00176 # Find all tests in the relevant paths 00177 for path in all_paths: 00178 all_tests.update(find_tests( 00179 base_dir=path, 00180 target_name=mcu, 00181 toolchain_name=toolchain, 00182 icetea=options.icetea, 00183 greentea=options.greentea, 00184 app_config=config)) 00185 00186 # Filter tests by name if specified 00187 if options.names: 00188 all_names = options.names 00189 all_names = [x.lower() for x in all_names] 00190 00191 for name in all_names: 00192 if any(fnmatch.fnmatch(testname, name) for testname in all_tests): 00193 for testname, test in all_tests.items(): 00194 if fnmatch.fnmatch(testname, name): 00195 tests[testname] = test 00196 else: 00197 print("[Warning] Test with name '%s' was not found in the " 00198 "available tests" % (name)) 00199 else: 00200 tests = all_tests 00201 00202 00203 if options.list: 00204 # Print available tests in order and exit 00205 print_tests(tests, options.format) 00206 sys.exit(0) 00207 else: 00208 # Build all tests 00209 if not options.build_dir: 00210 args_error(parser, "argument --build is required") 00211 00212 base_source_paths = options.source_dir 00213 00214 # Default base source path is the current directory 00215 if not base_source_paths: 00216 base_source_paths = ['.'] 00217 00218 build_report = {} 00219 build_properties = {} 00220 00221 library_build_success = False 00222 profile = extract_profile(parser, options, toolchain) 00223 try: 00224 # Build sources 00225 notify = TerminalNotifier(options.verbose) 00226 build_library(base_source_paths, options.build_dir, mcu, 00227 toolchain, jobs=options.jobs, 00228 clean=options.clean, report=build_report, 00229 properties=build_properties, name="mbed-build", 00230 macros=options.macros, 00231 notify=notify, archive=False, 00232 app_config=config, 00233 build_profile=profile, 00234 ignore=options.ignore) 00235 00236 library_build_success = True 00237 except ToolException as e: 00238 # ToolException output is handled by the build log 00239 pass 00240 except NotSupportedException as e: 00241 # NotSupportedException is handled by the build log 00242 pass 00243 except Exception as e: 00244 if options.verbose: 00245 import traceback 00246 traceback.print_exc() 00247 # Some other exception occurred, print the error message 00248 print(e) 00249 00250 if not library_build_success: 00251 print("Failed to build library") 00252 else: 00253 # Build all the tests 00254 notify = TerminalNotifier(options.verbose) 00255 test_build_success, test_build = build_tests( 00256 tests, 00257 [os.path.relpath(options.build_dir)], 00258 options.build_dir, 00259 mcu, 00260 toolchain, 00261 clean=options.clean, 00262 report=build_report, 00263 properties=build_properties, 00264 macros=options.macros, 00265 notify=notify, 00266 jobs=options.jobs, 00267 continue_on_build_fail=options.continue_on_build_fail, 00268 app_config=config, 00269 build_profile=profile, 00270 stats_depth=options.stats_depth, 00271 ignore=options.ignore) 00272 00273 # If a path to a test spec is provided, write it to a file 00274 if options.test_spec: 00275 write_json_to_file(test_spec_from_test_builds(test_build), options.test_spec) 00276 00277 # If a path to a JUnit build report spec is provided, write it to a file 00278 if options.build_report_junit: 00279 report_exporter = ReportExporter(ResultExporterType.JUNIT, package="build") 00280 report_exporter.report_to_file(build_report, options.build_report_junit, test_suite_properties=build_properties) 00281 00282 # Print memory map summary on screen 00283 if build_report: 00284 print 00285 print(print_build_memory_usage(build_report)) 00286 00287 print_report_exporter = ReportExporter(ResultExporterType.PRINT, package="build") 00288 status = print_report_exporter.report(build_report) 00289 if options.build_data: 00290 merge_build_data(options.build_data, build_report, "test") 00291 00292 if status: 00293 sys.exit(0) 00294 else: 00295 sys.exit(1) 00296 00297 except KeyboardInterrupt as e: 00298 print("\n[CTRL+c] exit") 00299 except ConfigException as e: 00300 # Catching ConfigException here to prevent a traceback 00301 print("[ERROR] %s" % str(e)) 00302 except Exception as e: 00303 import traceback 00304 traceback.print_exc(file=sys.stdout) 00305 print("[ERROR] %s" % str(e)) 00306 sys.exit(1) 00307
Generated on Tue Jul 12 2022 17:12:47 by
