diff --git a/Makefile b/Makefile index 71b3f8cf..a0ba3ca1 100644 --- a/Makefile +++ b/Makefile @@ -6,16 +6,15 @@ python_executables = \ cmtinv \ cmu python_test_executables = \ - tests/async_fetch \ tests/ansibletests \ + tests/async_fetch \ tests/atptests \ - tests/check_theme_use \ tests/checkstests \ + tests/check_theme_use \ tests/clptests \ tests/cmtlibtests \ tests/cnitests \ tests/coverage_stats \ - tests/cnitests \ tests/cursestests \ tests/datatests \ tests/dgtests \ diff --git a/clustermanagementtoolkit/fieldgetters.py b/clustermanagementtoolkit/fieldgetters.py index 3197d68f..30423355 100644 --- a/clustermanagementtoolkit/fieldgetters.py +++ b/clustermanagementtoolkit/fieldgetters.py @@ -30,8 +30,11 @@ def fieldgetter_executable_version(**kwargs: Any) -> list[Any]: Parameters: **kwargs (dict[str, Any]): Keyword arguments + executable (str): The executable to get the version for + args ([str]): The arguments to pass to the executable + version_regex (str): The regular expression to use to extract the version Returns: - [str]: The list of cmt versions + [str]: The version tuple """ executable: FilePath = FilePath(deep_get(kwargs, DictPath("executable"), "")) args: list[str] = deep_get(kwargs, DictPath("args"), []) @@ -101,7 +104,7 @@ def fieldgetter_crc_version(**kwargs: Any) -> list[Any]: fallback_allowlist = ["/bin", "/sbin", "/usr/bin", "/usr/sbin", "/usr/local/bin", "/usr/local/sbin", f"{HOMEDIR}/bin"] - versions = ["", "", ""] + versions = ["", "", "", ""] try: crc_path = secure_which(FilePath("/usr/bin/crc"), fallback_allowlist=fallback_allowlist, @@ -130,8 +133,10 @@ def fieldgetter_crc_version(**kwargs: Any) -> list[Any]: versions[0] = line.removeprefix("CRC version: ") elif line.startswith("OpenShift version: "): versions[1] = line.removeprefix("OpenShift version: ") + elif line.startswith("MicroShift version: "): + versions[2] = line.removeprefix("MicroShift version: ") elif line.startswith("Podman version: "): - versions[2] = line.removeprefix("Podman version: ") + versions[3] = line.removeprefix("Podman version: ") version_strings = [] for field in fields: diff --git a/tests/fgtests b/tests/fgtests index b5610894..cac65e06 100755 --- a/tests/fgtests +++ b/tests/fgtests @@ -15,11 +15,16 @@ import sys from typing import Any +from unittest import mock import yaml +from clustermanagementtoolkit import about + from clustermanagementtoolkit.cmttypes import deep_get, DictPath, ProgrammingError + from clustermanagementtoolkit.ansithemeprint import ANSIThemeStr from clustermanagementtoolkit.ansithemeprint import ansithemeprint, init_ansithemeprint + from clustermanagementtoolkit import fieldgetters # unit-tests for fieldgetters.py @@ -33,6 +38,68 @@ def yaml_dump(data: Any, base_indent: int = 4) -> str: return result +def test_fieldgetter_executable_version(verbose: bool = False) -> tuple[str, bool]: + message = "" + result = True + + fun = fieldgetters.fieldgetter_executable_version + + if result: + # Indata format: + # (kwargs, mock_return_value, expected_result, expected_exception) + testdata: tuple = ( + ( + { + "executable": "/bin/true", + "args": ["--version"], + "version_regex": r"true.+ (\d+)(\.)(\d+)", + }, + "true (GNU coreutils) 9.5", + ["9.5"], + None, + ), + ( + { + "executable": "NONEXISTING", + "args": ["version"], + "version_regex": r"true.+ (\d+)(\.)(\d+)", + }, + "", + [""], + None, + ), + ) + + for kwargs, mock_response, expected_result, expected_exception in testdata: + try: + with mock.patch("clustermanagementtoolkit.fieldgetters." + "execute_command_with_response", + return_value=mock_response): + tmp = fun(**kwargs) + if tmp != expected_result: + message = f"{fun.__name__}() did not yield expected result:\n" \ + f" expected: {expected_result}" + result = False + break + except Exception as e: + if expected_exception is not None: + if isinstance(e, expected_exception): + pass + else: + message = f"{fun.__name__}() did not yield expected result:\n" \ + f" exception: {type(e)}\n" \ + f" expected: {expected_exception}" + result = False + break + else: + message = f"{fun.__name__}() did not yield expected result:\n" \ + f" exception: {type(e)}\n" \ + f" expected: {expected_result}" + result = False + break + return message, result + + class FakeKH(): def __init__(self, version: tuple[int, int, str]) -> None: self.version = version @@ -92,11 +159,179 @@ def test_fieldgetter_api_server_version(verbose: bool = False) -> tuple[str, boo return message, result +def test_fieldgetter_cmt_version(verbose: bool = False) -> tuple[str, bool]: + message = "" + result = True + + fun = fieldgetters.fieldgetter_cmt_version + + if result: + # Indata format: + # (fields, expected_result, expected_exception) + testdata: tuple = ( + ( + [0, 1, 2, 3, 4, 5], + [ + about.PROGRAM_SUITE_VERSION, + about.UI_PROGRAM_VERSION, + about.TOOL_PROGRAM_VERSION, + about.ADMIN_PROGRAM_VERSION, + about.INVENTORY_PROGRAM_VERSION, + about.INSTALL_PROGRAM_VERSION, + ], + None, + ), + ( + [0, 3], + [ + about.PROGRAM_SUITE_VERSION, + about.ADMIN_PROGRAM_VERSION, + ], + None, + ), + ( + [42], + [], + None, + ), + ) + + for fields, expected_result, expected_exception in testdata: + try: + tmp = fun(fields=fields) + if tmp != expected_result: + message = f"{fun.__name__}() did not yield expected result:\n" \ + f" fields: {fields}\n" \ + f" expected: {expected_result}" + result = False + break + except Exception as e: + if expected_exception is not None: + if isinstance(e, expected_exception): + pass + else: + message = f"{fun.__name__}() did not yield expected result:\n" \ + f" fields: {fields}\n" \ + f" exception: {type(e)}\n" \ + f" expected: {expected_exception}" + result = False + break + else: + message = f"{fun.__name__}() did not yield expected result:\n" \ + f" fields: {fields}\n" \ + f" exception: {type(e)}\n" \ + f" expected: {expected_result}" + result = False + break + return message, result + + +def test_fieldgetter_crc_version(verbose: bool = False) -> tuple[str, bool]: + message = "" + result = True + + fun = fieldgetters.fieldgetter_crc_version + + if result: + # Indata format: + # (fields, mock_return_value1, mock_return_value_2, expected_result, expected_exception) + testdata: tuple = ( + ( + [0], + [FileNotFoundError], + ["Machine does not exist", ""], + [""], + None, + ), + ( + [0], + ["/usr/bin/crc"], + ["Machine does not exist", ""], + [""], + None, + ), + ( + [0], + ["/usr/bin/crc"], + ["CRC VM: Running", + "CRC version: 2.46.0+8f40e8\nOpenShift version: 4.17.10\n" + "MicroShift version: 4.17.10"], + ["2.46.0+8f40e8"], + None, + ), + ( + [0, 1, 3], + ["/usr/bin/crc"], + ["CRC VM: Running", + "CRC version: 2.46.0+8f40e8\nOpenShift version: 4.17.10\n" + "Podman version: 1.2.3\nSomething else here"], + ["2.46.0+8f40e8", "4.17.10", "1.2.3"], + None, + ), + ( + [4], + ["/usr/bin/crc"], + ["CRC VM: Running", + "CRC version: 2.46.0+8f40e8\nOpenShift version: 4.17.10\n" + "Podman version: 1.2.3\nSomething else here"], + [], + None, + ), + ) + + for fields, mock_response_1, mock_response_2, \ + expected_result, expected_exception in testdata: + try: + with mock.patch("clustermanagementtoolkit.fieldgetters.secure_which", + side_effect=mock_response_1), \ + mock.patch("clustermanagementtoolkit.fieldgetters." + "execute_command_with_response", + side_effect=mock_response_2): + tmp = fun(fields=fields) + if tmp != expected_result: + message = f"{fun.__name__}() did not yield expected result:\n" \ + f" fields: {fields}\n" \ + f" expected: {expected_result}" + result = False + break + except Exception as e: + if expected_exception is not None: + if isinstance(e, expected_exception): + pass + else: + message = f"{fun.__name__}() did not yield expected result:\n" \ + f" fields: {fields}\n" \ + f" exception: {type(e)}\n" \ + f" expected: {expected_exception}" + result = False + break + else: + message = f"{fun.__name__}() did not yield expected result:\n" \ + f" fields: {fields}\n" \ + f" exception: {type(e)}\n" \ + f" expected: {expected_result}" + result = False + break + return message, result + + tests: dict[tuple[str, ...], dict[str, Any]] = { + ("fieldgetter_executable_version()",): { + "callable": test_fieldgetter_executable_version, + "result": None, + }, ("fieldgetter_api_server_version()",): { "callable": test_fieldgetter_api_server_version, "result": None, }, + ("fieldgetter_cmt_version()",): { + "callable": test_fieldgetter_cmt_version, + "result": None, + }, + ("fieldgetter_crc_version()",): { + "callable": test_fieldgetter_crc_version, + "result": None, + }, }