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