diff --git a/pytest_tests/testsuites/conftest.py b/pytest_tests/testsuites/conftest.py index 2df6ce6f..2c0d7f3a 100644 --- a/pytest_tests/testsuites/conftest.py +++ b/pytest_tests/testsuites/conftest.py @@ -25,12 +25,6 @@ from wallet import init_wallet import allure -def robot_keyword_adapter(name=None, tags=(), types=()): - return allure.step(name) - - -deco.keyword = robot_keyword_adapter - logger = logging.getLogger("NeoLogger") diff --git a/robot/resources/lib/python_keywords/complex_object_actions.py b/robot/resources/lib/python_keywords/complex_object_actions.py index b16316c9..945183ec 100644 --- a/robot/resources/lib/python_keywords/complex_object_actions.py +++ b/robot/resources/lib/python_keywords/complex_object_actions.py @@ -10,11 +10,11 @@ first non-null response. """ +import allure from common import NEOFS_NETMAP, WALLET_CONFIG import neofs_verbs from robot.api import logger -from robot.api.deco import keyword from robot.libraries.BuiltIn import BuiltIn import neofs_verbs @@ -23,7 +23,7 @@ from common import NEOFS_NETMAP ROBOT_AUTO_KEYWORDS = False -@keyword('Get Link Object') +@allure.step('Get Link Object') def get_link_object(wallet: str, cid: str, oid: str, bearer_token: str = "", wallet_config: str = WALLET_CONFIG): """ @@ -55,7 +55,7 @@ def get_link_object(wallet: str, cid: str, oid: str, bearer_token: str = "", return None -@keyword('Get Last Object') +@allure.step('Get Last Object') def get_last_object(wallet: str, cid: str, oid: str): """ Args: diff --git a/robot/resources/lib/python_keywords/container.py b/robot/resources/lib/python_keywords/container.py index cf9850fe..ec14169e 100644 --- a/robot/resources/lib/python_keywords/container.py +++ b/robot/resources/lib/python_keywords/container.py @@ -4,6 +4,7 @@ This module contains keywords that utilize `neofs-cli container` commands. """ +import allure import json from time import sleep from typing import Optional, Union @@ -12,13 +13,12 @@ import json_transformers from cli_utils import NeofsCli from common import NEOFS_ENDPOINT, WALLET_CONFIG from robot.api import logger -from robot.api.deco import keyword ROBOT_AUTO_KEYWORDS = False DEFAULT_PLACEMENT_RULE = "REP 2 IN X CBF 1 SELECT 4 FROM * AS X" -@keyword('Create Container') +@allure.step('Create Container') def create_container(wallet: str, rule: str = DEFAULT_PLACEMENT_RULE, basic_acl: str = '', attributes: Optional[dict] = None, session_token: str = '', session_wallet: str = '', name: str = None, options: dict = None, @@ -84,7 +84,7 @@ def wait_for_container_deletion(wallet: str, cid: str, attempts: int = 30, sleep raise AssertionError(f'Expected container deleted during {attempts * sleep_interval} sec.') -@keyword('List Containers') +@allure.step('List Containers') def list_containers(wallet: str) -> list[str]: """ A wrapper for `neofs-cli container list` call. It returns all the @@ -100,7 +100,7 @@ def list_containers(wallet: str) -> list[str]: return output.split() -@keyword('Get Container') +@allure.step('Get Container') def get_container(wallet: str, cid: str, json_mode: bool = True) -> Union[dict, str]: """ A wrapper for `neofs-cli container get` call. It extracts container's @@ -127,7 +127,7 @@ def get_container(wallet: str, cid: str, json_mode: bool = True) -> Union[dict, return container_info -@keyword('Delete Container') +@allure.step('Delete Container') # TODO: make the error message about a non-found container more user-friendly # https://github.com/nspcc-dev/neofs-contract/issues/121 def delete_container(wallet: str, cid: str, force: bool = False) -> None: diff --git a/robot/resources/lib/python_keywords/epoch.py b/robot/resources/lib/python_keywords/epoch.py index 3c948d00..0a6c51f6 100644 --- a/robot/resources/lib/python_keywords/epoch.py +++ b/robot/resources/lib/python_keywords/epoch.py @@ -1,7 +1,6 @@ #!/usr/bin/python3.9 import allure from robot.api import logger -from robot.api.deco import keyword import contract import wrappers @@ -11,7 +10,7 @@ from common import (IR_WALLET_PATH, IR_WALLET_PASS, MORPH_ENDPOINT, NEOFS_ADM_EX ROBOT_AUTO_KEYWORDS = False -@keyword('Get Epoch') +@allure.step('Get Epoch') def get_epoch(): epoch = int(contract.testinvoke_contract( contract.get_netmap_contract_hash(MORPH_ENDPOINT), @@ -22,7 +21,7 @@ def get_epoch(): return epoch -@keyword('Tick Epoch') +@allure.step('Tick Epoch') def tick_epoch(): if NEOFS_ADM_EXEC and NEOFS_ADM_CONFIG_PATH: # If neofs-adm is available, then we tick epoch with it (to be consistent with UAT tests) diff --git a/robot/resources/lib/python_keywords/http_gate.py b/robot/resources/lib/python_keywords/http_gate.py index 2f70ff1f..6588aac2 100644 --- a/robot/resources/lib/python_keywords/http_gate.py +++ b/robot/resources/lib/python_keywords/http_gate.py @@ -1,5 +1,6 @@ #!/usr/bin/python3 +import allure import re import shutil import sys @@ -12,7 +13,6 @@ import requests from cli_helpers import _cmd_run from common import HTTP_GATE from robot.api import logger -from robot.api.deco import keyword from robot.libraries.BuiltIn import BuiltIn ROBOT_AUTO_KEYWORDS = False @@ -25,7 +25,7 @@ else: ASSETS_DIR = BuiltIn().get_variable_value("${ASSETS_DIR}") -@keyword('Get via HTTP Gate') +@allure.step('Get via HTTP Gate') def get_via_http_gate(cid: str, oid: str): """ This function gets given object from HTTP gate @@ -50,7 +50,7 @@ def get_via_http_gate(cid: str, oid: str): return filename -@keyword('Get via Zip HTTP Gate') +@allure.step('Get via Zip HTTP Gate') def get_via_zip_http_gate(cid: str, prefix: str): """ This function gets given object from HTTP gate @@ -79,7 +79,7 @@ def get_via_zip_http_gate(cid: str, prefix: str): return f'{ASSETS_DIR}/{prefix}' -@keyword('Get via HTTP Gate by attribute') +@allure.step('Get via HTTP Gate by attribute') def get_via_http_gate_by_attribute(cid: str, attribute: dict): """ This function gets given object from HTTP gate @@ -106,7 +106,7 @@ def get_via_http_gate_by_attribute(cid: str, attribute: dict): return filename -@keyword('Upload via HTTP Gate') +@allure.step('Upload via HTTP Gate') def upload_via_http_gate(cid: str, path: str, headers: dict = None) -> str: """ This function upload given object through HTTP gate @@ -135,7 +135,7 @@ def upload_via_http_gate(cid: str, path: str, headers: dict = None) -> str: return resp.json().get('object_id') -@keyword('Upload via HTTP Gate using Curl') +@allure.step('Upload via HTTP Gate using Curl') def upload_via_http_gate_curl(cid: str, filepath: str, large_object=False, headers: dict = None) -> str: """ This function upload given object through HTTP gate using curl utility. @@ -156,7 +156,7 @@ def upload_via_http_gate_curl(cid: str, filepath: str, large_object=False, heade return oid_re.group(1) -@keyword('Get via HTTP Gate using Curl') +@allure.step('Get via HTTP Gate using Curl') def get_via_http_curl(cid: str, oid: str) -> str: """ This function gets given object from HTTP gate using curl utility. diff --git a/robot/resources/lib/python_keywords/neofs_verbs.py b/robot/resources/lib/python_keywords/neofs_verbs.py index 83869f3d..103a5504 100644 --- a/robot/resources/lib/python_keywords/neofs_verbs.py +++ b/robot/resources/lib/python_keywords/neofs_verbs.py @@ -4,6 +4,7 @@ This module contains wrappers for NeoFS verbs executed via neofs-cli. """ +import allure import json import random import re @@ -14,12 +15,12 @@ import json_transformers from cli_utils import NeofsCli from common import ASSETS_DIR, NEOFS_ENDPOINT, NEOFS_NETMAP, WALLET_CONFIG from robot.api import logger -from robot.api.deco import keyword + ROBOT_AUTO_KEYWORDS = False -@keyword("Get object") +@allure.step("Get object") def get_object( wallet: str, cid: str, @@ -75,7 +76,7 @@ def get_object( # TODO: make `bearer_token` optional -@keyword("Get Range Hash") +@allure.step("Get Range Hash") def get_range_hash( wallet: str, cid: str, @@ -119,7 +120,7 @@ def get_range_hash( return output.split(":")[1].strip() -@keyword("Put object") +@allure.step("Put object") def put_object( wallet: str, path: str, @@ -177,7 +178,7 @@ def put_object( return oid.strip() -@keyword("Delete object") +@allure.step("Delete object") def delete_object( wallet: str, cid: str, @@ -220,7 +221,7 @@ def delete_object( return tombstone.strip() -@keyword("Get Range") +@allure.step("Get Range") def get_range( wallet: str, cid: str, @@ -269,7 +270,7 @@ def get_range( return range_file, content -@keyword("Search object") +@allure.step("Search object") def search_object( wallet: str, cid: str, @@ -332,7 +333,7 @@ def search_object( return found_objects -@keyword("Head object") +@allure.step("Head object") def head_object( wallet: str, cid: str, diff --git a/robot/resources/lib/python_keywords/node_management.py b/robot/resources/lib/python_keywords/node_management.py index 24b0a53d..e5aca957 100644 --- a/robot/resources/lib/python_keywords/node_management.py +++ b/robot/resources/lib/python_keywords/node_management.py @@ -4,6 +4,7 @@ This module contains keywords for tests that check management of storage nodes. """ +import allure import random import re import time @@ -14,7 +15,6 @@ from common import MAINNET_BLOCK_TIME, MORPH_BLOCK_TIME, NEOFS_NETMAP_DICT, STOR from data_formatters import get_wallet_public_key from epoch import tick_epoch from robot.api import logger -from robot.api.deco import keyword from service_helper import get_storage_service_helper from utility import robot_time_to_int @@ -37,7 +37,7 @@ class HealthStatus: return HealthStatus(network, health) -@keyword('Stop Nodes') +@allure.step('Stop Nodes') def stop_nodes(number: int, nodes: list) -> list: """ The function shuts down the given number of randomly @@ -55,7 +55,7 @@ def stop_nodes(number: int, nodes: list) -> list: return nodes_to_stop -@keyword('Start Nodes') +@allure.step('Start Nodes') def start_nodes(nodes: list) -> None: """ The function raises the given nodes. @@ -69,7 +69,7 @@ def start_nodes(nodes: list) -> None: helper.start(node) -@keyword('Get control endpoint and wallet') +@allure.step('Get control endpoint and wallet') def get_control_endpoint_and_wallet(endpoint_number: str = ''): """ Gets control endpoint for a random or given node @@ -96,7 +96,7 @@ def get_control_endpoint_and_wallet(endpoint_number: str = ''): return endpoint_num, endpoint_control, wallet -@keyword('Get Locode') +@allure.step('Get Locode') def get_locode(): endpoint_values = random.choice(list(NEOFS_NETMAP_DICT.values())) locode = endpoint_values['UN-LOCODE'] @@ -105,7 +105,7 @@ def get_locode(): return locode -@keyword('Healthcheck for node') +@allure.step('Healthcheck for node') def node_healthcheck(node_name: str) -> HealthStatus: """ The function returns node's health status. @@ -119,7 +119,7 @@ def node_healthcheck(node_name: str) -> HealthStatus: return HealthStatus.from_stdout(output) -@keyword('Set status for node') +@allure.step('Set status for node') def node_set_status(node_name: str, status: str, retries: int = 0) -> None: """ The function sets particular status for given node. @@ -134,7 +134,7 @@ def node_set_status(node_name: str, status: str, retries: int = 0) -> None: _run_control_command(node_name, command, retries) -@keyword('Get netmap snapshot') +@allure.step('Get netmap snapshot') def get_netmap_snapshot(node_name: Optional[str] = None) -> str: """ The function returns string representation of netmap-snapshot. @@ -148,7 +148,7 @@ def get_netmap_snapshot(node_name: Optional[str] = None) -> str: return _run_control_command(node_name, command) -@keyword('Shard list for node') +@allure.step('Shard list for node') def node_shard_list(node_name: str) -> list[str]: """ The function returns list of shards for particular node. @@ -162,7 +162,7 @@ def node_shard_list(node_name: str) -> list[str]: return re.findall(r'Shard (.*):', output) -@keyword('Shard list for node') +@allure.step('Shard list for node') def node_shard_set_mode(node_name: str, shard: str, mode: str) -> str: """ The function sets mode for node's particular shard. @@ -175,7 +175,7 @@ def node_shard_set_mode(node_name: str, shard: str, mode: str) -> str: return _run_control_command(node_name, command) -@keyword('Drop object from node {node_name}') +@allure.step('Drop object from node {node_name}') def drop_object(node_name: str, cid: str, oid: str) -> str: """ The function drops object from particular node. @@ -188,7 +188,7 @@ def drop_object(node_name: str, cid: str, oid: str) -> str: return _run_control_command(node_name, command) -@keyword('Delete data of node {node_name}') +@allure.step('Delete data of node {node_name}') def delete_node_data(node_name: str) -> None: helper = get_storage_service_helper() helper.stop_node(node_name) @@ -196,7 +196,7 @@ def delete_node_data(node_name: str) -> None: time.sleep(robot_time_to_int(MORPH_BLOCK_TIME)) -@keyword('Exclude node {node_to_include} from network map') +@allure.step('Exclude node {node_to_include} from network map') def exclude_node_from_network_map(node_to_exclude, alive_node): node_wallet_path = NEOFS_NETMAP_DICT[node_to_exclude]['wallet_path'] node_netmap_key = get_wallet_public_key( @@ -214,7 +214,7 @@ def exclude_node_from_network_map(node_to_exclude, alive_node): assert node_netmap_key not in snapshot, f'Expected node with key {node_netmap_key} not in network map' -@keyword('Include node {node_to_include} into network map') +@allure.step('Include node {node_to_include} into network map') def include_node_to_network_map(node_to_include: str, alive_node: str) -> None: node_set_status(node_to_include, status='online') @@ -224,7 +224,7 @@ def include_node_to_network_map(node_to_include: str, alive_node: str) -> None: check_node_in_map(node_to_include, alive_node) -@keyword('Check node {node_name} in network map') +@allure.step('Check node {node_name} in network map') def check_node_in_map(node_name: str, alive_node: str = None): alive_node = alive_node or node_name node_wallet_path = NEOFS_NETMAP_DICT[node_name]['wallet_path'] diff --git a/robot/resources/lib/python_keywords/payment_neogo.py b/robot/resources/lib/python_keywords/payment_neogo.py index 86eabb95..170f8aaa 100644 --- a/robot/resources/lib/python_keywords/payment_neogo.py +++ b/robot/resources/lib/python_keywords/payment_neogo.py @@ -1,11 +1,11 @@ #!/usr/bin/python3 +import allure import re import time from neo3 import wallet from robot.api import logger -from robot.api.deco import keyword import contract import converters @@ -27,7 +27,7 @@ morph_rpc_cli = rpc_client.RPCClient(MORPH_ENDPOINT) mainnet_rpc_cli = rpc_client.RPCClient(NEO_MAINNET_ENDPOINT) -@keyword('Withdraw Mainnet Gas') +@allure.step('Withdraw Mainnet Gas') def withdraw_mainnet_gas(wlt: str, amount: int): address = _address_from_wallet(wlt, EMPTY_PASSWORD) scripthash = wallet.Account.address_to_script_hash(address) @@ -72,7 +72,7 @@ def transaction_accepted(tx_id: str): return False -@keyword('Get NeoFS Balance') +@allure.step('Get NeoFS Balance') def get_balance(wallet_path: str): """ This function returns NeoFS balance for given wallet. @@ -99,7 +99,7 @@ def get_balance(wallet_path: str): raise out -@keyword('Transfer Mainnet Gas') +@allure.step('Transfer Mainnet Gas') def transfer_mainnet_gas(wallet_to: str, amount: int, wallet_password: str = EMPTY_PASSWORD, wallet_path: str = MAINNET_WALLET_PATH): """ @@ -123,7 +123,7 @@ def transfer_mainnet_gas(wallet_to: str, amount: int, wallet_password: str = EMP raise AssertionError(f"TX {txid} hasn't been processed") -@keyword('NeoFS Deposit') +@allure.step('NeoFS Deposit') def neofs_deposit(wallet_to: str, amount: int, wallet_password: str = EMPTY_PASSWORD): """ @@ -156,7 +156,7 @@ def _address_from_wallet(wlt: str, wallet_password: str): return address -@keyword('Get Mainnet Balance') +@allure.step('Get Mainnet Balance') def get_mainnet_balance(address: str): resp = mainnet_rpc_cli.get_nep17_balances(address=address) logger.info(f"Got getnep17balances response: {resp}") @@ -166,7 +166,7 @@ def get_mainnet_balance(address: str): return float(0) -@keyword('Get Sidechain Balance') +@allure.step('Get Sidechain Balance') def get_sidechain_balance(address: str): resp = morph_rpc_cli.get_nep17_balances(address=address) logger.info(f"Got getnep17balances response: {resp}") diff --git a/robot/resources/lib/python_keywords/s3_gate_bucket.py b/robot/resources/lib/python_keywords/s3_gate_bucket.py index 2f05ad5f..09239368 100644 --- a/robot/resources/lib/python_keywords/s3_gate_bucket.py +++ b/robot/resources/lib/python_keywords/s3_gate_bucket.py @@ -1,5 +1,6 @@ #!/usr/bin/python3 +import allure import json import os import re @@ -12,8 +13,6 @@ import boto3 import urllib3 from botocore.exceptions import ClientError from robot.api import logger -from robot.api.deco import keyword - from cli_helpers import _run_with_passwd, log_command_execution from common import NEOFS_ENDPOINT, S3_GATE, S3_GATE_WALLET_PATH, S3_GATE_WALLET_PASS from data_formatters import get_wallet_public_key @@ -39,7 +38,7 @@ class VersioningStatus(Enum): SUSPENDED = 'Suspended' -@keyword('Init S3 Credentials') +@allure.step('Init S3 Credentials') def init_s3_credentials(wallet_path, s3_bearer_rules_file: Optional[str] = None): bucket = str(uuid.uuid4()) s3_bearer_rules = s3_bearer_rules_file or 'robot/resources/files/s3_bearer_rules.json' @@ -79,7 +78,7 @@ def init_s3_credentials(wallet_path, s3_bearer_rules_file: Optional[str] = None) raise RuntimeError(f'Failed to init s3 credentials because of error\n{exc}') from exc -@keyword('Config S3 client') +@allure.step('Config S3 client') def config_s3_client(access_key_id: str, secret_access_key: str): try: @@ -99,7 +98,7 @@ def config_s3_client(access_key_id: str, secret_access_key: str): f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Create bucket S3') +@allure.step('Create bucket S3') def create_bucket_s3(s3_client): bucket_name = str(uuid.uuid4()) @@ -114,7 +113,7 @@ def create_bucket_s3(s3_client): f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('List buckets S3') +@allure.step('List buckets S3') def list_buckets_s3(s3_client): found_buckets = [] try: @@ -131,7 +130,7 @@ def list_buckets_s3(s3_client): f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Delete bucket S3') +@allure.step('Delete bucket S3') def delete_bucket_s3(s3_client, bucket: str): try: response = s3_client.delete_bucket(Bucket=bucket) @@ -145,7 +144,7 @@ def delete_bucket_s3(s3_client, bucket: str): f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Head bucket S3') +@allure.step('Head bucket S3') def head_bucket(s3_client, bucket: str): try: response = s3_client.head_bucket(Bucket=bucket) @@ -158,7 +157,7 @@ def head_bucket(s3_client, bucket: str): f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Set bucket versioning status') +@allure.step('Set bucket versioning status') def set_bucket_versioning(s3_client, bucket_name: str, status: VersioningStatus) -> None: try: response = s3_client.put_bucket_versioning(Bucket=bucket_name, VersioningConfiguration={'Status': status.value}) @@ -168,7 +167,7 @@ def set_bucket_versioning(s3_client, bucket_name: str, status: VersioningStatus) raise Exception(f'Got error during set bucket versioning: {err}') from err -@keyword('Get bucket versioning status') +@allure.step('Get bucket versioning status') def get_bucket_versioning_status(s3_client, bucket_name: str) -> str: try: response = s3_client.get_bucket_versioning(Bucket=bucket_name) @@ -179,7 +178,7 @@ def get_bucket_versioning_status(s3_client, bucket_name: str) -> str: raise Exception(f'Got error during get bucket versioning status: {err}') from err -@keyword('Put bucket tagging') +@allure.step('Put bucket tagging') def put_bucket_tagging(s3_client, bucket_name: str, tags: list): try: tags = [{'Key': tag_key, 'Value': tag_value} for tag_key, tag_value in tags] @@ -191,7 +190,7 @@ def put_bucket_tagging(s3_client, bucket_name: str, tags: list): raise Exception(f'Got error during put bucket tagging: {err}') from err -@keyword('Get bucket tagging') +@allure.step('Get bucket tagging') def get_bucket_tagging(s3_client, bucket_name: str) -> list: try: response = s3_client.get_bucket_tagging(Bucket=bucket_name) @@ -202,7 +201,7 @@ def get_bucket_tagging(s3_client, bucket_name: str) -> list: raise Exception(f'Got error during get bucket tagging: {err}') from err -@keyword('Delete bucket tagging') +@allure.step('Delete bucket tagging') def delete_bucket_tagging(s3_client, bucket_name: str) -> None: try: response = s3_client.delete_bucket_tagging(Bucket=bucket_name) diff --git a/robot/resources/lib/python_keywords/s3_gate_object.py b/robot/resources/lib/python_keywords/s3_gate_object.py index b878407a..32f78781 100644 --- a/robot/resources/lib/python_keywords/s3_gate_object.py +++ b/robot/resources/lib/python_keywords/s3_gate_object.py @@ -1,5 +1,6 @@ #!/usr/bin/python3.9 +import allure import os import uuid from enum import Enum @@ -9,8 +10,6 @@ from typing import Optional import urllib3 from botocore.exceptions import ClientError from robot.api import logger -from robot.api.deco import keyword - from cli_helpers import log_command_execution from python_keywords.aws_cli_client import AwsCliClient from python_keywords.s3_gate_bucket import S3_SYNC_WAIT_TIME @@ -32,7 +31,7 @@ class VersioningStatus(Enum): SUSPENDED = 'Suspended' -@keyword('List objects S3 v2') +@allure.step('List objects S3 v2') def list_objects_s3_v2(s3_client, bucket: str) -> list: try: response = s3_client.list_objects_v2(Bucket=bucket) @@ -49,7 +48,7 @@ def list_objects_s3_v2(s3_client, bucket: str) -> list: f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('List objects S3') +@allure.step('List objects S3') def list_objects_s3(s3_client, bucket: str) -> list: try: response = s3_client.list_objects(Bucket=bucket) @@ -66,7 +65,7 @@ def list_objects_s3(s3_client, bucket: str) -> list: f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('List objects versions S3') +@allure.step('List objects versions S3') def list_objects_versions_s3(s3_client, bucket: str) -> list: try: response = s3_client.list_object_versions(Bucket=bucket) @@ -79,7 +78,7 @@ def list_objects_versions_s3(s3_client, bucket: str) -> list: f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Put object S3') +@allure.step('Put object S3') def put_object_s3(s3_client, bucket: str, filepath: str): filename = os.path.basename(filepath) @@ -98,7 +97,7 @@ def put_object_s3(s3_client, bucket: str, filepath: str): f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Head object S3') +@allure.step('Head object S3') def head_object_s3(s3_client, bucket: str, object_key: str, version_id: str = None): try: params = {'Bucket': bucket, 'Key': object_key} @@ -113,7 +112,7 @@ def head_object_s3(s3_client, bucket: str, object_key: str, version_id: str = No f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Delete object S3') +@allure.step('Delete object S3') def delete_object_s3(s3_client, bucket, object_key, version_id: str = None): try: params = {'Bucket': bucket, 'Key': object_key} @@ -129,7 +128,7 @@ def delete_object_s3(s3_client, bucket, object_key, version_id: str = None): f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Delete objects S3') +@allure.step('Delete objects S3') def delete_objects_s3(s3_client, bucket: str, object_keys: list): try: response = s3_client.delete_objects(Bucket=bucket, Delete=_make_objs_dict(object_keys)) @@ -141,7 +140,7 @@ def delete_objects_s3(s3_client, bucket: str, object_keys: list): raise Exception(f'Error Message: {err.response["Error"]["Message"]}\n' f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Delete object versions S3') +@allure.step('Delete object versions S3') def delete_object_versions_s3(s3_client, bucket: str, object_versions: list): try: # Build deletion list in S3 format @@ -163,7 +162,7 @@ def delete_object_versions_s3(s3_client, bucket: str, object_versions: list): f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Copy object S3') +@allure.step('Copy object S3') def copy_object_s3(s3_client, bucket, object_key, bucket_dst=None): filename = f'{os.getcwd()}/{uuid.uuid4()}' try: @@ -178,7 +177,7 @@ def copy_object_s3(s3_client, bucket, object_key, bucket_dst=None): f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Get object S3') +@allure.step('Get object S3') def get_object_s3(s3_client, bucket: str, object_key: str, version_id: str = None): filename = f'{ASSETS_DIR}/{uuid.uuid4()}' try: @@ -206,7 +205,7 @@ def get_object_s3(s3_client, bucket: str, object_key: str, version_id: str = Non f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Create multipart upload S3') +@allure.step('Create multipart upload S3') def create_multipart_upload_s3(s3_client, bucket_name: str, object_key: str) -> str: try: response = s3_client.create_multipart_upload(Bucket=bucket_name, Key=object_key) @@ -220,7 +219,7 @@ def create_multipart_upload_s3(s3_client, bucket_name: str, object_key: str) -> f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('List multipart uploads S3') +@allure.step('List multipart uploads S3') def list_multipart_uploads_s3(s3_client, bucket_name: str) -> Optional[list[dict]]: try: response = s3_client.list_multipart_uploads(Bucket=bucket_name) @@ -233,7 +232,7 @@ def list_multipart_uploads_s3(s3_client, bucket_name: str) -> Optional[list[dict f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Abort multipart upload S3') +@allure.step('Abort multipart upload S3') def abort_multipart_uploads_s3(s3_client, bucket_name: str, object_key: str, upload_id: str): try: response = s3_client.abort_multipart_upload(Bucket=bucket_name, Key=object_key, UploadId=upload_id) @@ -244,7 +243,7 @@ def abort_multipart_uploads_s3(s3_client, bucket_name: str, object_key: str, upl f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Upload part S3') +@allure.step('Upload part S3') def upload_part_s3(s3_client, bucket_name: str, object_key: str, upload_id: str, part_num: int, filepath: str) -> str: if isinstance(s3_client, AwsCliClient): file_content = filepath @@ -264,7 +263,7 @@ def upload_part_s3(s3_client, bucket_name: str, object_key: str, upload_id: str, f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('List parts S3') +@allure.step('List parts S3') def list_parts_s3(s3_client, bucket_name: str, object_key: str, upload_id: str) -> list[dict]: try: response = s3_client.list_parts(UploadId=upload_id, Bucket=bucket_name, Key=object_key) @@ -277,7 +276,7 @@ def list_parts_s3(s3_client, bucket_name: str, object_key: str, upload_id: str) f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Complete multipart upload S3') +@allure.step('Complete multipart upload S3') def complete_multipart_upload_s3(s3_client, bucket_name: str, object_key: str, upload_id: str, parts: list): try: @@ -291,7 +290,7 @@ def complete_multipart_upload_s3(s3_client, bucket_name: str, object_key: str, u f'Http status code: {err.response["ResponseMetadata"]["HTTPStatusCode"]}') from err -@keyword('Put object tagging') +@allure.step('Put object tagging') def put_object_tagging(s3_client, bucket_name: str, object_key: str, tags: list): try: tags = [{'Key': tag_key, 'Value': tag_value} for tag_key, tag_value in tags] @@ -303,7 +302,7 @@ def put_object_tagging(s3_client, bucket_name: str, object_key: str, tags: list) raise Exception(f'Got error during put object tagging: {err}') from err -@keyword('Get object tagging') +@allure.step('Get object tagging') def get_object_tagging(s3_client, bucket_name: str, object_key: str) -> list: try: response = s3_client.get_object_tagging(Bucket=bucket_name, Key=object_key) @@ -314,7 +313,7 @@ def get_object_tagging(s3_client, bucket_name: str, object_key: str) -> list: raise Exception(f'Got error during get object tagging: {err}') from err -@keyword('Delete object tagging') +@allure.step('Delete object tagging') def delete_object_tagging(s3_client, bucket_name: str, object_key: str): try: response = s3_client.delete_object_tagging(Bucket=bucket_name, Key=object_key) @@ -324,7 +323,7 @@ def delete_object_tagging(s3_client, bucket_name: str, object_key: str): raise Exception(f'Got error during delete object tagging: {err}') from err -@keyword('Get object tagging') +@allure.step('Get object tagging') def get_object_attributes(s3_client, bucket_name: str, object_key: str, *attributes: str, version_id: str = None, max_parts: int = None, part_number: int = None, get_full_resp=True) -> dict: try: diff --git a/robot/resources/lib/python_keywords/session_token.py b/robot/resources/lib/python_keywords/session_token.py index 619386e3..c4e3b53c 100644 --- a/robot/resources/lib/python_keywords/session_token.py +++ b/robot/resources/lib/python_keywords/session_token.py @@ -4,6 +4,7 @@ This module contains keywords for work with session token. """ +import allure import base64 import json import os @@ -14,7 +15,6 @@ from cli_helpers import _cmd_run, _run_with_passwd from common import ASSETS_DIR, NEOFS_ENDPOINT, WALLET_CONFIG from neo3 import wallet from robot.api import logger -from robot.api.deco import keyword ROBOT_AUTO_KEYWORDS = False @@ -22,7 +22,7 @@ ROBOT_AUTO_KEYWORDS = False NEOFS_CLI_EXEC = os.getenv("NEOFS_CLI_EXEC", "neofs-cli") -@keyword("Generate Session Token") +@allure.step("Generate Session Token") def generate_session_token(owner: str, session_wallet: str, cid: str = "") -> str: """ This function generates session token for ContainerSessionContext @@ -78,7 +78,7 @@ def generate_session_token(owner: str, session_wallet: str, cid: str = "") -> st return file_path -@keyword("Create Session Token") +@allure.step("Create Session Token") def create_session_token(owner: str, wallet_path: str, rpc: str = NEOFS_ENDPOINT): """ Create session token for an object. @@ -98,7 +98,7 @@ def create_session_token(owner: str, wallet_path: str, rpc: str = NEOFS_ENDPOINT return session_token -@keyword("Sign Session Token") +@allure.step("Sign Session Token") def sign_session_token(session_token: str, wlt: str): """ This function signs the session token by the given wallet. diff --git a/robot/resources/lib/python_keywords/storage_policy.py b/robot/resources/lib/python_keywords/storage_policy.py index 42fede34..37026ddb 100644 --- a/robot/resources/lib/python_keywords/storage_policy.py +++ b/robot/resources/lib/python_keywords/storage_policy.py @@ -5,10 +5,10 @@ that storage policies are respected. """ +import allure from typing import Optional from robot.api import logger -from robot.api.deco import keyword import complex_object_actions import neofs_verbs @@ -19,7 +19,7 @@ from grpc_responses import OBJECT_NOT_FOUND, error_matches_status ROBOT_AUTO_KEYWORDS = False -@keyword('Get Object Copies') +@allure.step('Get Object Copies') def get_object_copies(complexity: str, wallet: str, cid: str, oid: str): """ The function performs requests to all nodes of the container and @@ -40,7 +40,7 @@ def get_object_copies(complexity: str, wallet: str, cid: str, oid: str): else get_complex_object_copies(wallet, cid, oid)) -@keyword('Get Simple Object Copies') +@allure.step('Get Simple Object Copies') def get_simple_object_copies(wallet: str, cid: str, oid: str): """ To figure out the number of a simple object copies, only direct @@ -69,7 +69,7 @@ def get_simple_object_copies(wallet: str, cid: str, oid: str): return copies -@keyword('Get Complex Object Copies') +@allure.step('Get Complex Object Copies') def get_complex_object_copies(wallet: str, cid: str, oid: str): """ To figure out the number of a complex object copies, we firstly @@ -89,7 +89,7 @@ def get_complex_object_copies(wallet: str, cid: str, oid: str): return get_simple_object_copies(wallet, cid, last_oid) -@keyword('Get Nodes With Object') +@allure.step('Get Nodes With Object') def get_nodes_with_object(wallet: str, cid: str, oid: str, skip_nodes: Optional[list[str]] = None) -> list[str]: """ The function returns list of nodes which store @@ -122,7 +122,7 @@ def get_nodes_with_object(wallet: str, cid: str, oid: str, skip_nodes: Optional[ return nodes_list -@keyword('Get Nodes Without Object') +@allure.step('Get Nodes Without Object') def get_nodes_without_object(wallet: str, cid: str, oid: str): """ The function returns list of nodes which do not store diff --git a/robot/resources/lib/python_keywords/tombstone.py b/robot/resources/lib/python_keywords/tombstone.py index 488c356f..35645a99 100644 --- a/robot/resources/lib/python_keywords/tombstone.py +++ b/robot/resources/lib/python_keywords/tombstone.py @@ -1,16 +1,16 @@ #!/usr/bin/python3 +import allure import json import neofs_verbs from neo3 import wallet -from robot.api.deco import keyword from robot.libraries.BuiltIn import BuiltIn ROBOT_AUTO_KEYWORDS = False -@keyword('Verify Head Tombstone') +@allure.step('Verify Head Tombstone') def verify_head_tombstone(wallet_path: str, cid: str, oid_ts: str, oid: str): header = neofs_verbs.head_object(wallet_path, cid, oid_ts) header = header['header'] diff --git a/robot/resources/lib/python_keywords/utility_keywords.py b/robot/resources/lib/python_keywords/utility_keywords.py index 4dc920c6..57b04b66 100644 --- a/robot/resources/lib/python_keywords/utility_keywords.py +++ b/robot/resources/lib/python_keywords/utility_keywords.py @@ -1,5 +1,6 @@ #!/usr/bin/python3.8 +import allure import hashlib import os import tarfile @@ -11,7 +12,6 @@ import wallet from common import ASSETS_DIR, SIMPLE_OBJ_SIZE from cli_helpers import _cmd_run from robot.api import logger -from robot.api.deco import keyword from robot.libraries.BuiltIn import BuiltIn ROBOT_AUTO_KEYWORDS = False @@ -33,7 +33,7 @@ def generate_file(size: int = SIMPLE_OBJ_SIZE) -> str: return file_path -@keyword('Generate file') +@allure.step('Generate file') def generate_file_and_file_hash(size: int) -> Tuple[str, str]: """ Function generates a binary file with the specified size in bytes @@ -50,7 +50,7 @@ def generate_file_and_file_hash(size: int) -> Tuple[str, str]: return file_path, file_hash -@keyword('Get File Hash') +@allure.step('Get File Hash') def get_file_hash(filename: str, len: int = None): """ This function generates hash for the specified file. @@ -69,12 +69,12 @@ def get_file_hash(filename: str, len: int = None): return file_hash.hexdigest() -@keyword('Generate Wallet') +@allure.step('Generate Wallet') def generate_wallet(): return wallet.init_wallet(ASSETS_DIR) -@keyword('Get Docker Logs') +@allure.step('Get Docker Logs') def get_container_logs(testcase_name: str) -> None: client = docker.APIClient(base_url='unix://var/run/docker.sock') logs_dir = BuiltIn().get_variable_value("${OUTPUT_DIR}") @@ -93,7 +93,7 @@ def get_container_logs(testcase_name: str) -> None: tar.close() -@keyword('Make Up') +@allure.step('Make Up') def make_up(services: list = [], config_dict: dict = {}): test_path = os.getcwd() dev_path = os.getenv('DEVENV_PATH', '../neofs-dev-env') @@ -117,7 +117,7 @@ def make_up(services: list = [], config_dict: dict = {}): os.chdir(test_path) -@keyword('Make Down') +@allure.step('Make Down') def make_down(services: list = []): test_path = os.getcwd() dev_path = os.getenv('DEVENV_PATH', '../neofs-dev-env')