Merge pull request #1928 from mbedmicro/tools_integration

Tools Updates (Tests and build logs)
pull/1929/head
Sam Grove 2016-06-14 04:56:48 +01:00 committed by GitHub
commit e8fda07d83
5 changed files with 84 additions and 101 deletions

View File

@ -383,8 +383,6 @@ def build_library(src_paths, build_path, target, toolchain_name,
if toolchain_output:
cur_result["output"] += toolchain_output
cur_result["output"] += str(e)
add_result_to_report(report, cur_result)
# Let Exception propagate
@ -523,8 +521,6 @@ def build_lib(lib_id, target, toolchain_name, options=None, verbose=False, clean
if toolchain_output:
cur_result["output"] += toolchain_output
cur_result["output"] += str(e)
add_result_to_report(report, cur_result)
# Let Exception propagate

View File

@ -21,6 +21,7 @@ TEST BUILD & RUN
import sys
import os
import json
import fnmatch
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.insert(0, ROOT)
@ -29,7 +30,7 @@ from tools.test_api import test_path_to_name, find_tests, print_tests, build_tes
from tools.options import get_default_options_parser
from tools.build_api import build_project, build_library
from tools.targets import TARGET_MAP
from tools.utils import mkdir
from tools.utils import mkdir, ToolException, NotSupportedException
from tools.test_exporters import ReportExporter, ResultExporterType
if __name__ == '__main__':
@ -102,11 +103,13 @@ if __name__ == '__main__':
# Filter tests by name if specified
if options.names:
all_names = options.names.split(",")
all_names = [x.lower() for x in all_names]
all_tests_keys = all_tests.keys()
for name in all_names:
if name in all_tests_keys:
tests[name] = all_tests[name]
if any(fnmatch.fnmatch(testname, name) for testname in all_tests):
for testname, test in all_tests.items():
if fnmatch.fnmatch(testname, name):
tests[testname] = test
else:
print "[Warning] Test with name '%s' was not found in the available tests" % (name)
else:
@ -134,7 +137,7 @@ if __name__ == '__main__':
build_report = {}
build_properties = {}
library_build_success = True
library_build_success = False
try:
# Build sources
build_library(base_source_paths, options.build_dir, target, options.tool,
@ -147,11 +150,21 @@ if __name__ == '__main__':
macros=options.macros,
verbose=options.verbose,
archive=False)
except Exception, e:
library_build_success = False
print "Failed to build library"
if library_build_success:
library_build_success = True
except ToolException, e:
# ToolException output is handled by the build log
pass
except NotSupportedException, e:
# NotSupportedException is handled by the build log
pass
except Exception, e:
# Some other exception occurred, print the error message
print e
if not library_build_success:
print "Failed to build library"
else:
# Build all the tests
test_build_success, test_build = build_tests(tests, [options.build_dir], options.build_dir, target, options.tool,
options=options.options,

View File

@ -1961,76 +1961,44 @@ def test_path_to_name(path):
name_parts.insert(0, tail)
head, tail = os.path.split(head)
return "-".join(name_parts)
return "-".join(name_parts).lower()
def find_tests(base_dir):
"""Given any directory, walk through the subdirectories and find all tests"""
def is_subdir(path, directory):
path = os.path.realpath(path)
directory = os.path.realpath(directory)
relative = os.path.relpath(path, directory)
return not (relative.startswith(os.pardir + os.sep) and relative.startswith(os.pardir))
def find_tests_in_tests_directory(directory):
def find_test_in_directory(directory, tests_path):
"""Given a 'TESTS' directory, return a dictionary of test names and test paths.
The formate of the dictionary is {"test-name": "./path/to/test"}"""
tests = {}
test = None
if tests_path in directory:
head, test_case_directory = os.path.split(directory)
if test_case_directory != tests_path and test_case_directory != "host_tests":
head, test_group_directory = os.path.split(head)
if test_group_directory != tests_path and test_case_directory != "host_tests":
test = {
"name": test_path_to_name(directory),
"path": directory
}
for d in os.listdir(directory):
# dir name host_tests is reserved for host python scripts.
if d != "host_tests":
# Loop on test case directories
for td in os.listdir(os.path.join(directory, d)):
# Add test case to the results if it is a directory and not "host_tests"
if td != "host_tests":
test_case_path = os.path.join(directory, d, td)
if os.path.isdir(test_case_path):
tests[test_path_to_name(test_case_path)] = test_case_path
return tests
return test
tests_path = 'TESTS'
tests = {}
dirs = scan_for_source_paths(base_dir)
# Determine if "base_dir" is already a "TESTS" directory
_, top_folder = os.path.split(base_dir)
for directory in dirs:
test = find_test_in_directory(directory, tests_path)
if test:
tests[test['name']] = test['path']
if top_folder == tests_path:
# Already pointing at a "TESTS" directory
return find_tests_in_tests_directory(base_dir)
else:
# Not pointing at a "TESTS" directory, so go find one!
tests = {}
dirs = scan_for_source_paths(base_dir)
test_and_sub_dirs = [x for x in dirs if tests_path in x]
test_dirs = []
for potential_test_dir in test_and_sub_dirs:
good_to_add = True
if test_dirs:
for test_dir in test_dirs:
if is_subdir(potential_test_dir, test_dir):
good_to_add = False
break
if good_to_add:
test_dirs.append(potential_test_dir)
# Only look at valid paths
for path in test_dirs:
# Get the tests inside of the "TESTS" directory
new_tests = find_tests_in_tests_directory(path)
if new_tests:
tests.update(new_tests)
return tests
return tests
def print_tests(tests, format="list"):
def print_tests(tests, format="list", sort=True):
"""Given a dictionary of tests (as returned from "find_tests"), print them
in the specified format"""
if format == "list":
for test_name, test_path in tests.iteritems():
for test_name in sorted(tests.keys()):
test_path = tests[test_name]
print "Test Case:"
print " Name: %s" % test_name
print " Path: %s" % test_path
@ -2064,7 +2032,7 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name,
for test_name, test_path in tests.iteritems():
test_build_path = os.path.join(build_path, test_path)
src_path = base_source_paths + [test_path]
bin_file = None
try:
bin_file = build_project(src_path, test_build_path, target, toolchain_name,
options=options,
@ -2077,12 +2045,13 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name,
verbose=verbose)
except Exception, e:
result = False
if continue_on_build_fail:
continue
else:
break
if not isinstance(e, NotSupportedException):
result = False
if continue_on_build_fail:
continue
else:
break
# If a clean build was carried out last time, disable it for the next build.
# Otherwise the previously built test will be deleted.
@ -2090,17 +2059,18 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name,
clean = False
# Normalize the path
bin_file = os.path.normpath(bin_file)
test_build['tests'][test_name] = {
"binaries": [
{
"path": bin_file
}
]
}
print 'Image: %s'% bin_file
if bin_file:
bin_file = os.path.normpath(bin_file)
test_build['tests'][test_name] = {
"binaries": [
{
"path": bin_file
}
]
}
print 'Image: %s'% bin_file
test_builds = {}
test_builds["%s-%s" % (target.name, toolchain_name)] = test_build

View File

@ -324,15 +324,18 @@ class ReportExporter():
for test_runner in test_runs:
#test_run = test_result_ext[target][toolchain][test][test_run_number][0]
test_run = test_runner[0]
if test_run["result"] == "FAIL":
failures.append(test_run)
elif test_run["result"] == "SKIP" or test_run["result"] == "NOT_SUPPORTED":
skips.append(test_run)
elif test_run["result"] == "OK":
successes.append(test_run)
if "result" in test_run:
if test_run["result"] == "FAIL":
failures.append(test_run)
elif test_run["result"] == "SKIP" or test_run["result"] == "NOT_SUPPORTED":
skips.append(test_run)
elif test_run["result"] == "OK":
successes.append(test_run)
else:
raise Exception("Unhandled result type: %s" % (test_run["result"]))
else:
raise Exception("Unhandled result type: %s" % (test_run["result"]))
raise Exception("'test_run' did not have a 'result' value")
if successes:
print "\n\nBuild successes:"

View File

@ -241,8 +241,9 @@ class mbedToolchain:
self.mp_pool = None
if 'UVISOR_PRESENT=1' in self.macros:
if 'UVISOR' in self.target.features and 'UVISOR_SUPPORTED' in self.target.extra_labels:
self.target.core = re.sub(r"F$", '', self.target.core)
self.flags = deepcopy(self.DEFAULT_FLAGS)
def get_output(self):
@ -253,9 +254,12 @@ class mbedToolchain:
"""
msg = None
if event['type'] in ['info', 'debug']:
if not self.VERBOSE and event['type'] == 'tool_error':
msg = event['message']
elif event['type'] in ['info', 'debug']:
msg = event['message']
elif event['type'] == 'cc':
event['severity'] = event['severity'].title()
event['file'] = basename(event['file'])
@ -775,9 +779,6 @@ class mbedToolchain:
def default_cmd(self, command):
self.debug("Command: %s"% ' '.join(command))
_stdout, _stderr, _rc = run_cmd(command)
# Print all warning / erros from stderr to console output
for error_line in _stderr.splitlines():
print error_line
self.debug("Return: %s"% _rc)