Compare commits

...

3 commits

Author SHA1 Message Date
6a91bb58b4 [#XX] Add AWS CLI command to report from Boto3 request
Signed-off-by: Kirill Sosnovskikh <k.sosnovskikh@yadro.com>
2024-10-26 14:10:12 +03:00
b2bf6677f1 [#310] Update test marking
Signed-off-by: a.berezin <a.berezin@yadro.com>
2024-10-25 18:52:43 +03:00
3f3be83d90 [#305] Added IAM abstract method 2024-10-25 08:07:47 +00:00
5 changed files with 680 additions and 403 deletions

View file

@ -8,5 +8,6 @@ def pytest_collection_modifyitems(items: list[pytest.Item]):
# 1. plugins # 1. plugins
# 2. testlib itself # 2. testlib itself
for item in items: for item in items:
if "frostfs" in item.nodeid and "plugin" not in item.nodeid and "testlib" not in item.nodeid: location = item.location[0]
if "frostfs" in location and "plugin" not in location and "testlib" not in location:
item.add_marker("frostfs") item.add_marker("frostfs")

File diff suppressed because it is too large Load diff

View file

@ -58,6 +58,10 @@ class S3ClientWrapper(HumanReadableABC):
def set_endpoint(self, s3gate_endpoint: str): def set_endpoint(self, s3gate_endpoint: str):
"""Set endpoint""" """Set endpoint"""
@abstractmethod
def set_iam_endpoint(self, iam_endpoint: str):
"""Set iam endpoint"""
@abstractmethod @abstractmethod
def create_bucket( def create_bucket(
self, self,

View file

@ -1,8 +1,8 @@
import re import re
from frostfs_testlib import reporter from frostfs_testlib import reporter
from frostfs_testlib.testing.test_control import wait_for_success
from frostfs_testlib.storage.cluster import ClusterNode from frostfs_testlib.storage.cluster import ClusterNode
from frostfs_testlib.testing.test_control import wait_for_success
@reporter.step("Check metrics result") @reporter.step("Check metrics result")
@ -19,7 +19,7 @@ def check_metrics_counter(
counter_act += get_metrics_value(cluster_node, parse_from_command, **metrics_greps) counter_act += get_metrics_value(cluster_node, parse_from_command, **metrics_greps)
assert eval( assert eval(
f"{counter_act} {operator} {counter_exp}" f"{counter_act} {operator} {counter_exp}"
), f"Expected: {counter_exp} {operator} Actual: {counter_act} in node: {cluster_node}" ), f"Expected: {counter_exp} {operator} Actual: {counter_act} in nodes: {cluster_nodes}"
@reporter.step("Get metrics value from node: {node}") @reporter.step("Get metrics value from node: {node}")

View file

@ -9,13 +9,12 @@ import csv
import json import json
import logging import logging
import re import re
import subprocess
import sys import sys
from contextlib import suppress from contextlib import suppress
from datetime import datetime from datetime import datetime
from io import StringIO from io import StringIO
from textwrap import shorten from textwrap import shorten
from typing import Dict, List, Optional, TypedDict, Union from typing import Any, Optional, Union
import pexpect import pexpect
@ -75,22 +74,75 @@ def _attach_allure_log(cmd: str, output: str, return_code: int, start_time: date
reporter.attach(command_attachment, "Command execution") reporter.attach(command_attachment, "Command execution")
def log_command_execution(url: str, cmd: str, output: Union[str, dict], params: Optional[dict] = None) -> None: def log_command_execution(cmd: str, output: Union[str, dict], params: Optional[dict] = None, **kwargs) -> None:
logger.info(f"{cmd}: {output}") logger.info(f"{cmd}: {output}")
with suppress(Exception): if not params:
json_output = json.dumps(output, indent=4, sort_keys=True) params = {}
output = json_output
output_params = params
try: try:
json_params = json.dumps(params, indent=4, sort_keys=True) json_params = json.dumps(params, indent=4, sort_keys=True, default=str)
except TypeError as err: except TypeError as err:
logger.warning(f"Failed to serialize '{cmd}' request parameters:\n{params}\nException: {err}") logger.warning(f"Failed to serialize '{cmd}' request parameters:\n{params}\nException: {err}")
else: else:
params = json_params output_params = json_params
command_attachment = f"COMMAND: '{cmd}'\n" f"URL: {url}\n" f"PARAMS:\n{params}\n" f"OUTPUT:\n{output}\n" output = json.dumps(output, indent=4, sort_keys=True, default=str)
reporter.attach(command_attachment, "Command execution")
command_execution = f"COMMAND: '{cmd}'\n" f"URL: {kwargs['endpoint']}\n" f"PARAMS:\n{output_params}\n" f"OUTPUT:\n{output}\n"
aws_command = _convert_request_to_aws_cli_command(cmd, params, **kwargs)
reporter.attach(command_execution, "Command execution")
reporter.attach(aws_command, "AWS CLI Command")
def _convert_request_to_aws_cli_command(command: str, params: dict, **kwargs) -> str:
overriden_names = [_convert_json_name_to_aws_cli(name) for name in kwargs.keys()]
command = command.replace("_", "-")
options = []
for name, value in params.items():
name = _convert_json_name_to_aws_cli(name)
# To override parameters for AWS CLI
if name in overriden_names:
continue
if option := _create_option(name, value):
options.append(option)
for name, value in kwargs.items():
name = _convert_json_name_to_aws_cli(name)
if option := _create_option(name, value):
options.append(option)
options = " ".join(options)
api = "s3api" if "s3" in kwargs["endpoint"] else "iam"
return f"aws --no-verify-ssl --no-paginate {api} {command} {options}"
def _convert_json_name_to_aws_cli(name: str) -> str:
specific_names = {"CORSConfiguration": "cors-configuration"}
if aws_cli_name := specific_names.get(name):
return aws_cli_name
return re.sub(r"([a-z])([A-Z])", r"\1 \2", name).lower().replace(" ", "-").replace("_", "-")
def _create_option(name: str, value: Any) -> str | None:
if isinstance(value, bool) and value:
return f"--{name}"
if isinstance(value, dict):
value = json.dumps(value, indent=4, sort_keys=True, default=str)
return f"--{name} '{value}'"
if value:
return f"--{name} {value}"
return None
def parse_netmap_output(output: str) -> list[NodeNetmapInfo]: def parse_netmap_output(output: str) -> list[NodeNetmapInfo]: