Backup 1

Committer:
borlanic
Date:
Tue Apr 24 11:45:18 2018 +0000
Revision:
0:02dd72d1d465
BaBoRo_test2 - backup 1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
borlanic 0:02dd72d1d465 1 #! /usr/bin/env python2
borlanic 0:02dd72d1d465 2 """
borlanic 0:02dd72d1d465 3 mbed SDK
borlanic 0:02dd72d1d465 4 Copyright (c) 2011-2013 ARM Limited
borlanic 0:02dd72d1d465 5
borlanic 0:02dd72d1d465 6 Licensed under the Apache License, Version 2.0 (the "License");
borlanic 0:02dd72d1d465 7 you may not use this file except in compliance with the License.
borlanic 0:02dd72d1d465 8 You may obtain a copy of the License at
borlanic 0:02dd72d1d465 9
borlanic 0:02dd72d1d465 10 http://www.apache.org/licenses/LICENSE-2.0
borlanic 0:02dd72d1d465 11
borlanic 0:02dd72d1d465 12 Unless required by applicable law or agreed to in writing, software
borlanic 0:02dd72d1d465 13 distributed under the License is distributed on an "AS IS" BASIS,
borlanic 0:02dd72d1d465 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
borlanic 0:02dd72d1d465 15 See the License for the specific language governing permissions and
borlanic 0:02dd72d1d465 16 limitations under the License.
borlanic 0:02dd72d1d465 17
borlanic 0:02dd72d1d465 18
borlanic 0:02dd72d1d465 19 TEST BUILD & RUN
borlanic 0:02dd72d1d465 20 """
borlanic 0:02dd72d1d465 21 from __future__ import print_function, division, absolute_import
borlanic 0:02dd72d1d465 22 import sys
borlanic 0:02dd72d1d465 23 import os
borlanic 0:02dd72d1d465 24 import json
borlanic 0:02dd72d1d465 25 import fnmatch
borlanic 0:02dd72d1d465 26
borlanic 0:02dd72d1d465 27 ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
borlanic 0:02dd72d1d465 28 sys.path.insert(0, ROOT)
borlanic 0:02dd72d1d465 29
borlanic 0:02dd72d1d465 30 from tools.config import ConfigException
borlanic 0:02dd72d1d465 31 from tools.test_api import test_path_to_name, find_tests, get_test_config, print_tests, build_tests, test_spec_from_test_builds
borlanic 0:02dd72d1d465 32 import tools.test_configs as TestConfig
borlanic 0:02dd72d1d465 33 from tools.options import get_default_options_parser, extract_profile, extract_mcus
borlanic 0:02dd72d1d465 34 from tools.build_api import build_project, build_library
borlanic 0:02dd72d1d465 35 from tools.build_api import print_build_memory_usage
borlanic 0:02dd72d1d465 36 from tools.build_api import merge_build_data
borlanic 0:02dd72d1d465 37 from tools.targets import TARGET_MAP
borlanic 0:02dd72d1d465 38 from tools.utils import mkdir, ToolException, NotSupportedException, args_error
borlanic 0:02dd72d1d465 39 from tools.test_exporters import ReportExporter, ResultExporterType
borlanic 0:02dd72d1d465 40 from tools.utils import argparse_filestring_type, argparse_lowercase_type, argparse_many
borlanic 0:02dd72d1d465 41 from tools.utils import argparse_dir_not_parent
borlanic 0:02dd72d1d465 42 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS, TOOLCHAIN_CLASSES
borlanic 0:02dd72d1d465 43 from tools.settings import CLI_COLOR_MAP
borlanic 0:02dd72d1d465 44
borlanic 0:02dd72d1d465 45 if __name__ == '__main__':
borlanic 0:02dd72d1d465 46 try:
borlanic 0:02dd72d1d465 47 # Parse Options
borlanic 0:02dd72d1d465 48 parser = get_default_options_parser(add_app_config=True)
borlanic 0:02dd72d1d465 49
borlanic 0:02dd72d1d465 50 parser.add_argument("-D",
borlanic 0:02dd72d1d465 51 action="append",
borlanic 0:02dd72d1d465 52 dest="macros",
borlanic 0:02dd72d1d465 53 help="Add a macro definition")
borlanic 0:02dd72d1d465 54
borlanic 0:02dd72d1d465 55 parser.add_argument("-j", "--jobs",
borlanic 0:02dd72d1d465 56 type=int,
borlanic 0:02dd72d1d465 57 dest="jobs",
borlanic 0:02dd72d1d465 58 default=0,
borlanic 0:02dd72d1d465 59 help="Number of concurrent jobs. Default: 0/auto (based on host machine's number of CPUs)")
borlanic 0:02dd72d1d465 60
borlanic 0:02dd72d1d465 61 parser.add_argument("--source", dest="source_dir",
borlanic 0:02dd72d1d465 62 type=argparse_filestring_type,
borlanic 0:02dd72d1d465 63 default=None, help="The source (input) directory (for sources other than tests). Defaults to current directory.", action="append")
borlanic 0:02dd72d1d465 64
borlanic 0:02dd72d1d465 65 parser.add_argument("--build", dest="build_dir", type=argparse_dir_not_parent(ROOT),
borlanic 0:02dd72d1d465 66 default=None, help="The build (output) directory")
borlanic 0:02dd72d1d465 67
borlanic 0:02dd72d1d465 68 parser.add_argument("-l", "--list", action="store_true", dest="list",
borlanic 0:02dd72d1d465 69 default=False, help="List (recursively) available tests in order and exit")
borlanic 0:02dd72d1d465 70
borlanic 0:02dd72d1d465 71 parser.add_argument("-p", "--paths", dest="paths",
borlanic 0:02dd72d1d465 72 type=argparse_many(argparse_filestring_type),
borlanic 0:02dd72d1d465 73 default=None, help="Limit the tests to those within the specified comma separated list of paths")
borlanic 0:02dd72d1d465 74
borlanic 0:02dd72d1d465 75 format_choices = ["list", "json"]
borlanic 0:02dd72d1d465 76 format_default_choice = "list"
borlanic 0:02dd72d1d465 77 format_help = "Change the format in which tests are listed. Choices include: %s. Default: %s" % (", ".join(format_choices), format_default_choice)
borlanic 0:02dd72d1d465 78 parser.add_argument("-f", "--format", dest="format",
borlanic 0:02dd72d1d465 79 type=argparse_lowercase_type(format_choices, "format"),
borlanic 0:02dd72d1d465 80 default=format_default_choice, help=format_help)
borlanic 0:02dd72d1d465 81
borlanic 0:02dd72d1d465 82 parser.add_argument("--continue-on-build-fail", action="store_true", dest="continue_on_build_fail",
borlanic 0:02dd72d1d465 83 default=None, help="Continue trying to build all tests if a build failure occurs")
borlanic 0:02dd72d1d465 84
borlanic 0:02dd72d1d465 85 #TODO validate the names instead of just passing through str
borlanic 0:02dd72d1d465 86 parser.add_argument("-n", "--names", dest="names", type=argparse_many(str),
borlanic 0:02dd72d1d465 87 default=None, help="Limit the tests to a comma separated list of names")
borlanic 0:02dd72d1d465 88
borlanic 0:02dd72d1d465 89 parser.add_argument("--test-config", dest="test_config", type=str,
borlanic 0:02dd72d1d465 90 default=None, help="Test config for a module")
borlanic 0:02dd72d1d465 91
borlanic 0:02dd72d1d465 92 parser.add_argument("--test-spec", dest="test_spec",
borlanic 0:02dd72d1d465 93 default=None, help="Destination path for a test spec file that can be used by the Greentea automated test tool")
borlanic 0:02dd72d1d465 94
borlanic 0:02dd72d1d465 95 parser.add_argument("--build-report-junit", dest="build_report_junit",
borlanic 0:02dd72d1d465 96 default=None, help="Destination path for a build report in the JUnit xml format")
borlanic 0:02dd72d1d465 97 parser.add_argument("--build-data",
borlanic 0:02dd72d1d465 98 dest="build_data",
borlanic 0:02dd72d1d465 99 default=None,
borlanic 0:02dd72d1d465 100 help="Dump build_data to this file")
borlanic 0:02dd72d1d465 101
borlanic 0:02dd72d1d465 102 parser.add_argument("-v", "--verbose",
borlanic 0:02dd72d1d465 103 action="store_true",
borlanic 0:02dd72d1d465 104 dest="verbose",
borlanic 0:02dd72d1d465 105 default=False,
borlanic 0:02dd72d1d465 106 help="Verbose diagnostic output")
borlanic 0:02dd72d1d465 107
borlanic 0:02dd72d1d465 108 parser.add_argument("--stats-depth",
borlanic 0:02dd72d1d465 109 type=int,
borlanic 0:02dd72d1d465 110 dest="stats_depth",
borlanic 0:02dd72d1d465 111 default=2,
borlanic 0:02dd72d1d465 112 help="Depth level for static memory report")
borlanic 0:02dd72d1d465 113
borlanic 0:02dd72d1d465 114 options = parser.parse_args()
borlanic 0:02dd72d1d465 115
borlanic 0:02dd72d1d465 116 # Filter tests by path if specified
borlanic 0:02dd72d1d465 117 if options.paths:
borlanic 0:02dd72d1d465 118 all_paths = options.paths
borlanic 0:02dd72d1d465 119 else:
borlanic 0:02dd72d1d465 120 all_paths = ["."]
borlanic 0:02dd72d1d465 121
borlanic 0:02dd72d1d465 122 all_tests = {}
borlanic 0:02dd72d1d465 123 tests = {}
borlanic 0:02dd72d1d465 124
borlanic 0:02dd72d1d465 125 # Target
borlanic 0:02dd72d1d465 126 if options.mcu is None :
borlanic 0:02dd72d1d465 127 args_error(parser, "argument -m/--mcu is required")
borlanic 0:02dd72d1d465 128 mcu = extract_mcus(parser, options)[0]
borlanic 0:02dd72d1d465 129
borlanic 0:02dd72d1d465 130 # Toolchain
borlanic 0:02dd72d1d465 131 if options.tool is None:
borlanic 0:02dd72d1d465 132 args_error(parser, "argument -t/--tool is required")
borlanic 0:02dd72d1d465 133 toolchain = options.tool[0]
borlanic 0:02dd72d1d465 134
borlanic 0:02dd72d1d465 135 if not TOOLCHAIN_CLASSES[toolchain].check_executable():
borlanic 0:02dd72d1d465 136 search_path = TOOLCHAIN_PATHS[toolchain] or "No path set"
borlanic 0:02dd72d1d465 137 args_error(parser, "Could not find executable for %s.\n"
borlanic 0:02dd72d1d465 138 "Currently set search path: %s"
borlanic 0:02dd72d1d465 139 % (toolchain, search_path))
borlanic 0:02dd72d1d465 140
borlanic 0:02dd72d1d465 141 # Assign config file. Precedence: test_config>app_config
borlanic 0:02dd72d1d465 142 # TODO: merge configs if both given
borlanic 0:02dd72d1d465 143 if options.test_config:
borlanic 0:02dd72d1d465 144 config = get_test_config(options.test_config, mcu)
borlanic 0:02dd72d1d465 145 if not config:
borlanic 0:02dd72d1d465 146 args_error(parser, "argument --test-config contains invalid path or identifier")
borlanic 0:02dd72d1d465 147 elif not options.app_config:
borlanic 0:02dd72d1d465 148 config = TestConfig.get_default_config(options.source_dir or ['.'], mcu)
borlanic 0:02dd72d1d465 149 else:
borlanic 0:02dd72d1d465 150 config = options.app_config
borlanic 0:02dd72d1d465 151
borlanic 0:02dd72d1d465 152 # Find all tests in the relevant paths
borlanic 0:02dd72d1d465 153 for path in all_paths:
borlanic 0:02dd72d1d465 154 all_tests.update(find_tests(path, mcu, toolchain,
borlanic 0:02dd72d1d465 155 app_config=config))
borlanic 0:02dd72d1d465 156
borlanic 0:02dd72d1d465 157 # Filter tests by name if specified
borlanic 0:02dd72d1d465 158 if options.names:
borlanic 0:02dd72d1d465 159 all_names = options.names
borlanic 0:02dd72d1d465 160 all_names = [x.lower() for x in all_names]
borlanic 0:02dd72d1d465 161
borlanic 0:02dd72d1d465 162 for name in all_names:
borlanic 0:02dd72d1d465 163 if any(fnmatch.fnmatch(testname, name) for testname in all_tests):
borlanic 0:02dd72d1d465 164 for testname, test in all_tests.items():
borlanic 0:02dd72d1d465 165 if fnmatch.fnmatch(testname, name):
borlanic 0:02dd72d1d465 166 tests[testname] = test
borlanic 0:02dd72d1d465 167 else:
borlanic 0:02dd72d1d465 168 print("[Warning] Test with name '%s' was not found in the "
borlanic 0:02dd72d1d465 169 "available tests" % (name))
borlanic 0:02dd72d1d465 170 else:
borlanic 0:02dd72d1d465 171 tests = all_tests
borlanic 0:02dd72d1d465 172
borlanic 0:02dd72d1d465 173 if options.color:
borlanic 0:02dd72d1d465 174 # This import happens late to prevent initializing colorization when we don't need it
borlanic 0:02dd72d1d465 175 import colorize
borlanic 0:02dd72d1d465 176 if options.verbose:
borlanic 0:02dd72d1d465 177 notify = mbedToolchain.print_notify_verbose
borlanic 0:02dd72d1d465 178 else:
borlanic 0:02dd72d1d465 179 notify = mbedToolchain.print_notify
borlanic 0:02dd72d1d465 180 notify = colorize.print_in_color_notifier(CLI_COLOR_MAP, notify)
borlanic 0:02dd72d1d465 181 else:
borlanic 0:02dd72d1d465 182 notify = None
borlanic 0:02dd72d1d465 183
borlanic 0:02dd72d1d465 184 if options.list:
borlanic 0:02dd72d1d465 185 # Print available tests in order and exit
borlanic 0:02dd72d1d465 186 print_tests(tests, options.format)
borlanic 0:02dd72d1d465 187 sys.exit(0)
borlanic 0:02dd72d1d465 188 else:
borlanic 0:02dd72d1d465 189 # Build all tests
borlanic 0:02dd72d1d465 190 if not options.build_dir:
borlanic 0:02dd72d1d465 191 args_error(parser, "argument --build is required")
borlanic 0:02dd72d1d465 192
borlanic 0:02dd72d1d465 193 base_source_paths = options.source_dir
borlanic 0:02dd72d1d465 194
borlanic 0:02dd72d1d465 195 # Default base source path is the current directory
borlanic 0:02dd72d1d465 196 if not base_source_paths:
borlanic 0:02dd72d1d465 197 base_source_paths = ['.']
borlanic 0:02dd72d1d465 198
borlanic 0:02dd72d1d465 199 build_report = {}
borlanic 0:02dd72d1d465 200 build_properties = {}
borlanic 0:02dd72d1d465 201
borlanic 0:02dd72d1d465 202 library_build_success = False
borlanic 0:02dd72d1d465 203 profile = extract_profile(parser, options, toolchain)
borlanic 0:02dd72d1d465 204 try:
borlanic 0:02dd72d1d465 205 # Build sources
borlanic 0:02dd72d1d465 206 build_library(base_source_paths, options.build_dir, mcu,
borlanic 0:02dd72d1d465 207 toolchain, jobs=options.jobs,
borlanic 0:02dd72d1d465 208 clean=options.clean, report=build_report,
borlanic 0:02dd72d1d465 209 properties=build_properties, name="mbed-build",
borlanic 0:02dd72d1d465 210 macros=options.macros, verbose=options.verbose,
borlanic 0:02dd72d1d465 211 notify=notify, archive=False,
borlanic 0:02dd72d1d465 212 app_config=config,
borlanic 0:02dd72d1d465 213 build_profile=profile)
borlanic 0:02dd72d1d465 214
borlanic 0:02dd72d1d465 215 library_build_success = True
borlanic 0:02dd72d1d465 216 except ToolException as e:
borlanic 0:02dd72d1d465 217 # ToolException output is handled by the build log
borlanic 0:02dd72d1d465 218 pass
borlanic 0:02dd72d1d465 219 except NotSupportedException as e:
borlanic 0:02dd72d1d465 220 # NotSupportedException is handled by the build log
borlanic 0:02dd72d1d465 221 pass
borlanic 0:02dd72d1d465 222 except Exception as e:
borlanic 0:02dd72d1d465 223 # Some other exception occurred, print the error message
borlanic 0:02dd72d1d465 224 print(e)
borlanic 0:02dd72d1d465 225
borlanic 0:02dd72d1d465 226 if not library_build_success:
borlanic 0:02dd72d1d465 227 print("Failed to build library")
borlanic 0:02dd72d1d465 228 else:
borlanic 0:02dd72d1d465 229 # Build all the tests
borlanic 0:02dd72d1d465 230
borlanic 0:02dd72d1d465 231 test_build_success, test_build = build_tests(tests, [options.build_dir], options.build_dir, mcu, toolchain,
borlanic 0:02dd72d1d465 232 clean=options.clean,
borlanic 0:02dd72d1d465 233 report=build_report,
borlanic 0:02dd72d1d465 234 properties=build_properties,
borlanic 0:02dd72d1d465 235 macros=options.macros,
borlanic 0:02dd72d1d465 236 verbose=options.verbose,
borlanic 0:02dd72d1d465 237 notify=notify,
borlanic 0:02dd72d1d465 238 jobs=options.jobs,
borlanic 0:02dd72d1d465 239 continue_on_build_fail=options.continue_on_build_fail,
borlanic 0:02dd72d1d465 240 app_config=config,
borlanic 0:02dd72d1d465 241 build_profile=profile,
borlanic 0:02dd72d1d465 242 stats_depth=options.stats_depth)
borlanic 0:02dd72d1d465 243
borlanic 0:02dd72d1d465 244 # If a path to a test spec is provided, write it to a file
borlanic 0:02dd72d1d465 245 if options.test_spec:
borlanic 0:02dd72d1d465 246 test_spec_data = test_spec_from_test_builds(test_build)
borlanic 0:02dd72d1d465 247
borlanic 0:02dd72d1d465 248 # Create the target dir for the test spec if necessary
borlanic 0:02dd72d1d465 249 # mkdir will not create the dir if it already exists
borlanic 0:02dd72d1d465 250 test_spec_dir = os.path.dirname(options.test_spec)
borlanic 0:02dd72d1d465 251 if test_spec_dir:
borlanic 0:02dd72d1d465 252 mkdir(test_spec_dir)
borlanic 0:02dd72d1d465 253
borlanic 0:02dd72d1d465 254 try:
borlanic 0:02dd72d1d465 255 with open(options.test_spec, 'w') as f:
borlanic 0:02dd72d1d465 256 f.write(json.dumps(test_spec_data, indent=2))
borlanic 0:02dd72d1d465 257 except IOError as e:
borlanic 0:02dd72d1d465 258 print("[ERROR] Error writing test spec to file")
borlanic 0:02dd72d1d465 259 print(e)
borlanic 0:02dd72d1d465 260
borlanic 0:02dd72d1d465 261 # If a path to a JUnit build report spec is provided, write it to a file
borlanic 0:02dd72d1d465 262 if options.build_report_junit:
borlanic 0:02dd72d1d465 263 report_exporter = ReportExporter(ResultExporterType.JUNIT, package="build")
borlanic 0:02dd72d1d465 264 report_exporter.report_to_file(build_report, options.build_report_junit, test_suite_properties=build_properties)
borlanic 0:02dd72d1d465 265
borlanic 0:02dd72d1d465 266 # Print memory map summary on screen
borlanic 0:02dd72d1d465 267 if build_report:
borlanic 0:02dd72d1d465 268 print
borlanic 0:02dd72d1d465 269 print(print_build_memory_usage(build_report))
borlanic 0:02dd72d1d465 270
borlanic 0:02dd72d1d465 271 print_report_exporter = ReportExporter(ResultExporterType.PRINT, package="build")
borlanic 0:02dd72d1d465 272 status = print_report_exporter.report(build_report)
borlanic 0:02dd72d1d465 273 if options.build_data:
borlanic 0:02dd72d1d465 274 merge_build_data(options.build_data, build_report, "test")
borlanic 0:02dd72d1d465 275
borlanic 0:02dd72d1d465 276 if status:
borlanic 0:02dd72d1d465 277 sys.exit(0)
borlanic 0:02dd72d1d465 278 else:
borlanic 0:02dd72d1d465 279 sys.exit(1)
borlanic 0:02dd72d1d465 280
borlanic 0:02dd72d1d465 281 except KeyboardInterrupt as e:
borlanic 0:02dd72d1d465 282 print("\n[CTRL+c] exit")
borlanic 0:02dd72d1d465 283 except ConfigException as e:
borlanic 0:02dd72d1d465 284 # Catching ConfigException here to prevent a traceback
borlanic 0:02dd72d1d465 285 print("[ERROR] %s" % str(e))
borlanic 0:02dd72d1d465 286 except Exception as e:
borlanic 0:02dd72d1d465 287 import traceback
borlanic 0:02dd72d1d465 288 traceback.print_exc(file=sys.stdout)
borlanic 0:02dd72d1d465 289 print("[ERROR] %s" % str(e))
borlanic 0:02dd72d1d465 290 sys.exit(1)