Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers api_test.py Source File

api_test.py

00001 """Tests for the toolchain sub-system"""
00002 import sys
00003 import os
00004 from string import printable
00005 from copy import deepcopy
00006 from mock import MagicMock, patch
00007 from hypothesis import given, settings
00008 from hypothesis.strategies import text, lists, fixed_dictionaries, booleans
00009 
00010 ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..",
00011                                     ".."))
00012 sys.path.insert(0, ROOT)
00013 
00014 from tools.toolchains import TOOLCHAIN_CLASSES, LEGACY_TOOLCHAIN_NAMES,\
00015     Resources, TOOLCHAIN_PATHS, mbedToolchain
00016 from tools.targets import TARGET_MAP
00017 
00018 ALPHABET = [char for char in printable if char not in [u'.', u'/']]
00019 
00020 @given(fixed_dictionaries({
00021     'common': lists(text()),
00022     'c': lists(text()),
00023     'cxx': lists(text()),
00024     'asm': lists(text()),
00025     'ld': lists(text())}),
00026        lists(text(min_size=1, alphabet=ALPHABET), min_size=1))
00027 def test_toolchain_profile_c (profile, source_file):
00028     """Test that the appropriate profile parameters are passed to the
00029     C compiler"""
00030     filename = deepcopy(source_file)
00031     filename[-1] += ".c"
00032     to_compile = os.path.join(*filename)
00033     with patch('os.mkdir') as _mkdir:
00034         for _, tc_class in TOOLCHAIN_CLASSES.items():
00035             toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile)
00036             toolchain.inc_md5 = ""
00037             toolchain.build_dir = ""
00038             toolchain.config = MagicMock(app_config_location=None)
00039             for parameter in profile['c'] + profile['common']:
00040                 assert any(parameter in cmd for cmd in toolchain.cc), \
00041                     "Toolchain %s did not propagate arg %s" % (toolchain.name,
00042                                                             parameter)
00043             compile_command = toolchain.compile_command(to_compile,
00044                                                         to_compile + ".o", [])
00045             for parameter in profile['c'] + profile['common']:
00046                 assert any(parameter in cmd for cmd in compile_command), \
00047                     "Toolchain %s did not propagate arg %s" % (toolchain.name,
00048                                                             parameter)
00049 
00050 @given(fixed_dictionaries({
00051     'common': lists(text()),
00052     'c': lists(text()),
00053     'cxx': lists(text()),
00054     'asm': lists(text()),
00055     'ld': lists(text())}),
00056        lists(text(min_size=1, alphabet=ALPHABET), min_size=1))
00057 def test_toolchain_profile_cpp (profile, source_file):
00058     """Test that the appropriate profile parameters are passed to the
00059     C++ compiler"""
00060     filename = deepcopy(source_file)
00061     filename[-1] += ".cpp"
00062     to_compile = os.path.join(*filename)
00063     with patch('os.mkdir') as _mkdir:
00064         for _, tc_class in TOOLCHAIN_CLASSES.items():
00065             toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile)
00066             toolchain.inc_md5 = ""
00067             toolchain.build_dir = ""
00068             toolchain.config = MagicMock(app_config_location=None)
00069             for parameter in profile['cxx'] + profile['common']:
00070                 assert any(parameter in cmd for cmd in toolchain.cppc), \
00071                     "Toolchain %s did not propagate arg %s" % (toolchain.name,
00072                                                             parameter)
00073             compile_command = toolchain.compile_command(to_compile,
00074                                                         to_compile + ".o", [])
00075             for parameter in profile['cxx'] + profile['common']:
00076                 assert any(parameter in cmd for cmd in compile_command), \
00077                     "Toolchain %s did not propagate arg %s" % (toolchain.name,
00078                                                             parameter)
00079 
00080 @given(fixed_dictionaries({
00081     'common': lists(text()),
00082     'c': lists(text()),
00083     'cxx': lists(text()),
00084     'asm': lists(text()),
00085     'ld': lists(text())}),
00086        lists(text(min_size=1, alphabet=ALPHABET), min_size=1))
00087 def test_toolchain_profile_asm (profile, source_file):
00088     """Test that the appropriate profile parameters are passed to the
00089     Assembler"""
00090     filename = deepcopy(source_file)
00091     filename[-1] += ".s"
00092     to_compile = os.path.join(*filename)
00093     with patch('os.mkdir') as _mkdir:
00094         for _, tc_class in TOOLCHAIN_CLASSES.items():
00095             toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile)
00096             toolchain.inc_md5 = ""
00097             toolchain.build_dir = ""
00098             for parameter in profile['asm']:
00099                 assert any(parameter in cmd for cmd in toolchain.asm), \
00100                     "Toolchain %s did not propagate arg %s" % (toolchain.name,
00101                                                                parameter)
00102             compile_command = toolchain.compile_command(to_compile,
00103                                                         to_compile + ".o", [])
00104             if not compile_command:
00105                 assert compile_command, to_compile
00106             for parameter in profile['asm']:
00107                 assert any(parameter in cmd for cmd in compile_command), \
00108                     "Toolchain %s did not propagate arg %s" % (toolchain.name,
00109                                                                parameter)
00110 
00111     for name, Class in  TOOLCHAIN_CLASSES.items():
00112         CLS = Class(TARGET_MAP["K64F"])
00113         assert name == CLS.name or name ==  LEGACY_TOOLCHAIN_NAMES[CLS.name]
00114 
00115 @given(fixed_dictionaries({
00116     'common': lists(text()),
00117     'c': lists(text()),
00118     'cxx': lists(text()),
00119     'asm': lists(text()),
00120     'ld': lists(text(min_size=1))}),
00121        lists(text(min_size=1, alphabet=ALPHABET), min_size=1))
00122 def test_toolchain_profile_ld (profile, source_file):
00123     """Test that the appropriate profile parameters are passed to the
00124     Linker"""
00125     filename = deepcopy(source_file)
00126     filename[-1] += ".o"
00127     to_compile = os.path.join(*filename)
00128     with patch('os.mkdir') as _mkdir,\
00129          patch('tools.toolchains.mbedToolchain.default_cmd') as _dflt_cmd:
00130         for _, tc_class in TOOLCHAIN_CLASSES.items():
00131             toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile)
00132             toolchain.RESPONSE_FILES = False
00133             toolchain.inc_md5 = ""
00134             toolchain.build_dir = ""
00135             for parameter in profile['ld']:
00136                 assert any(parameter in cmd for cmd in toolchain.ld), \
00137                     "Toolchain %s did not propagate arg %s" % (toolchain.name,
00138                                                                parameter)
00139             toolchain.link(to_compile + ".elf", [to_compile], [], [], None)
00140             compile_cmd = _dflt_cmd.call_args_list
00141             if not compile_cmd:
00142                 assert compile_cmd, to_compile
00143             for parameter in profile['ld']:
00144                 assert any(parameter in cmd[0][0] for cmd in compile_cmd), \
00145                     "Toolchain %s did not propagate arg %s" % (toolchain.name,
00146                                                                parameter)
00147 
00148     for name, Class in  TOOLCHAIN_CLASSES.items():
00149         CLS = Class(TARGET_MAP["K64F"])
00150         assert name == CLS.name or name ==  LEGACY_TOOLCHAIN_NAMES[CLS.name]
00151 
00152 
00153 @given(lists(text(alphabet=ALPHABET, min_size=1), min_size=1))
00154 def test_detect_duplicates(filenames):
00155     c_sources = [os.path.join(name, "dupe.c") for name in filenames]
00156     s_sources = [os.path.join(name, "dupe.s") for name in filenames]
00157     cpp_sources = [os.path.join(name, "dupe.cpp") for name in filenames]
00158     with MagicMock() as notify:
00159         toolchain = TOOLCHAIN_CLASSES["ARM"](TARGET_MAP["K64F"], notify=notify)
00160         res = Resources()
00161         res.c_sources = c_sources
00162         res.s_sources = s_sources
00163         res.cpp_sources = cpp_sources
00164         assert res.detect_duplicates(toolchain) == 1,\
00165             "Not Enough duplicates found"
00166 
00167         _, (notification, _), _ = notify.mock_calls[1]
00168         assert "dupe.o" in notification["message"]
00169         assert "dupe.s" in notification["message"]
00170         assert "dupe.c" in notification["message"]
00171         assert "dupe.cpp" in notification["message"]
00172 
00173 @given(text(alphabet=ALPHABET + ["/"], min_size=1))
00174 @given(booleans())
00175 @given(booleans())
00176 @settings(max_examples=20)
00177 def test_path_specified_gcc(gcc_loc, exists_at_loc, exists_in_path):
00178     with patch('tools.toolchains.gcc.exists') as _exists:
00179         with patch('tools.toolchains.gcc.find_executable') as _find:
00180             _exists.return_value = exists_at_loc
00181             _find.return_value = exists_in_path
00182             TOOLCHAIN_PATHS['GCC_ARM'] = gcc_loc
00183             toolchain_class = TOOLCHAIN_CLASSES["GCC_ARM"]
00184             found_p = toolchain_class.check_executable()
00185             assert found_p == (exists_at_loc or exists_in_path)
00186             if exists_at_loc:
00187                 assert TOOLCHAIN_PATHS['GCC_ARM'] == gcc_loc
00188             elif exists_in_path:
00189                 assert TOOLCHAIN_PATHS['GCC_ARM'] == ''