From 2e932d5535a8a4579c9fb2514f6f33a6edefa6c4 Mon Sep 17 00:00:00 2001 From: kai-ma Date: Thu, 24 Jul 2025 18:44:32 +0800 Subject: [PATCH] add run_ut --- msprobe/test/UT/.coveragerc | 3 ++ msprobe/test/UT/CMakeLists.txt | 1 + msprobe/test/UT/pytest.ini | 3 ++ msprobe/test/UT/run_ut.py | 35 ++++++++++++++++++++ msprobe/test/UT/run_ut.sh | 56 ++++++++++++++++++++++++++++++++ msprobe/test/UT/test___main__.py | 38 ++++++++++++++++++++++ 6 files changed, 136 insertions(+) create mode 100644 msprobe/test/UT/.coveragerc create mode 100644 msprobe/test/UT/CMakeLists.txt create mode 100644 msprobe/test/UT/pytest.ini create mode 100644 msprobe/test/UT/run_ut.py create mode 100644 msprobe/test/UT/run_ut.sh create mode 100644 msprobe/test/UT/test___main__.py diff --git a/msprobe/test/UT/.coveragerc b/msprobe/test/UT/.coveragerc new file mode 100644 index 000000000..99f94acd0 --- /dev/null +++ b/msprobe/test/UT/.coveragerc @@ -0,0 +1,3 @@ +[run] +# 计算覆盖率时排除单元测试文件本身 +omit = */test_*.py diff --git a/msprobe/test/UT/CMakeLists.txt b/msprobe/test/UT/CMakeLists.txt new file mode 100644 index 000000000..fe94d13c7 --- /dev/null +++ b/msprobe/test/UT/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(csrc_ut) diff --git a/msprobe/test/UT/pytest.ini b/msprobe/test/UT/pytest.ini new file mode 100644 index 000000000..c24fe5bb9 --- /dev/null +++ b/msprobe/test/UT/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +filterwarnings = + ignore::DeprecationWarning diff --git a/msprobe/test/UT/run_ut.py b/msprobe/test/UT/run_ut.py new file mode 100644 index 000000000..0a60699b6 --- /dev/null +++ b/msprobe/test/UT/run_ut.py @@ -0,0 +1,35 @@ +import os + +from msprobe.utils.log import logger +from msprobe.utils.toolkits import run_subprocess + + +class RunUT: + def __init__(self): + self.cur_dir = os.path.realpath(os.path.dirname(__file__)) + self.cov_dir = os.path.join(os.path.dirname(self.cur_dir), "../msprobe") + self.report_dir = os.path.join(self.cur_dir, "report") + self.cov_config_path = os.path.join(self.cur_dir, ".coveragerc") + self.final_xml_path = os.path.join(self.report_dir, "final.xml") + self.html_cov_report = os.path.join(self.report_dir, "htmlcov") + self.xml_cov_report = os.path.join(self.report_dir, "coverage.xml") + self.cmd = [ + "python3", + "-m", + "pytest", + self.cur_dir, + f"--junitxml={self.final_xml_path}", + f"--cov-config={self.cov_config_path}", + f"--cov={self.cov_dir}", + "--cov-branch", + f"--cov-report=html:{self.html_cov_report}", + f"--cov-report=xml:{self.xml_cov_report}", + ] + + def execute(self): + run_subprocess(self.cmd) + logger.info("Unit tests executed successfully.") + + +if __name__ == "__main__": + RunUT().execute() diff --git a/msprobe/test/UT/run_ut.sh b/msprobe/test/UT/run_ut.sh new file mode 100644 index 000000000..0fb1bb857 --- /dev/null +++ b/msprobe/test/UT/run_ut.sh @@ -0,0 +1,56 @@ +#!/bin/bash +CUR_DIR=$(dirname $(readlink -f $0)) +TOP_DIR=${CUR_DIR}/../.. +MSIT_TEST=${TOP_DIR}/output/release/test/UT/csrc_ut/msprobe_test +TEST_DIR=${TOP_DIR}/test/UT +SRC_DIR=${TOP_DIR}/ + +run_ut_cpp() { + echo "[INFO] Start compiling msprobe_test..." + ARCH_TYPE=$(uname -m) + PYTHON_VERSION=$(python3 -c 'import platform; print(".".join(platform.python_version_tuple()[:2]))') + BUILD_SCRIPT=${TOP_DIR}/build.sh + if [[ ! -f "${BUILD_SCRIPT}" ]]; then + echo "[ERROR] build.sh not found at ${BUILD_SCRIPT}" + exit 1 + fi + bash "${BUILD_SCRIPT}" \ + --release \ + -t \ + -a "${ARCH_TYPE}" \ + -v "${PYTHON_VERSION}" \ + -j 16 \ + + if [[ -x "${MSIT_TEST}" ]]; then + echo "[INFO] Running C++ unit test binary: ${MSIT_TEST}" + ${MSIT_TEST} + else + echo "[ERROR] msprobe_test binary not found or not executable at ${MSIT_TEST}" + exit 1 + fi +} + +install_pytest() { + if ! pip show pytest &> /dev/null; then + echo "pytest not found, trying to install..." + pip install pytest + fi + + if ! pip show pytest-cov &> /dev/null; then + echo "pytest-cov not found, trying to install..." + pip install pytest-cov + fi +} + +run_ut_py() { + install_pytest + export PYTHONPATH=${SRC_DIR}:${PYTHONPATH} + python3 run_ut.py +} + +main() { + run_ut_cpp + cd ${TEST_DIR} && run_ut_py +} + +main $@ diff --git a/msprobe/test/UT/test___main__.py b/msprobe/test/UT/test___main__.py new file mode 100644 index 000000000..00d4b1b27 --- /dev/null +++ b/msprobe/test/UT/test___main__.py @@ -0,0 +1,38 @@ +from unittest import TestCase +from unittest.mock import MagicMock, patch + + +class TestMainFunction(TestCase): + @patch("msprobe.__main__.MainCommand") + def test_main_execution_flow(self, mock_main_command): + mock_instance = MagicMock() + mock_main_command.return_value = mock_instance + mock_args = MagicMock() + mock_instance.parse.return_value = mock_args + from msprobe.__main__ import main + + main() + mock_main_command.assert_called_once() + mock_instance.parse.assert_called_once() + mock_instance.execute.assert_called_once_with(mock_args) + + @patch("msprobe.__main__.MainCommand") + def test_direct_execution(self, mock_main_command): + with patch("sys.argv", ["script_name"]): + from msprobe.__main__ import main + + main() + mock_main_command.return_value.execute.assert_called_once() + + def test_main_called_in_if_main(self): + mock_instance = MagicMock() + mock_instance.parse.return_value = "mock_args" + MockMainCommand = MagicMock(return_value=mock_instance) + with patch("msprobe.__main__.MainCommand", MockMainCommand): + from msprobe.__main__ import main + + main() + MockMainCommand.assert_called_once() + mock_instance.register.assert_called_once() + mock_instance.parse.assert_called_once() + mock_instance.execute.assert_called_once_with("mock_args") -- Gitee