Clone of official tools
Diff: test_api.py
- Revision:
- 13:ab47a20b66f0
- Parent:
- 0:66f3b5499f7f
- Child:
- 20:835f6355470d
--- a/test_api.py Tue Jun 14 11:33:06 2016 +0100 +++ b/test_api.py Thu Jul 14 20:21:19 2016 +0100 @@ -55,6 +55,7 @@ from tools.build_api import prep_properties from tools.build_api import create_result from tools.build_api import add_result_to_report +from tools.build_api import scan_for_source_paths from tools.libraries import LIBRARIES, LIBRARY_MAP from tools.toolchains import TOOLCHAIN_BIN_PATH from tools.test_exporters import ReportExporter, ResultExporterType @@ -897,7 +898,7 @@ reset=host_test_reset, reset_tout=reset_tout, copy_method=selected_copy_method, - program_cycle_s=target_by_mcu.program_cycle_s()) + program_cycle_s=target_by_mcu.program_cycle_s) single_test_result, single_test_output, single_testduration, single_timeout = host_test_result # Store test result @@ -1960,62 +1961,44 @@ 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 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 - 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' - - # Determine if "base_dir" is already a "TESTS" directory - _, top_folder = os.path.split(base_dir) + tests = {} + dirs = scan_for_source_paths(base_dir) - 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 = {} - - for root, dirs, files in os.walk(base_dir): - # Don't search build directories - if '.build' in dirs: - dirs.remove('.build') - - # If a "TESTS" directory is found, find the tests inside of it - if tests_path in dirs: - # Remove it from the directory walk - dirs.remove(tests_path) - - # Get the tests inside of the "TESTS" directory - new_tests = find_tests_in_tests_directory(os.path.join(root, tests_path)) - if new_tests: - tests.update(new_tests) - - return tests + for directory in dirs: + test = find_test_in_directory(directory, tests_path) + if test: + tests[test['name']] = test['path'] -def print_tests(tests, format="list"): + return tests + +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 @@ -2025,32 +2008,65 @@ print "Unknown format '%s'" % format sys.exit(1) +def norm_relative_path(path, start): + """This function will create a normalized, relative path. It mimics the + python os.path.relpath function, but also normalizes a Windows-syle path + that use backslashes to a Unix style path that uses forward slashes.""" + path = os.path.normpath(path) + path = os.path.relpath(path, start) + path = path.replace("\\", "/") + return path + 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): + macros=None, silent=False, report=None, properties=None, + continue_on_build_fail=False): """Given the data structure from 'find_tests' and the typical build parameters, - build all the tests and return a test build data structure""" + build all the tests + + Returns a tuple of the build result (True or False) followed by the test + build data structure""" + + execution_directory = "." + + base_path = norm_relative_path(build_path, execution_directory) + + target_name = target if isinstance(target, str) else target.name test_build = { - "platform": target.name, + "platform": target_name, "toolchain": toolchain_name, - "base_path": build_path, + "base_path": base_path, "baud_rate": 9600, "binary_type": "bootable", "tests": {} } + result = True + 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 = build_project(src_path, test_build_path, target, toolchain_name, - options=options, - jobs=jobs, - clean=clean, - name=test_name, - report=report, - properties=properties, - verbose=verbose) + bin_file = None + try: + bin_file = build_project(src_path, test_build_path, target, toolchain_name, + options=options, + jobs=jobs, + clean=clean, + macros=macros, + name=test_name, + report=report, + properties=properties, + verbose=verbose) + + except Exception, e: + 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. @@ -2058,27 +2074,27 @@ 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 = norm_relative_path(bin_file, execution_directory) + + 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 + test_builds["%s-%s" % (target_name, toolchain_name)] = test_build - return test_builds + return result, test_builds -def test_spec_from_test_build(test_builds): +def test_spec_from_test_builds(test_builds): return { "builds": test_builds } - \ No newline at end of file