From fd04ea2125c9433d76d5a1134f881269f5710ab3 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Tue, 27 Sep 2016 17:40:18 -0500 Subject: [PATCH] Added property based regression test to travis --- .travis.yml | 1 + tools/test/toolchains/api.py | 72 ++++++++++++++++++++++++++++++++++++ tools/toolchains/__init__.py | 4 +- 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eb45b7c638..d4174f2d10 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,3 +19,4 @@ install: - sudo pip install jinja2 - sudo pip install pytest - sudo pip install pylint + - sudo pip install hypothesis diff --git a/tools/test/toolchains/api.py b/tools/test/toolchains/api.py index 1452f58c01..618ce08fb8 100644 --- a/tools/test/toolchains/api.py +++ b/tools/test/toolchains/api.py @@ -1,5 +1,9 @@ import sys import os +from string import printable +from copy import deepcopy +from hypothesis import given +from hypothesis.strategies import text, lists, fixed_dictionaries ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..")) sys.path.insert(0, ROOT) @@ -11,3 +15,71 @@ def test_instantiation(): for name, Class in TOOLCHAIN_CLASSES.items(): CLS = Class(TARGET_MAP["K64F"]) assert name == CLS.name or name == LEGACY_TOOLCHAIN_NAMES[CLS.name] + +ALPHABET = [char for char in printable if char not in [u'.', u'/']] + +@given(fixed_dictionaries({ + 'common': lists(text()), + 'c': lists(text()), + 'cxx': lists(text()), + 'asm': lists(text()), + 'ld': lists(text())}), + lists(text(min_size=1, alphabet=ALPHABET), min_size=1) +) +def test_toolchain_profile_c(profile, source_file): + filename = deepcopy(source_file) + filename[-1] += ".c" + to_compile = os.path.join(*filename) + for name, Class in TOOLCHAIN_CLASSES.items(): + CLS = Class(TARGET_MAP["K64F"], build_profile=profile) + CLS.inc_md5 = "" + CLS.build_dir = "" + compile_command = CLS.compile_command(to_compile, to_compile + ".o", []) + for parameter in profile['c'] + profile['common']: + assert any(parameter in cmd for cmd in compile_command), \ + "Toolchain %s did not propigate arg %s" % (CLS.name, parameter) + +@given(fixed_dictionaries({ + 'common': lists(text()), + 'c': lists(text()), + 'cxx': lists(text()), + 'asm': lists(text()), + 'ld': lists(text())}), + lists(text(min_size=1, alphabet=ALPHABET), min_size=1) +) +def test_toolchain_profile_cpp(profile, source_file): + filename = deepcopy(source_file) + filename[-1] += ".cpp" + to_compile = os.path.join(*filename) + for name, Class in TOOLCHAIN_CLASSES.items(): + CLS = Class(TARGET_MAP["K64F"], build_profile=profile) + CLS.inc_md5 = "" + CLS.build_dir = "" + compile_command = CLS.compile_command(to_compile, to_compile + ".o", []) + for parameter in profile['cxx'] + profile['common']: + assert any(parameter in cmd for cmd in compile_command), \ + "Toolchain %s did not propigate arg %s" % (CLS.name, parameter) + +@given(fixed_dictionaries({ + 'common': lists(text()), + 'c': lists(text()), + 'cxx': lists(text()), + 'asm': lists(text()), + 'ld': lists(text())}), + lists(text(min_size=1, alphabet=ALPHABET), min_size=1) +) +def test_toolchain_profile_asm(profile, source_file): + filename = deepcopy(source_file) + filename[-1] += ".s" + to_compile = os.path.join(*filename) + for name, Class in TOOLCHAIN_CLASSES.items(): + CLS = Class(TARGET_MAP["K64F"], build_profile=profile) + CLS.inc_md5 = "" + CLS.build_dir = "" + compile_command = CLS.compile_command(to_compile, to_compile + ".o", []) + if not compile_command: + assert compile_command, to_compile + for parameter in profile['asm']: + assert any(parameter in cmd for cmd in compile_command), \ + "Toolchain %s did not propigate arg %s" % (CLS.name, parameter) + diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 54d50f0d2c..35a5509ec1 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -217,6 +217,8 @@ class mbedToolchain: __metaclass__ = ABCMeta + profile_template = {'common':[], 'c':[], 'cxx':[], 'asm':[], 'ld':[]} + def __init__(self, target, notify=None, macros=None, silent=False, extra_verbose=False, build_profile=None): self.target = target self.name = self.__class__.__name__ @@ -225,7 +227,7 @@ class mbedToolchain: self.hook = hooks.Hook(target, self) # Toolchain flags - self.flags = deepcopy(build_profile) + self.flags = deepcopy(build_profile or self.profile_template) # User-defined macros self.macros = macros or []