Check binaries versions

Signed-off-by: a.y.volkov <a.y.volkov@yadro.com>
This commit is contained in:
a.y.volkov 2022-08-08 17:49:08 +03:00 committed by Vladimir Domnich
parent ce099c61a4
commit 9fea2efe83
5 changed files with 103 additions and 9 deletions

View file

@ -126,8 +126,8 @@ class CloudVmStorageServiceHelper:
ssh_client.exec(f'systemctl stop {self.STORAGE_SERVICE}') ssh_client.exec(f'systemctl stop {self.STORAGE_SERVICE}')
ssh_client.exec('rm -rf /srv/neofs/*') ssh_client.exec('rm -rf /srv/neofs/*')
def get_binaries_version(self) -> dict: def get_binaries_version(self, binaries: list = None) -> dict:
binaries = [ default_binaries = [
'neo-go', 'neo-go',
'neofs-adm', 'neofs-adm',
'neofs-cli', 'neofs-cli',
@ -139,18 +139,24 @@ class CloudVmStorageServiceHelper:
'neofs-s3-gw', 'neofs-s3-gw',
'neogo-morph-cn', 'neogo-morph-cn',
] ]
binaries = binaries or default_binaries
version_map = {} version_map = {}
for node_name in NEOFS_NETMAP_DICT: for node_name in NEOFS_NETMAP_DICT:
with _create_ssh_client(node_name) as ssh_client: with _create_ssh_client(node_name) as ssh_client:
for binary in binaries: for binary in binaries:
try:
out = ssh_client.exec(f'{binary} --version').stdout out = ssh_client.exec(f'{binary} --version').stdout
version = re.search(r'version[:\s]*(.+)', out, re.IGNORECASE) except AssertionError as err:
version = version.group(1) if version else 'Unknown' logger.error(f'Can not get version for {binary} because of\n{err}')
if not version_map.get(binary.upper()): version_map[binary] = 'Can not get version'
version_map[binary.upper()] = version continue
version = re.search(r'version[:\s]*v?(.+)', out, re.IGNORECASE)
version = version.group(1).strip() if version else 'Unknown'
if not version_map.get(binary):
version_map[binary] = version
else: else:
assert version_map[binary.upper()] == version, \ assert version_map[binary] == version, \
f'Expected binary {binary} to have identical version on all nodes ' \ f'Expected binary {binary} to have identical version on all nodes ' \
f'(mismatch on node {node_name})' f'(mismatch on node {node_name})'
return version_map return version_map

View file

@ -22,3 +22,4 @@ markers =
failover_panic: tests for system recovery after panic reboot of a node failover_panic: tests for system recovery after panic reboot of a node
failover_net: tests for network failure failover_net: tests for network failure
add_nodes: add nodes to cluster add_nodes: add nodes to cluster
check_binaries: check neofs installed binaries versions

View file

@ -61,7 +61,7 @@ def _get_binaries_version_local(binaries: list) -> dict:
for binary in binaries: for binary in binaries:
out = _cmd_run(f'{binary} --version') out = _cmd_run(f'{binary} --version')
version = re.search(r'version[:\s]*(.+)', out, re.IGNORECASE) version = re.search(r'version[:\s]*(.+)', out, re.IGNORECASE)
env_out[binary.upper()] = version.group(1) if version else 'Unknown' env_out[binary] = version.group(1).strip() if version else 'Unknown'
return env_out return env_out

View file

@ -0,0 +1,86 @@
import logging
from http import HTTPStatus
from re import match
import allure
import pytest
import requests
from common import BIN_VERSIONS_FILE
from service_helper import get_storage_service_helper
logger = logging.getLogger('NeoLogger')
@allure.title('Check binaries versions')
@pytest.mark.check_binaries
def test_binaries_versions(request):
"""
Compare binaries versions from external source (url) and deployed on servers.
"""
if not BIN_VERSIONS_FILE:
pytest.skip('File with binaries and versions was not provided')
failed_versions = {}
environment_dir = request.config.getoption('--alluredir')
env_data = None
data_for_env = {}
binaries_to_check = download_versions_info(BIN_VERSIONS_FILE)
with allure.step('Get binaries versions from servers'):
helper = get_storage_service_helper()
got_versions = helper.get_binaries_version(binaries=list(binaries_to_check.keys()))
if environment_dir:
with open(f'{environment_dir}/environment.properties', 'r') as env_file:
env_data = env_file.read()
# compare versions from servers and file
for binary, version in binaries_to_check.items():
if binary not in got_versions:
failed_versions[binary] = 'Can not find binary'
if got_versions[binary] != version:
failed_versions[binary] = f'Expected version {version}, found version {got_versions[binary]}'
# if something missed in environment.properties file, let's add
if env_data and binary not in env_data:
data_for_env[binary] = got_versions[binary]
if environment_dir and data_for_env:
add_to_environment_properties(f'{environment_dir}/environment.properties', data_for_env)
# create clear beautiful error with aggregation info
if failed_versions:
msg = '\n'.join({f'{binary}: {error}' for binary, error in failed_versions.items()})
raise AssertionError(f'Found binaries with unexpected versions:\n{msg}')
@allure.step('Download 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
@allure.step('Update data in environment.properties')
def add_to_environment_properties(file_path: str, env_data: dict):
with open(file_path, 'a+') as env_file:
for env, env_value in env_data.items():
env_file.write(f'{env}={env_value}\n')

View file

@ -112,3 +112,4 @@ NEOFS_ADM_CONFIG_PATH = os.getenv("NEOFS_ADM_CONFIG_PATH")
INFRASTRUCTURE_TYPE = os.getenv("INFRASTRUCTURE_TYPE", "LOCAL_DEVENV") INFRASTRUCTURE_TYPE = os.getenv("INFRASTRUCTURE_TYPE", "LOCAL_DEVENV")
FREE_STORAGE = os.getenv("FREE_STORAGE", "false").lower() == "true" FREE_STORAGE = os.getenv("FREE_STORAGE", "false").lower() == "true"
BIN_VERSIONS_FILE = os.getenv("BIN_VERSIONS_FILE")