import logging import os from http import HTTPStatus from re import fullmatch, match import allure import pytest import requests from frostfs_testlib import reporter from frostfs_testlib.hosting import Hosting from frostfs_testlib.resources.common import ASSETS_DIR from frostfs_testlib.utils.env_utils import read_env_properties, save_env_properties from frostfs_testlib.utils.version_utils import get_remote_binaries_versions from pytest import FixtureRequest logger = logging.getLogger("NeoLogger") @allure.title("Check binaries versions") @pytest.mark.check_binaries def test_binaries_versions(request: FixtureRequest, hosting: Hosting): """ Compare binaries versions from external source (url) and deployed on servers. """ with reporter.step("Get binaries versions from servers"): got_versions, exсeptions_remote_binaries_versions = get_remote_binaries_versions(hosting) environment_dir = request.config.getoption("--alluredir") or ASSETS_DIR env_file = os.path.join(environment_dir, "environment.properties") env_properties = read_env_properties(env_file) # compare versions from servers and file exсeptions = [] additional_env_properties = {} for binary_name, binary in got_versions.items(): version = binary["version"] requires_check = binary["check"] if requires_check and not fullmatch(r"^\d+\.\d+\.\d+(-.*)?(?<!dirty)", version): exсeptions.append(f"{binary_name}: Actual version doesn't conform to format '0.0.0-000-aaaaaaa': {version}") # If some binary was not listed in the env properties file, let's add it # so that we have full information about versions in allure report if env_properties and binary_name not in env_properties: additional_env_properties[binary_name] = version if env_properties and additional_env_properties: save_env_properties(env_file, additional_env_properties) exсeptions.extend(exсeptions_remote_binaries_versions) # create clear beautiful error with aggregation info if exсeptions: msg = "\n".join(exсeptions) raise AssertionError(f"Found binaries with unexpected versions:\n{msg}") @reporter.step("Download versions info from {url}") def download_versions_info(url: str) -> dict: binaries_to_version = {} response = requests.get(url) assert response.status_code == HTTPStatus.OK, f"Got {response.status_code} code. Content {response.json()}" content = response.text assert content, f"Expected file with content, got {response}" for line in content.split("\n"): m = match("(.*)=(.*)", line) if not m: logger.warning(f"Could not get binary/version from {line}") continue bin_name, bin_version = m.group(1), m.group(2) binaries_to_version[bin_name] = bin_version return binaries_to_version