Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: test_api.py
- Revision:
- 22:9e85236d8716
- Parent:
- 20:835f6355470d
- Child:
- 24:25bff2709c20
--- a/test_api.py Fri Jul 15 22:58:15 2016 +0100
+++ b/test_api.py Sat Jul 16 00:34:03 2016 +0100
@@ -24,7 +24,7 @@
import uuid
import pprint
import random
-import optparse
+import argparse
import datetime
import threading
import ctypes
@@ -46,6 +46,7 @@
from tools.utils import ToolException
from tools.utils import NotSupportedException
from tools.utils import construct_enum
+from tools.memap import MemapParser
from tools.targets import TARGET_MAP
from tools.test_db import BaseDBAccess
from tools.build_api import build_project, build_mbed_libs, build_lib
@@ -58,7 +59,12 @@
from tools.build_api import scan_for_source_paths
from tools.libraries import LIBRARIES, LIBRARY_MAP
from tools.toolchains import TOOLCHAIN_PATHS
+from tools.toolchains import TOOLCHAINS
from tools.test_exporters import ReportExporter, ResultExporterType
+from tools.utils import argparse_filestring_type
+from tools.utils import argparse_uppercase_type
+from tools.utils import argparse_lowercase_type
+from tools.utils import argparse_many
import tools.host_tests.host_tests_plugins as host_tests_plugins
@@ -166,6 +172,7 @@
_opts_report_html_file_name=None,
_opts_report_junit_file_name=None,
_opts_report_build_file_name=None,
+ _opts_report_text_file_name=None,
_opts_build_report={},
_opts_build_properties={},
_test_spec={},
@@ -224,6 +231,7 @@
self.opts_report_html_file_name = _opts_report_html_file_name
self.opts_report_junit_file_name = _opts_report_junit_file_name
self.opts_report_build_file_name = _opts_report_build_file_name
+ self.opts_report_text_file_name = _opts_report_text_file_name
self.opts_goanna_for_mbed_sdk = _opts_goanna_for_mbed_sdk
self.opts_goanna_for_tests = _opts_goanna_for_tests
self.opts_shuffle_test_order = _opts_shuffle_test_order
@@ -623,7 +631,7 @@
for test_id in test_map_keys:
test = TEST_MAP[test_id]
- if self.opts_test_by_names and test_id not in self.opts_test_by_names.split(','):
+ if self.opts_test_by_names and test_id not in self.opts_test_by_names:
continue
if test_ids and test_id not in test_ids:
@@ -634,7 +642,7 @@
print self.logger.log_line(self.logger.LogType.INFO, 'Common test skipped for target %s'% (target))
continue
- if self.opts_peripheral_by_names and test.peripherals and not len([i for i in test.peripherals if i in self.opts_peripheral_by_names.split(',')]):
+ if self.opts_peripheral_by_names and test.peripherals and not len([i for i in test.peripherals if i in self.opts_peripheral_by_names]):
# We will skip tests not forced with -p option
if self.opts_verbose_skipped_tests:
print self.logger.log_line(self.logger.LogType.INFO, 'Common test skipped for target %s'% (target))
@@ -655,7 +663,7 @@
# When users are using 'build only flag' and test do not have
# specified peripherals we can allow test building by default
pass
- elif self.opts_peripheral_by_names and test_id not in self.opts_peripheral_by_names.split(','):
+ elif self.opts_peripheral_by_names and test_id not in self.opts_peripheral_by_names:
# If we force peripheral with option -p we expect test
# to pass even if peripheral is not in MUTs file.
pass
@@ -773,7 +781,7 @@
"""
result = {}
if test_loops_str:
- test_loops = test_loops_str.split(',')
+ test_loops = test_loops_str
for test_loop in test_loops:
test_loop_count = test_loop.split('=')
if len(test_loop_count) == 2:
@@ -1513,6 +1521,10 @@
# Export results in form of JUnit XML report to separate file
report_exporter = ReportExporter(ResultExporterType.JUNIT)
report_exporter.report_to_file(test_summary_ext, single_test.opts_report_junit_file_name, test_suite_properties=test_suite_properties_ext)
+ if single_test.opts_report_text_file_name:
+ # Export results in form of a text file
+ report_exporter = ReportExporter(ResultExporterType.TEXT)
+ report_exporter.report_to_file(test_summary_ext, single_test.opts_report_text_file_name, test_suite_properties=test_suite_properties_ext)
if single_test.opts_report_build_file_name:
# Export build results as html report to sparate file
report_exporter = ReportExporter(ResultExporterType.JUNIT, package="build")
@@ -1713,7 +1725,7 @@
toolchains += supported_toolchains
if toolchain_filter is not None:
all_toolchains = supported_toolchains + [default_toolchain]
- for toolchain in toolchain_filter.split(','):
+ for toolchain in toolchain_filter:
if toolchain in all_toolchains:
toolchains.append(toolchain)
@@ -1724,231 +1736,243 @@
def get_default_test_options_parser():
""" Get common test script options used by CLI, web services etc.
"""
- parser = optparse.OptionParser()
- parser.add_option('-i', '--tests',
- dest='test_spec_filename',
- metavar="FILE",
- help='Points to file with test specification')
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-i', '--tests',
+ dest='test_spec_filename',
+ metavar="FILE",
+ type=argparse_filestring_type,
+ help='Points to file with test specification')
- parser.add_option('-M', '--MUTS',
- dest='muts_spec_filename',
- metavar="FILE",
- help='Points to file with MUTs specification (overwrites settings.py and private_settings.py)')
+ parser.add_argument('-M', '--MUTS',
+ dest='muts_spec_filename',
+ metavar="FILE",
+ type=argparse_filestring_type,
+ help='Points to file with MUTs specification (overwrites settings.py and private_settings.py)')
- parser.add_option("-j", "--jobs",
- dest='jobs',
- metavar="NUMBER",
- type="int",
- help="Define number of compilation jobs. Default value is 1")
+ parser.add_argument("-j", "--jobs",
+ dest='jobs',
+ metavar="NUMBER",
+ type=int,
+ help="Define number of compilation jobs. Default value is 1")
if get_module_avail('mbed_lstools'):
# Additional features available when mbed_lstools is installed on host and imported
# mbed_lstools allow users to detect connected to host mbed-enabled devices
- parser.add_option('', '--auto',
- dest='auto_detect',
- metavar=False,
- action="store_true",
- help='Use mbed-ls module to detect all connected mbed devices')
+ parser.add_argument('--auto',
+ dest='auto_detect',
+ action="store_true",
+ help='Use mbed-ls module to detect all connected mbed devices')
- parser.add_option('', '--tc',
- dest='toolchains_filter',
- help="Toolchain filter for --auto option. Use toolchains names separated by comma, 'default' or 'all' to select toolchains")
+ toolchain_list = list(TOOLCHAINS) + ["DEFAULT", "ALL"]
+ parser.add_argument('--tc',
+ dest='toolchains_filter',
+ type=argparse_many(argparse_uppercase_type(toolchain_list, "toolchains")),
+ help="Toolchain filter for --auto argument. Use toolchains names separated by comma, 'default' or 'all' to select toolchains")
test_scopes = ','.join(["'%s'" % n for n in get_available_oper_test_scopes()])
- parser.add_option('', '--oper',
- dest='operability_checks',
- help='Perform interoperability tests between host and connected mbed devices. Available test scopes are: %s' % test_scopes)
+ parser.add_argument('--oper',
+ dest='operability_checks',
+ type=argparse_lowercase_type(get_available_oper_test_scopes(), "scopes"),
+ help='Perform interoperability tests between host and connected mbed devices. Available test scopes are: %s' % test_scopes)
- parser.add_option('', '--clean',
- dest='clean',
- metavar=False,
- action="store_true",
- help='Clean the build directory')
+ parser.add_argument('--clean',
+ dest='clean',
+ action="store_true",
+ help='Clean the build directory')
- parser.add_option('-P', '--only-peripherals',
- dest='test_only_peripheral',
- default=False,
- action="store_true",
- help='Test only peripheral declared for MUT and skip common tests')
+ parser.add_argument('-P', '--only-peripherals',
+ dest='test_only_peripheral',
+ default=False,
+ action="store_true",
+ help='Test only peripheral declared for MUT and skip common tests')
- parser.add_option('-C', '--only-commons',
- dest='test_only_common',
- default=False,
- action="store_true",
- help='Test only board internals. Skip perpherials tests and perform common tests')
+ parser.add_argument('-C', '--only-commons',
+ dest='test_only_common',
+ default=False,
+ action="store_true",
+ help='Test only board internals. Skip perpherials tests and perform common tests')
- parser.add_option('-n', '--test-by-names',
- dest='test_by_names',
- help='Runs only test enumerated it this switch. Use comma to separate test case names')
+ parser.add_argument('-n', '--test-by-names',
+ dest='test_by_names',
+ type=argparse_many(str),
+ help='Runs only test enumerated it this switch. Use comma to separate test case names')
- parser.add_option('-p', '--peripheral-by-names',
+ parser.add_argument('-p', '--peripheral-by-names',
dest='peripheral_by_names',
+ type=argparse_many(str),
help='Forces discovery of particular peripherals. Use comma to separate peripheral names')
copy_methods = host_tests_plugins.get_plugin_caps('CopyMethod')
copy_methods_str = "Plugin support: " + ', '.join(copy_methods)
- parser.add_option('-c', '--copy-method',
- dest='copy_method',
- help="Select binary copy (flash) method. Default is Python's shutil.copy() method. %s"% copy_methods_str)
+ parser.add_argument('-c', '--copy-method',
+ dest='copy_method',
+ type=argparse_uppercase_type(copy_methods, "flash method"),
+ help="Select binary copy (flash) method. Default is Python's shutil.copy() method. %s"% copy_methods_str)
reset_methods = host_tests_plugins.get_plugin_caps('ResetMethod')
reset_methods_str = "Plugin support: " + ', '.join(reset_methods)
- parser.add_option('-r', '--reset-type',
- dest='mut_reset_type',
- default=None,
- help='Extra reset method used to reset MUT by host test script. %s'% reset_methods_str)
+ parser.add_argument('-r', '--reset-type',
+ dest='mut_reset_type',
+ default=None,
+ type=argparse_uppercase_type(reset_methods, "reset method"),
+ help='Extra reset method used to reset MUT by host test script. %s'% reset_methods_str)
- parser.add_option('-g', '--goanna-for-tests',
- dest='goanna_for_tests',
- metavar=False,
- action="store_true",
- help='Run Goanna static analyse tool for tests. (Project will be rebuilded)')
+ parser.add_argument('-g', '--goanna-for-tests',
+ dest='goanna_for_tests',
+ action="store_true",
+ help='Run Goanna static analyse tool for tests. (Project will be rebuilded)')
- parser.add_option('-G', '--goanna-for-sdk',
- dest='goanna_for_mbed_sdk',
- metavar=False,
- action="store_true",
- help='Run Goanna static analyse tool for mbed SDK (Project will be rebuilded)')
+ parser.add_argument('-G', '--goanna-for-sdk',
+ dest='goanna_for_mbed_sdk',
+ action="store_true",
+ help='Run Goanna static analyse tool for mbed SDK (Project will be rebuilded)')
- parser.add_option('-s', '--suppress-summary',
- dest='suppress_summary',
- default=False,
- action="store_true",
- help='Suppresses display of wellformatted table with test results')
+ parser.add_argument('-s', '--suppress-summary',
+ dest='suppress_summary',
+ default=False,
+ action="store_true",
+ help='Suppresses display of wellformatted table with test results')
+
+ parser.add_argument('-t', '--test-summary',
+ dest='test_x_toolchain_summary',
+ default=False,
+ action="store_true",
+ help='Displays wellformatted table with test x toolchain test result per target')
- parser.add_option('-t', '--test-summary',
- dest='test_x_toolchain_summary',
- default=False,
- action="store_true",
- help='Displays wellformatted table with test x toolchain test result per target')
+ parser.add_argument('-A', '--test-automation-report',
+ dest='test_automation_report',
+ default=False,
+ action="store_true",
+ help='Prints information about all tests and exits')
- parser.add_option('-A', '--test-automation-report',
- dest='test_automation_report',
- default=False,
- action="store_true",
- help='Prints information about all tests and exits')
+ parser.add_argument('-R', '--test-case-report',
+ dest='test_case_report',
+ default=False,
+ action="store_true",
+ help='Prints information about all test cases and exits')
- parser.add_option('-R', '--test-case-report',
- dest='test_case_report',
- default=False,
- action="store_true",
- help='Prints information about all test cases and exits')
+ parser.add_argument("-S", "--supported-toolchains",
+ action="store_true",
+ dest="supported_toolchains",
+ default=False,
+ help="Displays supported matrix of MCUs and toolchains")
- parser.add_option("-S", "--supported-toolchains",
- action="store_true",
- dest="supported_toolchains",
- default=False,
- help="Displays supported matrix of MCUs and toolchains")
+ parser.add_argument("-O", "--only-build",
+ action="store_true",
+ dest="only_build_tests",
+ default=False,
+ help="Only build tests, skips actual test procedures (flashing etc.)")
- parser.add_option("-O", "--only-build",
- action="store_true",
- dest="only_build_tests",
- default=False,
- help="Only build tests, skips actual test procedures (flashing etc.)")
+ parser.add_argument('--parallel',
+ dest='parallel_test_exec',
+ default=False,
+ action="store_true",
+ help='Experimental, you execute test runners for connected to your host MUTs in parallel (speeds up test result collection)')
- parser.add_option('', '--parallel',
- dest='parallel_test_exec',
- default=False,
- action="store_true",
- help='Experimental, you execute test runners for connected to your host MUTs in parallel (speeds up test result collection)')
+ parser.add_argument('--config',
+ dest='verbose_test_configuration_only',
+ default=False,
+ action="store_true",
+ help='Displays full test specification and MUTs configration and exits')
+
+ parser.add_argument('--loops',
+ dest='test_loops_list',
+ type=argparse_many(str),
+ help='Set no. of loops per test. Format: TEST_1=1,TEST_2=2,TEST_3=3')
- parser.add_option('', '--config',
- dest='verbose_test_configuration_only',
- default=False,
- action="store_true",
- help='Displays full test specification and MUTs configration and exits')
+ parser.add_argument('--global-loops',
+ dest='test_global_loops_value',
+ type=int,
+ help='Set global number of test loops per test. Default value is set 1')
- parser.add_option('', '--loops',
- dest='test_loops_list',
- help='Set no. of loops per test. Format: TEST_1=1,TEST_2=2,TEST_3=3')
-
- parser.add_option('', '--global-loops',
- dest='test_global_loops_value',
- help='Set global number of test loops per test. Default value is set 1')
+ parser.add_argument('--consolidate-waterfall',
+ dest='consolidate_waterfall_test',
+ default=False,
+ action="store_true",
+ help='Used with --waterfall argument. Adds only one test to report reflecting outcome of waterfall test.')
- parser.add_option('', '--consolidate-waterfall',
- dest='consolidate_waterfall_test',
- default=False,
- action="store_true",
- help='Used with --waterfall option. Adds only one test to report reflecting outcome of waterfall test.')
+ parser.add_argument('-W', '--waterfall',
+ dest='waterfall_test',
+ default=False,
+ action="store_true",
+ help='Used with --loops or --global-loops arguments. Tests until OK result occurs and assumes test passed')
- parser.add_option('-W', '--waterfall',
- dest='waterfall_test',
- default=False,
- action="store_true",
- help='Used with --loops or --global-loops options. Tests until OK result occurs and assumes test passed')
+ parser.add_argument('-N', '--firmware-name',
+ dest='firmware_global_name',
+ help='Set global name for all produced projects. Note, proper file extension will be added by buid scripts')
- parser.add_option('-N', '--firmware-name',
- dest='firmware_global_name',
- help='Set global name for all produced projects. Note, proper file extension will be added by buid scripts')
+ parser.add_argument('-u', '--shuffle',
+ dest='shuffle_test_order',
+ default=False,
+ action="store_true",
+ help='Shuffles test execution order')
- parser.add_option('-u', '--shuffle',
- dest='shuffle_test_order',
- default=False,
- action="store_true",
- help='Shuffles test execution order')
-
- parser.add_option('', '--shuffle-seed',
- dest='shuffle_test_seed',
- default=None,
- help='Shuffle seed (If you want to reproduce your shuffle order please use seed provided in test summary)')
+ parser.add_argument('--shuffle-seed',
+ dest='shuffle_test_seed',
+ default=None,
+ help='Shuffle seed (If you want to reproduce your shuffle order please use seed provided in test summary)')
- parser.add_option('-f', '--filter',
- dest='general_filter_regex',
- default=None,
- help='For some commands you can use filter to filter out results')
+ parser.add_argument('-f', '--filter',
+ dest='general_filter_regex',
+ type=argparse_many(str),
+ default=None,
+ help='For some commands you can use filter to filter out results')
- parser.add_option('', '--inc-timeout',
- dest='extend_test_timeout',
- metavar="NUMBER",
- type="int",
- help='You can increase global timeout for each test by specifying additional test timeout in seconds')
+ parser.add_argument('--inc-timeout',
+ dest='extend_test_timeout',
+ metavar="NUMBER",
+ type=int,
+ help='You can increase global timeout for each test by specifying additional test timeout in seconds')
+
+ parser.add_argument('--db',
+ dest='db_url',
+ help='This specifies what database test suite uses to store its state. To pass DB connection info use database connection string. Example: \'mysql://username:password@127.0.0.1/db_name\'')
- parser.add_option('', '--db',
- dest='db_url',
- help='This specifies what database test suite uses to store its state. To pass DB connection info use database connection string. Example: \'mysql://username:password@127.0.0.1/db_name\'')
+ parser.add_argument('-l', '--log',
+ dest='log_file_name',
+ help='Log events to external file (note not all console entries may be visible in log file)')
- parser.add_option('-l', '--log',
- dest='log_file_name',
- help='Log events to external file (note not all console entries may be visible in log file)')
+ parser.add_argument('--report-html',
+ dest='report_html_file_name',
+ help='You can log test suite results in form of HTML report')
- parser.add_option('', '--report-html',
- dest='report_html_file_name',
- help='You can log test suite results in form of HTML report')
+ parser.add_argument('--report-junit',
+ dest='report_junit_file_name',
+ help='You can log test suite results in form of JUnit compliant XML report')
- parser.add_option('', '--report-junit',
- dest='report_junit_file_name',
- help='You can log test suite results in form of JUnit compliant XML report')
+ parser.add_argument("--report-build",
+ dest="report_build_file_name",
+ help="Output the build results to a junit xml file")
- parser.add_option("", "--report-build",
- dest="report_build_file_name",
- help="Output the build results to a junit xml file")
+ parser.add_argument("--report-text",
+ dest="report_text_file_name",
+ help="Output the build results to a text file")
- parser.add_option('', '--verbose-skipped',
- dest='verbose_skipped_tests',
- default=False,
- action="store_true",
- help='Prints some extra information about skipped tests')
+ parser.add_argument('--verbose-skipped',
+ dest='verbose_skipped_tests',
+ default=False,
+ action="store_true",
+ help='Prints some extra information about skipped tests')
- parser.add_option('-V', '--verbose-test-result',
- dest='verbose_test_result_only',
- default=False,
- action="store_true",
- help='Prints test serial output')
+ parser.add_argument('-V', '--verbose-test-result',
+ dest='verbose_test_result_only',
+ default=False,
+ action="store_true",
+ help='Prints test serial output')
- parser.add_option('-v', '--verbose',
- dest='verbose',
- default=False,
- action="store_true",
- help='Verbose mode (prints some extra information)')
+ parser.add_argument('-v', '--verbose',
+ dest='verbose',
+ default=False,
+ action="store_true",
+ help='Verbose mode (prints some extra information)')
- parser.add_option('', '--version',
- dest='version',
- default=False,
- action="store_true",
- help='Prints script version and exits')
+ parser.add_argument('--version',
+ dest='version',
+ default=False,
+ action="store_true",
+ help='Prints script version and exits')
return parser
def test_path_to_name(path):
@@ -1960,12 +1984,12 @@
while (tail and tail != "."):
name_parts.insert(0, tail)
head, tail = os.path.split(head)
-
+
return "-".join(name_parts).lower()
def find_tests(base_dir):
"""Given any directory, walk through the subdirectories and find all tests"""
-
+
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"}"""
@@ -1979,20 +2003,20 @@
"name": test_path_to_name(directory),
"path": directory
}
-
+
return test
tests_path = 'TESTS'
tests = {}
dirs = scan_for_source_paths(base_dir)
-
+
for directory in dirs:
test = find_test_in_directory(directory, tests_path)
if test:
tests[test['name']] = test['path']
-
+
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"""
@@ -2023,12 +2047,11 @@
continue_on_build_fail=False):
"""Given the data structure from 'find_tests' and the typical build parameters,
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
@@ -2041,9 +2064,10 @@
"binary_type": "bootable",
"tests": {}
}
-
+
result = True
-
+
+ map_outputs_total = list()
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]
@@ -2062,21 +2086,21 @@
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.
if clean:
clean = False
-
+
# Normalize the path
if bin_file:
bin_file = norm_relative_path(bin_file, execution_directory)
-
+
test_build['tests'][test_name] = {
"binaries": [
{
@@ -2084,15 +2108,15 @@
}
]
}
-
+
print 'Image: %s'% bin_file
-
+
test_builds = {}
test_builds["%s-%s" % (target_name, toolchain_name)] = test_build
-
+
return result, test_builds
-
+
def test_spec_from_test_builds(test_builds):
return {
