BA
/
BaBoRo_test2
Backup 1
mbed-os/tools/test/toolchains/api_test.py@0:02dd72d1d465, 2018-04-24 (annotated)
- Committer:
- borlanic
- Date:
- Tue Apr 24 11:45:18 2018 +0000
- Revision:
- 0:02dd72d1d465
BaBoRo_test2 - backup 1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
borlanic | 0:02dd72d1d465 | 1 | """Tests for the toolchain sub-system""" |
borlanic | 0:02dd72d1d465 | 2 | import sys |
borlanic | 0:02dd72d1d465 | 3 | import os |
borlanic | 0:02dd72d1d465 | 4 | from string import printable |
borlanic | 0:02dd72d1d465 | 5 | from copy import deepcopy |
borlanic | 0:02dd72d1d465 | 6 | from mock import MagicMock, patch |
borlanic | 0:02dd72d1d465 | 7 | from hypothesis import given, settings |
borlanic | 0:02dd72d1d465 | 8 | from hypothesis.strategies import text, lists, fixed_dictionaries, booleans |
borlanic | 0:02dd72d1d465 | 9 | |
borlanic | 0:02dd72d1d465 | 10 | ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", |
borlanic | 0:02dd72d1d465 | 11 | "..")) |
borlanic | 0:02dd72d1d465 | 12 | sys.path.insert(0, ROOT) |
borlanic | 0:02dd72d1d465 | 13 | |
borlanic | 0:02dd72d1d465 | 14 | from tools.toolchains import TOOLCHAIN_CLASSES, LEGACY_TOOLCHAIN_NAMES,\ |
borlanic | 0:02dd72d1d465 | 15 | Resources, TOOLCHAIN_PATHS, mbedToolchain |
borlanic | 0:02dd72d1d465 | 16 | from tools.targets import TARGET_MAP |
borlanic | 0:02dd72d1d465 | 17 | |
borlanic | 0:02dd72d1d465 | 18 | ALPHABET = [char for char in printable if char not in [u'.', u'/']] |
borlanic | 0:02dd72d1d465 | 19 | |
borlanic | 0:02dd72d1d465 | 20 | @given(fixed_dictionaries({ |
borlanic | 0:02dd72d1d465 | 21 | 'common': lists(text()), |
borlanic | 0:02dd72d1d465 | 22 | 'c': lists(text()), |
borlanic | 0:02dd72d1d465 | 23 | 'cxx': lists(text()), |
borlanic | 0:02dd72d1d465 | 24 | 'asm': lists(text()), |
borlanic | 0:02dd72d1d465 | 25 | 'ld': lists(text())}), |
borlanic | 0:02dd72d1d465 | 26 | lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) |
borlanic | 0:02dd72d1d465 | 27 | def test_toolchain_profile_c(profile, source_file): |
borlanic | 0:02dd72d1d465 | 28 | """Test that the appropriate profile parameters are passed to the |
borlanic | 0:02dd72d1d465 | 29 | C compiler""" |
borlanic | 0:02dd72d1d465 | 30 | filename = deepcopy(source_file) |
borlanic | 0:02dd72d1d465 | 31 | filename[-1] += ".c" |
borlanic | 0:02dd72d1d465 | 32 | to_compile = os.path.join(*filename) |
borlanic | 0:02dd72d1d465 | 33 | with patch('os.mkdir') as _mkdir: |
borlanic | 0:02dd72d1d465 | 34 | for _, tc_class in TOOLCHAIN_CLASSES.items(): |
borlanic | 0:02dd72d1d465 | 35 | toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile) |
borlanic | 0:02dd72d1d465 | 36 | toolchain.inc_md5 = "" |
borlanic | 0:02dd72d1d465 | 37 | toolchain.build_dir = "" |
borlanic | 0:02dd72d1d465 | 38 | toolchain.config = MagicMock(app_config_location=None) |
borlanic | 0:02dd72d1d465 | 39 | for parameter in profile['c'] + profile['common']: |
borlanic | 0:02dd72d1d465 | 40 | assert any(parameter in cmd for cmd in toolchain.cc), \ |
borlanic | 0:02dd72d1d465 | 41 | "Toolchain %s did not propagate arg %s" % (toolchain.name, |
borlanic | 0:02dd72d1d465 | 42 | parameter) |
borlanic | 0:02dd72d1d465 | 43 | compile_command = toolchain.compile_command(to_compile, |
borlanic | 0:02dd72d1d465 | 44 | to_compile + ".o", []) |
borlanic | 0:02dd72d1d465 | 45 | for parameter in profile['c'] + profile['common']: |
borlanic | 0:02dd72d1d465 | 46 | assert any(parameter in cmd for cmd in compile_command), \ |
borlanic | 0:02dd72d1d465 | 47 | "Toolchain %s did not propagate arg %s" % (toolchain.name, |
borlanic | 0:02dd72d1d465 | 48 | parameter) |
borlanic | 0:02dd72d1d465 | 49 | |
borlanic | 0:02dd72d1d465 | 50 | @given(fixed_dictionaries({ |
borlanic | 0:02dd72d1d465 | 51 | 'common': lists(text()), |
borlanic | 0:02dd72d1d465 | 52 | 'c': lists(text()), |
borlanic | 0:02dd72d1d465 | 53 | 'cxx': lists(text()), |
borlanic | 0:02dd72d1d465 | 54 | 'asm': lists(text()), |
borlanic | 0:02dd72d1d465 | 55 | 'ld': lists(text())}), |
borlanic | 0:02dd72d1d465 | 56 | lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) |
borlanic | 0:02dd72d1d465 | 57 | def test_toolchain_profile_cpp(profile, source_file): |
borlanic | 0:02dd72d1d465 | 58 | """Test that the appropriate profile parameters are passed to the |
borlanic | 0:02dd72d1d465 | 59 | C++ compiler""" |
borlanic | 0:02dd72d1d465 | 60 | filename = deepcopy(source_file) |
borlanic | 0:02dd72d1d465 | 61 | filename[-1] += ".cpp" |
borlanic | 0:02dd72d1d465 | 62 | to_compile = os.path.join(*filename) |
borlanic | 0:02dd72d1d465 | 63 | with patch('os.mkdir') as _mkdir: |
borlanic | 0:02dd72d1d465 | 64 | for _, tc_class in TOOLCHAIN_CLASSES.items(): |
borlanic | 0:02dd72d1d465 | 65 | toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile) |
borlanic | 0:02dd72d1d465 | 66 | toolchain.inc_md5 = "" |
borlanic | 0:02dd72d1d465 | 67 | toolchain.build_dir = "" |
borlanic | 0:02dd72d1d465 | 68 | toolchain.config = MagicMock(app_config_location=None) |
borlanic | 0:02dd72d1d465 | 69 | for parameter in profile['cxx'] + profile['common']: |
borlanic | 0:02dd72d1d465 | 70 | assert any(parameter in cmd for cmd in toolchain.cppc), \ |
borlanic | 0:02dd72d1d465 | 71 | "Toolchain %s did not propagate arg %s" % (toolchain.name, |
borlanic | 0:02dd72d1d465 | 72 | parameter) |
borlanic | 0:02dd72d1d465 | 73 | compile_command = toolchain.compile_command(to_compile, |
borlanic | 0:02dd72d1d465 | 74 | to_compile + ".o", []) |
borlanic | 0:02dd72d1d465 | 75 | for parameter in profile['cxx'] + profile['common']: |
borlanic | 0:02dd72d1d465 | 76 | assert any(parameter in cmd for cmd in compile_command), \ |
borlanic | 0:02dd72d1d465 | 77 | "Toolchain %s did not propagate arg %s" % (toolchain.name, |
borlanic | 0:02dd72d1d465 | 78 | parameter) |
borlanic | 0:02dd72d1d465 | 79 | |
borlanic | 0:02dd72d1d465 | 80 | @given(fixed_dictionaries({ |
borlanic | 0:02dd72d1d465 | 81 | 'common': lists(text()), |
borlanic | 0:02dd72d1d465 | 82 | 'c': lists(text()), |
borlanic | 0:02dd72d1d465 | 83 | 'cxx': lists(text()), |
borlanic | 0:02dd72d1d465 | 84 | 'asm': lists(text()), |
borlanic | 0:02dd72d1d465 | 85 | 'ld': lists(text())}), |
borlanic | 0:02dd72d1d465 | 86 | lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) |
borlanic | 0:02dd72d1d465 | 87 | def test_toolchain_profile_asm(profile, source_file): |
borlanic | 0:02dd72d1d465 | 88 | """Test that the appropriate profile parameters are passed to the |
borlanic | 0:02dd72d1d465 | 89 | Assembler""" |
borlanic | 0:02dd72d1d465 | 90 | filename = deepcopy(source_file) |
borlanic | 0:02dd72d1d465 | 91 | filename[-1] += ".s" |
borlanic | 0:02dd72d1d465 | 92 | to_compile = os.path.join(*filename) |
borlanic | 0:02dd72d1d465 | 93 | with patch('os.mkdir') as _mkdir: |
borlanic | 0:02dd72d1d465 | 94 | for _, tc_class in TOOLCHAIN_CLASSES.items(): |
borlanic | 0:02dd72d1d465 | 95 | toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile) |
borlanic | 0:02dd72d1d465 | 96 | toolchain.inc_md5 = "" |
borlanic | 0:02dd72d1d465 | 97 | toolchain.build_dir = "" |
borlanic | 0:02dd72d1d465 | 98 | for parameter in profile['asm']: |
borlanic | 0:02dd72d1d465 | 99 | assert any(parameter in cmd for cmd in toolchain.asm), \ |
borlanic | 0:02dd72d1d465 | 100 | "Toolchain %s did not propagate arg %s" % (toolchain.name, |
borlanic | 0:02dd72d1d465 | 101 | parameter) |
borlanic | 0:02dd72d1d465 | 102 | compile_command = toolchain.compile_command(to_compile, |
borlanic | 0:02dd72d1d465 | 103 | to_compile + ".o", []) |
borlanic | 0:02dd72d1d465 | 104 | if not compile_command: |
borlanic | 0:02dd72d1d465 | 105 | assert compile_command, to_compile |
borlanic | 0:02dd72d1d465 | 106 | for parameter in profile['asm']: |
borlanic | 0:02dd72d1d465 | 107 | assert any(parameter in cmd for cmd in compile_command), \ |
borlanic | 0:02dd72d1d465 | 108 | "Toolchain %s did not propagate arg %s" % (toolchain.name, |
borlanic | 0:02dd72d1d465 | 109 | parameter) |
borlanic | 0:02dd72d1d465 | 110 | |
borlanic | 0:02dd72d1d465 | 111 | for name, Class in TOOLCHAIN_CLASSES.items(): |
borlanic | 0:02dd72d1d465 | 112 | CLS = Class(TARGET_MAP["K64F"]) |
borlanic | 0:02dd72d1d465 | 113 | assert name == CLS.name or name == LEGACY_TOOLCHAIN_NAMES[CLS.name] |
borlanic | 0:02dd72d1d465 | 114 | |
borlanic | 0:02dd72d1d465 | 115 | @given(fixed_dictionaries({ |
borlanic | 0:02dd72d1d465 | 116 | 'common': lists(text()), |
borlanic | 0:02dd72d1d465 | 117 | 'c': lists(text()), |
borlanic | 0:02dd72d1d465 | 118 | 'cxx': lists(text()), |
borlanic | 0:02dd72d1d465 | 119 | 'asm': lists(text()), |
borlanic | 0:02dd72d1d465 | 120 | 'ld': lists(text(min_size=1))}), |
borlanic | 0:02dd72d1d465 | 121 | lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) |
borlanic | 0:02dd72d1d465 | 122 | def test_toolchain_profile_ld(profile, source_file): |
borlanic | 0:02dd72d1d465 | 123 | """Test that the appropriate profile parameters are passed to the |
borlanic | 0:02dd72d1d465 | 124 | Linker""" |
borlanic | 0:02dd72d1d465 | 125 | filename = deepcopy(source_file) |
borlanic | 0:02dd72d1d465 | 126 | filename[-1] += ".o" |
borlanic | 0:02dd72d1d465 | 127 | to_compile = os.path.join(*filename) |
borlanic | 0:02dd72d1d465 | 128 | with patch('os.mkdir') as _mkdir,\ |
borlanic | 0:02dd72d1d465 | 129 | patch('tools.toolchains.mbedToolchain.default_cmd') as _dflt_cmd: |
borlanic | 0:02dd72d1d465 | 130 | for _, tc_class in TOOLCHAIN_CLASSES.items(): |
borlanic | 0:02dd72d1d465 | 131 | toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile) |
borlanic | 0:02dd72d1d465 | 132 | toolchain.RESPONSE_FILES = False |
borlanic | 0:02dd72d1d465 | 133 | toolchain.inc_md5 = "" |
borlanic | 0:02dd72d1d465 | 134 | toolchain.build_dir = "" |
borlanic | 0:02dd72d1d465 | 135 | for parameter in profile['ld']: |
borlanic | 0:02dd72d1d465 | 136 | assert any(parameter in cmd for cmd in toolchain.ld), \ |
borlanic | 0:02dd72d1d465 | 137 | "Toolchain %s did not propagate arg %s" % (toolchain.name, |
borlanic | 0:02dd72d1d465 | 138 | parameter) |
borlanic | 0:02dd72d1d465 | 139 | toolchain.link(to_compile + ".elf", [to_compile], [], [], None) |
borlanic | 0:02dd72d1d465 | 140 | compile_cmd = _dflt_cmd.call_args_list |
borlanic | 0:02dd72d1d465 | 141 | if not compile_cmd: |
borlanic | 0:02dd72d1d465 | 142 | assert compile_cmd, to_compile |
borlanic | 0:02dd72d1d465 | 143 | for parameter in profile['ld']: |
borlanic | 0:02dd72d1d465 | 144 | assert any(parameter in cmd[0][0] for cmd in compile_cmd), \ |
borlanic | 0:02dd72d1d465 | 145 | "Toolchain %s did not propagate arg %s" % (toolchain.name, |
borlanic | 0:02dd72d1d465 | 146 | parameter) |
borlanic | 0:02dd72d1d465 | 147 | |
borlanic | 0:02dd72d1d465 | 148 | for name, Class in TOOLCHAIN_CLASSES.items(): |
borlanic | 0:02dd72d1d465 | 149 | CLS = Class(TARGET_MAP["K64F"]) |
borlanic | 0:02dd72d1d465 | 150 | assert name == CLS.name or name == LEGACY_TOOLCHAIN_NAMES[CLS.name] |
borlanic | 0:02dd72d1d465 | 151 | |
borlanic | 0:02dd72d1d465 | 152 | |
borlanic | 0:02dd72d1d465 | 153 | @given(lists(text(alphabet=ALPHABET, min_size=1), min_size=1)) |
borlanic | 0:02dd72d1d465 | 154 | def test_detect_duplicates(filenames): |
borlanic | 0:02dd72d1d465 | 155 | c_sources = [os.path.join(name, "dupe.c") for name in filenames] |
borlanic | 0:02dd72d1d465 | 156 | s_sources = [os.path.join(name, "dupe.s") for name in filenames] |
borlanic | 0:02dd72d1d465 | 157 | cpp_sources = [os.path.join(name, "dupe.cpp") for name in filenames] |
borlanic | 0:02dd72d1d465 | 158 | with MagicMock() as notify: |
borlanic | 0:02dd72d1d465 | 159 | toolchain = TOOLCHAIN_CLASSES["ARM"](TARGET_MAP["K64F"], notify=notify) |
borlanic | 0:02dd72d1d465 | 160 | res = Resources() |
borlanic | 0:02dd72d1d465 | 161 | res.c_sources = c_sources |
borlanic | 0:02dd72d1d465 | 162 | res.s_sources = s_sources |
borlanic | 0:02dd72d1d465 | 163 | res.cpp_sources = cpp_sources |
borlanic | 0:02dd72d1d465 | 164 | assert res.detect_duplicates(toolchain) == 1,\ |
borlanic | 0:02dd72d1d465 | 165 | "Not Enough duplicates found" |
borlanic | 0:02dd72d1d465 | 166 | |
borlanic | 0:02dd72d1d465 | 167 | _, (notification, _), _ = notify.mock_calls[1] |
borlanic | 0:02dd72d1d465 | 168 | assert "dupe.o" in notification["message"] |
borlanic | 0:02dd72d1d465 | 169 | assert "dupe.s" in notification["message"] |
borlanic | 0:02dd72d1d465 | 170 | assert "dupe.c" in notification["message"] |
borlanic | 0:02dd72d1d465 | 171 | assert "dupe.cpp" in notification["message"] |
borlanic | 0:02dd72d1d465 | 172 | |
borlanic | 0:02dd72d1d465 | 173 | @given(text(alphabet=ALPHABET + ["/"], min_size=1)) |
borlanic | 0:02dd72d1d465 | 174 | @given(booleans()) |
borlanic | 0:02dd72d1d465 | 175 | @given(booleans()) |
borlanic | 0:02dd72d1d465 | 176 | @settings(max_examples=20) |
borlanic | 0:02dd72d1d465 | 177 | def test_path_specified_gcc(gcc_loc, exists_at_loc, exists_in_path): |
borlanic | 0:02dd72d1d465 | 178 | with patch('tools.toolchains.gcc.exists') as _exists: |
borlanic | 0:02dd72d1d465 | 179 | with patch('tools.toolchains.gcc.find_executable') as _find: |
borlanic | 0:02dd72d1d465 | 180 | _exists.return_value = exists_at_loc |
borlanic | 0:02dd72d1d465 | 181 | _find.return_value = exists_in_path |
borlanic | 0:02dd72d1d465 | 182 | TOOLCHAIN_PATHS['GCC_ARM'] = gcc_loc |
borlanic | 0:02dd72d1d465 | 183 | toolchain_class = TOOLCHAIN_CLASSES["GCC_ARM"] |
borlanic | 0:02dd72d1d465 | 184 | found_p = toolchain_class.check_executable() |
borlanic | 0:02dd72d1d465 | 185 | assert found_p == (exists_at_loc or exists_in_path) |
borlanic | 0:02dd72d1d465 | 186 | if exists_at_loc: |
borlanic | 0:02dd72d1d465 | 187 | assert TOOLCHAIN_PATHS['GCC_ARM'] == gcc_loc |
borlanic | 0:02dd72d1d465 | 188 | elif exists_in_path: |
borlanic | 0:02dd72d1d465 | 189 | assert TOOLCHAIN_PATHS['GCC_ARM'] == '' |