Clone of official tools

Committer:
The Other Jimmy
Date:
Wed Feb 15 13:53:18 2017 -0600
Revision:
35:da9c89f8be7d
Parent:
31:8ea194f6145b
Update tools to mbed-os 5.3.5

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 25:aef6536015e3 1 #!/usr/bin/env python
screamer 25:aef6536015e3 2 """
screamer 25:aef6536015e3 3 mbed SDK
The Other Jimmy 31:8ea194f6145b 4 Copyright (c) 2011-2016 ARM Limited
screamer 25:aef6536015e3 5
screamer 25:aef6536015e3 6 Licensed under the Apache License, Version 2.0 (the "License");
screamer 25:aef6536015e3 7 you may not use this file except in compliance with the License.
screamer 25:aef6536015e3 8 You may obtain a copy of the License at
screamer 25:aef6536015e3 9
screamer 25:aef6536015e3 10 http://www.apache.org/licenses/LICENSE-2.0
screamer 25:aef6536015e3 11
screamer 25:aef6536015e3 12 Unless required by applicable law or agreed to in writing, software
screamer 25:aef6536015e3 13 distributed under the License is distributed on an "AS IS" BASIS,
screamer 25:aef6536015e3 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
screamer 25:aef6536015e3 15 See the License for the specific language governing permissions and
screamer 25:aef6536015e3 16 limitations under the License.
screamer 25:aef6536015e3 17 """
screamer 25:aef6536015e3 18
screamer 25:aef6536015e3 19 import sys
The Other Jimmy 31:8ea194f6145b 20 from os import remove, rename
The Other Jimmy 31:8ea194f6145b 21 from os.path import join, dirname, exists, abspath
The Other Jimmy 31:8ea194f6145b 22 ROOT = abspath(join(dirname(__file__), "..", "..", ".."))
The Other Jimmy 31:8ea194f6145b 23 sys.path.insert(0, ROOT)
screamer 25:aef6536015e3 24 import argparse
screamer 25:aef6536015e3 25 import os
The Other Jimmy 31:8ea194f6145b 26 from argparse import ArgumentTypeError
The Other Jimmy 31:8ea194f6145b 27 import sys
The Other Jimmy 31:8ea194f6145b 28 from shutil import rmtree
The Other Jimmy 31:8ea194f6145b 29 from collections import namedtuple
The Other Jimmy 31:8ea194f6145b 30 from copy import copy
screamer 25:aef6536015e3 31
screamer 25:aef6536015e3 32
The Other Jimmy 31:8ea194f6145b 33 from tools.paths import EXPORT_DIR
The Other Jimmy 31:8ea194f6145b 34 from tools.tests import TESTS
The Other Jimmy 31:8ea194f6145b 35 from tools.build_api import get_mbed_official_release, RELEASE_VERSIONS
The Other Jimmy 31:8ea194f6145b 36 from tools.test_api import find_tests
The Other Jimmy 31:8ea194f6145b 37 from tools.project import export
The Other Jimmy 31:8ea194f6145b 38 from Queue import Queue
The Other Jimmy 31:8ea194f6145b 39 from threading import Thread, Lock
The Other Jimmy 31:8ea194f6145b 40 from tools.project_api import print_results, get_exporter_toolchain
The Other Jimmy 31:8ea194f6145b 41 from tools.tests import test_name_known, test_known
The Other Jimmy 31:8ea194f6145b 42 from tools.export import EXPORTERS
The Other Jimmy 31:8ea194f6145b 43 from tools.utils import argparse_force_lowercase_type, \
The Other Jimmy 31:8ea194f6145b 44 argparse_many, columnate, args_error, \
The Other Jimmy 31:8ea194f6145b 45 argparse_filestring_type
The Other Jimmy 31:8ea194f6145b 46 from tools.options import extract_profile
The Other Jimmy 31:8ea194f6145b 47
The Other Jimmy 31:8ea194f6145b 48 print_lock = Lock()
The Other Jimmy 31:8ea194f6145b 49
The Other Jimmy 31:8ea194f6145b 50 def do_queue(Class, function, interable) :
The Other Jimmy 31:8ea194f6145b 51 q = Queue()
The Other Jimmy 31:8ea194f6145b 52 threads = [Class(q, function) for each in range(20)]
The Other Jimmy 31:8ea194f6145b 53 for thing in interable :
The Other Jimmy 31:8ea194f6145b 54 q.put(thing)
The Other Jimmy 31:8ea194f6145b 55 for each in threads :
The Other Jimmy 31:8ea194f6145b 56 each.setDaemon(True)
The Other Jimmy 31:8ea194f6145b 57 each.start()
The Other Jimmy 31:8ea194f6145b 58 q.join()
screamer 25:aef6536015e3 59
screamer 25:aef6536015e3 60
The Other Jimmy 31:8ea194f6145b 61 class Reader (Thread) :
The Other Jimmy 31:8ea194f6145b 62 def __init__(self, queue, func) :
The Other Jimmy 31:8ea194f6145b 63 Thread.__init__(self)
The Other Jimmy 31:8ea194f6145b 64 self.queue = queue
The Other Jimmy 31:8ea194f6145b 65 self.func = func
The Other Jimmy 31:8ea194f6145b 66
The Other Jimmy 31:8ea194f6145b 67 def start(self) :
The Other Jimmy 31:8ea194f6145b 68 sys.stdout.flush()
The Other Jimmy 31:8ea194f6145b 69 while not self.queue.empty() :
The Other Jimmy 31:8ea194f6145b 70 test = self.queue.get()
The Other Jimmy 31:8ea194f6145b 71 self.func(test)
The Other Jimmy 31:8ea194f6145b 72 self.queue.task_done()
The Other Jimmy 31:8ea194f6145b 73
The Other Jimmy 31:8ea194f6145b 74
The Other Jimmy 31:8ea194f6145b 75 class ExportBuildTest(object):
The Other Jimmy 31:8ea194f6145b 76 """Object to encapsulate logic for progen build testing"""
The Other Jimmy 31:8ea194f6145b 77 def __init__(self, tests, parser, options):
The Other Jimmy 31:8ea194f6145b 78 """
The Other Jimmy 31:8ea194f6145b 79 Initialize an instance of class ProgenBuildTest
The Other Jimmy 31:8ea194f6145b 80 Args:
The Other Jimmy 31:8ea194f6145b 81 tests: array of TestCase instances
The Other Jimmy 31:8ea194f6145b 82 """
The Other Jimmy 31:8ea194f6145b 83 self.total = len(tests)
The Other Jimmy 31:8ea194f6145b 84 self.parser = parser
The Other Jimmy 31:8ea194f6145b 85 self.options = options
The Other Jimmy 31:8ea194f6145b 86 self.counter = 0
The Other Jimmy 31:8ea194f6145b 87 self.successes = []
The Other Jimmy 31:8ea194f6145b 88 self.failures = []
The Other Jimmy 31:8ea194f6145b 89 self.skips = []
The Other Jimmy 31:8ea194f6145b 90 self.tests = [ExportBuildTest.test_case(test) for test in tests]
The Other Jimmy 31:8ea194f6145b 91 self.build_queue = Queue()
screamer 25:aef6536015e3 92
screamer 25:aef6536015e3 93 @staticmethod
The Other Jimmy 31:8ea194f6145b 94 def test_case(case):
The Other Jimmy 31:8ea194f6145b 95 TestCase = namedtuple('TestCase', case.keys())
The Other Jimmy 31:8ea194f6145b 96 return TestCase(**case)
The Other Jimmy 31:8ea194f6145b 97
The Other Jimmy 31:8ea194f6145b 98 def handle_log(self,log):
screamer 25:aef6536015e3 99 try:
The Other Jimmy 31:8ea194f6145b 100 with open(log, 'r') as in_log:
The Other Jimmy 31:8ea194f6145b 101 print in_log.read()
The Other Jimmy 31:8ea194f6145b 102 sys.stdout.flush()
The Other Jimmy 31:8ea194f6145b 103 log_name = join(EXPORT_DIR, dirname(log) + "_log.txt")
The Other Jimmy 31:8ea194f6145b 104 if exists(log_name):
The Other Jimmy 31:8ea194f6145b 105 # delete it if so
The Other Jimmy 31:8ea194f6145b 106 remove(log_name)
The Other Jimmy 31:8ea194f6145b 107 rename(log, log_name)
The Other Jimmy 31:8ea194f6145b 108 except IOError:
The Other Jimmy 31:8ea194f6145b 109 pass
screamer 25:aef6536015e3 110
The Other Jimmy 31:8ea194f6145b 111 def batch_tests(self, clean=False):
The Other Jimmy 31:8ea194f6145b 112 """Performs all exports of self.tests
The Other Jimmy 31:8ea194f6145b 113 Peroform_exports will fill self.build_queue.
The Other Jimmy 31:8ea194f6145b 114 This function will empty self.build_queue and call the test's
The Other Jimmy 31:8ea194f6145b 115 IDE's build function."""
The Other Jimmy 31:8ea194f6145b 116 do_queue(Reader, self.perform_exports, self.tests)
The Other Jimmy 31:8ea194f6145b 117 self.counter = 0
The Other Jimmy 31:8ea194f6145b 118 self.total = self.build_queue.qsize()
The Other Jimmy 31:8ea194f6145b 119 while not self.build_queue.empty():
The Other Jimmy 31:8ea194f6145b 120 build = self.build_queue.get()
The Other Jimmy 31:8ea194f6145b 121 self.counter +=1
The Other Jimmy 31:8ea194f6145b 122 exporter = build[0]
The Other Jimmy 31:8ea194f6145b 123 test_case = build[1]
The Other Jimmy 31:8ea194f6145b 124 self.display_counter("Building test case %s::%s\t%s"
The Other Jimmy 31:8ea194f6145b 125 % (test_case.mcu,
The Other Jimmy 31:8ea194f6145b 126 test_case.ide,
The Other Jimmy 31:8ea194f6145b 127 test_case.name))
screamer 25:aef6536015e3 128
The Other Jimmy 31:8ea194f6145b 129 cwd = os.getcwd()
The Other Jimmy 31:8ea194f6145b 130 os.chdir(exporter.export_dir)
The Other Jimmy 31:8ea194f6145b 131 res = EXPORTERS[exporter.NAME.lower()].build(exporter.project_name, cleanup=False)
The Other Jimmy 31:8ea194f6145b 132 os.chdir(cwd)
The Other Jimmy 31:8ea194f6145b 133 if res:
The Other Jimmy 31:8ea194f6145b 134 self.failures.append("%s::%s\t%s" % (test_case.mcu,
The Other Jimmy 31:8ea194f6145b 135 test_case.ide,
The Other Jimmy 31:8ea194f6145b 136 test_case.name))
The Other Jimmy 31:8ea194f6145b 137 else:
The Other Jimmy 31:8ea194f6145b 138 self.successes.append("%s::%s\t%s" % (test_case.mcu,
The Other Jimmy 31:8ea194f6145b 139 test_case.ide,
The Other Jimmy 31:8ea194f6145b 140 test_case.name))
The Other Jimmy 31:8ea194f6145b 141 self.handle_log(exporter.generated_files[-1])
The Other Jimmy 31:8ea194f6145b 142 if clean:
The Other Jimmy 31:8ea194f6145b 143 rmtree(exporter.export_dir)
The Other Jimmy 31:8ea194f6145b 144
The Other Jimmy 31:8ea194f6145b 145 def display_counter (self, message) :
The Other Jimmy 31:8ea194f6145b 146 with print_lock:
The Other Jimmy 31:8ea194f6145b 147 sys.stdout.write("{}/{} {}".format(self.counter, self.total,
The Other Jimmy 31:8ea194f6145b 148 message) +"\n")
The Other Jimmy 31:8ea194f6145b 149 sys.stdout.flush()
screamer 25:aef6536015e3 150
The Other Jimmy 31:8ea194f6145b 151 def perform_exports(self, test_case):
The Other Jimmy 31:8ea194f6145b 152 """
The Other Jimmy 31:8ea194f6145b 153 Generate the project file for test_case and fill self.build_queue
The Other Jimmy 31:8ea194f6145b 154 Args:
The Other Jimmy 31:8ea194f6145b 155 test_case: object of type TestCase
The Other Jimmy 31:8ea194f6145b 156 """
The Other Jimmy 31:8ea194f6145b 157 sys.stdout.flush()
The Other Jimmy 31:8ea194f6145b 158 self.counter += 1
The Other Jimmy 31:8ea194f6145b 159 name_str = ('%s_%s_%s') % (test_case.mcu, test_case.ide, test_case.name)
The Other Jimmy 31:8ea194f6145b 160 self.display_counter("Exporting test case %s::%s\t%s" % (test_case.mcu,
The Other Jimmy 31:8ea194f6145b 161 test_case.ide,
The Other Jimmy 31:8ea194f6145b 162 test_case.name))
The Other Jimmy 31:8ea194f6145b 163 exporter, toolchain = get_exporter_toolchain(test_case.ide)
The Other Jimmy 31:8ea194f6145b 164 if test_case.mcu not in exporter.TARGETS:
The Other Jimmy 31:8ea194f6145b 165 self.skips.append("%s::%s\t%s" % (test_case.mcu, test_case.ide,
The Other Jimmy 31:8ea194f6145b 166 test_case.name))
The Other Jimmy 31:8ea194f6145b 167 return
The Other Jimmy 31:8ea194f6145b 168 profile = extract_profile(self.parser, self.options, toolchain)
The Other Jimmy 31:8ea194f6145b 169 exporter = export(test_case.mcu, test_case.ide,
The Other Jimmy 35:da9c89f8be7d 170 project_id=test_case.id, zip_proj=None,
The Other Jimmy 35:da9c89f8be7d 171 src=test_case.src,
The Other Jimmy 35:da9c89f8be7d 172 export_path=join(EXPORT_DIR, name_str),
The Other Jimmy 35:da9c89f8be7d 173 silent=True, build_profile=profile)
The Other Jimmy 31:8ea194f6145b 174 exporter.generated_files.append(join(EXPORT_DIR,name_str,test_case.log))
The Other Jimmy 31:8ea194f6145b 175 self.build_queue.put((exporter,test_case))
The Other Jimmy 31:8ea194f6145b 176 # Check if the specified name is in all_os_tests
screamer 25:aef6536015e3 177
screamer 25:aef6536015e3 178
The Other Jimmy 31:8ea194f6145b 179 def check_valid_mbed_os(test):
The Other Jimmy 31:8ea194f6145b 180 """Check if the specified name is in all_os_tests
The Other Jimmy 31:8ea194f6145b 181 args:
The Other Jimmy 31:8ea194f6145b 182 test: string name to index all_os_tests
The Other Jimmy 31:8ea194f6145b 183 returns: tuple of test_name and source location of test,
The Other Jimmy 31:8ea194f6145b 184 as given by find_tests"""
The Other Jimmy 31:8ea194f6145b 185 all_os_tests = find_tests(ROOT, "K64F", "ARM")
The Other Jimmy 31:8ea194f6145b 186 if test in all_os_tests.keys():
The Other Jimmy 31:8ea194f6145b 187 return (test, all_os_tests[test])
The Other Jimmy 31:8ea194f6145b 188 else:
The Other Jimmy 31:8ea194f6145b 189 supported = columnate([t for t in all_os_tests.keys()])
The Other Jimmy 31:8ea194f6145b 190 raise ArgumentTypeError("Program with name '{0}' not found. "
The Other Jimmy 31:8ea194f6145b 191 "Supported tests are: \n{1}".format(test,supported))
The Other Jimmy 31:8ea194f6145b 192
The Other Jimmy 31:8ea194f6145b 193
The Other Jimmy 31:8ea194f6145b 194 def check_version(version):
The Other Jimmy 31:8ea194f6145b 195 """Check if the specified version is valid
The Other Jimmy 31:8ea194f6145b 196 args:
The Other Jimmy 31:8ea194f6145b 197 version: integer versio of mbed
The Other Jimmy 31:8ea194f6145b 198 returns:
The Other Jimmy 31:8ea194f6145b 199 version if it is valid"""
The Other Jimmy 31:8ea194f6145b 200 if version not in RELEASE_VERSIONS:
The Other Jimmy 31:8ea194f6145b 201 raise ArgumentTypeError("Choose from versions : %s"%", ".join(RELEASE_VERSIONS))
The Other Jimmy 31:8ea194f6145b 202 return version
screamer 25:aef6536015e3 203
The Other Jimmy 31:8ea194f6145b 204
The Other Jimmy 31:8ea194f6145b 205 def main():
The Other Jimmy 31:8ea194f6145b 206 """Entry point"""
The Other Jimmy 31:8ea194f6145b 207
The Other Jimmy 31:8ea194f6145b 208 ide_list = ["iar", "uvision"]
The Other Jimmy 31:8ea194f6145b 209
The Other Jimmy 31:8ea194f6145b 210 default_v2 = [test_name_known("MBED_BLINKY")]
The Other Jimmy 31:8ea194f6145b 211 default_v5 = [check_valid_mbed_os('tests-mbedmicro-rtos-mbed-basic')]
The Other Jimmy 31:8ea194f6145b 212
The Other Jimmy 31:8ea194f6145b 213 parser = argparse.ArgumentParser(description=
The Other Jimmy 31:8ea194f6145b 214 "Test progen builders. Leave any flag off"
The Other Jimmy 31:8ea194f6145b 215 " to run with all possible options.")
The Other Jimmy 31:8ea194f6145b 216 parser.add_argument("-i",
The Other Jimmy 31:8ea194f6145b 217 dest="ides",
The Other Jimmy 31:8ea194f6145b 218 default=ide_list,
The Other Jimmy 31:8ea194f6145b 219 type=argparse_many(argparse_force_lowercase_type(
The Other Jimmy 31:8ea194f6145b 220 ide_list, "toolchain")),
The Other Jimmy 31:8ea194f6145b 221 help="The target IDE: %s"% str(ide_list))
The Other Jimmy 31:8ea194f6145b 222
The Other Jimmy 31:8ea194f6145b 223 parser.add_argument( "-p",
The Other Jimmy 31:8ea194f6145b 224 type=argparse_many(test_known),
The Other Jimmy 31:8ea194f6145b 225 dest="programs",
The Other Jimmy 31:8ea194f6145b 226 help="The index of the desired test program: [0-%d]"
The Other Jimmy 31:8ea194f6145b 227 % (len(TESTS) - 1))
screamer 25:aef6536015e3 228
screamer 25:aef6536015e3 229 parser.add_argument("-n",
The Other Jimmy 31:8ea194f6145b 230 type=argparse_many(test_name_known),
The Other Jimmy 31:8ea194f6145b 231 dest="programs",
The Other Jimmy 31:8ea194f6145b 232 help="The name of the desired test program")
screamer 25:aef6536015e3 233
The Other Jimmy 31:8ea194f6145b 234 parser.add_argument("-m", "--mcu",
The Other Jimmy 31:8ea194f6145b 235 help=("Generate projects for the given MCUs"),
The Other Jimmy 31:8ea194f6145b 236 metavar="MCU",
The Other Jimmy 31:8ea194f6145b 237 type=argparse_many(str.upper))
The Other Jimmy 31:8ea194f6145b 238
The Other Jimmy 31:8ea194f6145b 239 parser.add_argument("-os-tests",
The Other Jimmy 31:8ea194f6145b 240 type=argparse_many(check_valid_mbed_os),
The Other Jimmy 31:8ea194f6145b 241 dest="os_tests",
The Other Jimmy 31:8ea194f6145b 242 help="Mbed-os tests")
screamer 25:aef6536015e3 243
screamer 25:aef6536015e3 244 parser.add_argument("-c", "--clean",
screamer 25:aef6536015e3 245 dest="clean",
The Other Jimmy 31:8ea194f6145b 246 action="store_true",
screamer 25:aef6536015e3 247 help="clean up the exported project files",
screamer 25:aef6536015e3 248 default=False)
screamer 25:aef6536015e3 249
The Other Jimmy 31:8ea194f6145b 250 parser.add_argument("--release",
The Other Jimmy 31:8ea194f6145b 251 dest="release",
The Other Jimmy 31:8ea194f6145b 252 type=check_version,
The Other Jimmy 31:8ea194f6145b 253 help="Which version of mbed to test",
The Other Jimmy 31:8ea194f6145b 254 default=RELEASE_VERSIONS[-1])
screamer 25:aef6536015e3 255
The Other Jimmy 31:8ea194f6145b 256 parser.add_argument("--profile",
The Other Jimmy 31:8ea194f6145b 257 dest="profile",
The Other Jimmy 31:8ea194f6145b 258 action="append",
The Other Jimmy 31:8ea194f6145b 259 type=argparse_filestring_type,
The Other Jimmy 31:8ea194f6145b 260 default=[])
screamer 25:aef6536015e3 261
The Other Jimmy 31:8ea194f6145b 262 options = parser.parse_args()
The Other Jimmy 31:8ea194f6145b 263 # targets in chosen release
The Other Jimmy 31:8ea194f6145b 264 targetnames = [target[0] for target in
The Other Jimmy 31:8ea194f6145b 265 get_mbed_official_release(options.release)]
The Other Jimmy 31:8ea194f6145b 266 # all targets in release are default
The Other Jimmy 31:8ea194f6145b 267 test_targets = options.mcu or targetnames
The Other Jimmy 31:8ea194f6145b 268 if not all([t in targetnames for t in test_targets]):
The Other Jimmy 31:8ea194f6145b 269 args_error(parser, "Only specify targets in release %s:\n%s"
The Other Jimmy 31:8ea194f6145b 270 %(options.release, columnate(sorted(targetnames))))
screamer 25:aef6536015e3 271
The Other Jimmy 31:8ea194f6145b 272 v2_tests, v5_tests = [],[]
The Other Jimmy 31:8ea194f6145b 273 if options.release == '5':
The Other Jimmy 31:8ea194f6145b 274 v5_tests = options.os_tests or default_v5
The Other Jimmy 31:8ea194f6145b 275 elif options.release == '2':
The Other Jimmy 31:8ea194f6145b 276 v2_tests = options.programs or default_v2
screamer 25:aef6536015e3 277
The Other Jimmy 31:8ea194f6145b 278 tests = []
The Other Jimmy 31:8ea194f6145b 279 default_test = {key:None for key in ['ide', 'mcu', 'name', 'id', 'src', 'log']}
The Other Jimmy 31:8ea194f6145b 280 for mcu in test_targets:
The Other Jimmy 31:8ea194f6145b 281 for ide in options.ides:
The Other Jimmy 31:8ea194f6145b 282 log = "build_log.txt" if ide == 'iar' \
The Other Jimmy 31:8ea194f6145b 283 else join('build', 'build_log.txt')
The Other Jimmy 31:8ea194f6145b 284 # add each test case to the tests array
The Other Jimmy 31:8ea194f6145b 285 default_test.update({'mcu': mcu, 'ide': ide, 'log':log})
The Other Jimmy 31:8ea194f6145b 286 for test in v2_tests:
The Other Jimmy 31:8ea194f6145b 287 default_test.update({'name':TESTS[test]["id"], 'id':test})
The Other Jimmy 31:8ea194f6145b 288 tests.append(copy(default_test))
The Other Jimmy 31:8ea194f6145b 289 for test in v5_tests:
The Other Jimmy 31:8ea194f6145b 290 default_test.update({'name':test[0],'src':[test[1],ROOT]})
The Other Jimmy 31:8ea194f6145b 291 tests.append(copy(default_test))
The Other Jimmy 31:8ea194f6145b 292 test = ExportBuildTest(tests, parser, options)
The Other Jimmy 31:8ea194f6145b 293 test.batch_tests(clean=options.clean)
The Other Jimmy 31:8ea194f6145b 294 print_results(test.successes, test.failures, test.skips)
The Other Jimmy 31:8ea194f6145b 295 sys.exit(len(test.failures))
screamer 25:aef6536015e3 296
The Other Jimmy 31:8ea194f6145b 297 if __name__ == "__main__":
The Other Jimmy 35:da9c89f8be7d 298 main()