| # Copyright (c) 2020 Teslabs Engineering S.L. |
| # |
| # SPDX-License-Identifier: Apache-2.0 |
| |
| import argparse |
| from pathlib import Path |
| from unittest.mock import patch, call |
| |
| import pytest |
| |
| from runners.stm32cubeprogrammer import STM32CubeProgrammerBinaryRunner |
| from conftest import RC_KERNEL_HEX, RC_KERNEL_ELF |
| |
| |
| CLI_PATH = Path("STM32_Programmer_CLI") |
| """Default CLI path used in tests.""" |
| |
| HOME_PATH = Path("/home", "test") |
| """Home path (used for Linux system CLI path).""" |
| |
| PROGRAMFILESX86_PATH = Path("C:", "Program Files (x86)") |
| """Program files x86 path (used for Windows system CLI path).""" |
| |
| ENVIRON = { |
| "PROGRAMFILES(X86)": str(PROGRAMFILESX86_PATH), |
| } |
| """Environment (used for Windows system CLI path).""" |
| |
| LINUX_CLI_PATH = ( |
| HOME_PATH |
| / "STMicroelectronics" |
| / "STM32Cube" |
| / "STM32CubeProgrammer" |
| / "bin" |
| / "STM32_Programmer_CLI" |
| ) |
| """Linux CLI path.""" |
| |
| WINDOWS_CLI_PATH = ( |
| PROGRAMFILESX86_PATH |
| / "STMicroelectronics" |
| / "STM32Cube" |
| / "STM32CubeProgrammer" |
| / "bin" |
| / "STM32_Programmer_CLI.exe" |
| ) |
| """Windows CLI path.""" |
| |
| MACOS_CLI_PATH = ( |
| Path("/Applications") |
| / "STMicroelectronics" |
| / "STM32Cube" |
| / "STM32CubeProgrammer" |
| / "STM32CubeProgrammer.app" |
| / "Contents" |
| / "MacOs" |
| / "bin" |
| / "STM32_Programmer_CLI" |
| ) |
| """macOS CLI path.""" |
| |
| TEST_CASES = ( |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": None, |
| "conn_modifiers": None, |
| "cli": CLI_PATH, |
| "use_elf": False, |
| "erase": False, |
| "extload": None, |
| "tool_opt": [], |
| "system": "", |
| "cli_path": str(CLI_PATH), |
| "calls": [ |
| [ |
| str(CLI_PATH), |
| "--connect", |
| "port=swd", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": "4000", |
| "reset_mode": None, |
| "conn_modifiers": None, |
| "cli": CLI_PATH, |
| "use_elf": False, |
| "erase": False, |
| "extload": None, |
| "tool_opt": [], |
| "system": "", |
| "cli_path": str(CLI_PATH), |
| "calls": [ |
| [ |
| str(CLI_PATH), |
| "--connect", |
| "port=swd freq=4000", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": "hw", |
| "conn_modifiers": None, |
| "cli": CLI_PATH, |
| "use_elf": False, |
| "erase": False, |
| "extload": None, |
| "tool_opt": [], |
| "system": "", |
| "cli_path": str(CLI_PATH), |
| "calls": [ |
| [ |
| str(CLI_PATH), |
| "--connect", |
| "port=swd reset=HWrst", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": "sw", |
| "conn_modifiers": None, |
| "cli": CLI_PATH, |
| "use_elf": False, |
| "erase": False, |
| "extload": None, |
| "tool_opt": [], |
| "system": "", |
| "cli_path": str(CLI_PATH), |
| "calls": [ |
| [ |
| str(CLI_PATH), |
| "--connect", |
| "port=swd reset=SWrst", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": "core", |
| "conn_modifiers": None, |
| "cli": CLI_PATH, |
| "use_elf": False, |
| "erase": False, |
| "extload": None, |
| "tool_opt": [], |
| "system": "", |
| "cli_path": str(CLI_PATH), |
| "calls": [ |
| [ |
| str(CLI_PATH), |
| "--connect", |
| "port=swd reset=Crst", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": None, |
| "conn_modifiers": "br=115200 sn=TEST", |
| "cli": CLI_PATH, |
| "use_elf": False, |
| "erase": False, |
| "extload": None, |
| "tool_opt": [], |
| "system": "", |
| "cli_path": str(CLI_PATH), |
| "calls": [ |
| [ |
| str(CLI_PATH), |
| "--connect", |
| "port=swd br=115200 sn=TEST", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": None, |
| "conn_modifiers": None, |
| "cli": CLI_PATH, |
| "use_elf": True, |
| "erase": False, |
| "extload": None, |
| "tool_opt": [], |
| "system": "", |
| "cli_path": str(CLI_PATH), |
| "calls": [ |
| [ |
| str(CLI_PATH), |
| "--connect", |
| "port=swd", |
| "--download", |
| RC_KERNEL_ELF, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": None, |
| "conn_modifiers": None, |
| "cli": CLI_PATH, |
| "use_elf": False, |
| "erase": True, |
| "extload": None, |
| "tool_opt": [], |
| "system": "", |
| "cli_path": str(CLI_PATH), |
| "calls": [ |
| [str(CLI_PATH), "--connect", "port=swd", "--erase", "all",], |
| [ |
| str(CLI_PATH), |
| "--connect", |
| "port=swd", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": None, |
| "conn_modifiers": None, |
| "cli": CLI_PATH, |
| "use_elf": False, |
| "erase": False, |
| "extload": None, |
| "tool_opt": ["--skipErase"], |
| "system": "", |
| "cli_path": str(CLI_PATH), |
| "calls": [ |
| [ |
| str(CLI_PATH), |
| "--connect", |
| "port=swd", |
| "--skipErase", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": None, |
| "conn_modifiers": None, |
| "cli": None, |
| "use_elf": False, |
| "erase": False, |
| "extload": None, |
| "tool_opt": [], |
| "system": "Linux", |
| "cli_path": str(LINUX_CLI_PATH), |
| "calls": [ |
| [ |
| str(LINUX_CLI_PATH), |
| "--connect", |
| "port=swd", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": None, |
| "conn_modifiers": None, |
| "cli": None, |
| "use_elf": False, |
| "erase": False, |
| "extload": None, |
| "tool_opt": [], |
| "system": "Darwin", |
| "cli_path": str(MACOS_CLI_PATH), |
| "calls": [ |
| [ |
| str(MACOS_CLI_PATH), |
| "--connect", |
| "port=swd", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| { |
| "port": "swd", |
| "frequency": None, |
| "reset_mode": None, |
| "conn_modifiers": None, |
| "cli": None, |
| "use_elf": False, |
| "erase": False, |
| "extload": None, |
| "tool_opt": [], |
| "system": "Windows", |
| "cli_path": str(WINDOWS_CLI_PATH), |
| "calls": [ |
| [ |
| str(WINDOWS_CLI_PATH), |
| "--connect", |
| "port=swd", |
| "--download", |
| RC_KERNEL_HEX, |
| "--start", |
| ], |
| ], |
| }, |
| ) |
| """Test cases.""" |
| |
| |
| @pytest.mark.parametrize("tc", TEST_CASES) |
| @patch("runners.stm32cubeprogrammer.platform.system") |
| @patch("runners.stm32cubeprogrammer.Path.home", return_value=HOME_PATH) |
| @patch("runners.stm32cubeprogrammer.Path.exists", return_value=True) |
| @patch.dict("runners.stm32cubeprogrammer.os.environ", ENVIRON) |
| @patch("runners.core.ZephyrBinaryRunner.require") |
| @patch("runners.stm32cubeprogrammer.STM32CubeProgrammerBinaryRunner.check_call") |
| def test_stm32cubeprogrammer_init( |
| check_call, require, path_exists, path_home, system, tc, runner_config |
| ): |
| """Tests that ``STM32CubeProgrammerBinaryRunner`` class can be initialized |
| and that ``flash`` command works as expected. |
| """ |
| |
| system.return_value = tc["system"] |
| |
| runner = STM32CubeProgrammerBinaryRunner( |
| cfg=runner_config, |
| port=tc["port"], |
| frequency=tc["frequency"], |
| reset_mode=tc["reset_mode"], |
| conn_modifiers=tc["conn_modifiers"], |
| cli=tc["cli"], |
| use_elf=tc["use_elf"], |
| erase=tc["erase"], |
| extload=tc["extload"], |
| tool_opt=tc["tool_opt"], |
| ) |
| |
| runner.run("flash") |
| |
| require.assert_called_with(tc["cli_path"]) |
| assert check_call.call_args_list == [call(x) for x in tc["calls"]] |
| |
| |
| @pytest.mark.parametrize("tc", TEST_CASES) |
| @patch("runners.stm32cubeprogrammer.platform.system") |
| @patch("runners.stm32cubeprogrammer.Path.home", return_value=HOME_PATH) |
| @patch("runners.stm32cubeprogrammer.Path.exists", return_value=True) |
| @patch.dict("runners.stm32cubeprogrammer.os.environ", ENVIRON) |
| @patch("runners.core.ZephyrBinaryRunner.require") |
| @patch("runners.stm32cubeprogrammer.STM32CubeProgrammerBinaryRunner.check_call") |
| def test_stm32cubeprogrammer_create( |
| check_call, require, path_exists, path_home, system, tc, runner_config |
| ): |
| """Tests that ``STM32CubeProgrammerBinaryRunner`` class can be created using |
| the ``create`` factory method and that ``flash`` command works as expected. |
| """ |
| |
| system.return_value = tc["system"] |
| |
| args = ["--port", tc["port"]] |
| if tc["frequency"]: |
| args.extend(["--frequency", tc["frequency"]]) |
| if tc["reset_mode"]: |
| args.extend(["--reset-mode", tc["reset_mode"]]) |
| if tc["conn_modifiers"]: |
| args.extend(["--conn-modifiers", tc["conn_modifiers"]]) |
| if tc["cli"]: |
| args.extend(["--cli", str(tc["cli"])]) |
| if tc["use_elf"]: |
| args.extend(["--use-elf"]) |
| if tc["erase"]: |
| args.append("--erase") |
| if tc["extload"]: |
| args.extend(["--extload", tc["extload"]]) |
| if tc["tool_opt"]: |
| args.extend(["--tool-opt", " " + tc["tool_opt"][0]]) |
| |
| parser = argparse.ArgumentParser(allow_abbrev=False) |
| STM32CubeProgrammerBinaryRunner.add_parser(parser) |
| arg_namespace = parser.parse_args(args) |
| |
| runner = STM32CubeProgrammerBinaryRunner.create(runner_config, arg_namespace) |
| runner.run("flash") |
| |
| require.assert_called_with(tc["cli_path"]) |
| assert check_call.call_args_list == [call(x) for x in tc["calls"]] |