"""
install_sys_pkg.py 系统测试
测试 ascend_deployer/library/install_sys_pkg.py 模块。
"""
import abc
import os
import sys
import types
from unittest.mock import patch, MagicMock, Mock
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))
test_dir = os.path.join(project_root, 'test')
path_method = getattr(sys, 'path')
insert_method = getattr(path_method, 'insert')
if project_root not in path_method:
insert_method(0, project_root)
if test_dir not in path_method:
insert_method(0, test_dir)
from library_test.base_test import BaseLibraryTest
from library_test.mock_manage.mock_model.mock_ansible_module import AnsibleModule
from library_test.mock_manage.mock_handlers.mock_cmd_handler import MockCmdHandler
ANSIBLE_FIELD = "ansible"
MODULE_UTILS_FIELD = f"{ANSIBLE_FIELD}.module_utils"
BASIC_FIELD = f"{MODULE_UTILS_FIELD}.basic"
COMMON_INFO_FIELD = f"{MODULE_UTILS_FIELD}.common_info"
PATH_MANAGER_FIELD = f"{MODULE_UTILS_FIELD}.path_manager"
SAFE_FILE_HANDLER_FIELD = f"{MODULE_UTILS_FIELD}.safe_file_handler"
COMMON_UTILS_FIELD = f"{MODULE_UTILS_FIELD}.common_utils"
DOCKER_FIELD = "docker"
DOCKER_CE_FIELD = "docker-ce"
OS_FIELD = "CentOS_7.6_aarch64"
class TestBaseSysPkg(BaseLibraryTest, metaclass=abc.ABCMeta):
TESTCASE_DIR = os.path.join(os.path.dirname(__file__), "testcase")
@classmethod
def get_module_path(cls):
return "ascend_deployer.library.install_sys_pkg"
@classmethod
def get_testcase_path(cls):
return os.path.join(cls.TESTCASE_DIR, "sys_pkg.yml")
@classmethod
def setUpClass(cls):
super().setUpClass()
if ANSIBLE_FIELD in sys.modules:
del sys.modules[ANSIBLE_FIELD]
if f'{MODULE_UTILS_FIELD}' in sys.modules:
del sys.modules[f'{MODULE_UTILS_FIELD}']
if BASIC_FIELD in sys.modules:
del sys.modules[BASIC_FIELD]
if COMMON_INFO_FIELD in sys.modules:
del sys.modules[COMMON_INFO_FIELD]
if COMMON_UTILS_FIELD in sys.modules:
del sys.modules[COMMON_UTILS_FIELD]
if PATH_MANAGER_FIELD in sys.modules:
del sys.modules[PATH_MANAGER_FIELD]
if SAFE_FILE_HANDLER_FIELD in sys.modules:
del sys.modules[SAFE_FILE_HANDLER_FIELD]
sys.modules[ANSIBLE_FIELD] = types.ModuleType(ANSIBLE_FIELD)
sys.modules[f'{MODULE_UTILS_FIELD}'] = types.ModuleType(MODULE_UTILS_FIELD)
sys.modules[BASIC_FIELD] = types.ModuleType(BASIC_FIELD)
sys.modules[COMMON_INFO_FIELD] = types.ModuleType(COMMON_INFO_FIELD)
sys.modules[COMMON_UTILS_FIELD] = types.ModuleType(COMMON_UTILS_FIELD)
sys.modules[PATH_MANAGER_FIELD] = types.ModuleType(PATH_MANAGER_FIELD)
sys.modules[SAFE_FILE_HANDLER_FIELD] = types.ModuleType(SAFE_FILE_HANDLER_FIELD)
def mock_ansible_module(argument_spec=None, **kwargs):
mock_module = Mock()
mock_module.params = {}
mock_module.fail_json = Mock(side_effect=Exception("Failed"))
mock_module.exit_json = Mock()
mock_module.get_bin_path = Mock(return_value=None)
mock_module.run_command = Mock(return_value=(0, "", ""))
mock_module.log = Mock()
return mock_module
sys.modules[BASIC_FIELD].AnsibleModule = mock_ansible_module
sys.modules[COMMON_INFO_FIELD].get_os_and_arch = Mock(return_value=OS_FIELD)
sys.modules[COMMON_INFO_FIELD].need_skip_sys_package = Mock(return_value=False)
sys.modules[COMMON_INFO_FIELD].DeployStatus = Mock()
sys.modules[COMMON_INFO_FIELD].DeployStatus.SKIP = "skip"
sys.modules[COMMON_INFO_FIELD].OSName = Mock()
sys.modules[COMMON_INFO_FIELD].OSName.BCLINUX_21_10_AARCH64 = "BCLinux 21.10 aarch64"
sys.modules[COMMON_INFO_FIELD].OSName.BCLINUX_21_10U4_AARCH64 = "BCLinux 21.10U4 aarch64"
sys.modules[COMMON_UTILS_FIELD].ensure_docker_daemon_exist = Mock()
sys.modules[PATH_MANAGER_FIELD].TmpPath = Mock()
sys.modules[PATH_MANAGER_FIELD].TmpPath.ROOT = "/tmp"
sys.modules[SAFE_FILE_HANDLER_FIELD].SafeFileHandler = Mock()
sys.modules[SAFE_FILE_HANDLER_FIELD].SafeFileHandler.safe_read_json = Mock(return_value={
"rpm_os": [OS_FIELD],
"codename": {OS_FIELD: "bionic"},
"common_docker": [DOCKER_FIELD, DOCKER_CE_FIELD],
"euler_docker": [DOCKER_FIELD, DOCKER_CE_FIELD],
"debian_docker": [DOCKER_FIELD, DOCKER_CE_FIELD]
})
sys.modules[SAFE_FILE_HANDLER_FIELD].SafeFileHandler.safe_read = Mock(return_value="")
sys.modules[SAFE_FILE_HANDLER_FIELD].SafeFileHandler.safe_write = Mock()
cls.get_os_and_arch_mocker = cls._mock_get_os_and_arch()
cls.need_skip_sys_package_mocker = cls._mock_need_skip_sys_package()
from ascend_deployer.library.install_sys_pkg import SysInstaller
cls.SysInstaller = SysInstaller
@classmethod
def _mock_get_os_and_arch(cls):
"""mock get_os_and_arch() 方法"""
patcher = patch(cls.get_module_path() + ".get_os_and_arch")
mocker = patcher.start()
mocker.return_value = OS_FIELD
return mocker
@classmethod
def _mock_need_skip_sys_package(cls):
"""mock need_skip_sys_package() 方法"""
patcher = patch(cls.get_module_path() + ".need_skip_sys_package")
mocker = patcher.start()
mocker.return_value = False
return mocker
class TestSysInstaller(TestBaseSysPkg):
"""测试 SysInstaller 类"""
def test_create_config_file(self):
"""测试创建配置文件"""
params = {
"nexus_url": "http://test-nexus.com",
"resources_dir": "/tmp/test",
"pkg_type": "rpm",
"ansible_run_tags": ["sys_pkg"]
}
module = self._create_ansible_module(params)
nexus_config = {
"rpm_os": [OS_FIELD],
"codename": {OS_FIELD: "bionic"}
}
with patch('ascend_deployer.library.install_sys_pkg.SafeFileHandler.safe_read_json') \
as mock_read_json:
mock_read_json.return_value = nexus_config
with patch('ascend_deployer.library.install_sys_pkg.SafeFileHandler.safe_write') \
as mock_write:
installer = self.SysInstaller(module, "http://test-nexus.com", OS_FIELD, "/tmp/test", "rpm")
installer.create_config_file()
mock_write.assert_called_once()
call_args = mock_write.call_args
file_path = call_args[0][0]
content = call_args[0][1]
self.assertIn("sources.repo", file_path)
self.assertIn("[nexus]", content)
self.assertIn(f"name = {OS_FIELD}", content)
self.assertIn(f"baseurl = http://test-nexus.com/repository/{OS_FIELD}/", content)
self.assertIn("gpgcheck = 0", content)
self.assertIn("enabled = 1", content)
def _create_ansible_module(self, params):
"""创建模拟的 AnsibleModule 实例"""
cmd_handler = MockCmdHandler([], {})
return AnsibleModule(params, cmd_handler)
if __name__ == '__main__':
import unittest
unittest.main()