Merge pull request #71 from bridadan/test-build

Building tests and test specs
Sam Grove 2016-05-05 13:51:11 -05:00
commit fc4f1e2da3
3 changed files with 164 additions and 17 deletions

View File

@ -21,17 +21,32 @@ TEST BUILD & RUN
import sys
import os
import json
from optparse import OptionParser
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.insert(0, ROOT)
from tools.test_api import test_path_to_name, find_tests, print_tests
from tools.test_api import test_path_to_name, find_tests, print_tests, build_tests, test_spec_from_test_build
from tools.options import get_default_options_parser
from tools.build_api import build_project
from tools.targets import TARGET_MAP
from tools.utils import mkdir
if __name__ == '__main__':
try:
# Parse Options
parser = OptionParser()
parser = get_default_options_parser()
parser.add_option("-j", "--jobs",
type="int",
dest="jobs",
default=1,
help="Number of concurrent jobs (default 1). Use 0 for auto based on host machine's number of CPUs")
parser.add_option("--source", dest="source_dir",
default=None, help="The source (input) directory (for sources other than tests). Defaults to current directory.", action="append")
parser.add_option("--build", dest="build_dir",
default=None, help="The build (output) directory")
parser.add_option("-l", "--list", action="store_true", dest="list",
default=False, help="List (recursively) available tests in order and exit")
@ -39,24 +54,93 @@ if __name__ == '__main__':
parser.add_option("-p", "--paths", dest="paths",
default=None, help="Limit the tests to those within the specified comma separated list of paths")
format_choices = ["list", "json"]
format_default_choice = "list"
format_help = "Change the format in which tests are listed. Choices include: %s. Default: %s" % (", ".join(format_choices), format_default_choice)
parser.add_option("-f", "--format", type="choice", dest="format",
choices=["list", "json"], default="list", help="List available tests in order and exit")
choices=format_choices, default=format_default_choice, help=format_help)
parser.add_option("-n", "--names", dest="names",
default=None, help="Limit the tests to a comma separated list of names")
parser.add_option("--test-spec", dest="test_spec",
default=None, help="Destination path for a test spec file that can be used by the Greentea automated test tool")
parser.add_option("-v", "--verbose",
action="store_true",
dest="verbose",
default=False,
help="Verbose diagnostic output")
(options, args) = parser.parse_args()
# Print available tests in order and exit
if options.list is True:
tests = {}
# Filter tests by path if specified
if options.paths:
all_paths = options.paths.split(",")
else:
all_paths = ["."]
if options.paths:
all_paths = options.paths.split(",")
for path in all_paths:
tests.update(find_tests(path))
else:
tests = find_tests('.')
all_tests = {}
tests = {}
# Find all tests in the relevant paths
for path in all_paths:
all_tests.update(find_tests(path))
# Filter tests by name if specified
if options.names:
all_names = options.names.split(",")
all_tests_keys = all_tests.keys()
for name in all_names:
if name in all_tests_keys:
tests[name] = all_tests[name]
else:
print "[Warning] Test with name '%s' was not found in the available tests" % (name)
else:
tests = all_tests
if options.list:
# Print available tests in order and exit
print_tests(tests, options.format)
sys.exit()
else:
# Build all tests
if not options.build_dir:
print "[ERROR] You must specify a build path"
sys.exit(1)
base_source_paths = options.source_dir
# Default base source path is the current directory
if not base_source_paths:
base_source_paths = ['.']
target = TARGET_MAP[options.mcu]
# Build all the tests
test_build = build_tests(tests, base_source_paths, options.build_dir, target, options.tool,
options=options.options,
clean=options.clean,
jobs=options.jobs)
# If a path to a test spec is provided, write it to a file
if options.test_spec:
test_spec_data = test_spec_from_test_build(test_build)
# Create the target dir for the test spec if necessary
# mkdir will not create the dir if it already exists
test_spec_dir = os.path.dirname(options.test_spec)
if test_spec_dir:
mkdir(test_spec_dir)
try:
with open(options.test_spec, 'w') as f:
f.write(json.dumps(test_spec_data, indent=2))
except IOError, e:
print "[ERROR] Error writing test spec to file"
print e
sys.exit()
except KeyboardInterrupt, e:
print "\n[CTRL+c] exit"

View File

@ -2024,3 +2024,61 @@ def print_tests(tests, format="list"):
else:
print "Unknown format '%s'" % format
sys.exit(1)
def build_tests(tests, base_source_paths, build_path, target, toolchain_name,
options=None, clean=False, notify=None, verbose=False, jobs=1,
silent=False, report=None, properties=None):
"""Given the data structure from 'find_tests' and the typical build parameters,
build all the tests and return a test build data structure"""
test_build = {
"platform": target.name,
"toolchain": toolchain_name,
"base_path": build_path,
"baud_rate": 9600,
"binary_type": "bootable",
"tests": {}
}
for test_name, test_path in tests.iteritems():
src_path = base_source_paths + [test_path]
artifact_name = os.path.join(test_path, test_name)
bin_file = build_project(src_path, build_path, target, toolchain_name,
options=options,
jobs=jobs,
clean=clean,
name=artifact_name,
report=report,
properties=properties,
verbose=verbose)
# If a clean build was carried out last time, disable it for the next build.
# Otherwise the previously built test will be deleted.
if clean:
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
test_builds = {}
test_builds["%s-%s" % (target.name, toolchain_name)] = test_build
return test_builds
def test_spec_from_test_build(test_builds):
return {
"builds": test_builds
}

View File

@ -686,6 +686,11 @@ class mbedToolchain:
name = name[0:8]
ext = ext[0:3]
# Create destination directory
head, tail = split(name)
new_path = join(tmp_path, head)
mkdir(new_path)
filename = name+'.'+ext
elf = join(tmp_path, name + '.elf')
bin = join(tmp_path, filename)