From 873d6e3d149d311b0ee312e1fd6752dd7e1e7780 Mon Sep 17 00:00:00 2001 From: Andrey Berezin Date: Wed, 29 Nov 2023 16:34:59 +0300 Subject: [PATCH] [#161] Improve logging Signed-off-by: Andrey Berezin --- pytest_tests/helpers/object_access.py | 16 +- pytest_tests/helpers/utility.py | 4 +- pytest_tests/testsuites/acl/conftest.py | 18 +- pytest_tests/testsuites/acl/test_acl.py | 35 +- pytest_tests/testsuites/acl/test_bearer.py | 57 +-- pytest_tests/testsuites/acl/test_eacl.py | 43 +- .../testsuites/acl/test_eacl_filters.py | 45 +- pytest_tests/testsuites/conftest.py | 84 +++- .../testsuites/container/test_container.py | 11 +- .../testsuites/container/test_policy.py | 423 +++++++++--------- .../failovers/test_discrete_time.py | 19 +- .../failovers/test_failover_network.py | 87 ++-- .../failovers/test_failover_server.py | 66 +-- .../failovers/test_failover_storage.py | 195 ++++---- .../management/test_node_management.py | 105 ++--- .../testsuites/object/test_object_api.py | 29 +- .../object/test_object_api_bearer.py | 7 +- .../testsuites/object/test_object_lifetime.py | 19 +- .../testsuites/object/test_object_lock.py | 55 +-- .../replication/test_replication.py | 9 +- .../services/http_gate/test_http_bearer.py | 7 +- .../services/http_gate/test_http_gate.py | 23 +- .../services/http_gate/test_http_headers.py | 15 +- .../services/http_gate/test_http_object.py | 15 +- .../services/http_gate/test_http_streaming.py | 7 +- .../http_gate/test_http_system_header.py | 33 +- .../services/s3_gate/test_s3_ACL.py | 15 +- .../services/s3_gate/test_s3_bucket.py | 27 +- .../services/s3_gate/test_s3_gate.py | 95 ++-- .../services/s3_gate/test_s3_locking.py | 41 +- .../services/s3_gate/test_s3_multipart.py | 35 +- .../services/s3_gate/test_s3_object.py | 149 +++--- .../services/s3_gate/test_s3_policy.py | 27 +- .../services/s3_gate/test_s3_tagging.py | 29 +- .../services/s3_gate/test_s3_versioning.py | 13 +- .../testsuites/services/test_binaries.py | 5 +- .../test_object_session_token.py | 21 +- .../test_static_object_session_token.py | 25 +- .../test_static_session_token_container.py | 16 +- pytest_tests/testsuites/special/test_logs.py | 5 +- 40 files changed, 980 insertions(+), 950 deletions(-) diff --git a/pytest_tests/helpers/object_access.py b/pytest_tests/helpers/object_access.py index a772b7a..f474440 100644 --- a/pytest_tests/helpers/object_access.py +++ b/pytest_tests/helpers/object_access.py @@ -1,6 +1,6 @@ from typing import Optional -import allure +from frostfs_testlib import reporter from frostfs_testlib.resources.cli import CLI_DEFAULT_TIMEOUT from frostfs_testlib.resources.error_patterns import OBJECT_ACCESS_DENIED from frostfs_testlib.shell import Shell @@ -31,7 +31,7 @@ def can_get_object( wallet_config: Optional[str] = None, xhdr: Optional[dict] = None, ) -> bool: - with allure.step("Try get object from container"): + with reporter.step("Try get object from container"): try: got_file_path = get_object_from_random_node( wallet, @@ -63,7 +63,7 @@ def can_put_object( xhdr: Optional[dict] = None, attributes: Optional[dict] = None, ) -> bool: - with allure.step("Try put object to container"): + with reporter.step("Try put object to container"): try: put_object_to_random_node( wallet, @@ -94,7 +94,7 @@ def can_delete_object( wallet_config: Optional[str] = None, xhdr: Optional[dict] = None, ) -> bool: - with allure.step("Try delete object from container"): + with reporter.step("Try delete object from container"): try: delete_object( wallet, @@ -125,7 +125,7 @@ def can_get_head_object( xhdr: Optional[dict] = None, timeout: Optional[str] = CLI_DEFAULT_TIMEOUT, ) -> bool: - with allure.step("Try get head of object"): + with reporter.step("Try get head of object"): try: head_object( wallet, @@ -157,7 +157,7 @@ def can_get_range_of_object( xhdr: Optional[dict] = None, timeout: Optional[str] = CLI_DEFAULT_TIMEOUT, ) -> bool: - with allure.step("Try get range of object"): + with reporter.step("Try get range of object"): try: get_range( wallet, @@ -190,7 +190,7 @@ def can_get_range_hash_of_object( xhdr: Optional[dict] = None, timeout: Optional[str] = CLI_DEFAULT_TIMEOUT, ) -> bool: - with allure.step("Try get range hash of object"): + with reporter.step("Try get range hash of object"): try: get_range_hash( wallet, @@ -223,7 +223,7 @@ def can_search_object( xhdr: Optional[dict] = None, timeout: Optional[str] = CLI_DEFAULT_TIMEOUT, ) -> bool: - with allure.step("Try search object in container"): + with reporter.step("Try search object in container"): try: oids = search_object( wallet, diff --git a/pytest_tests/helpers/utility.py b/pytest_tests/helpers/utility.py index f557d5e..e417502 100644 --- a/pytest_tests/helpers/utility.py +++ b/pytest_tests/helpers/utility.py @@ -1,6 +1,6 @@ import time -import allure +from frostfs_testlib import reporter from frostfs_testlib.resources.common import STORAGE_GC_TIME from frostfs_testlib.utils import datetime_utils @@ -33,5 +33,5 @@ def placement_policy_from_container(container_info: str) -> str: def wait_for_gc_pass_on_storage_nodes() -> None: wait_time = datetime_utils.parse_time(STORAGE_GC_TIME) - with allure.step(f"Wait {wait_time}s until GC completes on storage nodes"): + with reporter.step(f"Wait {wait_time}s until GC completes on storage nodes"): time.sleep(wait_time) diff --git a/pytest_tests/testsuites/acl/conftest.py b/pytest_tests/testsuites/acl/conftest.py index 3148136..1c3f6e2 100644 --- a/pytest_tests/testsuites/acl/conftest.py +++ b/pytest_tests/testsuites/acl/conftest.py @@ -3,8 +3,8 @@ import uuid from dataclasses import dataclass from typing import Optional -import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.common import DEFAULT_WALLET_CONFIG, DEFAULT_WALLET_PASS from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.shell import Shell @@ -39,9 +39,7 @@ class Wallets: @pytest.fixture(scope="module") def wallets(default_wallet: str, temp_directory: str, cluster: Cluster) -> Wallets: - other_wallets_paths = [ - os.path.join(temp_directory, f"{str(uuid.uuid4())}.json") for _ in range(2) - ] + other_wallets_paths = [os.path.join(temp_directory, f"{str(uuid.uuid4())}.json") for _ in range(2)] for other_wallet_path in other_wallets_paths: wallet_utils.init_wallet(other_wallet_path, DEFAULT_WALLET_PASS) @@ -72,11 +70,7 @@ def wallets(default_wallet: str, temp_directory: str, cluster: Cluster) -> Walle if role == EACLRole.SYSTEM: continue for wallet in wallets: - allure.attach.file( - wallet.wallet_path, - os.path.basename(wallet.wallet_path), - allure.attachment_type.JSON, - ) + reporter.attach(wallet.wallet_path, os.path.basename(wallet.wallet_path)) return wallets_collection @@ -91,7 +85,7 @@ def eacl_container_with_objects( wallets: Wallets, client_shell: Shell, cluster: Cluster, file_path: str ) -> tuple[str, list[str], str]: user_wallet = wallets.get_wallet() - with allure.step("Create eACL public container"): + with reporter.step("Create eACL public container"): cid = create_container( user_wallet.wallet_path, basic_acl=PUBLIC_ACL, @@ -99,7 +93,7 @@ def eacl_container_with_objects( endpoint=cluster.default_rpc_endpoint, ) - with allure.step("Add test objects to container"): + with reporter.step("Add test objects to container"): objects_oids = [ put_object_to_random_node( user_wallet.wallet_path, @@ -114,5 +108,5 @@ def eacl_container_with_objects( yield cid, objects_oids, file_path - # with allure.step('Delete eACL public container'): + # with reporter.step('Delete eACL public container'): # delete_container(user_wallet, cid) diff --git a/pytest_tests/testsuites/acl/test_acl.py b/pytest_tests/testsuites/acl/test_acl.py index 64ce500..aa608b4 100644 --- a/pytest_tests/testsuites/acl/test_acl.py +++ b/pytest_tests/testsuites/acl/test_acl.py @@ -1,5 +1,6 @@ import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PRIVATE_ACL_F, PUBLIC_ACL_F, READONLY_ACL_F from frostfs_testlib.shell import Shell from frostfs_testlib.steps.cli.container import create_container @@ -23,7 +24,7 @@ class TestACLBasic(ClusterTestBase): @pytest.fixture(scope="function") def public_container(self, wallets): user_wallet = wallets.get_wallet() - with allure.step("Create public container"): + with reporter.step("Create public container"): cid_public = create_container( user_wallet.wallet_path, basic_acl=PUBLIC_ACL_F, @@ -33,13 +34,13 @@ class TestACLBasic(ClusterTestBase): yield cid_public - # with allure.step('Delete public container'): + # with reporter.step('Delete public container'): # delete_container(user_wallet.wallet_path, cid_public) @pytest.fixture(scope="function") def private_container(self, wallets: Wallets): user_wallet = wallets.get_wallet() - with allure.step("Create private container"): + with reporter.step("Create private container"): cid_private = create_container( user_wallet.wallet_path, basic_acl=PRIVATE_ACL_F, @@ -49,13 +50,13 @@ class TestACLBasic(ClusterTestBase): yield cid_private - # with allure.step('Delete private container'): + # with reporter.step('Delete private container'): # delete_container(user_wallet.wallet_path, cid_private) @pytest.fixture(scope="function") def read_only_container(self, wallets: Wallets): user_wallet = wallets.get_wallet() - with allure.step("Create public readonly container"): + with reporter.step("Create public readonly container"): cid_read_only = create_container( user_wallet.wallet_path, basic_acl=READONLY_ACL_F, @@ -65,7 +66,7 @@ class TestACLBasic(ClusterTestBase): yield cid_read_only - # with allure.step('Delete public readonly container'): + # with reporter.step('Delete public readonly container'): # delete_container(user_wallet.wallet_path, cid_read_only) @allure.title("Operations with basic ACL on public container (obj_size={object_size})") @@ -77,7 +78,7 @@ class TestACLBasic(ClusterTestBase): other_wallet = wallets.get_wallet(role=EACLRole.OTHERS) cid = public_container for wallet, desc in ((user_wallet, "owner"), (other_wallet, "other users")): - with allure.step("Add test objects to container"): + with reporter.step("Add test objects to container"): # We create new objects for each wallet because check_full_access_to_container # deletes the object owner_object_oid = put_object_to_random_node( @@ -96,7 +97,7 @@ class TestACLBasic(ClusterTestBase): cluster=self.cluster, attributes={"created": "other"}, ) - with allure.step(f"Check {desc} has full access to public container"): + with reporter.step(f"Check {desc} has full access to public container"): check_full_access_to_container( wallet.wallet_path, cid, @@ -122,13 +123,13 @@ class TestACLBasic(ClusterTestBase): user_wallet = wallets.get_wallet() other_wallet = wallets.get_wallet(role=EACLRole.OTHERS) cid = private_container - with allure.step("Add test objects to container"): + with reporter.step("Add test objects to container"): owner_object_oid = put_object_to_random_node( user_wallet.wallet_path, file_path, cid, shell=self.shell, cluster=self.cluster ) - with allure.step("Check only owner has full access to private container"): - with allure.step("Check no one except owner has access to operations with container"): + with reporter.step("Check only owner has full access to private container"): + with reporter.step("Check no one except owner has access to operations with container"): check_no_access_to_container( other_wallet.wallet_path, cid, @@ -138,7 +139,7 @@ class TestACLBasic(ClusterTestBase): cluster=self.cluster, ) - with allure.step("Check owner has full access to private container"): + with reporter.step("Check owner has full access to private container"): check_full_access_to_container( user_wallet.wallet_path, cid, @@ -149,9 +150,7 @@ class TestACLBasic(ClusterTestBase): ) @allure.title("Operations with basic ACL on READONLY container (obj_size={object_size})") - def test_basic_acl_readonly( - self, wallets: Wallets, client_shell: Shell, read_only_container: str, file_path: str - ): + def test_basic_acl_readonly(self, wallets: Wallets, client_shell: Shell, read_only_container: str, file_path: str): """ Test basic ACL Operations for Read-Only Container. """ @@ -159,12 +158,12 @@ class TestACLBasic(ClusterTestBase): other_wallet = wallets.get_wallet(role=EACLRole.OTHERS) cid = read_only_container - with allure.step("Add test objects to container"): + with reporter.step("Add test objects to container"): object_oid = put_object_to_random_node( user_wallet.wallet_path, file_path, cid, shell=client_shell, cluster=self.cluster ) - with allure.step("Check other has read-only access to operations with container"): + with reporter.step("Check other has read-only access to operations with container"): check_read_only_container( other_wallet.wallet_path, cid, @@ -174,7 +173,7 @@ class TestACLBasic(ClusterTestBase): cluster=self.cluster, ) - with allure.step("Check owner has full access to public container"): + with reporter.step("Check owner has full access to public container"): check_full_access_to_container( user_wallet.wallet_path, cid, diff --git a/pytest_tests/testsuites/acl/test_bearer.py b/pytest_tests/testsuites/acl/test_bearer.py index 7950b48..ecc20ca 100644 --- a/pytest_tests/testsuites/acl/test_bearer.py +++ b/pytest_tests/testsuites/acl/test_bearer.py @@ -1,11 +1,7 @@ import allure import pytest -from frostfs_testlib.steps.acl import ( - create_eacl, - form_bearertoken_file, - set_eacl, - wait_for_cache_expired, -) +from frostfs_testlib import reporter +from frostfs_testlib.steps.acl import create_eacl, form_bearertoken_file, set_eacl, wait_for_cache_expired from frostfs_testlib.storage.dataclasses.acl import EACLAccess, EACLOperation, EACLRole, EACLRule from frostfs_testlib.testing.cluster_test_base import ClusterTestBase @@ -34,7 +30,7 @@ class TestACLBearer(ClusterTestBase): deny_wallet = wallets.get_wallet(role) endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Check {role.value} has full access to container without bearer token"): + with reporter.step(f"Check {role.value} has full access to container without bearer token"): check_full_access_to_container( deny_wallet.wallet_path, cid, @@ -45,29 +41,22 @@ class TestACLBearer(ClusterTestBase): cluster=self.cluster, ) - with allure.step(f"Set deny all operations for {role.value} via eACL"): - eacl = [ - EACLRule(access=EACLAccess.DENY, role=role, operation=op) for op in EACLOperation - ] + with reporter.step(f"Set deny all operations for {role.value} via eACL"): + eacl = [EACLRule(access=EACLAccess.DENY, role=role, operation=op) for op in EACLOperation] eacl_file = create_eacl(cid, eacl, shell=self.shell) set_eacl(user_wallet.wallet_path, cid, eacl_file, shell=self.shell, endpoint=endpoint) wait_for_cache_expired() - with allure.step(f"Create bearer token for {role.value} with all operations allowed"): + with reporter.step(f"Create bearer token for {role.value} with all operations allowed"): bearer = form_bearertoken_file( user_wallet.wallet_path, cid, - [ - EACLRule(operation=op, access=EACLAccess.ALLOW, role=role) - for op in EACLOperation - ], + [EACLRule(operation=op, access=EACLAccess.ALLOW, role=role) for op in EACLOperation], shell=self.shell, endpoint=self.cluster.default_rpc_endpoint, ) - with allure.step( - f"Check {role.value} without token has no access to all operations with container" - ): + with reporter.step(f"Check {role.value} without token has no access to all operations with container"): check_no_access_to_container( deny_wallet.wallet_path, cid, @@ -78,9 +67,7 @@ class TestACLBearer(ClusterTestBase): cluster=self.cluster, ) - with allure.step( - f"Check {role.value} with token has access to all operations with container" - ): + with reporter.step(f"Check {role.value} with token has access to all operations with container"): check_full_access_to_container( deny_wallet.wallet_path, cid, @@ -92,17 +79,13 @@ class TestACLBearer(ClusterTestBase): cluster=self.cluster, ) - with allure.step(f"Set allow all operations for {role.value} via eACL"): - eacl = [ - EACLRule(access=EACLAccess.ALLOW, role=role, operation=op) for op in EACLOperation - ] + with reporter.step(f"Set allow all operations for {role.value} via eACL"): + eacl = [EACLRule(access=EACLAccess.ALLOW, role=role, operation=op) for op in EACLOperation] eacl_file = create_eacl(cid, eacl, shell=self.shell) set_eacl(user_wallet.wallet_path, cid, eacl_file, shell=self.shell, endpoint=endpoint) wait_for_cache_expired() - with allure.step( - f"Check {role.value} without token has access to all operations with container" - ): + with reporter.step(f"Check {role.value} without token has access to all operations with container"): check_full_access_to_container( deny_wallet.wallet_path, cid, @@ -145,19 +128,13 @@ class TestACLBearer(ClusterTestBase): } deny_map_with_bearer = { - EACLRole.USER: [ - op for op in deny_map[EACLRole.USER] if op not in bearer_map[EACLRole.USER] - ], - EACLRole.OTHERS: [ - op for op in deny_map[EACLRole.OTHERS] if op not in bearer_map[EACLRole.OTHERS] - ], + EACLRole.USER: [op for op in deny_map[EACLRole.USER] if op not in bearer_map[EACLRole.USER]], + EACLRole.OTHERS: [op for op in deny_map[EACLRole.OTHERS] if op not in bearer_map[EACLRole.OTHERS]], } eacl_deny = [] for role, operations in deny_map.items(): - eacl_deny += [ - EACLRule(access=EACLAccess.DENY, role=role, operation=op) for op in operations - ] + eacl_deny += [EACLRule(access=EACLAccess.DENY, role=role, operation=op) for op in operations] set_eacl( user_wallet.wallet_path, cid, @@ -167,7 +144,7 @@ class TestACLBearer(ClusterTestBase): ) wait_for_cache_expired() - with allure.step("Check rule consistency without bearer"): + with reporter.step("Check rule consistency without bearer"): check_custom_access_to_container( user_wallet.wallet_path, cid, @@ -189,7 +166,7 @@ class TestACLBearer(ClusterTestBase): cluster=self.cluster, ) - with allure.step("Check rule consistency using bearer token"): + with reporter.step("Check rule consistency using bearer token"): bearer_user = form_bearertoken_file( user_wallet.wallet_path, cid, diff --git a/pytest_tests/testsuites/acl/test_eacl.py b/pytest_tests/testsuites/acl/test_eacl.py index 5472069..8f3014a 100644 --- a/pytest_tests/testsuites/acl/test_eacl.py +++ b/pytest_tests/testsuites/acl/test_eacl.py @@ -1,5 +1,6 @@ import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.steps.acl import create_eacl, set_eacl, wait_for_cache_expired from frostfs_testlib.steps.cli.container import create_container @@ -30,7 +31,7 @@ class TestEACLContainer(ClusterTestBase): user_wallet = wallets.get_wallet() storage_nodes = self.cluster.storage_nodes node_count = len(storage_nodes) - with allure.step("Create eACL public container with full placement rule"): + with reporter.step("Create eACL public container with full placement rule"): full_placement_rule = f"REP {node_count} IN X CBF 1 SELECT {node_count} FROM * AS X" cid = create_container( wallet=user_wallet.wallet_path, @@ -40,7 +41,7 @@ class TestEACLContainer(ClusterTestBase): endpoint=self.cluster.default_rpc_endpoint, ) - with allure.step("Add test object to container"): + with reporter.step("Add test object to container"): oid = put_object_to_random_node( user_wallet.wallet_path, file_path, cid, shell=self.shell, cluster=self.cluster ) @@ -71,7 +72,7 @@ class TestEACLContainer(ClusterTestBase): not_deny_role_str = "user" if deny_role == EACLRole.OTHERS else "all others" cid, object_oids, file_path = eacl_container_with_objects - with allure.step(f"Deny all operations for {deny_role_str} via eACL"): + with reporter.step(f"Deny all operations for {deny_role_str} via eACL"): eacl_deny = [EACLRule(access=EACLAccess.DENY, role=deny_role, operation=op) for op in EACLOperation] set_eacl( user_wallet.wallet_path, @@ -82,8 +83,8 @@ class TestEACLContainer(ClusterTestBase): ) wait_for_cache_expired() - with allure.step(f"Check only {not_deny_role_str} has full access to container"): - with allure.step(f"Check {deny_role_str} has not access to any operations with container"): + with reporter.step(f"Check only {not_deny_role_str} has full access to container"): + with reporter.step(f"Check {deny_role_str} has not access to any operations with container"): check_no_access_to_container( deny_role_wallet.wallet_path, cid, @@ -93,7 +94,7 @@ class TestEACLContainer(ClusterTestBase): cluster=self.cluster, ) - with allure.step(f"Check {not_deny_role_wallet} has full access to eACL public container"): + with reporter.step(f"Check {not_deny_role_wallet} has full access to eACL public container"): check_full_access_to_container( not_deny_role_wallet.wallet_path, cid, @@ -103,7 +104,7 @@ class TestEACLContainer(ClusterTestBase): cluster=self.cluster, ) - with allure.step(f"Allow all operations for {deny_role_str} via eACL"): + with reporter.step(f"Allow all operations for {deny_role_str} via eACL"): eacl_deny = [EACLRule(access=EACLAccess.ALLOW, role=deny_role, operation=op) for op in EACLOperation] set_eacl( user_wallet.wallet_path, @@ -114,7 +115,7 @@ class TestEACLContainer(ClusterTestBase): ) wait_for_cache_expired() - with allure.step("Check all have full access to eACL public container"): + with reporter.step("Check all have full access to eACL public container"): check_full_access_to_container( user_wallet.wallet_path, cid, @@ -140,7 +141,7 @@ class TestEACLContainer(ClusterTestBase): other_wallet, other_wallet_allow = wallets.get_wallets_list(EACLRole.OTHERS)[0:2] cid, object_oids, file_path = eacl_container_with_objects - with allure.step("Deny all operations for others except single wallet via eACL"): + with reporter.step("Deny all operations for others except single wallet via eACL"): eacl = [ EACLRule( access=EACLAccess.ALLOW, @@ -159,8 +160,8 @@ class TestEACLContainer(ClusterTestBase): ) wait_for_cache_expired() - with allure.step("Check only owner and allowed other have full access to public container"): - with allure.step("Check other has not access to operations with container"): + with reporter.step("Check only owner and allowed other have full access to public container"): + with reporter.step("Check other has not access to operations with container"): check_no_access_to_container( other_wallet.wallet_path, cid, @@ -170,7 +171,7 @@ class TestEACLContainer(ClusterTestBase): cluster=self.cluster, ) - with allure.step("Check owner has full access to public container"): + with reporter.step("Check owner has full access to public container"): check_full_access_to_container( user_wallet.wallet_path, cid, @@ -180,7 +181,7 @@ class TestEACLContainer(ClusterTestBase): cluster=self.cluster, ) - with allure.step("Check allowed other has full access to public container"): + with reporter.step("Check allowed other has full access to public container"): check_full_access_to_container( other_wallet_allow.wallet_path, cid, @@ -201,7 +202,7 @@ class TestEACLContainer(ClusterTestBase): storage_nodes = self.cluster.storage_nodes storage_node = self.cluster.storage_nodes[0] - with allure.step("Deny all operations for user via eACL"): + with reporter.step("Deny all operations for user via eACL"): eacl_deny = [EACLRule(access=EACLAccess.DENY, role=EACLRole.USER, operation=op) for op in EACLOperation] eacl_deny += [EACLRule(access=EACLAccess.DENY, role=EACLRole.OTHERS, operation=op) for op in EACLOperation] set_eacl( @@ -213,11 +214,11 @@ class TestEACLContainer(ClusterTestBase): ) wait_for_cache_expired() - with allure.step("Drop object to check replication"): + with reporter.step("Drop object to check replication"): drop_object(storage_node, cid=cid, oid=oid) storage_wallet_path = storage_node.get_wallet_path() - with allure.step("Wait for dropped object replicated"): + with reporter.step("Wait for dropped object replicated"): wait_object_replication( cid, oid, @@ -234,7 +235,7 @@ class TestEACLContainer(ClusterTestBase): cid, object_oids, file_path = eacl_container_with_objects endpoint = self.cluster.default_rpc_endpoint - with allure.step("Check IR and STORAGE rules compliance"): + with reporter.step("Check IR and STORAGE rules compliance"): assert not can_put_object( ir_wallet.wallet_path, cid, @@ -361,7 +362,7 @@ class TestEACLContainer(ClusterTestBase): wallet_config=storage_wallet.config_path, ) - with allure.step("Deny all operations for SYSTEM via eACL"): + with reporter.step("Deny all operations for SYSTEM via eACL"): set_eacl( user_wallet.wallet_path, cid, @@ -377,7 +378,7 @@ class TestEACLContainer(ClusterTestBase): ) wait_for_cache_expired() - with allure.step("Check IR and STORAGE rules compliance with deny eACL"): + with reporter.step("Check IR and STORAGE rules compliance with deny eACL"): assert not can_put_object( wallet=ir_wallet.wallet_path, cid=cid, @@ -511,7 +512,7 @@ class TestEACLContainer(ClusterTestBase): wallet_config=storage_wallet.config_path, ) - with allure.step("Allow all operations for SYSTEM via eACL"): + with reporter.step("Allow all operations for SYSTEM via eACL"): set_eacl( user_wallet.wallet_path, cid, @@ -527,7 +528,7 @@ class TestEACLContainer(ClusterTestBase): ) wait_for_cache_expired() - with allure.step("Check IR and STORAGE rules compliance with allow eACL"): + with reporter.step("Check IR and STORAGE rules compliance with allow eACL"): assert not can_put_object( wallet=ir_wallet.wallet_path, cid=cid, diff --git a/pytest_tests/testsuites/acl/test_eacl_filters.py b/pytest_tests/testsuites/acl/test_eacl_filters.py index 55262d9..edb7e06 100644 --- a/pytest_tests/testsuites/acl/test_eacl_filters.py +++ b/pytest_tests/testsuites/acl/test_eacl_filters.py @@ -1,5 +1,6 @@ import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.steps.acl import create_eacl, form_bearertoken_file, set_eacl, wait_for_cache_expired from frostfs_testlib.steps.cli.container import create_container, delete_container @@ -61,7 +62,7 @@ class TestEACLFilters(ClusterTestBase): @pytest.fixture(scope="function") def eacl_container_with_objects(self, wallets: Wallets, file_path: str): user_wallet = wallets.get_wallet() - with allure.step("Create eACL public container"): + with reporter.step("Create eACL public container"): cid = create_container( user_wallet.wallet_path, basic_acl=PUBLIC_ACL, @@ -69,7 +70,7 @@ class TestEACLFilters(ClusterTestBase): endpoint=self.cluster.default_rpc_endpoint, ) - with allure.step("Add test objects to container"): + with reporter.step("Add test objects to container"): objects_with_header = [ put_object_to_random_node( user_wallet.wallet_path, @@ -107,7 +108,7 @@ class TestEACLFilters(ClusterTestBase): yield cid, objects_with_header, objects_with_other_header, objects_without_header, file_path - with allure.step("Delete eACL public container"): + with reporter.step("Delete eACL public container"): delete_container( user_wallet.wallet_path, cid, @@ -134,7 +135,7 @@ class TestEACLFilters(ClusterTestBase): file_path, ) = eacl_container_with_objects - with allure.step("Deny all operations for other with eACL request filter"): + with reporter.step("Deny all operations for other with eACL request filter"): equal_filter = EACLFilter(**self.REQ_EQUAL_FILTER.__dict__) equal_filter.match_type = match_type eacl_deny = [ @@ -168,7 +169,7 @@ class TestEACLFilters(ClusterTestBase): objects_with_other_header, objects_without_header, ): - with allure.step("Check other has full access when sending request without headers"): + with reporter.step("Check other has full access when sending request without headers"): check_full_access_to_container( other_wallet.wallet_path, cid, @@ -178,7 +179,7 @@ class TestEACLFilters(ClusterTestBase): cluster=self.cluster, ) - with allure.step("Check other has full access when sending request with allowed headers"): + with reporter.step("Check other has full access when sending request with allowed headers"): check_full_access_to_container( other_wallet.wallet_path, cid, @@ -189,7 +190,7 @@ class TestEACLFilters(ClusterTestBase): xhdr=allow_headers, ) - with allure.step("Check other has no access when sending request with denied headers"): + with reporter.step("Check other has no access when sending request with denied headers"): check_no_access_to_container( other_wallet.wallet_path, cid, @@ -200,7 +201,7 @@ class TestEACLFilters(ClusterTestBase): xhdr=deny_headers, ) - with allure.step( + with reporter.step( "Check other has full access when sending request " "with denied headers and using bearer token" ): bearer_other = form_bearertoken_file( @@ -239,7 +240,7 @@ class TestEACLFilters(ClusterTestBase): file_path, ) = eacl_container_with_objects - with allure.step("Deny all operations for other with object filter"): + with reporter.step("Deny all operations for other with object filter"): equal_filter = EACLFilter(**self.OBJ_EQUAL_FILTER.__dict__) equal_filter.match_type = match_type eacl_deny = [ @@ -267,7 +268,7 @@ class TestEACLFilters(ClusterTestBase): # but eACL rule should ignore request headers and validate # only object headers for xhdr in (self.ATTRIBUTE, self.OTHER_ATTRIBUTE, None): - with allure.step("Check other have full access to objects without attributes"): + with reporter.step("Check other have full access to objects without attributes"): check_full_access_to_container( other_wallet.wallet_path, cid, @@ -278,7 +279,7 @@ class TestEACLFilters(ClusterTestBase): xhdr=xhdr, ) - with allure.step("Check other have full access to objects without deny attribute"): + with reporter.step("Check other have full access to objects without deny attribute"): check_full_access_to_container( other_wallet.wallet_path, cid, @@ -289,7 +290,7 @@ class TestEACLFilters(ClusterTestBase): xhdr=xhdr, ) - with allure.step("Check other have no access to objects with deny attribute"): + with reporter.step("Check other have no access to objects with deny attribute"): with pytest.raises(AssertionError): assert can_get_head_object( other_wallet.wallet_path, @@ -310,7 +311,7 @@ class TestEACLFilters(ClusterTestBase): xhdr=xhdr, ) - with allure.step("Check other have access to objects with deny attribute and using bearer token"): + with reporter.step("Check other have access to objects with deny attribute and using bearer token"): bearer_other = form_bearertoken_file( user_wallet.wallet_path, cid, @@ -337,7 +338,7 @@ class TestEACLFilters(ClusterTestBase): ) allow_attribute = self.OTHER_ATTRIBUTE if match_type == EACLMatchType.STRING_EQUAL else self.ATTRIBUTE - with allure.step("Check other can PUT objects without denied attribute"): + with reporter.step("Check other can PUT objects without denied attribute"): assert can_put_object( other_wallet.wallet_path, cid, @@ -349,7 +350,7 @@ class TestEACLFilters(ClusterTestBase): assert can_put_object(other_wallet.wallet_path, cid, file_path, shell=self.shell, cluster=self.cluster) deny_attribute = self.ATTRIBUTE if match_type == EACLMatchType.STRING_EQUAL else self.OTHER_ATTRIBUTE - with allure.step("Check other can not PUT objects with denied attribute"): + with reporter.step("Check other can not PUT objects with denied attribute"): with pytest.raises(AssertionError): assert can_put_object( other_wallet.wallet_path, @@ -360,7 +361,7 @@ class TestEACLFilters(ClusterTestBase): attributes=deny_attribute, ) - with allure.step("Check other can PUT objects with denied attribute and using bearer token"): + with reporter.step("Check other can PUT objects with denied attribute and using bearer token"): bearer_other_for_put = form_bearertoken_file( user_wallet.wallet_path, cid, @@ -402,7 +403,7 @@ class TestEACLFilters(ClusterTestBase): file_path, ) = eacl_container_with_objects - with allure.step("Deny all operations for others except few operations allowed by object filter"): + with reporter.step("Deny all operations for others except few operations allowed by object filter"): equal_filter = EACLFilter(**self.OBJ_EQUAL_FILTER.__dict__) equal_filter.match_type = match_type eacl = [ @@ -437,7 +438,7 @@ class TestEACLFilters(ClusterTestBase): allow_attribute = self.OTHER_ATTRIBUTE deny_attribute = self.ATTRIBUTE - with allure.step("Check other cannot get and put objects without attributes"): + with reporter.step("Check other cannot get and put objects without attributes"): oid = objects_without_header.pop() with pytest.raises(AssertionError): assert can_get_head_object( @@ -459,7 +460,7 @@ class TestEACLFilters(ClusterTestBase): with pytest.raises(AssertionError): assert can_put_object(other_wallet.wallet_path, cid, file_path, shell=self.shell, cluster=self.cluster) - with allure.step("Check other can get and put objects without attributes and using bearer token"): + with reporter.step("Check other can get and put objects without attributes and using bearer token"): bearer_other = form_bearertoken_file( user_wallet.wallet_path, cid, @@ -500,7 +501,7 @@ class TestEACLFilters(ClusterTestBase): bearer=bearer_other, ) - with allure.step("Check other can get objects with attributes matching the filter"): + with reporter.step("Check other can get objects with attributes matching the filter"): oid = allow_objects.pop() assert can_get_head_object( other_wallet.wallet_path, @@ -526,7 +527,7 @@ class TestEACLFilters(ClusterTestBase): attributes=allow_attribute, ) - with allure.step("Check other cannot get objects without attributes matching the filter"): + with reporter.step("Check other cannot get objects without attributes matching the filter"): with pytest.raises(AssertionError): assert can_get_head_object( other_wallet.wallet_path, @@ -554,7 +555,7 @@ class TestEACLFilters(ClusterTestBase): cluster=self.cluster, ) - with allure.step( + with reporter.step( "Check other can get objects without attributes matching the filter " "and using bearer token" ): oid = deny_objects.pop() diff --git a/pytest_tests/testsuites/conftest.py b/pytest_tests/testsuites/conftest.py index 619ce29..0ea2e72 100644 --- a/pytest_tests/testsuites/conftest.py +++ b/pytest_tests/testsuites/conftest.py @@ -10,10 +10,10 @@ import allure import pytest import yaml from dateutil import parser -from frostfs_testlib import plugins +from frostfs_testlib import plugins, reporter from frostfs_testlib.healthcheck.interfaces import Healthcheck from frostfs_testlib.hosting import Hosting -from frostfs_testlib.reporter import AllureHandler, get_reporter +from frostfs_testlib.reporter import AllureHandler, StepsLogger from frostfs_testlib.resources.common import ( ASSETS_DIR, COMPLEX_OBJECT_CHUNKS_COUNT, @@ -48,6 +48,9 @@ def pytest_configure(config: pytest.Config): config.option.markexpr = f"logs_after_session or ({markers})" +number_key = pytest.StashKey[str]() +start_time = pytest.StashKey[int]() +test_outcome = pytest.StashKey[str]() # pytest hook. Do not rename def pytest_collection_modifyitems(items: list[pytest.Item]): # Make network tests last based on @pytest.mark.node_mgmt and logs_test to be latest @@ -60,6 +63,35 @@ def pytest_collection_modifyitems(items: list[pytest.Item]): items.sort(key=lambda item: priority(item)) +# pytest hook. Do not rename +def pytest_collection_finish(session: pytest.Session): + items_total = len(session.items) + for number, item in enumerate(session.items, 1): + item.stash[number_key] = f"[{number}/{items_total}]" + item.stash[test_outcome] = "" + + +# pytest hook. Do not rename +def pytest_runtest_setup(item: pytest.Item): + item.stash[start_time] = int(datetime.now().timestamp()) + logger.info(f"STARTED {item.stash[number_key]}: {item.name}") + + +# pytest hook. Do not rename +def pytest_runtest_makereport(item: pytest.Item, call: pytest.CallInfo): + if call.excinfo is not None: + item.stash[test_outcome] += f"FAILED on {call.when}; " + + if call.when == "teardown": + duration = int(datetime.now().timestamp()) - item.stash[start_time] + if not item.stash[test_outcome]: + outcome = "PASSED " + else: + outcome = item.stash[test_outcome] + logger.info(f"ENDED {item.stash[number_key]}: {item.name}: {outcome}(duration={duration}s)") + + +# pytest hook. Do not rename def pytest_generate_tests(metafunc: pytest.Metafunc): if ( TEST_CYCLES_COUNT <= 1 @@ -78,7 +110,9 @@ def pytest_generate_tests(metafunc: pytest.Metafunc): @pytest.fixture(scope="session") def configure_testlib(): - get_reporter().register_handler(AllureHandler()) + reporter.get_reporter().register_handler(AllureHandler()) + reporter.get_reporter().register_handler(StepsLogger()) + logging.getLogger("paramiko").setLevel(logging.INFO) # Register Services for cluster @@ -186,7 +220,7 @@ def cluster(temp_directory: str, hosting: Hosting, client_shell: Shell) -> Clust yield cluster -@allure.step("[Class]: Provide S3 policy") +@reporter.step("[Class]: Provide S3 policy") @pytest.fixture(scope="class") def s3_policy(request: pytest.FixtureRequest): policy = None @@ -212,7 +246,7 @@ def cluster_state_controller(client_shell: Shell, cluster: Cluster, healthcheck: yield controller -@allure.step("[Class]: Create S3 client") +@reporter.step("[Class]: Create S3 client") @pytest.fixture( scope="class", params=[ @@ -254,7 +288,7 @@ def versioning_status(request: pytest.FixtureRequest) -> VersioningStatus: return VersioningStatus.UNDEFINED -@allure.step("Create/delete bucket") +@reporter.step("Create/delete bucket") @pytest.fixture def bucket(s3_client: S3ClientWrapper, versioning_status: VersioningStatus, request: pytest.FixtureRequest): @@ -269,7 +303,7 @@ def bucket(s3_client: S3ClientWrapper, versioning_status: VersioningStatus, requ s3_helper.delete_bucket_with_objects(s3_client, bucket_name) -@allure.step("Create two buckets") +@reporter.step("Create two buckets") @pytest.fixture def two_buckets(s3_client: S3ClientWrapper, request: pytest.FixtureRequest): bucket_1 = s3_client.create_bucket() @@ -281,13 +315,16 @@ def two_buckets(s3_client: S3ClientWrapper, request: pytest.FixtureRequest): s3_helper.delete_bucket_with_objects(s3_client, bucket_name) -@allure.step("[Autouse/Session] Check binary versions") +@reporter.step("[Autouse/Session] Check binary versions") @pytest.fixture(scope="session", autouse=True) def check_binary_versions(hosting: Hosting, client_shell: Shell, request: pytest.FixtureRequest): local_versions = version_utils.get_local_binaries_versions(client_shell) remote_versions = version_utils.get_remote_binaries_versions(hosting) - all_versions = {**local_versions, **remote_versions} + all_versions = { + **local_versions, + **{binary_name: binary["version"] for binary_name, binary in remote_versions.items()}, + } environment_dir = request.config.getoption("--alluredir") if not environment_dir: @@ -297,23 +334,23 @@ def check_binary_versions(hosting: Hosting, client_shell: Shell, request: pytest env_utils.save_env_properties(file_path, all_versions) -@allure.step("Prepare tmp directory") +@reporter.step("Prepare tmp directory") @pytest.fixture(scope="session") -def temp_directory(): - with allure.step("Prepare tmp directory"): +def temp_directory(configure_testlib): + with reporter.step("Prepare tmp directory"): full_path = os.path.join(os.getcwd(), ASSETS_DIR) shutil.rmtree(full_path, ignore_errors=True) os.mkdir(full_path) yield full_path - with allure.step("Remove tmp directory"): + with reporter.step("Remove tmp directory"): shutil.rmtree(full_path) -@allure.step("[Autouse/Session] Test session start time") +@reporter.step("[Autouse/Session] Test session start time") @pytest.fixture(scope="session", autouse=True) -def session_start_time(): +def session_start_time(configure_testlib): start_time = datetime.utcnow() return start_time @@ -321,23 +358,22 @@ def session_start_time(): @allure.title("[Autouse/Session] After deploy healthcheck") @pytest.fixture(scope="session", autouse=True) def after_deploy_healthcheck(cluster: Cluster): - with allure.step("Wait for cluster readiness after deploy"): + with reporter.step("Wait for cluster readiness after deploy"): parallel(readiness_on_node, cluster.cluster_nodes) SERVICE_ACTIVE_TIME = 20 -@wait_for_success(60 * SERVICE_ACTIVE_TIME * 3, 60) -@allure.step("Check readiness on node {cluster_node}") +@wait_for_success(60 * SERVICE_ACTIVE_TIME * 3, 60, title="Wait for {cluster_node} readiness") def readiness_on_node(cluster_node: ClusterNode): # TODO: Move to healtcheck classes svc_name = cluster_node.service(StorageNode).get_service_systemctl_name() - with allure.step(f"Check service {svc_name} is active"): + with reporter.step(f"Check service {svc_name} is active"): result = cluster_node.host.get_shell().exec(f"systemctl is-active {svc_name}") assert "active" == result.stdout.strip(), f"Service {svc_name} should be in active state" - with allure.step(f"Check service {svc_name} is active more than {SERVICE_ACTIVE_TIME} minutes"): + with reporter.step(f"Check service {svc_name} is active more than {SERVICE_ACTIVE_TIME} minutes"): result = cluster_node.host.get_shell().exec( f"systemctl show {svc_name} --property ActiveEnterTimestamp | cut -d '=' -f 2" ) @@ -362,15 +398,15 @@ def run_health_check(healthcheck: Healthcheck, cluster: Cluster, request: pytest parallel(healthcheck.storage_healthcheck, cluster.cluster_nodes) -@allure.step("Prepare wallet and deposit") +@reporter.step("Prepare wallet and deposit") @pytest.fixture(scope="session") def default_wallet(wallet_factory: WalletFactory) -> str: wallet = wallet_factory.create_wallet(password=DEFAULT_WALLET_PASS) - allure.attach.file(wallet.path, os.path.basename(wallet.path), allure.attachment_type.JSON) + reporter.attach(wallet.path, os.path.basename(wallet.path)) return wallet.path -@allure.step("[Class]: Container placement policy for keys") +@reporter.step("[Class]: Container placement policy for keys") @pytest.fixture(scope="class") def auth_container_placement_policy(cluster: Cluster, request: pytest.FixtureRequest): placeholders = { @@ -389,5 +425,5 @@ def auth_container_placement_policy(cluster: Cluster, request: pytest.FixtureReq @allure.title("Select random node for testing") def node_under_test(cluster: Cluster) -> ClusterNode: selected_node = random.choice(cluster.cluster_nodes) - allure.attach(f"{selected_node}", "Selected node", allure.attachment_type.TEXT) + reporter.attach(f"{selected_node}", "Selected node") return selected_node diff --git a/pytest_tests/testsuites/container/test_container.py b/pytest_tests/testsuites/container/test_container.py index e097b7c..cae08f8 100644 --- a/pytest_tests/testsuites/container/test_container.py +++ b/pytest_tests/testsuites/container/test_container.py @@ -2,6 +2,7 @@ import json import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PRIVATE_ACL_F from frostfs_testlib.steps.cli.container import ( create_container, @@ -58,7 +59,7 @@ class TestContainer(ClusterTestBase): if name: info_to_check.add(f"Name={name}") - with allure.step("Check container has correct information"): + with reporter.step("Check container has correct information"): expected_policy = placement_rule.casefold() actual_policy = placement_policy_from_container(container_info) assert ( @@ -69,7 +70,7 @@ class TestContainer(ClusterTestBase): expected_info = info.casefold() assert expected_info in container_info, f"Expected {expected_info} in container info:\n{container_info}" - with allure.step("Delete container and check it was deleted"): + with reporter.step("Delete container and check it was deleted"): delete_container( wallet, cid, @@ -87,7 +88,7 @@ class TestContainer(ClusterTestBase): placement_rule = "REP 2 IN X CBF 1 SELECT 2 FROM * AS X" cids: list[str] = [] - with allure.step(f"Create {containers_count} containers"): + with reporter.step(f"Create {containers_count} containers"): for _ in range(containers_count): cids.append( create_container( @@ -100,7 +101,7 @@ class TestContainer(ClusterTestBase): ) ) - with allure.step("Wait for containers occur in container list"): + with reporter.step("Wait for containers occur in container list"): for cid in cids: wait_for_container_creation( wallet, @@ -110,7 +111,7 @@ class TestContainer(ClusterTestBase): endpoint=self.cluster.default_rpc_endpoint, ) - with allure.step("Delete containers and check they were deleted"): + with reporter.step("Delete containers and check they were deleted"): for cid in cids: delete_container(wallet, cid, shell=self.shell, endpoint=self.cluster.default_rpc_endpoint) self.tick_epoch() diff --git a/pytest_tests/testsuites/container/test_policy.py b/pytest_tests/testsuites/container/test_policy.py index 6efa4be..765be4c 100644 --- a/pytest_tests/testsuites/container/test_policy.py +++ b/pytest_tests/testsuites/container/test_policy.py @@ -1,5 +1,6 @@ import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.steps.cli.container import create_container, delete_container, get_container from frostfs_testlib.steps.cli.object import delete_object, put_object_to_random_node @@ -31,7 +32,7 @@ class TestPolicy(ClusterTestBase): """ placement_rule = "REP 1 IN SPB REP 1 in MSK CBF 1 SELECT 1 FROM SPBRU AS SPB SELECT 1 FROM MSKRU AS MSK FILTER SubDivCode EQ SPE AS SPBRU FILTER NOT (Country EQ Sweden OR CountryCode EQ FI) AND Location EQ Moskva AS MSKRU" endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): with pytest.raises(Exception, match=NOT_PARSE_POLICY): cid = create_container( wallet=default_wallet, @@ -48,7 +49,7 @@ class TestPolicy(ClusterTestBase): """ placement_rule = "REP 2 IN RU SELECT 2 FROM RUS AS RU FILTER Country EQ Russia AND SubDivCode EQ SPE AS RUS" endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): with pytest.raises(Exception, match=NOT_ENOUGH_TO_SELECT): cid = create_container( wallet=default_wallet, @@ -65,7 +66,7 @@ class TestPolicy(ClusterTestBase): """ placement_rule = "REP 2 IN HALF CBF 1 SELECT 2 FROM GT15 AS HALF FILTER @NOTRU AND Price GT 15 AS GT15 FILTER CountryCode NE RU AS NOTRU" endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): with pytest.raises(Exception, match=NOT_FOUND_FILTER): cid = create_container( wallet=default_wallet, @@ -82,7 +83,7 @@ class TestPolicy(ClusterTestBase): """ placement_rule = "REP 2 IN HALFIC CBF 1 SELECT 2 FROM GT15 AS HALF FILTER Price GT 15 AS GT15" endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): with pytest.raises(Exception, match=NOT_FOUND_SELECTOR): cid = create_container( wallet=default_wallet, @@ -107,27 +108,27 @@ class TestPolicy(ClusterTestBase): expected_copies = 1 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Policy with SELECT results with one node") @@ -144,27 +145,27 @@ class TestPolicy(ClusterTestBase): expected_copies = 1 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.sanity @@ -183,24 +184,24 @@ class TestPolicy(ClusterTestBase): endpoint = self.cluster.default_rpc_endpoint expected_params = {"country": "Russia"} - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) node_address = resulting_copies[0].get_rpc_endpoint().split(":")[0] @@ -208,10 +209,10 @@ class TestPolicy(ClusterTestBase): expected_params["country"] == netmap[node_address]["country"] ), f"The node is selected from the wrong country. Expected {expected_params['country']} and got {netmap[node_address]['country']}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Policy with SELECT and Complex FILTER results with one node") @@ -230,24 +231,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 1 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) node_address = resulting_copies[0].get_rpc_endpoint().split(":")[0] @@ -258,10 +259,10 @@ class TestPolicy(ClusterTestBase): and (expected_params["country"][0] == netmap[node_address]["country"]) ), f"The node is selected from the wrong country or country code. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.sanity @@ -281,24 +282,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -309,10 +310,10 @@ class TestPolicy(ClusterTestBase): or (expected_params["country_code"] == netmap[node_address]["country_code"]) ), f"The node is selected from the wrong country or country code. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.sanity @@ -331,24 +332,24 @@ class TestPolicy(ClusterTestBase): endpoint = self.cluster.default_rpc_endpoint expected_params = {"country": "Russia"} - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): self.check_for_the_uniqueness_of_the_nodes(resulting_copies) netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) @@ -358,10 +359,10 @@ class TestPolicy(ClusterTestBase): expected_params["country"] == netmap[node_address]["country"] ), f"The node is selected from the wrong country. Expected {expected_params['country']} and got {netmap[node_address]['country']}" - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Simple policy results with 25% of available nodes") @@ -378,27 +379,27 @@ class TestPolicy(ClusterTestBase): expected_copies = 1 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Policy with SELECT results with 25% of available nodes") @@ -415,27 +416,27 @@ class TestPolicy(ClusterTestBase): expected_copies = 1 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.skip(reason="price") @@ -454,24 +455,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 1 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -480,10 +481,10 @@ class TestPolicy(ClusterTestBase): int(netmap[node_address]["price"]) <= expected_params["price"] ), f"The node is selected from the wrong price. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.skip(reason="price") @@ -502,24 +503,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 1 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -533,10 +534,10 @@ class TestPolicy(ClusterTestBase): ) ), f"The node is selected from the wrong price. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.skip(reason="price") @@ -555,24 +556,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -587,10 +588,10 @@ class TestPolicy(ClusterTestBase): ), f"The node is selected from the wrong price. Expected {expected_params} and got {netmap[node_address]}" self.check_for_the_uniqueness_of_the_nodes(resulting_copies) - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Simple policy results with 50% of available nodes") @@ -607,27 +608,27 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Policy with SELECT results with 50% of available nodes") @@ -644,27 +645,27 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.skip(reason="price") @@ -683,24 +684,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -709,10 +710,10 @@ class TestPolicy(ClusterTestBase): int(netmap[node_address]["price"]) > expected_params["price"] ), f"The node is selected from the wrong price. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.skip(reason="price") @@ -732,24 +733,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -759,10 +760,10 @@ class TestPolicy(ClusterTestBase): and int(netmap[node_address]["price"]) >= expected_params["price"] ), f"The node is selected from the wrong price or country_code. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.skip(reason="price") @@ -781,24 +782,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 4 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -816,10 +817,10 @@ class TestPolicy(ClusterTestBase): ) ), f"The node is selected from the wrong price or un_locode. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.sanity @@ -837,27 +838,27 @@ class TestPolicy(ClusterTestBase): expected_copies = 1 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Policy with SELECT results with 75% of available nodes") @@ -874,27 +875,27 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.skip(reason="price") @@ -913,24 +914,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -939,10 +940,10 @@ class TestPolicy(ClusterTestBase): int(netmap[node_address]["price"]) < expected_params["price"] ), f"The node is selected from the wrong price. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.skip(reason="price") @@ -962,24 +963,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 3 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -991,10 +992,10 @@ class TestPolicy(ClusterTestBase): netmap[node_address]["continent"] == unexpected_params["continent"] ), f"The node is selected from the wrong price or continent. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.skip(reason="price") @@ -1014,24 +1015,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 4 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -1048,10 +1049,10 @@ class TestPolicy(ClusterTestBase): or (netmap[node_address]["continent"] == unexpected_params["continent"]) ), f"The node is selected from the wrong price or continent. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.sanity @@ -1069,27 +1070,27 @@ class TestPolicy(ClusterTestBase): expected_copies = 4 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Policy with SELECT results with 100% of available nodes") @@ -1106,27 +1107,27 @@ class TestPolicy(ClusterTestBase): expected_copies = 1 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.skip(reason="price") @@ -1145,24 +1146,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 1 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): self.check_for_the_uniqueness_of_the_nodes(resulting_copies) netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) @@ -1171,10 +1172,10 @@ class TestPolicy(ClusterTestBase): expected_params["price"] ), f"The node is selected from the wrong price. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Policy with SELECT and Complex FILTER results with 100% of available nodes") @@ -1192,24 +1193,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -1220,10 +1221,10 @@ class TestPolicy(ClusterTestBase): and (netmap[node_address]["continent"] in expected_params["continent"]) ), f"The node is selected from the wrong country or continent. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Policy with Multi SELECTs and FILTERs results with 100% of available nodes") @@ -1241,24 +1242,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 4 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) for node in resulting_copies: @@ -1267,10 +1268,10 @@ class TestPolicy(ClusterTestBase): netmap[node_address]["price"] in expected_params["price"] ), f"The node is selected from the wrong country or price. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.sanity @@ -1288,31 +1289,31 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" self.check_for_the_uniqueness_of_the_nodes(resulting_copies) - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): self.check_for_the_uniqueness_of_the_nodes(resulting_copies) - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Policy with SELECT results with UNIQUE nodes") @@ -1329,30 +1330,30 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): self.check_for_the_uniqueness_of_the_nodes(resulting_copies) - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.sanity @@ -1372,24 +1373,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 2 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): self.check_for_the_uniqueness_of_the_nodes(resulting_copies) netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) @@ -1401,10 +1402,10 @@ class TestPolicy(ClusterTestBase): or (expected_params["country"] == netmap[node_address]["country"]) ), f"The node is selected from the wrong country or country code. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @pytest.mark.sanity @@ -1424,24 +1425,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 3 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert ( len(resulting_copies) == expected_copies ), f"Expected {expected_copies} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): self.check_for_the_uniqueness_of_the_nodes(resulting_copies) netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) @@ -1453,10 +1454,10 @@ class TestPolicy(ClusterTestBase): or (expected_params["country_code"] == netmap[node_address]["country_code"]) ), f"The node is selected from the wrong country or country code. Expected {expected_params} and got {netmap[node_address]}" - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) @allure.title("Policy: REP 1 IN SPB REP 1 IN MSK REP 3") @@ -1474,24 +1475,24 @@ class TestPolicy(ClusterTestBase): expected_copies = 3 endpoint = self.cluster.default_rpc_endpoint - with allure.step(f"Create container with policy {placement_rule}"): + with reporter.step(f"Create container with policy {placement_rule}"): cid = create_container( wallet=default_wallet, rule=placement_rule, basic_acl=PUBLIC_ACL, shell=self.shell, endpoint=endpoint ) - with allure.step(f"Check container policy"): + with reporter.step(f"Check container policy"): self.validate_object_policy(default_wallet, placement_rule, cid, endpoint) - with allure.step(f"Put object in container"): + with reporter.step(f"Put object in container"): oid = put_object_to_random_node(default_wallet, file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Check object expected copies"): + with reporter.step(f"Check object expected copies"): resulting_copies = get_nodes_with_object(cid, oid, shell=self.shell, nodes=self.cluster.storage_nodes) assert len(resulting_copies) >= expected_copies and len(resulting_copies) <= len( self.cluster.storage_nodes ), f"Expected {expected_copies} or {expected_copies + 1} copies, got {len(resulting_copies)}" - with allure.step(f"Check the object appearance"): + with reporter.step(f"Check the object appearance"): netmap = parse_netmap_output(get_netmap_snapshot(node=resulting_copies[0], shell=self.shell)) netmap = self.get_netmap_param(netmap) list_of_location = [] @@ -1507,10 +1508,10 @@ class TestPolicy(ClusterTestBase): self.check_for_the_uniqueness_of_the_nodes(resulting_copies) - with allure.step(f"Delete the object from the container"): + with reporter.step(f"Delete the object from the container"): delete_object(wallet=default_wallet, cid=cid, oid=oid, shell=self.shell, endpoint=endpoint) - with allure.step(f"Delete the container"): + with reporter.step(f"Delete the container"): delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint) def validate_object_policy(self, wallet: str, placement_rule: str, cid: str, endpoint: str): diff --git a/pytest_tests/testsuites/failovers/test_discrete_time.py b/pytest_tests/testsuites/failovers/test_discrete_time.py index 8313ebe..35aac1d 100644 --- a/pytest_tests/testsuites/failovers/test_discrete_time.py +++ b/pytest_tests/testsuites/failovers/test_discrete_time.py @@ -3,6 +3,7 @@ from time import sleep import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.common import MORPH_BLOCK_TIME from frostfs_testlib.steps.cli.object import neo_go_query_height from frostfs_testlib.storage.controllers import ClusterStateController @@ -13,18 +14,18 @@ from frostfs_testlib.utils import datetime_utils @pytest.mark.time @pytest.mark.failover class TestTime(ClusterTestBase): - @allure.step("Neo-go should continue to release blocks") + @reporter.step("Neo-go should continue to release blocks") def check_nodes_block(self, cluster_state_controller: ClusterStateController): count_blocks = {} - with allure.step("Get current block id"): + with reporter.step("Get current block id"): for cluster_node in self.cluster.cluster_nodes: cluster_state_controller.get_node_date(cluster_node) count_blocks[cluster_node] = neo_go_query_height( shell=cluster_node.host.get_shell(), endpoint=cluster_node.morph_chain.get_http_endpoint() )["Latest block"] - with allure.step("Wait for 3 blocks"): + with reporter.step("Wait for 3 blocks"): sleep(datetime_utils.parse_time(MORPH_BLOCK_TIME) * 3) - with allure.step("Current block id should be higher than before"): + with reporter.step("Current block id should be higher than before"): for cluster_node in self.cluster.cluster_nodes: shell = cluster_node.host.get_shell() now_block = neo_go_query_height(shell=shell, endpoint=cluster_node.morph_chain.get_http_endpoint())[ @@ -44,34 +45,34 @@ class TestTime(ClusterTestBase): timezone_utc = datetime.timezone.utc node_1, node_2, node_3 = cluster_nodes[0:3] - with allure.step("On node 1, move the system time forward by 5 days"): + with reporter.step("On node 1, move the system time forward by 5 days"): cluster_state_controller.change_node_date( node_1, (datetime.datetime.now(timezone_utc) + datetime.timedelta(days=5)) ) self.check_nodes_block(cluster_state_controller) - with allure.step("On node 2, move the system time back 5 days."): + with reporter.step("On node 2, move the system time back 5 days."): cluster_state_controller.change_node_date( node_2, (datetime.datetime.now(timezone_utc) - datetime.timedelta(days=5)) ) self.check_nodes_block(cluster_state_controller) - with allure.step("On node 3, move the system time forward by 10 days"): + with reporter.step("On node 3, move the system time forward by 10 days"): cluster_state_controller.change_node_date( node_3, (datetime.datetime.now(timezone_utc) + datetime.timedelta(days=10)) ) self.check_nodes_block(cluster_state_controller) - with allure.step("Return the time on all nodes to the current one"): + with reporter.step("Return the time on all nodes to the current one"): for cluster_node in self.cluster.cluster_nodes: cluster_state_controller.restore_node_date(cluster_node) self.check_nodes_block(cluster_state_controller) - with allure.step("Reboot all nodes"): + with reporter.step("Reboot all nodes"): cluster_state_controller.shutdown_cluster(mode="soft") cluster_state_controller.start_stopped_hosts() diff --git a/pytest_tests/testsuites/failovers/test_failover_network.py b/pytest_tests/testsuites/failovers/test_failover_network.py index 817a600..2f7358a 100644 --- a/pytest_tests/testsuites/failovers/test_failover_network.py +++ b/pytest_tests/testsuites/failovers/test_failover_network.py @@ -5,6 +5,7 @@ from time import sleep import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.healthcheck.interfaces import Healthcheck from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.steps.cli.container import create_container @@ -46,10 +47,10 @@ class TestFailoverNetwork(ClusterTestBase): @allure.title("Restore network") def restore_network(self, healthcheck: Healthcheck, cluster_state_controller: ClusterStateController): yield - with allure.step(f"Count blocked nodes {len(blocked_nodes)}"): + with reporter.step(f"Count blocked nodes {len(blocked_nodes)}"): not_empty = len(blocked_nodes) != 0 for node in list(blocked_nodes): - with allure.step(f"Restore network for {node}"): + with reporter.step(f"Restore network for {node}"): cluster_state_controller.restore_traffic(mode="ports", node=node) blocked_nodes.remove(node) if not_empty: @@ -79,7 +80,7 @@ class TestFailoverNetwork(ClusterTestBase): file_path = generate_file(simple_object_size.value) file_hash = get_file_hash(file_path) - with allure.step("Create container"): + with reporter.step("Create container"): placement_rule = "REP 1 CBF 1" cid = create_container( wallet=default_wallet, @@ -91,7 +92,7 @@ class TestFailoverNetwork(ClusterTestBase): storage_objects = [] - with allure.step("Put object"): + with reporter.step("Put object"): for attribute in OBJECT_ATTRIBUTES: oid = put_object_to_random_node( wallet=default_wallet, @@ -150,7 +151,7 @@ class TestFailoverNetwork(ClusterTestBase): excluded_nodes = [] for node in nodes_to_block: - with allure.step(f"Block incoming traffic at node {node} on port {PORTS_TO_BLOCK}"): + with reporter.step(f"Block incoming traffic at node {node} on port {PORTS_TO_BLOCK}"): block_node = [ cluster_node for cluster_node in self.cluster.cluster_nodes if cluster_node.storage_node == node ] @@ -163,7 +164,7 @@ class TestFailoverNetwork(ClusterTestBase): ports=PORTS_TO_BLOCK, ) - with allure.step(f"Check object is not stored on node {node}"): + with reporter.step(f"Check object is not stored on node {node}"): new_nodes = wait_object_replication( cid, oid, @@ -173,12 +174,12 @@ class TestFailoverNetwork(ClusterTestBase): ) assert node not in new_nodes - with allure.step("Check object data is not corrupted"): + with reporter.step("Check object data is not corrupted"): got_file_path = get_object(wallet, cid, oid, endpoint=new_nodes[0].get_rpc_endpoint(), shell=self.shell) assert get_file_hash(source_file_path) == get_file_hash(got_file_path) for node in nodes_to_block: - with allure.step(f"Unblock incoming traffic at host {node} on port {PORTS_TO_BLOCK}"): + with reporter.step(f"Unblock incoming traffic at host {node} on port {PORTS_TO_BLOCK}"): cluster_state_controller.restore_traffic(mode="ports", node=node) block_node = [ cluster_node for cluster_node in self.cluster.cluster_nodes if cluster_node.storage_node == node @@ -186,7 +187,7 @@ class TestFailoverNetwork(ClusterTestBase): blocked_nodes.remove(*block_node) sleep(wakeup_node_timeout) - with allure.step("Check object data is not corrupted"): + with reporter.step("Check object data is not corrupted"): new_nodes = wait_object_replication(cid, oid, 2, shell=self.shell, nodes=self.cluster.storage_nodes) got_file_path = get_object(wallet, cid, oid, shell=self.shell, endpoint=new_nodes[0].get_rpc_endpoint()) @@ -204,7 +205,7 @@ class TestFailoverNetwork(ClusterTestBase): ): storage_object = storage_objects[0] - with allure.step("Search nodes with object"): + with reporter.step("Search nodes with object"): nodes_with_object = get_object_nodes( cluster=self.cluster, wallet=default_wallet, @@ -214,20 +215,20 @@ class TestFailoverNetwork(ClusterTestBase): endpoint=self.cluster.default_rpc_endpoint, ) - with allure.step("Get data interface to node"): + with reporter.step("Get data interface to node"): config_interfaces = list(nodes_with_object[0].host.config.interfaces.keys()) - with allure.step(f"Get data in {config_interfaces}"): + with reporter.step(f"Get data in {config_interfaces}"): data_interfaces = [interface for interface in config_interfaces if "data" in interface] - with allure.step("Block data interfaces for node"): + with reporter.step("Block data interfaces for node"): for interface in data_interfaces: cluster_state_controller.down_interface(nodes=nodes_with_object, interface=interface) - with allure.step("Tick epoch and wait 2 block"): + with reporter.step("Tick epoch and wait 2 block"): nodes_without_an_object = list(set(self.cluster.cluster_nodes) - set(nodes_with_object)) self.tick_epochs(1, alive_node=nodes_without_an_object[0].storage_node, wait_block=2) - with allure.step("Get object for target nodes to data interfaces, expect false"): + with reporter.step("Get object for target nodes to data interfaces, expect false"): with pytest.raises(RuntimeError, match="return code: 1"): get_object( wallet=default_wallet, @@ -237,7 +238,7 @@ class TestFailoverNetwork(ClusterTestBase): endpoint=nodes_with_object[0].storage_node.get_rpc_endpoint(), ) - with allure.step(f"Get object others nodes, expect true"): + with reporter.step(f"Get object others nodes, expect true"): input_file = get_object( wallet=default_wallet, cid=storage_object.cid, @@ -247,7 +248,7 @@ class TestFailoverNetwork(ClusterTestBase): ) file_wait_delete.append(input_file) - with allure.step("Restore interface and tick 1 epoch, wait 2 block"): + with reporter.step("Restore interface and tick 1 epoch, wait 2 block"): cluster_state_controller.restore_interfaces() self.tick_epochs(1, alive_node=nodes_without_an_object[0].storage_node, wait_block=2) @@ -264,7 +265,7 @@ class TestFailoverNetwork(ClusterTestBase): ): storage_object = storage_objects[0] - with allure.step("Search nodes with object"): + with reporter.step("Search nodes with object"): nodes_with_object = get_object_nodes( cluster=self.cluster, wallet=default_wallet, @@ -274,20 +275,20 @@ class TestFailoverNetwork(ClusterTestBase): endpoint=self.cluster.default_rpc_endpoint, ) - with allure.step("Get internal interface to node"): + with reporter.step("Get internal interface to node"): config_interfaces = list(nodes_with_object[0].host.config.interfaces.keys()) - with allure.step(f"Get internal in {config_interfaces}"): + with reporter.step(f"Get internal in {config_interfaces}"): internal_interfaces = [interface for interface in config_interfaces if "internal" in interface] - with allure.step("Block internal interfaces for node"): + with reporter.step("Block internal interfaces for node"): for interface in internal_interfaces: cluster_state_controller.down_interface(nodes=nodes_with_object, interface=interface) - with allure.step("Tick epoch and wait 2 block"): + with reporter.step("Tick epoch and wait 2 block"): nodes_without_an_object = list(set(self.cluster.cluster_nodes) - set(nodes_with_object)) self.tick_epochs(1, alive_node=nodes_without_an_object[0].storage_node, wait_block=2) - with allure.step("Get object others node, expect false"): + with reporter.step("Get object others node, expect false"): with pytest.raises(RuntimeError, match="return code: 1"): get_object( wallet=default_wallet, @@ -297,7 +298,7 @@ class TestFailoverNetwork(ClusterTestBase): endpoint=nodes_without_an_object[0].storage_node.get_rpc_endpoint(), ) - with allure.step("Put object, others node, expect false"): + with reporter.step("Put object, others node, expect false"): with pytest.raises(RuntimeError, match="return code: 1"): put_object( wallet=default_wallet, @@ -307,7 +308,7 @@ class TestFailoverNetwork(ClusterTestBase): endpoint=nodes_without_an_object[0].storage_node.get_rpc_endpoint(), ) - with allure.step(f"Get object nodes with object, expect true"): + with reporter.step(f"Get object nodes with object, expect true"): input_file = get_object( wallet=default_wallet, cid=storage_object.cid, @@ -317,7 +318,7 @@ class TestFailoverNetwork(ClusterTestBase): ) file_wait_delete.append(input_file) - with allure.step(f"Put object nodes with object, expect true"): + with reporter.step(f"Put object nodes with object, expect true"): temp_file_path = generate_file(simple_object_size.value) _ = put_object( wallet=default_wallet, @@ -327,7 +328,7 @@ class TestFailoverNetwork(ClusterTestBase): endpoint=nodes_with_object[0].storage_node.get_rpc_endpoint(), ) file_wait_delete.append(temp_file_path) - with allure.step("Restore interface and tick 1 epoch, wait 2 block"): + with reporter.step("Restore interface and tick 1 epoch, wait 2 block"): cluster_state_controller.restore_interfaces() self.tick_epochs(1, alive_node=nodes_without_an_object[0].storage_node, wait_block=2) @@ -350,13 +351,13 @@ class TestFailoverNetwork(ClusterTestBase): other_interface: Interfaces, ): cluster_nodes = self.cluster.cluster_nodes - with allure.step(f"Block {block_interface.value} interfaces"): + with reporter.step(f"Block {block_interface.value} interfaces"): cluster_state_controller.down_interface(cluster_nodes, block_interface.value) - with allure.step("Tick 1 epoch and wait 2 block for sync all nodes"): + with reporter.step("Tick 1 epoch and wait 2 block for sync all nodes"): self.tick_epochs(1, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Create container"): + with reporter.step("Create container"): cid = create_container( wallet=default_wallet, shell=self.shell, @@ -364,7 +365,7 @@ class TestFailoverNetwork(ClusterTestBase): rule="REP 4 CBF 1", ) - with allure.step("Put object"): + with reporter.step("Put object"): file_path = generate_file(simple_object_size.value) file_wait_delete.append(file_path) @@ -376,7 +377,7 @@ class TestFailoverNetwork(ClusterTestBase): endpoint=f"{cluster_nodes[0].get_data_interface(other_interface.value)[0]}:8080", ) - with allure.step("Get object"): + with reporter.step("Get object"): file_get_path = get_object( wallet=default_wallet, cid=cid, @@ -386,7 +387,7 @@ class TestFailoverNetwork(ClusterTestBase): ) file_wait_delete.append(file_get_path) - with allure.step("Restore interfaces all nodes"): + with reporter.step("Restore interfaces all nodes"): cluster_state_controller.restore_interfaces() self.tick_epochs(1, alive_node=cluster_nodes[0].storage_node, wait_block=2) @@ -407,19 +408,19 @@ class TestFailoverNetwork(ClusterTestBase): cluster_nodes = self.cluster.cluster_nodes latest_block = {} - with allure.step("Get block all nodes"): + with reporter.step("Get block all nodes"): for cluster_node in cluster_nodes: latest_block[cluster_node] = neo_go_query_height( shell=cluster_node.host.get_shell(), endpoint=cluster_node.morph_chain.get_http_endpoint() ) - with allure.step(f"Block {interface} interfaces"): + with reporter.step(f"Block {interface} interfaces"): cluster_state_controller.down_interface(cluster_nodes, interface.value) - with allure.step("Tick 1 epoch and wait 2 block for sync all nodes"): + with reporter.step("Tick 1 epoch and wait 2 block for sync all nodes"): self.tick_epochs(1, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Create container"): + with reporter.step("Create container"): cid = create_container( wallet=default_wallet, shell=self.shell, @@ -427,7 +428,7 @@ class TestFailoverNetwork(ClusterTestBase): rule="REP 4 CBF 1", ) - with allure.step(f"Put object, after down {interface}"): + with reporter.step(f"Put object, after down {interface}"): file_path = generate_file(simple_object_size.value) file_wait_delete.append(file_path) @@ -439,7 +440,7 @@ class TestFailoverNetwork(ClusterTestBase): endpoint=self.cluster.default_rpc_endpoint, ) - with allure.step("Get object"): + with reporter.step("Get object"): file_get_path = get_object( wallet=default_wallet, cid=cid, @@ -451,19 +452,19 @@ class TestFailoverNetwork(ClusterTestBase): now_block = {} - with allure.step("Get actual block"): + with reporter.step("Get actual block"): for cluster_node in cluster_nodes: now_block[cluster_node] = neo_go_query_height( shell=cluster_node.host.get_shell(), endpoint=cluster_node.morph_chain.get_http_endpoint() ) - with allure.step(f"Compare block"): + with reporter.step(f"Compare block"): for cluster_node, items in now_block.items(): - with allure.step( + with reporter.step( f"Node - {cluster_node.host_ip}, old block - {latest_block[cluster_node]['Latest block']}, " f"now block - {now_block[cluster_node]['Latest block']}" ): assert latest_block[cluster_node]["Latest block"] < now_block[cluster_node]["Latest block"] - with allure.step("Restore interfaces all nodes"): + with reporter.step("Restore interfaces all nodes"): cluster_state_controller.restore_interfaces() self.tick_epochs(1, alive_node=self.cluster.cluster_nodes[0].storage_node, wait_block=2) diff --git a/pytest_tests/testsuites/failovers/test_failover_server.py b/pytest_tests/testsuites/failovers/test_failover_server.py index c28b6a0..38cf9db 100644 --- a/pytest_tests/testsuites/failovers/test_failover_server.py +++ b/pytest_tests/testsuites/failovers/test_failover_server.py @@ -1,10 +1,10 @@ import logging import os.path import random -import time import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.common import MORPH_BLOCK_TIME from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.steps.cli.container import StorageContainer, StorageContainerInfo, create_container @@ -36,7 +36,7 @@ class TestFailoverServer(ClusterTestBase): def wait_node_in_map(self, *args, **kwargs): check_node_in_map(*args, **kwargs) - @allure.step("Create {count_containers} containers and {count_files} objects") + @reporter.step("Create {count_containers} containers and {count_files} objects") @pytest.fixture def containers( self, @@ -64,7 +64,7 @@ class TestFailoverServer(ClusterTestBase): return containers - @allure.step("Creation container") + @reporter.step("Creation container") @pytest.fixture() def container(self, default_wallet: str) -> StorageContainer: select = len(self.cluster.cluster_nodes) @@ -80,7 +80,7 @@ class TestFailoverServer(ClusterTestBase): storage_cont_info = StorageContainerInfo(id=cont_id, wallet_file=wallet) return StorageContainer(storage_container_info=storage_cont_info, shell=self.shell, cluster=self.cluster) - @allure.step("Create object and delete after test") + @reporter.step("Create object and delete after test") @pytest.fixture(scope="class") def storage_objects( self, @@ -101,16 +101,16 @@ class TestFailoverServer(ClusterTestBase): yield object_list - @allure.step("Select random node to stop and start it after test") + @reporter.step("Select random node to stop and start it after test") @pytest.fixture def node_to_stop( self, node_under_test: ClusterNode, cluster_state_controller: ClusterStateController ) -> ClusterNode: yield node_under_test - with allure.step(f"start {node_under_test.storage_node}"): + with reporter.step(f"start {node_under_test.storage_node}"): cluster_state_controller.start_stopped_hosts() - @allure.step("Upload object with nodes and compare") + @reporter.step("Upload object with nodes and compare") def get_corrupted_objects_list( self, nodes: list[StorageNode], storage_objects: list[StorageObjectInfo] ) -> list[StorageObjectInfo]: @@ -179,34 +179,34 @@ class TestFailoverServer(ClusterTestBase): cluster_state_controller: ClusterStateController, ): - with allure.step(f"Remove {node_to_stop} from the list of nodes"): + with reporter.step(f"Remove {node_to_stop} from the list of nodes"): alive_nodes = list(set(self.cluster.cluster_nodes) - {node_to_stop}) storage_nodes = [cluster.storage_node for cluster in alive_nodes] - with allure.step("Tick epoch and wait for 2 blocks"): + with reporter.step("Tick epoch and wait for 2 blocks"): self.tick_epochs(1, storage_nodes[0], wait_block=2) - with allure.step(f"Stop node"): + with reporter.step(f"Stop node"): cluster_state_controller.stop_node_host(node=node_to_stop, mode="hard") - with allure.step("Verify that there are no corrupted objects"): + with reporter.step("Verify that there are no corrupted objects"): corrupted_objects_list = self.get_corrupted_objects_list(storage_nodes, storage_objects) assert not corrupted_objects_list - with allure.step(f"check {node_to_stop.storage_node} in map"): + with reporter.step(f"check {node_to_stop.storage_node} in map"): self.wait_node_in_map(node_to_stop.storage_node, self.shell, alive_node=storage_nodes[0]) count_tick_epoch = int(alive_nodes[0].ir_node.get_netmap_cleaner_threshold()) + 4 - with allure.step(f"Tick {count_tick_epoch} epochs and wait for 2 blocks"): + with reporter.step(f"Tick {count_tick_epoch} epochs and wait for 2 blocks"): self.tick_epochs(count_tick_epoch, storage_nodes[0], wait_block=2) - with allure.step(f"Check {node_to_stop} in not map"): + with reporter.step(f"Check {node_to_stop} in not map"): self.wait_node_not_in_map(node_to_stop.storage_node, self.shell, alive_node=storage_nodes[0]) - with allure.step(f"Verify that there are no corrupted objects after {count_tick_epoch} epoch"): + with reporter.step(f"Verify that there are no corrupted objects after {count_tick_epoch} epoch"): corrupted_objects_list = self.get_corrupted_objects_list(storage_nodes, storage_objects) assert not corrupted_objects_list @@ -218,25 +218,25 @@ class TestFailoverServer(ClusterTestBase): node_to_stop: ClusterNode, cluster_state_controller: ClusterStateController, ): - with allure.step(f"Remove {node_to_stop} from the list of nodes"): + with reporter.step(f"Remove {node_to_stop} from the list of nodes"): storage_nodes = list(set(self.cluster.storage_nodes) - {node_to_stop.storage_node}) - with allure.step("Tick epoch and wait for 2 blocks"): + with reporter.step("Tick epoch and wait for 2 blocks"): self.tick_epochs(1, storage_nodes[0], wait_block=2) - with allure.step(f"Stop node"): + with reporter.step(f"Stop node"): cluster_state_controller.stop_node_host(node=node_to_stop, mode="hard") - with allure.step("Verify that there are no corrupted objects"): + with reporter.step("Verify that there are no corrupted objects"): corrupted_objects_list = self.get_corrupted_objects_list(storage_nodes, storage_objects) assert not corrupted_objects_list - with allure.step(f"Check {node_to_stop} in map"): + with reporter.step(f"Check {node_to_stop} in map"): self.wait_node_in_map(node_to_stop.storage_node, self.shell, alive_node=storage_nodes[0]) cluster_state_controller.start_node_host(node_to_stop) - with allure.step("Verify that there are no corrupted objects"): + with reporter.step("Verify that there are no corrupted objects"): corrupted_objects_list = self.get_corrupted_objects_list(storage_nodes, storage_objects) assert not corrupted_objects_list @@ -253,12 +253,12 @@ class TestFailoverServer(ClusterTestBase): object_info, object_nodes = object_and_nodes node_not_object = list(set(self.cluster.cluster_nodes) - set(object_nodes))[0] - with allure.step("Stop all nodes with object, except 1"): + with reporter.step("Stop all nodes with object, except 1"): for cluster_node in object_nodes[1:]: cluster_state_controller.stop_node_host(node=cluster_node, mode="hard") - with allure.step("Get object"): - with allure.step(f"Get operation to {node_not_object} where it does not exist, expect success"): + with reporter.step("Get object"): + with reporter.step(f"Get operation to {node_not_object} where it does not exist, expect success"): get_object( wallet=default_wallet, cid=object_info.cid, @@ -266,7 +266,7 @@ class TestFailoverServer(ClusterTestBase): shell=self.shell, endpoint=node_not_object.storage_node.get_rpc_endpoint(), ) - with allure.step(f"Get operation to {object_nodes[0]} with object, expect success"): + with reporter.step(f"Get operation to {object_nodes[0]} with object, expect success"): get_object( wallet=default_wallet, cid=object_info.cid, @@ -275,7 +275,7 @@ class TestFailoverServer(ClusterTestBase): endpoint=object_nodes[0].storage_node.get_rpc_endpoint(), ) - with allure.step(f"Put operation to node with object, expect error"): + with reporter.step(f"Put operation to node with object, expect error"): with pytest.raises(RuntimeError): put_object( wallet=default_wallet, @@ -293,7 +293,7 @@ class TestFailoverServer(ClusterTestBase): simple_file: str, up_stop_nodes: None, ): - with allure.step("Creating a container with a full network map"): + with reporter.step("Creating a container with a full network map"): select = len(self.cluster.cluster_nodes) placement_rule = f"REP {select - 2} IN X CBF 2 SELECT {select} FROM * AS X" cid_1 = create_container( @@ -303,7 +303,7 @@ class TestFailoverServer(ClusterTestBase): rule=placement_rule, basic_acl=PUBLIC_ACL, ) - with allure.step("Put object"): + with reporter.step("Put object"): oid = put_object( wallet=default_wallet, path=simple_file, @@ -311,7 +311,7 @@ class TestFailoverServer(ClusterTestBase): shell=self.shell, endpoint=self.cluster.default_rpc_endpoint, ) - with allure.step("Search nodes with object"): + with reporter.step("Search nodes with object"): object_nodes = get_object_nodes( cluster=self.cluster, wallet=default_wallet, @@ -320,9 +320,9 @@ class TestFailoverServer(ClusterTestBase): shell=self.shell, endpoint=self.cluster.default_rpc_endpoint, ) - with allure.step("Turn off random node with object"): + with reporter.step("Turn off random node with object"): cluster_state_controller.stop_node_host(node=random.choice(object_nodes[1:]), mode="hard") - with allure.step("Checking PUT operation"): + with reporter.step("Checking PUT operation"): oid_2 = put_object( wallet=default_wallet, path=simple_file, @@ -330,7 +330,7 @@ class TestFailoverServer(ClusterTestBase): shell=self.shell, endpoint=self.cluster.default_rpc_endpoint, ) - with allure.step("Checking GET operation"): + with reporter.step("Checking GET operation"): get_file = get_object( wallet=default_wallet, cid=cid_1, @@ -339,7 +339,7 @@ class TestFailoverServer(ClusterTestBase): endpoint=object_nodes[0].storage_node.get_rpc_endpoint(), ) os.remove(get_file) - with allure.step("Checking creating container"): + with reporter.step("Checking creating container"): _ = create_container( default_wallet, shell=self.shell, diff --git a/pytest_tests/testsuites/failovers/test_failover_storage.py b/pytest_tests/testsuites/failovers/test_failover_storage.py index aa78db1..98030e0 100644 --- a/pytest_tests/testsuites/failovers/test_failover_storage.py +++ b/pytest_tests/testsuites/failovers/test_failover_storage.py @@ -5,6 +5,7 @@ from time import sleep import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.common import MORPH_BLOCK_TIME from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.s3 import S3ClientWrapper, VersioningStatus @@ -43,14 +44,14 @@ def file_keeper(): keeper.restore_files() -@allure.step("Return all stopped hosts") +@reporter.step("Return all stopped hosts") @pytest.fixture(scope="function", autouse=True) def after_run_return_all_stopped_hosts(cluster_state_controller: ClusterStateController) -> str: yield cluster_state_controller.start_stopped_hosts() -@allure.step("Return all stopped services after test") +@reporter.step("Return all stopped services after test") @pytest.fixture(scope="function") def after_run_return_all_stopped_services(cluster_state_controller: ClusterStateController): yield @@ -77,7 +78,7 @@ class TestFailoverStorage(ClusterTestBase): source_file_path = generate_file(simple_object_size.value) stopped_hosts_nodes = [] - with allure.step(f"Create container and put object"): + with reporter.step(f"Create container and put object"): cid = create_container( wallet, shell=self.shell, @@ -87,10 +88,10 @@ class TestFailoverStorage(ClusterTestBase): ) oid = put_object_to_random_node(wallet, source_file_path, cid, shell=self.shell, cluster=self.cluster) - with allure.step(f"Wait for replication and get nodes with object"): + with reporter.step(f"Wait for replication and get nodes with object"): nodes_with_object = wait_object_replication(cid, oid, 2, shell=self.shell, nodes=self.cluster.storage_nodes) - with allure.step(f"Stop 2 nodes with object and wait replication one by one"): + with reporter.step(f"Stop 2 nodes with object and wait replication one by one"): for storage_node in random.sample(nodes_with_object, 2): stopped_hosts_nodes.append(storage_node) @@ -105,16 +106,16 @@ class TestFailoverStorage(ClusterTestBase): nodes=list(set(self.cluster.storage_nodes) - {*stopped_hosts_nodes}), ) - with allure.step("Check object data is not corrupted"): + with reporter.step("Check object data is not corrupted"): got_file_path = get_object( wallet, cid, oid, endpoint=replicated_nodes[0].get_rpc_endpoint(), shell=self.shell ) assert get_file_hash(source_file_path) == get_file_hash(got_file_path) - with allure.step("Return all hosts"): + with reporter.step("Return all hosts"): cluster_state_controller.start_stopped_hosts() - with allure.step("Check object data is not corrupted"): + with reporter.step("Check object data is not corrupted"): replicated_nodes = wait_object_replication(cid, oid, 2, shell=self.shell, nodes=self.cluster.storage_nodes) got_file_path = get_object( wallet, cid, oid, shell=self.shell, endpoint=replicated_nodes[0].get_rpc_endpoint() @@ -131,38 +132,38 @@ class TestFailoverStorage(ClusterTestBase): ): default_node = self.cluster.cluster_nodes[0] - with allure.step("Turn S3 GW off on default node"): + with reporter.step("Turn S3 GW off on default node"): cluster_state_controller.stop_service_of_type(default_node, S3Gate) - with allure.step("Turn off storage on default node"): + with reporter.step("Turn off storage on default node"): cluster_state_controller.stop_service_of_type(default_node, StorageNode) - with allure.step("Turn on S3 GW on default node"): + with reporter.step("Turn on S3 GW on default node"): cluster_state_controller.start_service_of_type(default_node, S3Gate) - with allure.step("Turn on storage on default node"): + with reporter.step("Turn on storage on default node"): cluster_state_controller.start_service_of_type(default_node, StorageNode) - with allure.step("Create bucket with REP 1 SELECT 1 policy"): + with reporter.step("Create bucket with REP 1 SELECT 1 policy"): bucket = s3_client.create_bucket( location_constraint="load-1-1", ) file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) - with allure.step("Put object into bucket"): + with reporter.step("Put object into bucket"): put_object = s3_client.put_object(bucket, file_path) s3_helper.check_objects_in_bucket(s3_client, bucket, expected_objects=[file_name]) - with allure.step("Turn off all storage nodes except default"): + with reporter.step("Turn off all storage nodes except default"): for node in self.cluster.cluster_nodes[1:]: - with allure.step(f"Stop storage service on node: {node}"): + with reporter.step(f"Stop storage service on node: {node}"): cluster_state_controller.stop_service_of_type(node, StorageNode) - with allure.step("Check that object is available"): + with reporter.step("Check that object is available"): s3_helper.check_objects_in_bucket(s3_client, bucket, expected_objects=[file_name]) - with allure.step("Start storage nodes"): + with reporter.step("Start storage nodes"): cluster_state_controller.start_all_stopped_services() @@ -173,11 +174,11 @@ class TestEmptyMap(ClusterTestBase): A set of tests for makes map empty and verify that we can read objects after that """ - @allure.step("Teardown after EmptyMap offline test") + @reporter.step("Teardown after EmptyMap offline test") @pytest.fixture() def empty_map_offline_teardown(self): yield - with allure.step("Return all storage nodes to network map"): + with reporter.step("Return all storage nodes to network map"): for node in stopped_nodes: include_node_to_network_map(node, node, shell=self.shell, cluster=self.cluster) stopped_nodes.remove(node) @@ -212,31 +213,31 @@ class TestEmptyMap(ClusterTestBase): objects_list = s3_client.list_objects(bucket) assert not objects_list, f"Expected empty bucket, got {objects_list}" - with allure.step("Put object into bucket"): + with reporter.step("Put object into bucket"): s3_client.put_object(bucket, file_path) - with allure.step("Check that object exists in bucket"): + with reporter.step("Check that object exists in bucket"): s3_helper.check_objects_in_bucket(s3_client, bucket, bucket_objects) storage_nodes = self.cluster.storage_nodes - with allure.step("Exclude all storage nodes from network map"): + with reporter.step("Exclude all storage nodes from network map"): for node in storage_nodes: stopped_nodes.append(node) exclude_node_from_network_map(node, node, shell=self.shell, cluster=self.cluster) - with allure.step("Return all storage nodes to network map"): + with reporter.step("Return all storage nodes to network map"): for node in storage_nodes: include_node_to_network_map(node, node, shell=self.shell, cluster=self.cluster) stopped_nodes.remove(node) - with allure.step("Check that we can read object"): + with reporter.step("Check that we can read object"): s3_helper.check_objects_in_bucket(s3_client, bucket, bucket_objects) - @allure.step("Teardown after EmptyMap stop service test") + @reporter.step("Teardown after EmptyMap stop service test") @pytest.fixture() def empty_map_stop_service_teardown(self, cluster_state_controller: ClusterStateController): yield - with allure.step("Return all storage nodes to network map"): + with reporter.step("Return all storage nodes to network map"): cluster_state_controller.start_all_stopped_services() for node in stopped_nodes: check_node_in_map(node, shell=self.shell, alive_node=node) @@ -275,31 +276,31 @@ class TestEmptyMap(ClusterTestBase): objects_list = s3_client.list_objects(bucket) assert not objects_list, f"Expected empty bucket, got {objects_list}" - with allure.step("Put object into bucket"): + with reporter.step("Put object into bucket"): s3_client.put_object(bucket, file_path) - with allure.step("Check that object exists in bucket"): + with reporter.step("Check that object exists in bucket"): s3_helper.check_objects_in_bucket(s3_client, bucket, bucket_objects) - with allure.step("Stop all storage nodes"): + with reporter.step("Stop all storage nodes"): cluster_state_controller.stop_services_of_type(StorageNode) - with allure.step("Remove all nodes from network map"): + with reporter.step("Remove all nodes from network map"): remove_nodes_from_map_morph( shell=self.shell, cluster=self.cluster, remove_nodes=self.cluster.services(StorageNode) ) - with allure.step("Return all storage nodes to network map"): + with reporter.step("Return all storage nodes to network map"): self.return_nodes_after_stop_with_check_empty_map(cluster_state_controller) - with allure.step("Check that object exists in bucket"): + with reporter.step("Check that object exists in bucket"): s3_helper.check_objects_in_bucket(s3_client, bucket, bucket_objects) - @allure.step("Return all nodes to cluster with check empty map first") + @reporter.step("Return all nodes to cluster with check empty map first") def return_nodes_after_stop_with_check_empty_map(self, cluster_state_controller: ClusterStateController) -> None: first_node = self.cluster.cluster_nodes[0].service(StorageNode) - with allure.step("Start first node and check network map"): + with reporter.step("Start first node and check network map"): cluster_state_controller.start_service_of_type(self.cluster.cluster_nodes[0], StorageNode) wait_for_node_to_be_ready(first_node) @@ -331,33 +332,33 @@ class TestEmptyMap(ClusterTestBase): file_name = s3_helper.object_key_from_file_path(file_path) object_versions = [] - with allure.step("Put object into one bucket"): + with reporter.step("Put object into one bucket"): put_object = s3_client.put_object(bucket, file_path) s3_helper.check_objects_in_bucket(s3_client, bucket, expected_objects=[file_name]) object_versions.append(put_object) - with allure.step("Stop all storage nodes"): + with reporter.step("Stop all storage nodes"): cluster_state_controller.stop_services_of_type(StorageNode) - with allure.step("Delete blobovnicza and fstree from all nodes"): + with reporter.step("Delete blobovnicza and fstree from all nodes"): for node in self.cluster.storage_nodes: node.delete_blobovnicza() node.delete_fstree() - with allure.step("Start all storage nodes"): + with reporter.step("Start all storage nodes"): cluster_state_controller.start_all_stopped_services() # need to get Delete Marker first - with allure.step("Delete the object from the bucket"): + with reporter.step("Delete the object from the bucket"): delete_object = s3_client.delete_object(bucket, file_name) object_versions.append(delete_object["VersionId"]) # and now delete all versions of object (including Delete Markers) - with allure.step("Delete all versions of the object from the bucket"): + with reporter.step("Delete all versions of the object from the bucket"): for version in object_versions: delete_object = s3_client.delete_object(bucket, file_name, version_id=version) - with allure.step("Delete bucket"): + with reporter.step("Delete bucket"): s3_client.delete_bucket(bucket) @allure.title("Object loss from fstree/blobovnicza (versioning=disabled, s3_client={s3_client})") @@ -372,25 +373,25 @@ class TestEmptyMap(ClusterTestBase): file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) - with allure.step("Put object into one bucket"): + with reporter.step("Put object into one bucket"): s3_client.put_object(bucket, file_path) s3_helper.check_objects_in_bucket(s3_client, bucket, expected_objects=[file_name]) - with allure.step("Stop all storage nodes"): + with reporter.step("Stop all storage nodes"): cluster_state_controller.stop_services_of_type(StorageNode) - with allure.step("Delete blobovnicza and fstree from all nodes"): + with reporter.step("Delete blobovnicza and fstree from all nodes"): for node in self.cluster.storage_nodes: node.delete_blobovnicza() node.delete_fstree() - with allure.step("Start all storage nodes"): + with reporter.step("Start all storage nodes"): cluster_state_controller.start_all_stopped_services() - with allure.step("Delete the object from the bucket"): + with reporter.step("Delete the object from the bucket"): s3_client.delete_object(bucket, file_name) - with allure.step("Delete bucket"): + with reporter.step("Delete bucket"): s3_client.delete_bucket(bucket) @pytest.mark.skip(reason="Need to increase cache lifetime") @@ -415,36 +416,36 @@ class TestEmptyMap(ClusterTestBase): file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) - with allure.step("Put object into one bucket"): + with reporter.step("Put object into one bucket"): s3_client.put_object(bucket, file_path) s3_helper.check_objects_in_bucket(s3_client, bucket, expected_objects=[file_name]) - with allure.step("Stop all storage nodes"): + with reporter.step("Stop all storage nodes"): cluster_state_controller.stop_services_of_type(StorageNode) - with allure.step("Delete pilorama.db from all nodes"): + with reporter.step("Delete pilorama.db from all nodes"): for node in self.cluster.storage_nodes: node.delete_pilorama() - with allure.step("Start all storage nodes"): + with reporter.step("Start all storage nodes"): cluster_state_controller.start_all_stopped_services() - with allure.step("Check list objects first time"): + with reporter.step("Check list objects first time"): objects_list = s3_client.list_objects(bucket) assert objects_list, f"Expected not empty bucket" - with allure.step("Check list objects second time"): + with reporter.step("Check list objects second time"): objects_list = s3_client.list_objects(bucket) assert not objects_list, f"Expected empty bucket, got {objects_list}" - with allure.step("Delete bucket"): + with reporter.step("Delete bucket"): s3_client.delete_bucket(bucket) @pytest.mark.failover @pytest.mark.failover_data_loss class TestStorageDataLoss(ClusterTestBase): - @allure.step("Get list of all piloramas on node") + @reporter.step("Get list of all piloramas on node") def get_piloramas_list(self, node: StorageNode) -> list: data_directory_path = node.get_data_directory() @@ -470,10 +471,10 @@ class TestStorageDataLoss(ClusterTestBase): ): allure.dynamic.description(after_run_return_all_stopped_services) - with allure.step("Create bucket"): + with reporter.step("Create bucket"): bucket = s3_client.create_bucket() - with allure.step("Put objects into bucket"): + with reporter.step("Put objects into bucket"): simple_object_path = generate_file(simple_object_size.value) simple_object_key = s3_helper.object_key_from_file_path(simple_object_path) @@ -483,44 +484,44 @@ class TestStorageDataLoss(ClusterTestBase): s3_client.put_object(bucket, simple_object_path) s3_client.put_object(bucket, complex_object_path) - with allure.step("Check objects are in bucket"): + with reporter.step("Check objects are in bucket"): s3_helper.check_objects_in_bucket( s3_client, bucket, expected_objects=[simple_object_key, complex_object_key] ) - with allure.step("Stop storage services on all nodes"): + with reporter.step("Stop storage services on all nodes"): cluster_state_controller.stop_services_of_type(StorageNode) - with allure.step("Delete metabase from all nodes"): + with reporter.step("Delete metabase from all nodes"): for node in cluster_state_controller.cluster.storage_nodes: node.delete_metabase() - with allure.step("Enable resync_metabase option for storage services"): + with reporter.step("Enable resync_metabase option for storage services"): for storage_node in cluster_state_controller.cluster.storage_nodes: - with allure.step(f"Enable resync_metabase option for {storage_node}"): + with reporter.step(f"Enable resync_metabase option for {storage_node}"): config_file_path, config = storage_node.get_shards_config() if not config["storage"]["shard"]["default"]["resync_metabase"]: file_keeper.add(storage_node, config_file_path) config["storage"]["shard"]["default"]["resync_metabase"] = True storage_node.save_config(config, config_file_path) - with allure.step("Start storage services on all nodes"): + with reporter.step("Start storage services on all nodes"): cluster_state_controller.start_all_stopped_services() - with allure.step("Wait for tree rebalance"): + with reporter.step("Wait for tree rebalance"): # TODO: Use product metric when we have proper ones for this check sleep(30) - with allure.step("Delete objects from bucket"): - with allure.step("Delete simple object from bucket"): + with reporter.step("Delete objects from bucket"): + with reporter.step("Delete simple object from bucket"): with expect_not_raises(): s3_client.delete_object(bucket, simple_object_key) - with allure.step("Delete complex object from bucket"): + with reporter.step("Delete complex object from bucket"): with expect_not_raises(): s3_client.delete_object(bucket, complex_object_key) - with allure.step("Delete bucket"): + with reporter.step("Delete bucket"): with expect_not_raises(): s3_client.delete_bucket(bucket) @@ -539,7 +540,7 @@ class TestStorageDataLoss(ClusterTestBase): exception_messages = [] allure.dynamic.description(after_run_return_all_stopped_services) - with allure.step(f"Create container on node {node_under_test}"): + with reporter.step(f"Create container on node {node_under_test}"): locode = node_under_test.storage_node.get_un_locode() placement_rule = f"""REP 1 IN X CBF 1 @@ -557,7 +558,7 @@ class TestStorageDataLoss(ClusterTestBase): cluster_state_controller.cluster, ) - with allure.step(f"Put couple objects to container on node {node_under_test}"): + with reporter.step(f"Put couple objects to container on node {node_under_test}"): storage_objects: list[StorageObjectInfo] = [] for _ in range(5): storage_object = container.generate_object( @@ -566,19 +567,19 @@ class TestStorageDataLoss(ClusterTestBase): ) storage_objects.append(storage_object) - with allure.step("Take shards snapshot"): + with reporter.step("Take shards snapshot"): shards_watcher.take_shards_snapshot() - with allure.step(f"Stop storage service on node {node_under_test}"): + with reporter.step(f"Stop storage service on node {node_under_test}"): cluster_state_controller.stop_service_of_type(node_under_test, StorageNode) - with allure.step(f"Delete write cache from node {node_under_test}"): + with reporter.step(f"Delete write cache from node {node_under_test}"): node_under_test.storage_node.delete_write_cache() - with allure.step(f"Start storage service on node {node_under_test}"): + with reporter.step(f"Start storage service on node {node_under_test}"): cluster_state_controller.start_all_stopped_services() - with allure.step("Objects should be available"): + with reporter.step("Objects should be available"): for storage_object in storage_objects: get_object( storage_object.wallet_file_path, @@ -588,26 +589,26 @@ class TestStorageDataLoss(ClusterTestBase): node_under_test.storage_node.get_rpc_endpoint(), ) - with allure.step("No shards should have new errors"): + with reporter.step("No shards should have new errors"): shards_watcher.take_shards_snapshot() shards_with_errors = shards_watcher.get_shards_with_new_errors() if shards_with_errors: exception_messages.append(f"Shards have new errors: {shards_with_errors}") - with allure.step("No shards should have degraded status"): + with reporter.step("No shards should have degraded status"): snapshot = shards_watcher.get_shards_snapshot() for shard in snapshot: status = snapshot[shard]["mode"] if status != "read-write": exception_messages.append(f"Shard {shard} changed status to {status}") - with allure.step("No related errors should be in log"): + with reporter.step("No related errors should be in log"): if node_under_test.host.is_message_in_logs( message_regex=r"\Wno such file or directory\W", since=test_start_time ): exception_messages.append(f"Node {node_under_test} have shard errors in logs") - with allure.step("Pass test if no errors found"): + with reporter.step("Pass test if no errors found"): assert not exception_messages, "\n".join(exception_messages) @allure.title( @@ -623,7 +624,7 @@ class TestStorageDataLoss(ClusterTestBase): ): # TODO: need to check that s3 gate is connected to localhost (such metric will be supported in 1.3) - with allure.step("Stop one node and wait for rebalance connection of s3 gate to storage service"): + with reporter.step("Stop one node and wait for rebalance connection of s3 gate to storage service"): current_node = self.cluster.cluster_nodes[0] cluster_state_controller.stop_service_of_type(current_node, StorageNode) # waiting for rebalance connection of s3 gate to storage service @@ -631,7 +632,7 @@ class TestStorageDataLoss(ClusterTestBase): file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) - with allure.step("Put object into one bucket"): + with reporter.step("Put object into one bucket"): put_object = s3_client.put_object(bucket, file_path) s3_helper.check_objects_in_bucket(s3_client, bucket, expected_objects=[file_name]) @@ -648,7 +649,7 @@ class TestStorageDataLoss(ClusterTestBase): ) s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Check bucket versioning"): + with reporter.step("Check bucket versioning"): bucket_versioning = s3_client.get_bucket_versioning_status(bucket) assert bucket_versioning == "Enabled", "Bucket should have enabled versioning" @@ -656,59 +657,59 @@ class TestStorageDataLoss(ClusterTestBase): file_name = s3_helper.object_key_from_file_path(file_path) object_versions = [] - with allure.step("Put object into one bucket"): + with reporter.step("Put object into one bucket"): put_object = s3_client.put_object(bucket, file_path) s3_helper.check_objects_in_bucket(s3_client, bucket, expected_objects=[file_name]) object_versions.append(put_object) node_to_check = self.cluster.storage_nodes[0] piloramas_list_before_removing = {} - with allure.step("Get list of all pilorama.db"): + with reporter.step("Get list of all pilorama.db"): piloramas_list_before_removing = self.get_piloramas_list(node_to_check) - with allure.step("Stop all storage nodes"): + with reporter.step("Stop all storage nodes"): cluster_state_controller.stop_services_of_type(StorageNode) - with allure.step("Delete pilorama.db from one node"): + with reporter.step("Delete pilorama.db from one node"): node_to_check.delete_pilorama() - with allure.step("Start all storage nodes"): + with reporter.step("Start all storage nodes"): cluster_state_controller.start_all_stopped_services() - with allure.step("Tick epoch to trigger sync and then wait for 1 minute"): + with reporter.step("Tick epoch to trigger sync and then wait for 1 minute"): self.tick_epochs(1) sleep(120) piloramas_list_afrer_removing = {} - with allure.step("Get list of all pilorama.db after sync"): + with reporter.step("Get list of all pilorama.db after sync"): piloramas_list_afrer_removing = self.get_piloramas_list(node_to_check) assert piloramas_list_afrer_removing == piloramas_list_before_removing, "List of pilorama.db is different" - with allure.step("Check bucket versioning"): + with reporter.step("Check bucket versioning"): bucket_versioning = s3_client.get_bucket_versioning_status(bucket) assert bucket_versioning == "Enabled", "Bucket should have enabled versioning" - with allure.step("Check list objects"): + with reporter.step("Check list objects"): objects_list = s3_client.list_objects(bucket) assert objects_list, f"Expected not empty bucket" - with allure.step("Delete the object from the bucket"): + with reporter.step("Delete the object from the bucket"): delete_object = s3_client.delete_object(bucket, file_name) assert "DeleteMarker" in delete_object.keys(), "Delete markers not found" - with allure.step("Check list objects"): + with reporter.step("Check list objects"): objects_list = s3_client.list_objects_versions(bucket) assert objects_list, f"Expected not empty bucket" object_versions.append(delete_object["VersionId"]) # and now delete all versions of object (including Delete Markers) - with allure.step("Delete all versions of the object from the bucket"): + with reporter.step("Delete all versions of the object from the bucket"): for version in object_versions: delete_object = s3_client.delete_object(bucket, file_name, version_id=version) - with allure.step("Check list objects"): + with reporter.step("Check list objects"): objects_list = s3_client.list_objects_versions(bucket) assert not objects_list, f"Expected empty bucket" - with allure.step("Delete bucket"): + with reporter.step("Delete bucket"): s3_client.delete_bucket(bucket) diff --git a/pytest_tests/testsuites/management/test_node_management.py b/pytest_tests/testsuites/management/test_node_management.py index b199c4a..4a82e20 100644 --- a/pytest_tests/testsuites/management/test_node_management.py +++ b/pytest_tests/testsuites/management/test_node_management.py @@ -6,6 +6,7 @@ from typing import Optional, Tuple import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.cli import FrostfsCli from frostfs_testlib.cli.netmap_parser import NetmapParser from frostfs_testlib.resources.cli import FROSTFS_CLI_EXEC @@ -86,7 +87,7 @@ class TestNodeManagement(ClusterTestBase): node_shard_list(node) - @allure.step("Tick epoch with retries") + @reporter.step("Tick epoch with retries") def tick_epoch_with_retries(self, attempts: int = 3, timeout: int = 3, wait_block: int = None): for attempt in range(attempts): try: @@ -108,19 +109,19 @@ class TestNodeManagement(ClusterTestBase): yield self.return_nodes() - @allure.step("Return node to cluster") + @reporter.step("Return node to cluster") def return_nodes(self, alive_node: Optional[StorageNode] = None) -> None: for node in list(check_nodes): - with allure.step(f"Start node {node}"): + with reporter.step(f"Start node {node}"): node.start_service() - with allure.step(f"Waiting status ready for node {node}"): + with reporter.step(f"Waiting status ready for node {node}"): wait_for_node_to_be_ready(node) # We need to wait for node to establish notifications from morph-chain # Otherwise it will hang up when we will try to set status sleep(datetime_utils.parse_time(MORPH_BLOCK_TIME)) - with allure.step(f"Move node {node} to online state"): + with reporter.step(f"Move node {node} to online state"): storage_node_set_status(node, status="online", retries=2) check_nodes.remove(node) @@ -175,7 +176,7 @@ class TestNodeManagement(ClusterTestBase): self.return_nodes(alive_node) - with allure.step("Check data could be replicated to new node"): + with reporter.step("Check data could be replicated to new node"): random_node = random.choice(list(set(storage_nodes) - {random_node, alive_node})) # Add node to recovery list before messing with it check_nodes.append(random_node) @@ -191,7 +192,7 @@ class TestNodeManagement(ClusterTestBase): include_node_to_network_map(random_node, alive_node, shell=self.shell, cluster=self.cluster) wait_object_replication(cid, oid, 3, shell=self.shell, nodes=storage_nodes) - with allure.step("Check container could be created with new node"): + with reporter.step("Check container could be created with new node"): cid = create_container( wallet, rule=placement_rule_4, @@ -233,7 +234,7 @@ class TestNodeManagement(ClusterTestBase): random_node = random.choice(nodes_with_object) for oid in (oid_simple, oid_complex): - with allure.step(f"Drop object {oid}"): + with reporter.step(f"Drop object {oid}"): get_object_from_random_node(wallet, cid, oid, shell=self.shell, cluster=self.cluster) head_object(wallet, cid, oid, shell=self.shell, endpoint=endpoint) drop_object(random_node, cid, oid) @@ -302,10 +303,10 @@ class TestNodeManagement(ClusterTestBase): shell=self.shell, endpoint=random_node.get_rpc_endpoint(), ) - with allure.step("Stop the random node"): + with reporter.step("Stop the random node"): check_nodes.append(random_node) random_node.stop_service() - with allure.step("Try to put an object and expect success"): + with reporter.step("Try to put an object and expect success"): put_object( wallet, source_file_path, @@ -315,7 +316,7 @@ class TestNodeManagement(ClusterTestBase): ) self.return_nodes(alive_node) - @allure.step("Wait for object to be dropped") + @reporter.step("Wait for object to be dropped") def wait_for_obj_dropped(self, wallet: str, cid: str, oid: str, endpoint: str, checker) -> None: for _ in range(3): try: @@ -370,7 +371,7 @@ class TestMaintenanceMode(ClusterTestBase): put_object: {"path": file_path}, } for index, operation, kw in enumerate(operations.items()): - with allure.step(f"Run {operation.__name__} object, waiting response - {matchs[index]}"): + with reporter.step(f"Run {operation.__name__} object, waiting response - {matchs[index]}"): default_kw.update(kw) if operation == search_object and "Found" in matchs[index]: operation(**default_kw) @@ -387,7 +388,7 @@ class TestMaintenanceMode(ClusterTestBase): cluster_state_controller: ClusterStateController, restore_online_mode_node: None, ): - with allure.step("Create container and create\put object"): + with reporter.step("Create container and create\put object"): cid = create_container( wallet=default_wallet, shell=self.shell, @@ -410,7 +411,7 @@ class TestMaintenanceMode(ClusterTestBase): shell=self.shell, endpoint=self.change_node.storage_node.get_rpc_endpoint(), ) - with allure.step("Enable MaintenanceModeAllowed:"): + with reporter.step("Enable MaintenanceModeAllowed:"): cluster_state_controller.set_mode_node( cluster_node=self.change_node, wallet=default_wallet, status="maintenance" ) @@ -425,7 +426,7 @@ class TestMaintenanceMode(ClusterTestBase): "node is under maintenance", ], } - with allure.step("Run basic operations"): + with reporter.step("Run basic operations"): for cluster_node, matchs in node_and_match.items(): self.basic_operations( wallet=default_wallet, @@ -450,20 +451,20 @@ class TestMaintenanceMode(ClusterTestBase): self.change_node = node_under_test cluster_nodes = list(set(self.cluster.cluster_nodes) - {node_under_test}) - with allure.step("Tick epoch"): + with reporter.step("Tick epoch"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Set node mode to offline"): + with reporter.step("Set node mode to offline"): cluster_state_controller.set_mode_node( cluster_node=node_under_test, wallet=default_wallet, status=ModeNode.OFFLINE.value, ) - with allure.step("Tick epoch to update the network map"): + with reporter.step("Tick epoch to update the network map"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with ((allure.step("Check node mode = offline, after update the network map"))): + with reporter.step("Check node mode = offline, after update the network map"): netmap = frostfs_cli.netmap.snapshot( rpc_endpoint=cluster_nodes[0].storage_node.get_rpc_endpoint(), wallet=default_wallet ).stdout @@ -472,14 +473,14 @@ class TestMaintenanceMode(ClusterTestBase): netmap_node.node for netmap_node in netmap ], f"Node {node_under_test.host_ip} not in state offline" - with allure.step("Restart storage service"): + with reporter.step("Restart storage service"): cluster_state_controller.stop_storage_service(node_under_test) cluster_state_controller.start_storage_service(node_under_test) - with allure.step("Tick epoch after restart storage service and set mode to offline"): + with reporter.step("Tick epoch after restart storage service and set mode to offline"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with (allure.step("Check node mode = online, after restart storage service")): + with (reporter.step("Check node mode = online, after restart storage service")): netmap = frostfs_cli.netmap.snapshot( rpc_endpoint=cluster_nodes[0].storage_node.get_rpc_endpoint(), wallet=default_wallet ).stdout @@ -488,21 +489,21 @@ class TestMaintenanceMode(ClusterTestBase): f"Node actual state - {node_state}, " f"expect - {ModeNode.ONLINE.value}" ) - with allure.step("Tick epoch"): + with reporter.step("Tick epoch"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Set node mode to maintenance"): + with reporter.step("Set node mode to maintenance"): cluster_state_controller.set_mode_node( cluster_node=node_under_test, wallet=default_wallet, status=ModeNode.MAINTENANCE.value ) - with allure.step("Restart storage service"): + with reporter.step("Restart storage service"): cluster_state_controller.stop_storage_service(node_under_test) cluster_state_controller.start_storage_service(node_under_test) - with allure.step("Tick epoch after restart storage service"): + with reporter.step("Tick epoch after restart storage service"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Check node mode = maintenance, after restart storage service and tick epoch"): + with reporter.step("Check node mode = maintenance, after restart storage service and tick epoch"): netmap = frostfs_cli.netmap.snapshot( rpc_endpoint=cluster_nodes[0].storage_node.get_rpc_endpoint(), wallet=default_wallet ).stdout @@ -511,10 +512,10 @@ class TestMaintenanceMode(ClusterTestBase): f"Node actual state - {node_state}, " f"expect - {ModeNode.MAINTENANCE.value}" ) - with allure.step("Tick epoch"): + with reporter.step("Tick epoch"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Set node mode to offline"): + with reporter.step("Set node mode to offline"): netmap = frostfs_cli.netmap.snapshot( rpc_endpoint=cluster_nodes[0].storage_node.get_rpc_endpoint(), wallet=default_wallet ).stdout @@ -523,16 +524,16 @@ class TestMaintenanceMode(ClusterTestBase): f"Node actual state - {node_state}, " f"expect - {ModeNode.OFFLINE.value}" ) - with allure.step("Stop storage service"): + with reporter.step("Stop storage service"): cluster_state_controller.stop_storage_service(node_under_test) - with allure.step("Tick epoch"): + with reporter.step("Tick epoch"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Start storage service"): + with reporter.step("Start storage service"): cluster_state_controller.start_storage_service(node_under_test) - with allure.step("Check node mode = offline, after tick epoch and start storage service"): + with reporter.step("Check node mode = offline, after tick epoch and start storage service"): netmap = frostfs_cli.netmap.snapshot( rpc_endpoint=cluster_nodes[0].storage_node.get_rpc_endpoint(), wallet=default_wallet ).stdout @@ -541,10 +542,10 @@ class TestMaintenanceMode(ClusterTestBase): f"Node actual state - {node_state}, " f"expect - {ModeNode.OFFLINE.value}" ) - with allure.step("Tick epoch"): + with reporter.step("Tick epoch"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Check node mode = online, after start storage service and tick epoch"): + with reporter.step("Check node mode = online, after start storage service and tick epoch"): netmap = frostfs_cli.netmap.snapshot( rpc_endpoint=cluster_nodes[0].storage_node.get_rpc_endpoint(), wallet=default_wallet ).stdout @@ -553,24 +554,24 @@ class TestMaintenanceMode(ClusterTestBase): f"Node actual state - {node_state}, " f"expect - {ModeNode.ONLINE.value}" ) - with allure.step("Tick epoch"): + with reporter.step("Tick epoch"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Set node mode to maintenance"): + with reporter.step("Set node mode to maintenance"): cluster_state_controller.set_mode_node( cluster_node=node_under_test, wallet=default_wallet, status=ModeNode.MAINTENANCE.value ) - with allure.step("Stop storage service"): + with reporter.step("Stop storage service"): cluster_state_controller.stop_storage_service(node_under_test) - with allure.step("Tick epoch"): + with reporter.step("Tick epoch"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Start storage service"): + with reporter.step("Start storage service"): cluster_state_controller.start_storage_service(node_under_test) - with allure.step("Check node mode = maintenance"): + with reporter.step("Check node mode = maintenance"): netmap = frostfs_cli.netmap.snapshot( rpc_endpoint=cluster_nodes[0].storage_node.get_rpc_endpoint(), wallet=default_wallet ).stdout @@ -580,10 +581,10 @@ class TestMaintenanceMode(ClusterTestBase): node_state == ModeNode.MAINTENANCE.value.upper() ), f"Node actual state - {node_state}, expect - {ModeNode.MAINTENANCE.value}" - with allure.step("Tick epoch"): + with reporter.step("Tick epoch"): self.tick_epochs(epochs_to_tick=2, alive_node=cluster_nodes[0].storage_node, wait_block=2) - with allure.step("Check node mode = maintenance"): + with reporter.step("Check node mode = maintenance"): netmap = frostfs_cli.netmap.snapshot( rpc_endpoint=cluster_nodes[0].storage_node.get_rpc_endpoint(), wallet=default_wallet ).stdout @@ -605,24 +606,24 @@ class TestMaintenanceMode(ClusterTestBase): self.change_node = node_under_test control_endpoint = node_under_test.service(StorageNode).get_control_endpoint() - with allure.step("Set MaintenanceModeAllowed = false"): + with reporter.step("Set MaintenanceModeAllowed = false"): cluster_state_controller.set_maintenance_mode_allowed("false", node_under_test) - with allure.step("Set status node - maintenance"): + with reporter.step("Set status node - maintenance"): with pytest.raises(RuntimeError, match="maintenance mode is not allowed by the network"): frostfs_cli_remote.control.set_status(endpoint=control_endpoint, status="maintenance") - with allure.step("Set MaintenanceModeAllowed = true"): + with reporter.step("Set MaintenanceModeAllowed = true"): cluster_state_controller.set_maintenance_mode_allowed("true", node_under_test) - with allure.step("Set status node - maintenance"): + with reporter.step("Set status node - maintenance"): output = frostfs_cli_remote.control.set_status(endpoint=control_endpoint, status="maintenance") assert "update request successfully sent" in output.stdout, f"Response = {output}" - with allure.step("Tick epoch"): + with reporter.step("Tick epoch"): self.tick_epoch(wait_block=2) - with allure.step("Check state node = maintenance "): + with reporter.step("Check state node = maintenance "): netmap_node = NetmapParser.snapshot_one_node( frostfs_cli.netmap.snapshot( rpc_endpoint=node_under_test.storage_node.get_rpc_endpoint(), wallet=default_wallet @@ -633,13 +634,13 @@ class TestMaintenanceMode(ClusterTestBase): netmap_node.node_status == ModeNode.MAINTENANCE.value.upper() ), f"Node actual state - {netmap_node.node_status}, expect - {ModeNode.MAINTENANCE.value}" - with allure.step("Set status node - online "): + with reporter.step("Set status node - online "): frostfs_cli_remote.control.set_status(endpoint=control_endpoint, status="online") - with allure.step("Tick epoch"): + with reporter.step("Tick epoch"): self.tick_epoch() - with allure.step("Check state node: online"): + with reporter.step("Check state node: online"): netmap_node = NetmapParser.snapshot_one_node( frostfs_cli.netmap.snapshot( rpc_endpoint=node_under_test.storage_node.get_rpc_endpoint(), wallet=default_wallet diff --git a/pytest_tests/testsuites/object/test_object_api.py b/pytest_tests/testsuites/object/test_object_api.py index c62d9d2..700cdb4 100755 --- a/pytest_tests/testsuites/object/test_object_api.py +++ b/pytest_tests/testsuites/object/test_object_api.py @@ -4,6 +4,7 @@ import sys import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.error_patterns import ( INVALID_LENGTH_SPECIFIER, INVALID_OFFSET_SPECIFIER, @@ -102,7 +103,7 @@ def storage_objects( storage_objects = [] - with allure.step("Put objects"): + with reporter.step("Put objects"): # We need to upload objects multiple times with different attributes for attributes in OBJECT_ATTRIBUTES: storage_object_id = put_object_to_random_node( @@ -142,7 +143,7 @@ class TestObjectApi(ClusterTestBase): Validate object storage policy """ - with allure.step("Validate storage policy for objects"): + with reporter.step("Validate storage policy for objects"): for storage_object in storage_objects: if storage_object.size == simple_object_size.value: copies = get_simple_object_copies( @@ -168,7 +169,7 @@ class TestObjectApi(ClusterTestBase): Validate get object native API """ - with allure.step("Get objects and compare hashes"): + with reporter.step("Get objects and compare hashes"): for storage_object in storage_objects: file_path = get_object_from_random_node( storage_object.wallet_file_path, @@ -189,7 +190,7 @@ class TestObjectApi(ClusterTestBase): storage_object_1 = storage_objects[0] storage_object_2 = storage_objects[1] - with allure.step("Head object and validate"): + with reporter.step("Head object and validate"): head_object( storage_object_1.wallet_file_path, storage_object_1.cid, @@ -222,7 +223,7 @@ class TestObjectApi(ClusterTestBase): (COMMON_ATTRIBUTE, oids[1:3]), ] - with allure.step("Search objects"): + with reporter.step("Search objects"): # Search with no attributes result = search_object( wallet, @@ -256,7 +257,7 @@ class TestObjectApi(ClusterTestBase): wallet = default_wallet cid = create_container(wallet, self.shell, self.cluster.default_rpc_endpoint) - with allure.step("Upload file"): + with reporter.step("Upload file"): file_path = generate_file(object_size.value) file_hash = get_file_hash(file_path) @@ -269,20 +270,20 @@ class TestObjectApi(ClusterTestBase): file_hash=file_hash, ) - with allure.step("Search object"): + with reporter.step("Search object"): # Root Search object should return root object oid result = search_object(wallet, cid, shell=self.shell, endpoint=self.cluster.default_rpc_endpoint, root=True) assert result == [storage_object.oid] - with allure.step("Delete file"): + with reporter.step("Delete file"): delete_objects([storage_object], self.shell, self.cluster) - with allure.step("Search deleted object with --root"): + with reporter.step("Search deleted object with --root"): # Root Search object should return nothing result = search_object(wallet, cid, shell=self.shell, endpoint=self.cluster.default_rpc_endpoint, root=True) assert len(result) == 0 - with allure.step("Search deleted object with --phy should return only tombstones"): + with reporter.step("Search deleted object with --phy should return only tombstones"): # Physical Search object should return only tombstones result = search_object(wallet, cid, shell=self.shell, endpoint=self.cluster.default_rpc_endpoint, phy=True) assert storage_object.tombstone in result, "Search result should contain tombstone of removed object" @@ -317,7 +318,7 @@ class TestObjectApi(ClusterTestBase): for range_start, range_len in file_ranges_to_test: range_cut = f"{range_start}:{range_len}" - with allure.step(f"Get range hash ({range_cut})"): + with reporter.step(f"Get range hash ({range_cut})"): for oid in oids: range_hash = get_range_hash( wallet, @@ -348,7 +349,7 @@ class TestObjectApi(ClusterTestBase): for range_start, range_len in file_ranges_to_test: range_cut = f"{range_start}:{range_len}" - with allure.step(f"Get range ({range_cut})"): + with reporter.step(f"Get range ({range_cut})"): for oid in oids: _, range_content = get_range( wallet, @@ -399,7 +400,7 @@ class TestObjectApi(ClusterTestBase): for range_start, range_len, expected_error in file_ranges_to_test: range_cut = f"{range_start}:{range_len}" expected_error = expected_error.format(range=range_cut) if "{range}" in expected_error else expected_error - with allure.step(f"Get range ({range_cut})"): + with reporter.step(f"Get range ({range_cut})"): for oid in oids: with pytest.raises(Exception, match=expected_error): get_range( @@ -446,7 +447,7 @@ class TestObjectApi(ClusterTestBase): for range_start, range_len, expected_error in file_ranges_to_test: range_cut = f"{range_start}:{range_len}" expected_error = expected_error.format(range=range_cut) if "{range}" in expected_error else expected_error - with allure.step(f"Get range hash ({range_cut})"): + with reporter.step(f"Get range hash ({range_cut})"): for oid in oids: with pytest.raises(Exception, match=expected_error): get_range_hash( diff --git a/pytest_tests/testsuites/object/test_object_api_bearer.py b/pytest_tests/testsuites/object/test_object_api_bearer.py index c0afe6e..f2f03cd 100644 --- a/pytest_tests/testsuites/object/test_object_api_bearer.py +++ b/pytest_tests/testsuites/object/test_object_api_bearer.py @@ -1,5 +1,6 @@ import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import EACL_PUBLIC_READ_WRITE from frostfs_testlib.shell import Shell from frostfs_testlib.steps.acl import form_bearertoken_file @@ -94,7 +95,7 @@ class TestObjectApiWithBearerToken(ClusterTestBase): bearer_token_file_all_allow: str, ): s3_gate_wallet = self.cluster.s3_gates[0] - with allure.step("Try to delete each object from first storage node"): + with reporter.step("Try to delete each object from first storage node"): for storage_object in storage_objects: with expect_not_raises(): delete_object( @@ -120,13 +121,13 @@ class TestObjectApiWithBearerToken(ClusterTestBase): bearer_token_file_all_allow: str, ): s3_gate_wallet = self.cluster.s3_gates[0] - with allure.step("Put one object to container"): + with reporter.step("Put one object to container"): epoch = self.get_epoch() storage_object = user_container.generate_object( object_size.value, epoch + 3, bearer_token=bearer_token_file_all_allow ) - with allure.step("Try to fetch object from each storage node"): + with reporter.step("Try to fetch object from each storage node"): for node in self.cluster.storage_nodes: with expect_not_raises(): get_object( diff --git a/pytest_tests/testsuites/object/test_object_lifetime.py b/pytest_tests/testsuites/object/test_object_lifetime.py index bf2c964..934e463 100644 --- a/pytest_tests/testsuites/object/test_object_lifetime.py +++ b/pytest_tests/testsuites/object/test_object_lifetime.py @@ -2,13 +2,10 @@ import logging import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.error_patterns import OBJECT_NOT_FOUND from frostfs_testlib.steps.cli.container import create_container -from frostfs_testlib.steps.cli.object import ( - get_object_from_random_node, - head_object, - put_object_to_random_node, -) +from frostfs_testlib.steps.cli.object import get_object_from_random_node, head_object, put_object_to_random_node from frostfs_testlib.steps.epoch import get_epoch from frostfs_testlib.storage.dataclasses.object_size import ObjectSize from frostfs_testlib.testing.cluster_test_base import ClusterTestBase @@ -36,31 +33,29 @@ class TestObjectApiLifetime(ClusterTestBase): file_hash = get_file_hash(file_path) epoch = get_epoch(self.shell, self.cluster) - oid = put_object_to_random_node( - wallet, file_path, cid, self.shell, self.cluster, expire_at=epoch + 1 - ) + oid = put_object_to_random_node(wallet, file_path, cid, self.shell, self.cluster, expire_at=epoch + 1) got_file = get_object_from_random_node(wallet, cid, oid, self.shell, self.cluster) assert get_file_hash(got_file) == file_hash - with allure.step("Tick two epochs"): + with reporter.step("Tick two epochs"): for _ in range(2): self.tick_epoch() # Wait for GC, because object with expiration is counted as alive until GC removes it wait_for_gc_pass_on_storage_nodes() - with allure.step("Check object deleted because it expires on epoch"): + with reporter.step("Check object deleted because it expires on epoch"): with pytest.raises(Exception, match=OBJECT_NOT_FOUND): head_object(wallet, cid, oid, self.shell, self.cluster.default_rpc_endpoint) with pytest.raises(Exception, match=OBJECT_NOT_FOUND): get_object_from_random_node(wallet, cid, oid, self.shell, self.cluster) - with allure.step("Tick additional epoch"): + with reporter.step("Tick additional epoch"): self.tick_epoch() wait_for_gc_pass_on_storage_nodes() - with allure.step("Check object deleted because it expires on previous epoch"): + with reporter.step("Check object deleted because it expires on previous epoch"): with pytest.raises(Exception, match=OBJECT_NOT_FOUND): head_object(wallet, cid, oid, self.shell, self.cluster.default_rpc_endpoint) with pytest.raises(Exception, match=OBJECT_NOT_FOUND): diff --git a/pytest_tests/testsuites/object/test_object_lock.py b/pytest_tests/testsuites/object/test_object_lock.py index 9f12538..b3cb946 100755 --- a/pytest_tests/testsuites/object/test_object_lock.py +++ b/pytest_tests/testsuites/object/test_object_lock.py @@ -3,6 +3,7 @@ import re import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.common import STORAGE_GC_TIME from frostfs_testlib.resources.error_patterns import ( LIFETIME_REQUIRED, @@ -41,7 +42,7 @@ FIXTURE_OBJECT_LIFETIME = 10 scope="module", ) def user_wallet(wallet_factory: WalletFactory): - with allure.step("Create user wallet with container"): + with reporter.step("Create user wallet with container"): wallet_file = wallet_factory.create_wallet() return wallet_file @@ -66,7 +67,7 @@ def locked_storage_object( """ Intention of this fixture is to provide storage object which is NOT expected to be deleted during test act phase """ - with allure.step("Creating locked object"): + with reporter.step("Creating locked object"): current_epoch = ensure_fresh_epoch(client_shell, cluster) expiration_epoch = current_epoch + FIXTURE_LOCK_LIFETIME @@ -87,12 +88,12 @@ def locked_storage_object( yield storage_object - with allure.step("Delete created locked object"): + with reporter.step("Delete created locked object"): current_epoch = get_epoch(client_shell, cluster) epoch_diff = expiration_epoch - current_epoch + 1 if epoch_diff > 0: - with allure.step(f"Tick {epoch_diff} epochs"): + with reporter.step(f"Tick {epoch_diff} epochs"): for _ in range(epoch_diff): tick_epoch(client_shell, cluster) try: @@ -142,7 +143,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): Intention of this fixture is to provide new storage object for tests which may delete or corrupt the object or it's complementary objects So we need a new one each time we ask for it """ - with allure.step("Creating locked object"): + with reporter.step("Creating locked object"): current_epoch = self.get_epoch() storage_object = user_container.generate_object( @@ -278,7 +279,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): current_epoch = self.ensure_fresh_epoch() storage_object = user_container.generate_object(object_size.value, expire_at=current_epoch + 1) - with allure.step("Lock object for couple epochs"): + with reporter.step("Lock object for couple epochs"): lock_object( storage_object.wallet_file_path, storage_object.cid, @@ -296,7 +297,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): expire_at=current_epoch + 2, ) - with allure.step("Check object is not deleted at expiration time"): + with reporter.step("Check object is not deleted at expiration time"): self.tick_epochs(2) # Must wait to ensure object is not deleted wait_for_gc_pass_on_storage_nodes() @@ -309,7 +310,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.cluster.default_rpc_endpoint, ) - with allure.step("Wait for object to be deleted after third epoch"): + with reporter.step("Wait for object to be deleted after third epoch"): self.tick_epoch() check_object_not_found( storage_object.wallet_file_path, @@ -332,7 +333,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): current_epoch = ensure_fresh_epoch(self.shell, self.cluster) storage_objects: list[StorageObjectInfo] = [] - with allure.step("Generate three objects"): + with reporter.step("Generate three objects"): for _ in range(3): storage_objects.append(user_container.generate_object(object_size.value, expire_at=current_epoch + 5)) @@ -346,7 +347,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): ) for storage_object in storage_objects: - with allure.step(f"Try to delete object {storage_object.oid}"): + with reporter.step(f"Try to delete object {storage_object.oid}"): with pytest.raises(Exception, match=OBJECT_IS_LOCKED): delete_object( storage_object.wallet_file_path, @@ -356,7 +357,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.cluster.default_rpc_endpoint, ) - with allure.step("Tick two epochs"): + with reporter.step("Tick two epochs"): self.tick_epoch() self.tick_epoch() @@ -477,7 +478,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): chunk_object_ids = get_storage_object_chunks(locked_storage_object, self.shell, self.cluster) for chunk_object_id in chunk_object_ids: - with allure.step(f"Try to delete chunk object {chunk_object_id}"): + with reporter.step(f"Try to delete chunk object {chunk_object_id}"): with pytest.raises(Exception, match=OBJECT_IS_LOCKED): delete_object( locked_storage_object.wallet_file_path, @@ -504,7 +505,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.cluster.storage_nodes, ) - with allure.step(f"Drop link object with id {link_object_id} from nodes"): + with reporter.step(f"Drop link object with id {link_object_id} from nodes"): nodes_with_object = get_nodes_with_object( new_locked_storage_object.cid, link_object_id, @@ -527,7 +528,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): chunk_objects = get_storage_object_chunks(new_locked_storage_object, self.shell, self.cluster) for chunk_object_id in chunk_objects: - with allure.step(f"Drop chunk object with id {chunk_object_id} from nodes"): + with reporter.step(f"Drop chunk object with id {chunk_object_id} from nodes"): nodes_with_object = get_nodes_with_object( new_locked_storage_object.cid, chunk_object_id, @@ -575,7 +576,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.cluster.storage_nodes, is_direct=False, ) - with allure.step(f"Try to delete link object {link_object_id}"): + with reporter.step(f"Try to delete link object {link_object_id}"): with pytest.raises(Exception, match=OBJECT_IS_LOCKED): delete_object( locked_storage_object.wallet_file_path, @@ -594,7 +595,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): current_epoch = self.ensure_fresh_epoch() storage_object = user_container.generate_object(object_size.value, expire_at=current_epoch + 1) - with allure.step("Apply first lock to object for 3 epochs"): + with reporter.step("Apply first lock to object for 3 epochs"): lock_object_id_0 = lock_object( storage_object.wallet_file_path, storage_object.cid, @@ -606,7 +607,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.tick_epochs(2) - with allure.step("Check first lock is still available"): + with reporter.step("Check first lock is still available"): verify_object_available( storage_object.wallet_file_path, storage_object.cid, @@ -615,7 +616,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.cluster.default_rpc_endpoint, ) - with allure.step("Apply second lock to object for 3 more epochs"): + with reporter.step("Apply second lock to object for 3 more epochs"): lock_object_id_1 = lock_object( storage_object.wallet_file_path, storage_object.cid, @@ -627,7 +628,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.tick_epochs(2) - with allure.step("Verify first lock is expired and removed"): + with reporter.step("Verify first lock is expired and removed"): check_object_not_found( storage_object.wallet_file_path, storage_object.cid, @@ -636,7 +637,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.cluster.default_rpc_endpoint, ) - with allure.step("Verify second lock is still available"): + with reporter.step("Verify second lock is still available"): verify_object_available( storage_object.wallet_file_path, storage_object.cid, @@ -645,7 +646,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.cluster.default_rpc_endpoint, ) - with allure.step("Apply third lock to object for 3 more epochs"): + with reporter.step("Apply third lock to object for 3 more epochs"): lock_object( storage_object.wallet_file_path, storage_object.cid, @@ -655,7 +656,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): expire_at=current_epoch + 7, ) - with allure.step("Verify object is deleted after all locks are expired"): + with reporter.step("Verify object is deleted after all locks are expired"): self.tick_epochs(4) check_object_not_found( storage_object.wallet_file_path, @@ -676,7 +677,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): current_epoch = self.ensure_fresh_epoch() storage_objects: list[StorageObjectInfo] = [] - with allure.step("Generate two objects"): + with reporter.step("Generate two objects"): for epoch_i in range(2): storage_objects.append( user_container.generate_object(object_size.value, expire_at=current_epoch + epoch_i + 3) @@ -684,7 +685,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.tick_epoch() - with allure.step("Lock objects for 4 epochs"): + with reporter.step("Lock objects for 4 epochs"): lock_object( storage_objects[0].wallet_file_path, storage_objects[0].cid, @@ -694,10 +695,10 @@ class TestObjectLockWithGrpc(ClusterTestBase): expire_at=current_epoch + 4, ) - with allure.step("Verify objects are available during next three epochs"): + with reporter.step("Verify objects are available during next three epochs"): for epoch_i in range(3): self.tick_epoch() - with allure.step(f"Check objects at epoch {current_epoch + epoch_i + 2}"): + with reporter.step(f"Check objects at epoch {current_epoch + epoch_i + 2}"): for storage_object in storage_objects: verify_object_available( storage_object.wallet_file_path, @@ -707,7 +708,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.cluster.default_rpc_endpoint, ) - with allure.step("Verify objects are deleted after lock was expired"): + with reporter.step("Verify objects are deleted after lock was expired"): self.tick_epoch() for storage_object in storage_objects: check_object_not_found( diff --git a/pytest_tests/testsuites/replication/test_replication.py b/pytest_tests/testsuites/replication/test_replication.py index 1e7baf8..a4bdefc 100644 --- a/pytest_tests/testsuites/replication/test_replication.py +++ b/pytest_tests/testsuites/replication/test_replication.py @@ -4,6 +4,7 @@ from time import sleep import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.shell import Shell from frostfs_testlib.steps.cli.container import create_container, delete_container from frostfs_testlib.steps.cli.object import delete_object, head_object, put_object @@ -56,7 +57,7 @@ class TestReplication(ClusterTestBase): file_path = generate_file(object_size.value) - with allure.step("Put object"): + with reporter.step("Put object"): oid = put_object( wallet=default_wallet, path=file_path, @@ -69,7 +70,7 @@ class TestReplication(ClusterTestBase): ) cluster_state_controller.start_node_host(node_for_rep) - with allure.step(f"Wait for replication."): + with reporter.step(f"Wait for replication."): object_nodes = wait_object_replication( cid=cid, oid=oid, @@ -78,7 +79,7 @@ class TestReplication(ClusterTestBase): nodes=self.cluster.storage_nodes, ) - with allure.step("Check attributes"): + with reporter.step("Check attributes"): for node in object_nodes: header_info = head_object( wallet=default_wallet, @@ -97,7 +98,7 @@ class TestReplication(ClusterTestBase): f"expected attribute value: {attribute_value}" ) - with allure.step("Cleanup"): + with reporter.step("Cleanup"): delete_object( wallet=default_wallet, cid=cid, diff --git a/pytest_tests/testsuites/services/http_gate/test_http_bearer.py b/pytest_tests/testsuites/services/http_gate/test_http_bearer.py index 92d996a..d5f6682 100644 --- a/pytest_tests/testsuites/services/http_gate/test_http_bearer.py +++ b/pytest_tests/testsuites/services/http_gate/test_http_bearer.py @@ -2,6 +2,7 @@ import logging import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.steps.acl import ( bearer_token_base64_from_file, @@ -44,7 +45,7 @@ class Test_http_bearer(ClusterTestBase): @pytest.fixture(scope="class") def eacl_deny_for_others(self, user_container: str) -> None: - with allure.step(f"Set deny all operations for {EACLRole.OTHERS} via eACL"): + with reporter.step(f"Set deny all operations for {EACLRole.OTHERS} via eACL"): eacl = EACLRule(access=EACLAccess.DENY, role=EACLRole.OTHERS, operation=EACLOperation.PUT) set_eacl( self.wallet, @@ -57,7 +58,7 @@ class Test_http_bearer(ClusterTestBase): @pytest.fixture(scope="class") def bearer_token_no_limit_for_others(self, user_container: str) -> str: - with allure.step(f"Create bearer token for {EACLRole.OTHERS} with all operations allowed"): + with reporter.step(f"Create bearer token for {EACLRole.OTHERS} with all operations allowed"): bearer = form_bearertoken_file( self.wallet, user_container, @@ -98,7 +99,7 @@ class Test_http_bearer(ClusterTestBase): eacl_deny_for_others bearer = bearer_token_no_limit_for_others file_path = generate_file(object_size.value) - with allure.step(f"Put object with bearer token for {EACLRole.OTHERS}, then get and verify hashes"): + with reporter.step(f"Put object with bearer token for {EACLRole.OTHERS}, then get and verify hashes"): headers = [f" -H 'Authorization: Bearer {bearer}'"] oid = upload_via_http_gate_curl( cid=user_container, diff --git a/pytest_tests/testsuites/services/http_gate/test_http_gate.py b/pytest_tests/testsuites/services/http_gate/test_http_gate.py index eea454e..1641e48 100644 --- a/pytest_tests/testsuites/services/http_gate/test_http_gate.py +++ b/pytest_tests/testsuites/services/http_gate/test_http_gate.py @@ -1,7 +1,6 @@ -import os - import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.steps.cli.container import create_container from frostfs_testlib.steps.cli.object import put_object_to_random_node @@ -69,7 +68,7 @@ class TestHttpGate(ClusterTestBase): file_path_simple = generate_file(simple_object_size.value) file_path_large = generate_file(complex_object_size.value) - with allure.step("Put objects using gRPC"): + with reporter.step("Put objects using gRPC"): oid_simple = put_object_to_random_node( wallet=self.wallet, path=file_path_simple, @@ -135,7 +134,7 @@ class TestHttpPut(ClusterTestBase): file_path_simple = generate_file(simple_object_size.value) file_path_large = generate_file(complex_object_size.value) - with allure.step("Put objects using HTTP"): + with reporter.step("Put objects using HTTP"): oid_simple = upload_via_http_gate( cid=cid, path=file_path_simple, endpoint=self.cluster.default_http_gate_endpoint ) @@ -191,7 +190,7 @@ class TestHttpPut(ClusterTestBase): ) file_path = generate_file(simple_object_size.value) - with allure.step("Put objects using HTTP with attribute"): + with reporter.step("Put objects using HTTP with attribute"): headers = attr_into_header(attributes) oid = upload_via_http_gate( cid=cid, @@ -231,7 +230,7 @@ class TestHttpPut(ClusterTestBase): valid_until = min_valid_epoch + gap_until headers = {"X-Attribute-System-Expiration-Epoch": str(valid_until)} - with allure.step("Put objects using HTTP with attribute Expiration-Epoch"): + with reporter.step("Put objects using HTTP with attribute Expiration-Epoch"): oid = upload_via_http_gate( cid=cid, path=file_path, @@ -243,7 +242,7 @@ class TestHttpPut(ClusterTestBase): oids_to_be_valid.append(oid) else: oids_to_be_expired.append(oid) - with allure.step("This object can be got"): + with reporter.step("This object can be got"): get_via_http_gate( cid=cid, oid=oid, @@ -257,7 +256,7 @@ class TestHttpPut(ClusterTestBase): wait_for_gc_pass_on_storage_nodes() for oid in oids_to_be_expired: - with allure.step(f"{oid} shall be expired and cannot be got"): + with reporter.step(f"{oid} shall be expired and cannot be got"): try_to_get_object_and_expect_error( cid=cid, oid=oid, @@ -266,7 +265,7 @@ class TestHttpPut(ClusterTestBase): http_hostname=self.cluster.default_http_hostname[0], ) for oid in oids_to_be_valid: - with allure.step(f"{oid} shall be valid and can be got"): + with reporter.step(f"{oid} shall be valid and can be got"): get_via_http_gate( cid=cid, oid=oid, @@ -310,7 +309,7 @@ class TestHttpPut(ClusterTestBase): http_hostname=self.cluster.default_http_hostname[0], ) - with allure.step("Verify hashes"): + with reporter.step("Verify hashes"): assert get_file_hash(f"{dir_path}/file1") == get_file_hash(file_path_simple) assert get_file_hash(f"{dir_path}/file2") == get_file_hash(file_path_large) @@ -331,7 +330,7 @@ class TestHttpPut(ClusterTestBase): file_path = generate_file(complex_object_size.value) - with allure.step("Put objects using HTTP"): + with reporter.step("Put objects using HTTP"): oid_gate = upload_via_http_gate(cid=cid, path=file_path, endpoint=self.cluster.default_http_gate_endpoint) oid_curl = upload_via_http_gate_curl( cid=cid, @@ -376,7 +375,7 @@ class TestHttpPut(ClusterTestBase): file_path_simple = generate_file(simple_object_size.value) file_path_large = generate_file(complex_object_size.value) - with allure.step("Put objects using curl utility"): + with reporter.step("Put objects using curl utility"): oid_simple = upload_via_http_gate_curl( cid=cid, filepath=file_path_simple, endpoint=self.cluster.default_http_gate_endpoint ) diff --git a/pytest_tests/testsuites/services/http_gate/test_http_headers.py b/pytest_tests/testsuites/services/http_gate/test_http_headers.py index 074097c..3d320cd 100644 --- a/pytest_tests/testsuites/services/http_gate/test_http_headers.py +++ b/pytest_tests/testsuites/services/http_gate/test_http_headers.py @@ -3,6 +3,7 @@ import os import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.steps.cli.container import ( create_container, @@ -88,7 +89,7 @@ class Test_http_headers(ClusterTestBase): storage_object_1 = storage_objects_with_attributes[0] - with allure.step( + with reporter.step( f'Download object#1 via wget with attributes Chapter2: {storage_object_1.attributes["Chapter2"]} and compare hashes' ): get_object_by_attr_and_verify_hashes( @@ -115,7 +116,7 @@ class Test_http_headers(ClusterTestBase): storage_object_1 = storage_objects_with_attributes[0] storage_object_2 = storage_objects_with_attributes[1] - with allure.step( + with reporter.step( f'Download object#2 via wget with attributes [chapter2={storage_object_2.attributes["chapter2"]}] / [Ch@pter1={storage_object_2.attributes["Ch@pter1"]}] and compare hashes' ): selected_attributes_object2 = [ @@ -131,7 +132,7 @@ class Test_http_headers(ClusterTestBase): endpoint=self.cluster.default_http_gate_endpoint, http_hostname=self.cluster.default_http_hostname[0], ) - with allure.step("Delete object#2 and verify is the container deleted"): + with reporter.step("Delete object#2 and verify is the container deleted"): delete_object( wallet=self.wallet, cid=storage_object_2.cid, @@ -148,7 +149,7 @@ class Test_http_headers(ClusterTestBase): ) storage_objects_with_attributes.remove(storage_object_2) - with allure.step( + with reporter.step( f'Download object#1 with attributes [Writer={storage_object_1.attributes["Writer"]}] and compare hashes' ): key_value_pair = {"Writer": storage_object_1.attributes["Writer"]} @@ -175,7 +176,7 @@ class Test_http_headers(ClusterTestBase): """ storage_object_1 = storage_objects_with_attributes[0] - with allure.step( + with reporter.step( "[Negative] Allocate and attemt to put object#3 via http with attributes: [Writer=Leo Tolstoy, Writer=peace, peace=peace]" ): file_path_3 = generate_file(storage_object_1.size) @@ -190,7 +191,7 @@ class Test_http_headers(ClusterTestBase): headers=headers, error_pattern=error_pattern, ) - with allure.step("Delete container and verify container deletion"): + with reporter.step("Delete container and verify container deletion"): delete_container( wallet=self.wallet, cid=storage_object_1.cid, @@ -208,7 +209,7 @@ class Test_http_headers(ClusterTestBase): assert storage_object_1.cid not in list_containers( self.wallet, shell=self.shell, endpoint=self.cluster.default_rpc_endpoint ) - with allure.step("[Negative] Try to download (wget) object via wget with attributes [peace=peace]"): + with reporter.step("[Negative] Try to download (wget) object via wget with attributes [peace=peace]"): request = f"/get/{storage_object_1.cid}/peace/peace" error_pattern = "404 Not Found" try_to_get_object_via_passed_request_and_expect_error( diff --git a/pytest_tests/testsuites/services/http_gate/test_http_object.py b/pytest_tests/testsuites/services/http_gate/test_http_object.py index a75ba4f..2bd8924 100644 --- a/pytest_tests/testsuites/services/http_gate/test_http_object.py +++ b/pytest_tests/testsuites/services/http_gate/test_http_object.py @@ -2,6 +2,7 @@ import logging import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.s3 import AwsCliClient, S3ClientWrapper from frostfs_testlib.steps.cli.container import create_container @@ -51,7 +52,7 @@ class Test_http_object(ClusterTestBase): Hashes must be the same. """ - with allure.step("Create public container"): + with reporter.step("Create public container"): cid = create_container( self.wallet, shell=self.shell, @@ -73,7 +74,7 @@ class Test_http_object(ClusterTestBase): key_value1 = obj_key1 + "=" + obj_value1 key_value2 = obj_key2 + "=" + obj_value2 - with allure.step("Put objects using gRPC [--attributes chapter1=peace,chapter2=war]"): + with reporter.step("Put objects using gRPC [--attributes chapter1=peace,chapter2=war]"): oid = put_object_to_random_node( wallet=self.wallet, path=file_path, @@ -82,7 +83,7 @@ class Test_http_object(ClusterTestBase): cluster=self.cluster, attributes=f"{key_value1},{key_value2}", ) - with allure.step("Get object and verify hashes [ get/$CID/$OID ]"): + with reporter.step("Get object and verify hashes [ get/$CID/$OID ]"): verify_object_hash( oid=oid, file_name=file_path, @@ -94,7 +95,7 @@ class Test_http_object(ClusterTestBase): http_hostname=self.cluster.default_http_hostname[0], ) - with allure.step("[Negative] try to get object: [get/$CID/chapter1/peace]"): + with reporter.step("[Negative] try to get object: [get/$CID/chapter1/peace]"): attrs = {obj_key1: obj_value1, obj_key2: obj_value2} request = f"/get/{cid}/{obj_key1}/{obj_value1}" expected_err_msg = "Failed to get object via HTTP gate:" @@ -108,7 +109,7 @@ class Test_http_object(ClusterTestBase): http_hostname=self.cluster.default_http_hostname[0], ) - with allure.step("Download the object with attribute [get_by_attribute/$CID/chapter1/peace]"): + with reporter.step("Download the object with attribute [get_by_attribute/$CID/chapter1/peace]"): get_object_by_attr_and_verify_hashes( oid=oid, file_name=file_path, @@ -117,7 +118,7 @@ class Test_http_object(ClusterTestBase): endpoint=self.cluster.default_http_gate_endpoint, http_hostname=self.cluster.default_http_hostname[0], ) - with allure.step("[Negative] try to get object: get_by_attribute/$CID/$OID"): + with reporter.step("[Negative] try to get object: get_by_attribute/$CID/$OID"): request = f"/get_by_attribute/{cid}/{oid}" try_to_get_object_via_passed_request_and_expect_error( cid=cid, @@ -159,5 +160,5 @@ class Test_http_object(ClusterTestBase): http_hostname=self.cluster.default_http_hostname[0], request_path=request, ) - with allure.step("Verify hashes"): + with reporter.step("Verify hashes"): assert_hashes_are_equal(file_path, obj_http, obj_s3) diff --git a/pytest_tests/testsuites/services/http_gate/test_http_streaming.py b/pytest_tests/testsuites/services/http_gate/test_http_streaming.py index 2275db3..c36e4cd 100644 --- a/pytest_tests/testsuites/services/http_gate/test_http_streaming.py +++ b/pytest_tests/testsuites/services/http_gate/test_http_streaming.py @@ -2,6 +2,7 @@ import logging import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.steps.cli.container import create_container from frostfs_testlib.steps.http.http_gate import upload_via_http_gate_curl, verify_object_hash @@ -37,7 +38,7 @@ class Test_http_streaming(ClusterTestBase): Expected result: Hashes must be the same. """ - with allure.step("Create public container and verify container creation"): + with reporter.step("Create public container and verify container creation"): cid = create_container( self.wallet, shell=self.shell, @@ -45,11 +46,11 @@ class Test_http_streaming(ClusterTestBase): rule=self.PLACEMENT_RULE, basic_acl=PUBLIC_ACL, ) - with allure.step("Allocate big object"): + with reporter.step("Allocate big object"): # Generate file file_path = generate_file(complex_object_size.value) - with allure.step("Put objects using curl utility and Get object and verify hashes [ get/$CID/$OID ]"): + with reporter.step("Put objects using curl utility and Get object and verify hashes [ get/$CID/$OID ]"): oid = upload_via_http_gate_curl( cid=cid, filepath=file_path, endpoint=self.cluster.default_http_gate_endpoint ) diff --git a/pytest_tests/testsuites/services/http_gate/test_http_system_header.py b/pytest_tests/testsuites/services/http_gate/test_http_system_header.py index 5567a33..82f469e 100644 --- a/pytest_tests/testsuites/services/http_gate/test_http_system_header.py +++ b/pytest_tests/testsuites/services/http_gate/test_http_system_header.py @@ -5,6 +5,7 @@ from typing import Optional import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.error_patterns import OBJECT_NOT_FOUND from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.steps.cli.container import create_container @@ -139,7 +140,7 @@ class Test_http_system_header(ClusterTestBase): def test_unable_put_expired_epoch(self, user_container: str, simple_object_size: ObjectSize): headers = attr_into_str_header_curl({"System-Expiration-Epoch": str(get_epoch(self.shell, self.cluster) - 1)}) file_path = generate_file(simple_object_size.value) - with allure.step("Put object using HTTP with attribute Expiration-Epoch where epoch is expired"): + with reporter.step("Put object using HTTP with attribute Expiration-Epoch where epoch is expired"): upload_via_http_gate_curl( cid=user_container, filepath=file_path, @@ -152,7 +153,9 @@ class Test_http_system_header(ClusterTestBase): def test_unable_put_negative_duration(self, user_container: str, simple_object_size: ObjectSize): headers = attr_into_str_header_curl({"System-Expiration-Duration": "-1h"}) file_path = generate_file(simple_object_size.value) - with allure.step("Put object using HTTP with attribute System-Expiration-Duration where duration is negative"): + with reporter.step( + "Put object using HTTP with attribute System-Expiration-Duration where duration is negative" + ): upload_via_http_gate_curl( cid=user_container, filepath=file_path, @@ -165,7 +168,7 @@ class Test_http_system_header(ClusterTestBase): def test_unable_put_expired_timestamp(self, user_container: str, simple_object_size: ObjectSize): headers = attr_into_str_header_curl({"System-Expiration-Timestamp": "1635075727"}) file_path = generate_file(simple_object_size.value) - with allure.step( + with reporter.step( "Put object using HTTP with attribute System-Expiration-Timestamp where duration is in the past" ): upload_via_http_gate_curl( @@ -200,21 +203,21 @@ class Test_http_system_header(ClusterTestBase): ) attributes = {SYSTEM_EXPIRATION_EPOCH: expected_epoch, SYSTEM_EXPIRATION_DURATION: "1m"} file_path = generate_file(object_size.value) - with allure.step( + with reporter.step( f"Put objects using HTTP with attributes and head command should display {EXPIRATION_EPOCH_HEADER}: {expected_epoch} attr" ): oid, head_info = self.oid_header_info_for_object( file_path=file_path, attributes=attributes, user_container=user_container ) self.validation_for_http_header_attr(head_info=head_info, expected_epoch=expected_epoch) - with allure.step("Check that object becomes unavailable when epoch is expired"): + with reporter.step("Check that object becomes unavailable when epoch is expired"): for _ in range(0, epoch_count + 1): self.tick_epoch() assert ( get_epoch(self.shell, self.cluster) == expected_epoch + 1 ), f"Epochs should be equal: {get_epoch(self.shell, self.cluster)} != {expected_epoch + 1}" - with allure.step("Check object deleted because it expires-on epoch"): + with reporter.step("Check object deleted because it expires-on epoch"): wait_for_epochs_align(self.shell, self.cluster) try_to_get_object_and_expect_error( cid=user_container, @@ -240,21 +243,21 @@ class Test_http_system_header(ClusterTestBase): SYSTEM_EXPIRATION_TIMESTAMP: self.epoch_count_into_timestamp(epoch_duration=epoch_duration, epoch=1), } file_path = generate_file(object_size.value) - with allure.step( + with reporter.step( f"Put objects using HTTP with attributes and head command should display {EXPIRATION_EPOCH_HEADER}: {expected_epoch} attr" ): oid, head_info = self.oid_header_info_for_object( file_path=file_path, attributes=attributes, user_container=user_container ) self.validation_for_http_header_attr(head_info=head_info, expected_epoch=expected_epoch) - with allure.step("Check that object becomes unavailable when epoch is expired"): + with reporter.step("Check that object becomes unavailable when epoch is expired"): for _ in range(0, epoch_count + 1): self.tick_epoch() assert ( get_epoch(self.shell, self.cluster) == expected_epoch + 1 ), f"Epochs should be equal: {get_epoch(self.shell, self.cluster)} != {expected_epoch + 1}" - with allure.step("Check object deleted because it expires-on epoch"): + with reporter.step("Check object deleted because it expires-on epoch"): wait_for_epochs_align(self.shell, self.cluster) try_to_get_object_and_expect_error( cid=user_container, @@ -282,21 +285,21 @@ class Test_http_system_header(ClusterTestBase): ), } file_path = generate_file(object_size.value) - with allure.step( + with reporter.step( f"Put objects using HTTP with attributes and head command should display {EXPIRATION_EPOCH_HEADER}: {expected_epoch} attr" ): oid, head_info = self.oid_header_info_for_object( file_path=file_path, attributes=attributes, user_container=user_container ) self.validation_for_http_header_attr(head_info=head_info, expected_epoch=expected_epoch) - with allure.step("Check that object becomes unavailable when epoch is expired"): + with reporter.step("Check that object becomes unavailable when epoch is expired"): for _ in range(0, epoch_count + 1): self.tick_epoch() assert ( get_epoch(self.shell, self.cluster) == expected_epoch + 1 ), f"Epochs should be equal: {get_epoch(self.shell, self.cluster)} != {expected_epoch + 1}" - with allure.step("Check object deleted because it expires-on epoch"): + with reporter.step("Check object deleted because it expires-on epoch"): wait_for_epochs_align(self.shell, self.cluster) try_to_get_object_and_expect_error( cid=user_container, @@ -331,7 +334,7 @@ class Test_http_system_header(ClusterTestBase): ) } file_path = generate_file(object_size.value) - with allure.step( + with reporter.step( f"Put objects using HTTP with attributes and head command should display {EXPIRATION_EPOCH_HEADER}: {expected_epoch} attr" ): oid, head_info = self.oid_header_info_for_object( @@ -340,7 +343,7 @@ class Test_http_system_header(ClusterTestBase): user_container=user_container, ) self.validation_for_http_header_attr(head_info=head_info, expected_epoch=expected_epoch) - with allure.step("Check that object becomes unavailable when epoch is expired"): + with reporter.step("Check that object becomes unavailable when epoch is expired"): for _ in range(0, epoch_count + 1): self.tick_epoch() # check that {EXPIRATION_EXPIRATION_RFC} absents in header output @@ -348,7 +351,7 @@ class Test_http_system_header(ClusterTestBase): get_epoch(self.shell, self.cluster) == expected_epoch + 1 ), f"Epochs should be equal: {get_epoch(self.shell, self.cluster)} != {expected_epoch + 1}" - with allure.step("Check object deleted because it expires-on epoch"): + with reporter.step("Check object deleted because it expires-on epoch"): wait_for_epochs_align(self.shell, self.cluster) try_to_get_object_and_expect_error( cid=user_container, diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_ACL.py b/pytest_tests/testsuites/services/s3_gate/test_s3_ACL.py index 6040aea..8c0eb2b 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_ACL.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_ACL.py @@ -1,5 +1,6 @@ import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.s3 import AwsCliClient, Boto3ClientWrapper, S3ClientWrapper from frostfs_testlib.steps.s3 import s3_helper from frostfs_testlib.storage.dataclasses.object_size import ObjectSize @@ -15,22 +16,22 @@ class TestS3GateACL: file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) - with allure.step("Put object into bucket, Check ACL is empty"): + with reporter.step("Put object into bucket, Check ACL is empty"): s3_client.put_object(bucket, file_path) obj_acl = s3_client.get_object_acl(bucket, file_name) assert obj_acl == [], f"Expected ACL is empty, got {obj_acl}" - with allure.step("Put object ACL = public-read"): + with reporter.step("Put object ACL = public-read"): s3_client.put_object_acl(bucket, file_name, "public-read") obj_acl = s3_client.get_object_acl(bucket, file_name) s3_helper.assert_s3_acl(acl_grants=obj_acl, permitted_users="AllUsers") - with allure.step("Put object ACL = private"): + with reporter.step("Put object ACL = private"): s3_client.put_object_acl(bucket, file_name, "private") obj_acl = s3_client.get_object_acl(bucket, file_name) s3_helper.assert_s3_acl(acl_grants=obj_acl, permitted_users="CanonicalUser") - with allure.step("Put object with grant-read uri=http://acs.amazonaws.com/groups/global/AllUsers"): + with reporter.step("Put object with grant-read uri=http://acs.amazonaws.com/groups/global/AllUsers"): s3_client.put_object_acl( bucket, file_name, @@ -42,17 +43,17 @@ class TestS3GateACL: @allure.title("Bucket ACL (s3_client={s3_client})") @pytest.mark.parametrize("s3_client", [AwsCliClient, Boto3ClientWrapper], indirect=True) def test_s3_bucket_ACL(self, s3_client: S3ClientWrapper): - with allure.step("Create bucket with ACL = public-read-write"): + with reporter.step("Create bucket with ACL = public-read-write"): bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=True, acl="public-read-write") bucket_acl = s3_client.get_bucket_acl(bucket) s3_helper.assert_s3_acl(acl_grants=bucket_acl, permitted_users="AllUsers") - with allure.step("Change bucket ACL to private"): + with reporter.step("Change bucket ACL to private"): s3_client.put_bucket_acl(bucket, acl="private") bucket_acl = s3_client.get_bucket_acl(bucket) s3_helper.assert_s3_acl(acl_grants=bucket_acl, permitted_users="CanonicalUser") - with allure.step("Change bucket acl to --grant-write uri=http://acs.amazonaws.com/groups/global/AllUsers"): + with reporter.step("Change bucket acl to --grant-write uri=http://acs.amazonaws.com/groups/global/AllUsers"): s3_client.put_bucket_acl( bucket, grant_write="uri=http://acs.amazonaws.com/groups/global/AllUsers", diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_bucket.py b/pytest_tests/testsuites/services/s3_gate/test_s3_bucket.py index beded52..bee48e2 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_bucket.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_bucket.py @@ -2,6 +2,7 @@ from datetime import datetime, timedelta import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.s3 import S3ClientWrapper from frostfs_testlib.steps.s3 import s3_helper from frostfs_testlib.storage.dataclasses.object_size import ObjectSize @@ -14,22 +15,22 @@ class TestS3GateBucket: @allure.title("Create Bucket with different ACL (s3_client={s3_client})") def test_s3_create_bucket_with_ACL(self, s3_client: S3ClientWrapper): - with allure.step("Create bucket with ACL private"): + with reporter.step("Create bucket with ACL private"): bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=True, acl="private") bucket_acl = s3_client.get_bucket_acl(bucket) s3_helper.assert_s3_acl(acl_grants=bucket_acl, permitted_users="CanonicalUser") - with allure.step("Create bucket with ACL = public-read"): + with reporter.step("Create bucket with ACL = public-read"): bucket_1 = s3_client.create_bucket(object_lock_enabled_for_bucket=True, acl="public-read") bucket_acl_1 = s3_client.get_bucket_acl(bucket_1) s3_helper.assert_s3_acl(acl_grants=bucket_acl_1, permitted_users="AllUsers") - with allure.step("Create bucket with ACL public-read-write"): + with reporter.step("Create bucket with ACL public-read-write"): bucket_2 = s3_client.create_bucket(object_lock_enabled_for_bucket=True, acl="public-read-write") bucket_acl_2 = s3_client.get_bucket_acl(bucket_2) s3_helper.assert_s3_acl(acl_grants=bucket_acl_2, permitted_users="AllUsers") - with allure.step("Create bucket with ACL = authenticated-read"): + with reporter.step("Create bucket with ACL = authenticated-read"): bucket_3 = s3_client.create_bucket(object_lock_enabled_for_bucket=True, acl="authenticated-read") bucket_acl_3 = s3_client.get_bucket_acl(bucket_3) s3_helper.assert_s3_acl(acl_grants=bucket_acl_3, permitted_users="AllUsers") @@ -37,7 +38,7 @@ class TestS3GateBucket: @allure.title("Create Bucket with different ACL by grant (s3_client={s3_client})") def test_s3_create_bucket_with_grands(self, s3_client: S3ClientWrapper): - with allure.step("Create bucket with --grant-read"): + with reporter.step("Create bucket with --grant-read"): bucket = s3_client.create_bucket( object_lock_enabled_for_bucket=True, grant_read="uri=http://acs.amazonaws.com/groups/global/AllUsers", @@ -45,7 +46,7 @@ class TestS3GateBucket: bucket_acl = s3_client.get_bucket_acl(bucket) s3_helper.assert_s3_acl(acl_grants=bucket_acl, permitted_users="AllUsers") - with allure.step("Create bucket with --grant-wtite"): + with reporter.step("Create bucket with --grant-wtite"): bucket_1 = s3_client.create_bucket( object_lock_enabled_for_bucket=True, grant_write="uri=http://acs.amazonaws.com/groups/global/AllUsers", @@ -53,7 +54,7 @@ class TestS3GateBucket: bucket_acl_1 = s3_client.get_bucket_acl(bucket_1) s3_helper.assert_s3_acl(acl_grants=bucket_acl_1, permitted_users="AllUsers") - with allure.step("Create bucket with --grant-full-control"): + with reporter.step("Create bucket with --grant-full-control"): bucket_2 = s3_client.create_bucket( object_lock_enabled_for_bucket=True, grant_full_control="uri=http://acs.amazonaws.com/groups/global/AllUsers", @@ -66,7 +67,7 @@ class TestS3GateBucket: file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) - with allure.step("Create bucket with --no-object-lock-enabled-for-bucket"): + with reporter.step("Create bucket with --no-object-lock-enabled-for-bucket"): bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=False) date_obj = datetime.utcnow() + timedelta(days=1) with pytest.raises(Exception, match=r".*Object Lock configuration does not exist for this bucket.*"): @@ -78,7 +79,7 @@ class TestS3GateBucket: object_lock_mode="COMPLIANCE", object_lock_retain_until_date=date_obj.strftime("%Y-%m-%dT%H:%M:%S"), ) - with allure.step("Create bucket with --object-lock-enabled-for-bucket"): + with reporter.step("Create bucket with --object-lock-enabled-for-bucket"): bucket_1 = s3_client.create_bucket(object_lock_enabled_for_bucket=True) date_obj_1 = datetime.utcnow() + timedelta(days=1) s3_client.put_object( @@ -98,21 +99,21 @@ class TestS3GateBucket: file_name_2 = s3_helper.object_key_from_file_path(file_path_2) bucket = s3_client.create_bucket() - with allure.step("Put two objects into bucket"): + with reporter.step("Put two objects into bucket"): s3_client.put_object(bucket, file_path_1) s3_client.put_object(bucket, file_path_2) s3_helper.check_objects_in_bucket(s3_client, bucket, [file_name_1, file_name_2]) - with allure.step("Try to delete not empty bucket and get error"): + with reporter.step("Try to delete not empty bucket and get error"): with pytest.raises(Exception, match=r".*The bucket you tried to delete is not empty.*"): s3_client.delete_bucket(bucket) - with allure.step("Delete object in bucket"): + with reporter.step("Delete object in bucket"): s3_client.delete_object(bucket, file_name_1) s3_client.delete_object(bucket, file_name_2) s3_helper.check_objects_in_bucket(s3_client, bucket, []) - with allure.step("Delete empty bucket"): + with reporter.step("Delete empty bucket"): s3_client.delete_bucket(bucket) with pytest.raises(Exception, match=r".*Not Found.*"): s3_client.head_bucket(bucket) diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py b/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py index a9a49d4..ff30fef 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py @@ -4,6 +4,7 @@ from random import choice, choices import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.common import ASSETS_DIR from frostfs_testlib.s3 import AwsCliClient, Boto3ClientWrapper, S3ClientWrapper, VersioningStatus from frostfs_testlib.shell import Shell @@ -42,43 +43,43 @@ class TestS3Gate: file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) - with allure.step("Create buckets"): + with reporter.step("Create buckets"): bucket_1 = s3_client.create_bucket(object_lock_enabled_for_bucket=True) s3_helper.set_bucket_versioning(s3_client, bucket_1, VersioningStatus.ENABLED) bucket_2 = s3_client.create_bucket() - with allure.step("Check buckets are presented in the system"): + with reporter.step("Check buckets are presented in the system"): buckets = s3_client.list_buckets() assert bucket_1 in buckets, f"Expected bucket {bucket_1} is in the list" assert bucket_2 in buckets, f"Expected bucket {bucket_2} is in the list" - with allure.step("Bucket must be empty"): + with reporter.step("Bucket must be empty"): for bucket in (bucket_1, bucket_2): objects_list = s3_client.list_objects(bucket) assert not objects_list, f"Expected empty bucket, got {objects_list}" - with allure.step("Check buckets are visible with S3 head command"): + with reporter.step("Check buckets are visible with S3 head command"): s3_client.head_bucket(bucket_1) s3_client.head_bucket(bucket_2) - with allure.step("Check we can put/list object with S3 commands"): + with reporter.step("Check we can put/list object with S3 commands"): version_id = s3_client.put_object(bucket_1, file_path) s3_client.head_object(bucket_1, file_name) bucket_objects = s3_client.list_objects(bucket_1) assert file_name in bucket_objects, f"Expected file {file_name} in objects list {bucket_objects}" - with allure.step("Try to delete not empty bucket and get error"): + with reporter.step("Try to delete not empty bucket and get error"): with pytest.raises(Exception, match=r".*The bucket you tried to delete is not empty.*"): s3_client.delete_bucket(bucket_1) s3_client.head_bucket(bucket_1) - with allure.step(f"Delete empty bucket {bucket_2}"): + with reporter.step(f"Delete empty bucket {bucket_2}"): s3_client.delete_bucket(bucket_2) tick_epoch(client_shell, cluster) - with allure.step(f"Check bucket {bucket_2} deleted"): + with reporter.step(f"Check bucket {bucket_2} deleted"): with pytest.raises(Exception, match=r".*Not Found.*"): s3_client.head_bucket(bucket_2) @@ -86,15 +87,15 @@ class TestS3Gate: assert bucket_1 in buckets, f"Expected bucket {bucket_1} is in the list" assert bucket_2 not in buckets, f"Expected bucket {bucket_2} is not in the list" - with allure.step(f"Delete object from {bucket_1}"): + with reporter.step(f"Delete object from {bucket_1}"): s3_client.delete_object(bucket_1, file_name, version_id) s3_helper.check_objects_in_bucket(s3_client, bucket_1, expected_objects=[]) - with allure.step(f"Delete bucket {bucket_1}"): + with reporter.step(f"Delete bucket {bucket_1}"): s3_client.delete_bucket(bucket_1) tick_epoch(client_shell, cluster) - with allure.step(f"Check bucket {bucket_1} deleted"): + with reporter.step(f"Check bucket {bucket_1} deleted"): with pytest.raises(Exception, match=r".*Not Found.*"): s3_client.head_bucket(bucket_1) @@ -119,7 +120,7 @@ class TestS3Gate: bucket_1, bucket_2 = two_buckets for bucket in (bucket_1, bucket_2): - with allure.step("Bucket must be empty"): + with reporter.step("Bucket must be empty"): objects_list = s3_client.list_objects(bucket) assert not objects_list, f"Expected empty bucket, got {objects_list}" @@ -129,7 +130,7 @@ class TestS3Gate: bucket_objects = s3_client.list_objects(bucket) assert file_name in bucket_objects, f"Expected file {file_name} in objects list {bucket_objects}" - with allure.step("Check object's attributes"): + with reporter.step("Check object's attributes"): for attrs in (["ETag"], ["ObjectSize", "StorageClass"]): s3_client.get_object_attributes(bucket, file_name, attrs) @@ -148,10 +149,10 @@ class TestS3Gate: s3_client.sync(bucket=bucket, dir_path=os.path.dirname(file_path_1)) - with allure.step("Check objects are synced"): + with reporter.step("Check objects are synced"): objects = s3_client.list_objects(bucket) - with allure.step("Check these are the same objects"): + with reporter.step("Check these are the same objects"): assert set(key_to_path.keys()) == set(objects), f"Expected all objects saved. Got {objects}" for obj_key in objects: got_object = s3_client.get_object(bucket, obj_key) @@ -170,12 +171,12 @@ class TestS3Gate: obj_key = os.path.basename(file_name_simple) s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): version_id_1 = s3_client.put_object(bucket, file_name_simple) generate_file_with_content(simple_object_size.value, file_path=file_name_simple, content=version_2_content) version_id_2 = s3_client.put_object(bucket, file_name_simple) - with allure.step("Check bucket shows all versions"): + with reporter.step("Check bucket shows all versions"): versions = s3_client.list_objects_versions(bucket) obj_versions = {version.get("VersionId") for version in versions if version.get("Key") == obj_key} assert obj_versions == { @@ -183,7 +184,7 @@ class TestS3Gate: version_id_2, }, f"Expected object has versions: {version_id_1, version_id_2}" - with allure.step("Show information about particular version"): + with reporter.step("Show information about particular version"): for version_id in (version_id_1, version_id_2): response = s3_client.head_object(bucket, obj_key, version_id=version_id) assert "LastModified" in response, "Expected LastModified field" @@ -191,20 +192,20 @@ class TestS3Gate: assert response.get("VersionId") == version_id, f"Expected VersionId is {version_id}" assert response.get("ContentLength") != 0, "Expected ContentLength is not zero" - with allure.step("Check object's attributes"): + with reporter.step("Check object's attributes"): for version_id in (version_id_1, version_id_2): got_attrs = s3_client.get_object_attributes(bucket, obj_key, ["ETag"], version_id=version_id) if got_attrs: assert got_attrs.get("VersionId") == version_id, f"Expected VersionId is {version_id}" - with allure.step("Delete object and check it was deleted"): + with reporter.step("Delete object and check it was deleted"): response = s3_client.delete_object(bucket, obj_key) version_id_delete = response.get("VersionId") with pytest.raises(Exception, match=r".*Not Found.*"): s3_client.head_object(bucket, obj_key) - with allure.step("Get content for all versions and check it is correct"): + with reporter.step("Get content for all versions and check it is correct"): for version, content in ( (version_id_2, version_2_content), (version_id_1, version_1_content), @@ -213,7 +214,7 @@ class TestS3Gate: got_content = get_file_content(file_name) assert got_content == content, f"Expected object content is\n{content}\nGot\n{got_content}" - with allure.step("Restore previous object version"): + with reporter.step("Restore previous object version"): s3_client.delete_object(bucket, obj_key, version_id=version_id_delete) file_name = s3_client.get_object(bucket, obj_key) @@ -238,7 +239,7 @@ class TestS3Gate: uploads = s3_client.list_multipart_uploads(bucket) assert not uploads, f"Expected there is no uploads in bucket {bucket}" - with allure.step("Create and abort multipart upload"): + with reporter.step("Create and abort multipart upload"): upload_id = s3_client.create_multipart_upload(bucket, object_key) uploads = s3_client.list_multipart_uploads(bucket) assert uploads, f"Expected there one upload in bucket {bucket}" @@ -249,13 +250,13 @@ class TestS3Gate: uploads = s3_client.list_multipart_uploads(bucket) assert not uploads, f"Expected there is no uploads in bucket {bucket}" - with allure.step("Create new multipart upload and upload several parts"): + with reporter.step("Create new multipart upload and upload several parts"): upload_id = s3_client.create_multipart_upload(bucket, object_key) for part_id, file_path in enumerate(part_files, start=1): etag = s3_client.upload_part(bucket, object_key, upload_id, part_id, file_path) parts.append((part_id, etag)) - with allure.step("Check all parts are visible in bucket"): + with reporter.step("Check all parts are visible in bucket"): got_parts = s3_client.list_parts(bucket, object_key, upload_id) assert len(got_parts) == len(part_files), f"Expected {parts_count} parts, got\n{got_parts}" @@ -264,7 +265,7 @@ class TestS3Gate: uploads = s3_client.list_multipart_uploads(bucket) assert not uploads, f"Expected there is no uploads in bucket {bucket}" - with allure.step("Check we can get whole object from bucket"): + with reporter.step("Check we can get whole object from bucket"): got_object = s3_client.get_object(bucket, object_key) assert get_file_hash(got_object) == get_file_hash(file_name_large) @@ -333,12 +334,12 @@ class TestS3Gate: bucket_1, bucket_2 = two_buckets - with allure.step(f"Generate {max_obj_count} files"): + with reporter.step(f"Generate {max_obj_count} files"): for _ in range(max_obj_count): file_paths.append(generate_file(choice(obj_sizes).value)) for bucket in (bucket_1, bucket_2): - with allure.step(f"Bucket {bucket} must be empty as it just created"): + with reporter.step(f"Bucket {bucket} must be empty as it just created"): objects_list = s3_client.list_objects_v2(bucket) assert not objects_list, f"Expected empty bucket, got {objects_list}" @@ -346,18 +347,18 @@ class TestS3Gate: s3_client.put_object(bucket, file_path) put_objects.append(s3_helper.object_key_from_file_path(file_path)) - with allure.step(f"Check all objects put in bucket {bucket} successfully"): + with reporter.step(f"Check all objects put in bucket {bucket} successfully"): bucket_objects = s3_client.list_objects_v2(bucket) assert set(put_objects) == set( bucket_objects ), f"Expected all objects {put_objects} in objects list {bucket_objects}" - with allure.step("Delete some objects from bucket_1 one by one"): + with reporter.step("Delete some objects from bucket_1 one by one"): objects_to_delete_b1 = choices(put_objects, k=max_delete_objects) for obj in objects_to_delete_b1: s3_client.delete_object(bucket_1, obj) - with allure.step("Check deleted objects are not visible in bucket bucket_1"): + with reporter.step("Check deleted objects are not visible in bucket bucket_1"): bucket_objects = s3_client.list_objects_v2(bucket_1) assert set(put_objects).difference(set(objects_to_delete_b1)) == set( bucket_objects @@ -366,11 +367,11 @@ class TestS3Gate: with pytest.raises(Exception, match="The specified key does not exist"): s3_client.get_object(bucket_1, object_key) - with allure.step("Delete some objects from bucket_2 at once"): + with reporter.step("Delete some objects from bucket_2 at once"): objects_to_delete_b2 = choices(put_objects, k=max_delete_objects) s3_client.delete_objects(bucket_2, objects_to_delete_b2) - with allure.step("Check deleted objects are not visible in bucket bucket_2"): + with reporter.step("Check deleted objects are not visible in bucket bucket_2"): objects_list = s3_client.list_objects_v2(bucket_2) assert set(put_objects).difference(set(objects_to_delete_b2)) == set( objects_list @@ -397,25 +398,25 @@ class TestS3Gate: file_name_large = s3_helper.object_key_from_file_path(file_path_large) bucket_objects = [file_name_simple, file_name_large] - with allure.step("Bucket must be empty"): + with reporter.step("Bucket must be empty"): objects_list = s3_client.list_objects(bucket) assert not objects_list, f"Expected empty bucket, got {objects_list}" - with allure.step("Put objects into bucket"): + with reporter.step("Put objects into bucket"): for file_path in (file_path_simple, file_path_large): s3_client.put_object(bucket, file_path) - with allure.step("Copy one object into the same bucket"): + with reporter.step("Copy one object into the same bucket"): copy_obj_path = s3_client.copy_object(bucket, file_name_simple) bucket_objects.append(copy_obj_path) s3_helper.check_objects_in_bucket(s3_client, bucket, bucket_objects) - with allure.step("Check copied object has the same content"): + with reporter.step("Check copied object has the same content"): got_copied_file = s3_client.get_object(bucket, copy_obj_path) assert get_file_hash(file_path_simple) == get_file_hash(got_copied_file), "Hashes must be the same" - with allure.step("Delete one object from bucket"): + with reporter.step("Delete one object from bucket"): s3_client.delete_object(bucket, file_name_simple) bucket_objects.remove(file_name_simple) @@ -446,32 +447,32 @@ class TestS3Gate: bucket_1, bucket_2 = two_buckets - with allure.step("Buckets must be empty"): + with reporter.step("Buckets must be empty"): for bucket in (bucket_1, bucket_2): objects_list = s3_client.list_objects(bucket) assert not objects_list, f"Expected empty bucket, got {objects_list}" - with allure.step("Put objects into one bucket"): + with reporter.step("Put objects into one bucket"): for file_path in (file_path_simple, file_path_large): s3_client.put_object(bucket_1, file_path) - with allure.step("Copy object from first bucket into second"): + with reporter.step("Copy object from first bucket into second"): copy_obj_path_b2 = s3_client.copy_object(bucket_1, file_name_large, bucket=bucket_2) s3_helper.check_objects_in_bucket(s3_client, bucket_1, expected_objects=bucket_1_objects) s3_helper.check_objects_in_bucket(s3_client, bucket_2, expected_objects=[copy_obj_path_b2]) - with allure.step("Check copied object has the same content"): + with reporter.step("Check copied object has the same content"): got_copied_file_b2 = s3_client.get_object(bucket_2, copy_obj_path_b2) assert get_file_hash(file_path_large) == get_file_hash(got_copied_file_b2), "Hashes must be the same" - with allure.step("Delete one object from first bucket"): + with reporter.step("Delete one object from first bucket"): s3_client.delete_object(bucket_1, file_name_simple) bucket_1_objects.remove(file_name_simple) s3_helper.check_objects_in_bucket(s3_client, bucket_1, expected_objects=bucket_1_objects) s3_helper.check_objects_in_bucket(s3_client, bucket_2, expected_objects=[copy_obj_path_b2]) - with allure.step("Delete one object from second bucket and check it is empty"): + with reporter.step("Delete one object from second bucket and check it is empty"): s3_client.delete_object(bucket_2, copy_obj_path_b2) s3_helper.check_objects_in_bucket(s3_client, bucket_2, expected_objects=[]) @@ -480,12 +481,12 @@ class TestS3Gate: logger.warning("Attributes check is not supported for boto3 implementation") return - with allure.step("Check object's attributes"): + with reporter.step("Check object's attributes"): obj_parts = s3_client.get_object_attributes(bucket, object_key, ["ObjectParts"], full_output=False) assert obj_parts.get("TotalPartsCount") == parts_count, f"Expected TotalPartsCount is {parts_count}" assert len(obj_parts.get("Parts")) == parts_count, f"Expected Parts cunt is {parts_count}" - with allure.step("Check object's attribute max-parts"): + with reporter.step("Check object's attribute max-parts"): max_parts = 2 obj_parts = s3_client.get_object_attributes( bucket, @@ -498,7 +499,7 @@ class TestS3Gate: assert obj_parts.get("MaxParts") == max_parts, f"Expected MaxParts is {parts_count}" assert len(obj_parts.get("Parts")) == max_parts, f"Expected Parts count is {parts_count}" - with allure.step("Check object's attribute part-number-marker"): + with reporter.step("Check object's attribute part-number-marker"): part_number_marker = 3 obj_parts = s3_client.get_object_attributes( bucket, diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_locking.py b/pytest_tests/testsuites/services/s3_gate/test_s3_locking.py index 9e1857b..907f57b 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_locking.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_locking.py @@ -3,6 +3,7 @@ from datetime import datetime, timedelta import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.s3 import S3ClientWrapper from frostfs_testlib.steps.s3 import s3_helper from frostfs_testlib.storage.dataclasses.object_size import ObjectSize @@ -21,7 +22,7 @@ class TestS3GateLocking: bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=True) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): s3_client.put_object(bucket, file_path) file_name_1 = generate_file_with_content(simple_object_size.value, file_path=file_path) version_id_2 = s3_client.put_object(bucket, file_name_1) @@ -29,7 +30,7 @@ class TestS3GateLocking: if version_id: version_id = version_id_2 - with allure.step(f"Put retention period {retention_period}min to object {file_name}"): + with reporter.step(f"Put retention period {retention_period}min to object {file_name}"): date_obj = datetime.utcnow() + timedelta(minutes=retention_period) retention = { "Mode": "COMPLIANCE", @@ -38,21 +39,21 @@ class TestS3GateLocking: s3_client.put_object_retention(bucket, file_name, retention, version_id) s3_helper.assert_object_lock_mode(s3_client, bucket, file_name, "COMPLIANCE", date_obj, "OFF") - with allure.step(f"Put legal hold to object {file_name}"): + with reporter.step(f"Put legal hold to object {file_name}"): s3_client.put_object_legal_hold(bucket, file_name, "ON", version_id) s3_helper.assert_object_lock_mode(s3_client, bucket, file_name, "COMPLIANCE", date_obj, "ON") - with allure.step("Fail with deleting object with legal hold and retention period"): + with reporter.step("Fail with deleting object with legal hold and retention period"): if version_id: with pytest.raises(Exception): # An error occurred (AccessDenied) when calling the DeleteObject operation (reached max retries: 0): Access Denied. s3_client.delete_object(bucket, file_name, version_id) - with allure.step("Check retention period is no longer set on the uploaded object"): + with reporter.step("Check retention period is no longer set on the uploaded object"): time.sleep((retention_period + 1) * 60) s3_helper.assert_object_lock_mode(s3_client, bucket, file_name, "COMPLIANCE", date_obj, "ON") - with allure.step("Fail with deleting object with legal hold and retention period"): + with reporter.step("Fail with deleting object with legal hold and retention period"): if version_id: with pytest.raises(Exception): # An error occurred (AccessDenied) when calling the DeleteObject operation (reached max retries: 0): Access Denied. @@ -69,13 +70,13 @@ class TestS3GateLocking: bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=True) - with allure.step("Put object into bucket"): + with reporter.step("Put object into bucket"): obj_version = s3_client.put_object(bucket, file_path) if version_id: version_id = obj_version s3_helper.check_objects_in_bucket(s3_client, bucket, [file_name]) - with allure.step(f"Put retention period {retention_period}min to object {file_name}"): + with reporter.step(f"Put retention period {retention_period}min to object {file_name}"): date_obj = datetime.utcnow() + timedelta(minutes=retention_period) retention = { "Mode": "COMPLIANCE", @@ -84,7 +85,7 @@ class TestS3GateLocking: s3_client.put_object_retention(bucket, file_name, retention, version_id) s3_helper.assert_object_lock_mode(s3_client, bucket, file_name, "COMPLIANCE", date_obj, "OFF") - with allure.step(f"Try to change retention period {retention_period_1}min to object {file_name}"): + with reporter.step(f"Try to change retention period {retention_period_1}min to object {file_name}"): date_obj = datetime.utcnow() + timedelta(minutes=retention_period_1) retention = { "Mode": "COMPLIANCE", @@ -103,13 +104,13 @@ class TestS3GateLocking: bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=True) - with allure.step("Put object into bucket"): + with reporter.step("Put object into bucket"): obj_version = s3_client.put_object(bucket, file_path) if version_id: version_id = obj_version s3_helper.check_objects_in_bucket(s3_client, bucket, [file_name]) - with allure.step(f"Put retention period {retention_period}min to object {file_name}"): + with reporter.step(f"Put retention period {retention_period}min to object {file_name}"): date_obj = datetime.utcnow() + timedelta(minutes=retention_period) retention = { "Mode": "GOVERNANCE", @@ -118,7 +119,7 @@ class TestS3GateLocking: s3_client.put_object_retention(bucket, file_name, retention, version_id) s3_helper.assert_object_lock_mode(s3_client, bucket, file_name, "GOVERNANCE", date_obj, "OFF") - with allure.step(f"Try to change retention period {retention_period_1}min to object {file_name}"): + with reporter.step(f"Try to change retention period {retention_period_1}min to object {file_name}"): date_obj = datetime.utcnow() + timedelta(minutes=retention_period_1) retention = { "Mode": "GOVERNANCE", @@ -127,7 +128,7 @@ class TestS3GateLocking: with pytest.raises(Exception): s3_client.put_object_retention(bucket, file_name, retention, version_id) - with allure.step(f"Try to change retention period {retention_period_1}min to object {file_name}"): + with reporter.step(f"Try to change retention period {retention_period_1}min to object {file_name}"): date_obj = datetime.utcnow() + timedelta(minutes=retention_period_1) retention = { "Mode": "GOVERNANCE", @@ -136,7 +137,7 @@ class TestS3GateLocking: with pytest.raises(Exception): s3_client.put_object_retention(bucket, file_name, retention, version_id) - with allure.step(f"Put new retention period {retention_period_2}min to object {file_name}"): + with reporter.step(f"Put new retention period {retention_period_2}min to object {file_name}"): date_obj = datetime.utcnow() + timedelta(minutes=retention_period_2) retention = { "Mode": "GOVERNANCE", @@ -154,13 +155,13 @@ class TestS3GateLocking: bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=False) - with allure.step("Put object into bucket"): + with reporter.step("Put object into bucket"): obj_version = s3_client.put_object(bucket, file_path) if version_id: version_id = obj_version s3_helper.check_objects_in_bucket(s3_client, bucket, [file_name]) - with allure.step(f"Put legal hold to object {file_name}"): + with reporter.step(f"Put legal hold to object {file_name}"): with pytest.raises(Exception): s3_client.put_object_legal_hold(bucket, file_name, "ON", version_id) @@ -175,18 +176,18 @@ class TestS3GateLockingBucket: bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=True) - with allure.step("PutObjectLockConfiguration with ObjectLockEnabled=False"): + with reporter.step("PutObjectLockConfiguration with ObjectLockEnabled=False"): s3_client.put_object_lock_configuration(bucket, configuration) - with allure.step("PutObjectLockConfiguration with ObjectLockEnabled=True"): + with reporter.step("PutObjectLockConfiguration with ObjectLockEnabled=True"): configuration["ObjectLockEnabled"] = "Enabled" s3_client.put_object_lock_configuration(bucket, configuration) - with allure.step("GetObjectLockConfiguration"): + with reporter.step("GetObjectLockConfiguration"): config = s3_client.get_object_lock_configuration(bucket) configuration["Rule"]["DefaultRetention"]["Years"] = 0 assert config == configuration, f"Configurations must be equal {configuration}" - with allure.step("Put object into bucket"): + with reporter.step("Put object into bucket"): s3_client.put_object(bucket, file_path) s3_helper.assert_object_lock_mode(s3_client, bucket, file_name, "COMPLIANCE", None, "OFF", 1) diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_multipart.py b/pytest_tests/testsuites/services/s3_gate/test_s3_multipart.py index 12f1e93..89846a2 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_multipart.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_multipart.py @@ -1,5 +1,6 @@ import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.s3 import S3ClientWrapper, VersioningStatus from frostfs_testlib.steps.cli.container import list_objects, search_container_by_name from frostfs_testlib.steps.s3 import s3_helper @@ -24,7 +25,7 @@ class TestS3GateMultipart(ClusterTestBase): part_files = split_file(file_name_large, parts_count) parts = [] - with allure.step("Upload first part"): + with reporter.step("Upload first part"): upload_id = s3_client.create_multipart_upload(bucket, object_key) uploads = s3_client.list_multipart_uploads(bucket) etag = s3_client.upload_part(bucket, object_key, upload_id, 1, part_files[0]) @@ -32,7 +33,7 @@ class TestS3GateMultipart(ClusterTestBase): got_parts = s3_client.list_parts(bucket, object_key, upload_id) assert len(got_parts) == 1, f"Expected {1} parts, got\n{got_parts}" - with allure.step("Upload last parts"): + with reporter.step("Upload last parts"): for part_id, file_path in enumerate(part_files[1:], start=2): etag = s3_client.upload_part(bucket, object_key, upload_id, part_id, file_path) parts.append((part_id, etag)) @@ -40,11 +41,11 @@ class TestS3GateMultipart(ClusterTestBase): s3_client.complete_multipart_upload(bucket, object_key, upload_id, parts) assert len(got_parts) == len(part_files), f"Expected {parts_count} parts, got\n{got_parts}" - with allure.step("Check upload list is empty"): + with reporter.step("Check upload list is empty"): uploads = s3_client.list_multipart_uploads(bucket) assert not uploads, f"Expected there is no uploads in bucket {bucket}" - with allure.step("Check we can get whole object from bucket"): + with reporter.step("Check we can get whole object from bucket"): got_object = s3_client.get_object(bucket, object_key) assert get_file_hash(got_object) == get_file_hash(file_name_large) @@ -64,36 +65,36 @@ class TestS3GateMultipart(ClusterTestBase): files_count = len(to_upload) upload_key = "multipart_abort" - with allure.step(f"Get related container_id for bucket '{bucket}'"): + with reporter.step(f"Get related container_id for bucket '{bucket}'"): container_id = search_container_by_name( default_wallet, bucket, self.shell, self.cluster.default_rpc_endpoint ) - with allure.step("Create multipart upload"): + with reporter.step("Create multipart upload"): upload_id = s3_client.create_multipart_upload(bucket, upload_key) - with allure.step(f"Upload {files_count} files to multipart upload"): + with reporter.step(f"Upload {files_count} files to multipart upload"): for i, file in enumerate(to_upload, 1): s3_client.upload_part(bucket, upload_key, upload_id, i, file) - with allure.step(f"Check that we have {files_count} files in bucket"): + with reporter.step(f"Check that we have {files_count} files in bucket"): parts = s3_client.list_parts(bucket, upload_key, upload_id) assert len(parts) == files_count, f"Expected {files_count} parts, got\n{parts}" - with allure.step(f"Check that we have {files_count} files in container '{container_id}'"): + with reporter.step(f"Check that we have {files_count} files in container '{container_id}'"): objects = list_objects(default_wallet, self.shell, container_id, self.cluster.default_rpc_endpoint) assert len(objects) == files_count, f"Expected {files_count} objects in container, got\n{objects}" - with allure.step("Abort multipart upload"): + with reporter.step("Abort multipart upload"): s3_client.abort_multipart_upload(bucket, upload_key, upload_id) uploads = s3_client.list_multipart_uploads(bucket) assert not uploads, f"Expected no uploads in bucket {bucket}" - with allure.step("Check that we have no files in bucket since upload was aborted"): + with reporter.step("Check that we have no files in bucket since upload was aborted"): with pytest.raises(Exception, match=self.NO_SUCH_UPLOAD): s3_client.list_parts(bucket, upload_key, upload_id) - with allure.step("Check that we have no files in container since upload was aborted"): + with reporter.step("Check that we have no files in container since upload was aborted"): objects = list_objects(default_wallet, self.shell, container_id, self.cluster.default_rpc_endpoint) assert len(objects) == 0, f"Expected no objects in container, got\n{objects}" @@ -107,27 +108,27 @@ class TestS3GateMultipart(ClusterTestBase): parts = [] objs = [] - with allure.step(f"Put {parts_count} objects in bucket"): + with reporter.step(f"Put {parts_count} objects in bucket"): for part in part_files: s3_client.put_object(bucket, part) objs.append(s3_helper.object_key_from_file_path(part)) s3_helper.check_objects_in_bucket(s3_client, bucket, objs) - with allure.step("Create multipart upload object"): + with reporter.step("Create multipart upload object"): upload_id = s3_client.create_multipart_upload(bucket, object_key) uploads = s3_client.list_multipart_uploads(bucket) assert uploads, f"Expected there are uploads in bucket {bucket}" - with allure.step("Upload parts to multipart upload"): + with reporter.step("Upload parts to multipart upload"): for part_id, obj_key in enumerate(objs, start=1): etag = s3_client.upload_part_copy(bucket, object_key, upload_id, part_id, f"{bucket}/{obj_key}") parts.append((part_id, etag)) got_parts = s3_client.list_parts(bucket, object_key, upload_id) - with allure.step("Complete multipart upload"): + with reporter.step("Complete multipart upload"): s3_client.complete_multipart_upload(bucket, object_key, upload_id, parts) assert len(got_parts) == len(part_files), f"Expected {parts_count} parts, got\n{got_parts}" - with allure.step("Check we can get whole object from bucket"): + with reporter.step("Check we can get whole object from bucket"): got_object = s3_client.get_object(bucket, object_key) assert get_file_hash(got_object) == get_file_hash(file_name_large) diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_object.py b/pytest_tests/testsuites/services/s3_gate/test_s3_object.py index f876ad7..fd475bd 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_object.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_object.py @@ -7,6 +7,7 @@ from typing import Literal import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.common import ASSETS_DIR, DEFAULT_WALLET_PASS from frostfs_testlib.resources.error_patterns import S3_MALFORMED_XML_REQUEST from frostfs_testlib.s3 import AwsCliClient, S3ClientWrapper, VersioningStatus @@ -43,10 +44,10 @@ class TestS3GateObject: objects_list = s3_client.list_objects(bucket_1) assert not objects_list, f"Expected empty bucket, got {objects_list}" - with allure.step("Put object into one bucket"): + with reporter.step("Put object into one bucket"): s3_client.put_object(bucket_1, file_path) - with allure.step("Copy one object into the same bucket"): + with reporter.step("Copy one object into the same bucket"): copy_obj_path = s3_client.copy_object(bucket_1, file_name) bucket_1_objects.append(copy_obj_path) s3_helper.check_objects_in_bucket(s3_client, bucket_1, bucket_1_objects) @@ -54,22 +55,22 @@ class TestS3GateObject: objects_list = s3_client.list_objects(bucket_2) assert not objects_list, f"Expected empty bucket, got {objects_list}" - with allure.step("Copy object from first bucket into second"): + with reporter.step("Copy object from first bucket into second"): copy_obj_path_b2 = s3_client.copy_object(bucket_1, file_name, bucket=bucket_2) s3_helper.check_objects_in_bucket(s3_client, bucket_1, expected_objects=bucket_1_objects) s3_helper.check_objects_in_bucket(s3_client, bucket_2, expected_objects=[copy_obj_path_b2]) - with allure.step("Check copied object has the same content"): + with reporter.step("Check copied object has the same content"): got_copied_file_b2 = s3_client.get_object(bucket_2, copy_obj_path_b2) assert get_file_hash(file_path) == get_file_hash(got_copied_file_b2), "Hashes must be the same" - with allure.step("Delete one object from first bucket"): + with reporter.step("Delete one object from first bucket"): s3_client.delete_object(bucket_1, file_name) bucket_1_objects.remove(file_name) s3_helper.check_objects_in_bucket(s3_client, bucket_1, expected_objects=bucket_1_objects) s3_helper.check_objects_in_bucket(s3_client, bucket_2, expected_objects=[copy_obj_path_b2]) - with allure.step("Copy one object into the same bucket"): + with reporter.step("Copy one object into the same bucket"): with pytest.raises(Exception): s3_client.copy_object(bucket_1, file_name) @@ -87,28 +88,28 @@ class TestS3GateObject: bucket_1, bucket_2 = two_buckets s3_helper.set_bucket_versioning(s3_client, bucket_1, VersioningStatus.ENABLED) - with allure.step("Put object into bucket"): + with reporter.step("Put object into bucket"): s3_client.put_object(bucket_1, file_name_simple) bucket_1_objects = [obj_key] s3_helper.check_objects_in_bucket(s3_client, bucket_1, [obj_key]) - with allure.step("Copy one object into the same bucket"): + with reporter.step("Copy one object into the same bucket"): copy_obj_path = s3_client.copy_object(bucket_1, obj_key) bucket_1_objects.append(copy_obj_path) s3_helper.check_objects_in_bucket(s3_client, bucket_1, bucket_1_objects) s3_helper.set_bucket_versioning(s3_client, bucket_2, VersioningStatus.ENABLED) - with allure.step("Copy object from first bucket into second"): + with reporter.step("Copy object from first bucket into second"): copy_obj_path_b2 = s3_client.copy_object(bucket_1, obj_key, bucket=bucket_2) s3_helper.check_objects_in_bucket(s3_client, bucket_1, expected_objects=bucket_1_objects) s3_helper.check_objects_in_bucket(s3_client, bucket_2, expected_objects=[copy_obj_path_b2]) - with allure.step("Delete one object from first bucket and check object in bucket"): + with reporter.step("Delete one object from first bucket and check object in bucket"): s3_client.delete_object(bucket_1, obj_key) bucket_1_objects.remove(obj_key) s3_helper.check_objects_in_bucket(s3_client, bucket_1, expected_objects=bucket_1_objects) - with allure.step("Copy one object into the same bucket"): + with reporter.step("Copy one object into the same bucket"): with pytest.raises(Exception): s3_client.copy_object(bucket_1, obj_key) @@ -120,11 +121,11 @@ class TestS3GateObject: s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): s3_client.put_object(bucket, file_name_simple) s3_helper.check_objects_in_bucket(s3_client, bucket, [obj_key]) - with allure.step("Copy object and check acl attribute"): + with reporter.step("Copy object and check acl attribute"): copy_obj_path = s3_client.copy_object(bucket, obj_key, acl="public-read-write") obj_acl = s3_client.get_object_acl(bucket, copy_obj_path) s3_helper.assert_s3_acl(acl_grants=obj_acl, permitted_users="CanonicalUser") @@ -138,25 +139,25 @@ class TestS3GateObject: s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put object into bucket"): + with reporter.step("Put object into bucket"): s3_client.put_object(bucket, file_path, metadata=object_metadata) bucket_1_objects = [file_name] s3_helper.check_objects_in_bucket(s3_client, bucket, bucket_1_objects) - with allure.step("Copy one object"): + with reporter.step("Copy one object"): copy_obj_path = s3_client.copy_object(bucket, file_name) bucket_1_objects.append(copy_obj_path) s3_helper.check_objects_in_bucket(s3_client, bucket, bucket_1_objects) obj_head = s3_client.head_object(bucket, copy_obj_path) assert obj_head.get("Metadata") == object_metadata, f"Metadata must be {object_metadata}" - with allure.step("Copy one object with metadata"): + with reporter.step("Copy one object with metadata"): copy_obj_path = s3_client.copy_object(bucket, file_name, metadata_directive="COPY") bucket_1_objects.append(copy_obj_path) obj_head = s3_client.head_object(bucket, copy_obj_path) assert obj_head.get("Metadata") == object_metadata, f"Metadata must be {object_metadata}" - with allure.step("Copy one object with new metadata"): + with reporter.step("Copy one object with new metadata"): object_metadata_1 = {f"{uuid.uuid4()}": f"{uuid.uuid4()}"} copy_obj_path = s3_client.copy_object( bucket, @@ -177,13 +178,13 @@ class TestS3GateObject: s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): s3_client.put_object(bucket, file_path) s3_client.put_object_tagging(bucket, file_name_simple, tags=object_tagging) bucket_1_objects = [file_name_simple] s3_helper.check_objects_in_bucket(s3_client, bucket, bucket_1_objects) - with allure.step("Copy one object without tag"): + with reporter.step("Copy one object without tag"): copy_obj_path = s3_client.copy_object(bucket, file_name_simple) got_tags = s3_client.get_object_tagging(bucket, copy_obj_path) assert got_tags, f"Expected tags, got {got_tags}" @@ -191,7 +192,7 @@ class TestS3GateObject: for tag in expected_tags: assert tag in got_tags, f"Expected tag {tag} in {got_tags}" - with allure.step("Copy one object with tag"): + with reporter.step("Copy one object with tag"): copy_obj_path_1 = s3_client.copy_object(bucket, file_name_simple, tagging_directive="COPY") got_tags = s3_client.get_object_tagging(bucket, copy_obj_path_1) assert got_tags, f"Expected tags, got {got_tags}" @@ -199,7 +200,7 @@ class TestS3GateObject: for tag in expected_tags: assert tag in got_tags, f"Expected tag {tag} in {got_tags}" - with allure.step("Copy one object with new tag"): + with reporter.step("Copy one object with new tag"): tag_key = "tag1" tag_value = uuid.uuid4() new_tag = f"{tag_key}={tag_value}" @@ -230,14 +231,14 @@ class TestS3GateObject: obj_key = os.path.basename(file_name_simple) s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): version_id_1 = s3_client.put_object(bucket, file_name_simple) file_name_1 = generate_file_with_content( simple_object_size.value, file_path=file_name_simple, content=version_2_content ) version_id_2 = s3_client.put_object(bucket, file_name_1) - with allure.step("Check bucket shows all versions"): + with reporter.step("Check bucket shows all versions"): versions = s3_client.list_objects_versions(bucket) obj_versions = {version.get("VersionId") for version in versions if version.get("Key") == obj_key} assert obj_versions == { @@ -245,26 +246,26 @@ class TestS3GateObject: version_id_2, }, f"Object should have versions: {version_id_1, version_id_2}" - with allure.step("Delete 1 version of object"): + with reporter.step("Delete 1 version of object"): delete_obj = s3_client.delete_object(bucket, obj_key, version_id=version_id_1) versions = s3_client.list_objects_versions(bucket) obj_versions = {version.get("VersionId") for version in versions if version.get("Key") == obj_key} assert obj_versions == {version_id_2}, f"Object should have versions: {version_id_2}" assert "DeleteMarker" not in delete_obj.keys(), "Delete markers should not be created" - with allure.step("Delete second version of object"): + with reporter.step("Delete second version of object"): delete_obj = s3_client.delete_object(bucket, obj_key, version_id=version_id_2) versions = s3_client.list_objects_versions(bucket) obj_versions = {version.get("VersionId") for version in versions if version.get("Key") == obj_key} assert not obj_versions, "Expected object not found" assert "DeleteMarker" not in delete_obj.keys(), "Delete markers should not be created" - with allure.step("Put new object into bucket"): + with reporter.step("Put new object into bucket"): file_name_simple = generate_file(complex_object_size.value) obj_key = os.path.basename(file_name_simple) s3_client.put_object(bucket, file_name_simple) - with allure.step("Delete last object"): + with reporter.step("Delete last object"): delete_obj = s3_client.delete_object(bucket, obj_key) versions = s3_client.list_objects_versions(bucket, True) assert versions.get("DeleteMarkers", None), "Expected delete Marker" @@ -281,7 +282,7 @@ class TestS3GateObject: obj_key = os.path.basename(file_name_1) s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): version_id_1 = s3_client.put_object(bucket, file_name_1) file_name_2 = generate_file_with_content( simple_object_size.value, file_path=file_name_1, content=version_2_content @@ -297,18 +298,18 @@ class TestS3GateObject: version_id_4 = s3_client.put_object(bucket, file_name_4) version_ids = {version_id_1, version_id_2, version_id_3, version_id_4} - with allure.step("Check bucket shows all versions"): + with reporter.step("Check bucket shows all versions"): versions = s3_client.list_objects_versions(bucket) obj_versions = {version.get("VersionId") for version in versions if version.get("Key") == obj_key} assert obj_versions == version_ids, f"Object should have versions: {version_ids}" - with allure.step("Delete two objects from bucket one by one"): + with reporter.step("Delete two objects from bucket one by one"): version_to_delete_b1 = sample([version_id_1, version_id_2, version_id_3, version_id_4], k=2) version_to_save = list(set(version_ids) - set(version_to_delete_b1)) for ver in version_to_delete_b1: s3_client.delete_object(bucket, obj_key, ver) - with allure.step("Check bucket shows all versions"): + with reporter.step("Check bucket shows all versions"): versions = s3_client.list_objects_versions(bucket) obj_versions = [version.get("VersionId") for version in versions if version.get("Key") == obj_key] assert obj_versions.sort() == version_to_save.sort(), f"Object should have versions: {version_to_save}" @@ -321,22 +322,22 @@ class TestS3GateObject: obj_key = os.path.basename(file_name_simple) s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): version_id_1 = s3_client.put_object(bucket, file_name_simple) file_name_1 = generate_file_with_content( simple_object_size.value, file_path=file_name_simple, content=version_2_content ) version_id_2 = s3_client.put_object(bucket, file_name_1) - with allure.step("Get first version of object"): + with reporter.step("Get first version of object"): object_1 = s3_client.get_object(bucket, obj_key, version_id_1, full_output=True) assert object_1.get("VersionId") == version_id_1, f"Get object with version {version_id_1}" - with allure.step("Get second version of object"): + with reporter.step("Get second version of object"): object_2 = s3_client.get_object(bucket, obj_key, version_id_2, full_output=True) assert object_2.get("VersionId") == version_id_2, f"Get object with version {version_id_2}" - with allure.step("Get object"): + with reporter.step("Get object"): object_3 = s3_client.get_object(bucket, obj_key, full_output=True) assert object_3.get("VersionId") == version_id_2, f"Get object with version {version_id_2}" @@ -352,12 +353,12 @@ class TestS3GateObject: file_name = s3_helper.object_key_from_file_path(file_path) file_hash = get_file_hash(file_path) s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): version_id_1 = s3_client.put_object(bucket, file_path) file_name_1 = generate_file_with_content(simple_object_size.value, file_path=file_path) version_id_2 = s3_client.put_object(bucket, file_name_1) - with allure.step("Get first version of object"): + with reporter.step("Get first version of object"): object_1_part_1 = s3_client.get_object( bucket, file_name, @@ -385,7 +386,7 @@ class TestS3GateObject: con_file = concat_files([object_1_part_1, object_1_part_2, object_1_part_3]) assert get_file_hash(con_file) == file_hash, "Hashes must be the same" - with allure.step("Get second version of object"): + with reporter.step("Get second version of object"): object_2_part_1 = s3_client.get_object( bucket, file_name, @@ -410,7 +411,7 @@ class TestS3GateObject: con_file_1 = concat_files([object_2_part_1, object_2_part_2, object_2_part_3]) assert get_file_hash(con_file_1) == get_file_hash(file_name_1), "Hashes must be the same" - with allure.step("Get object"): + with reporter.step("Get object"): object_3_part_1 = s3_client.get_object( bucket, file_name, object_range=[0, int(simple_object_size.value / 3)] ) @@ -450,7 +451,7 @@ class TestS3GateObject: objects_in_bucket = [] objects_count = 3 - with allure.step(f"Put {objects_count} into bucket"): + with reporter.step(f"Put {objects_count} into bucket"): for _ in range(objects_count): file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) @@ -459,11 +460,11 @@ class TestS3GateObject: # Extend deletion list to 1001 elements with same keys for test speed objects_to_delete = self.copy_extend_list(objects_in_bucket, 1001) - with allure.step("Send delete request with 1001 objects and expect error"): + with reporter.step("Send delete request with 1001 objects and expect error"): with pytest.raises(Exception, match=S3_MALFORMED_XML_REQUEST): s3_client.delete_objects(bucket, objects_to_delete) - with allure.step("Send delete request with 1000 objects without error"): + with reporter.step("Send delete request with 1000 objects without error"): with expect_not_raises(): s3_client.delete_objects(bucket, objects_to_delete[:1000]) @@ -481,12 +482,12 @@ class TestS3GateObject: file_name = s3_helper.object_key_from_file_path(file_path) s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): version_id_1 = s3_client.put_object(bucket, file_path, metadata=object_metadata) file_name_1 = generate_file_with_content(simple_object_size.value, file_path=file_path) version_id_2 = s3_client.put_object(bucket, file_name_1) - with allure.step("Get head of first version of object"): + with reporter.step("Get head of first version of object"): response = s3_client.head_object(bucket, file_name) assert "LastModified" in response, "Expected LastModified field" assert "ETag" in response, "Expected ETag field" @@ -494,7 +495,7 @@ class TestS3GateObject: assert response.get("VersionId") == version_id_2, f"Expected VersionId is {version_id_2}" assert response.get("ContentLength") != 0, "Expected ContentLength is not zero" - with allure.step("Get head ob first version of object"): + with reporter.step("Get head ob first version of object"): response = s3_client.head_object(bucket, file_name, version_id=version_id_1) assert "LastModified" in response, "Expected LastModified field" assert "ETag" in response, "Expected ETag field" @@ -517,11 +518,11 @@ class TestS3GateObject: file_name_2 = s3_helper.object_key_from_file_path(file_path_2) s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): s3_client.put_object(bucket, file_path_1) s3_client.put_object(bucket, file_path_2) - with allure.step("Get list of object"): + with reporter.step("Get list of object"): if list_type == "v1": list_obj = s3_client.list_objects(bucket) elif list_type == "v2": @@ -531,7 +532,7 @@ class TestS3GateObject: list_obj.sort() == [file_name, file_name_2].sort() ), f"bucket should have object key {file_name, file_name_2}" - with allure.step("Delete object"): + with reporter.step("Delete object"): delete_obj = s3_client.delete_object(bucket, file_name) if list_type == "v1": list_obj_1 = s3_client.list_objects(bucket, full_output=True) @@ -562,7 +563,7 @@ class TestS3GateObject: tag_2 = f"{tag_key_2}={tag_value_2}" s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.SUSPENDED) - with allure.step("Put first object into bucket"): + with reporter.step("Put first object into bucket"): s3_client.put_object(bucket, file_path_1, metadata=object_1_metadata, tagging=tag_1) obj_head = s3_client.head_object(bucket, file_name) assert obj_head.get("Metadata") == object_1_metadata, "Metadata must be the same" @@ -570,7 +571,7 @@ class TestS3GateObject: assert got_tags, f"Expected tags, got {got_tags}" assert got_tags == [{"Key": tag_key_1, "Value": str(tag_value_1)}], "Tags must be the same" - with allure.step("Rewrite file into bucket"): + with reporter.step("Rewrite file into bucket"): file_path_2 = generate_file_with_content(simple_object_size.value, file_path=file_path_1) s3_client.put_object(bucket, file_path_2, metadata=object_2_metadata, tagging=tag_2) obj_head = s3_client.head_object(bucket, file_name) @@ -589,7 +590,7 @@ class TestS3GateObject: tag_value_3 = uuid.uuid4() tag_3 = f"{tag_key_3}={tag_value_3}" - with allure.step("Put third object into bucket"): + with reporter.step("Put third object into bucket"): version_id_1 = s3_client.put_object(bucket, file_path_3, metadata=object_3_metadata, tagging=tag_3) obj_head_3 = s3_client.head_object(bucket, file_name_3) assert obj_head_3.get("Metadata") == object_3_metadata, "Matadata must be the same" @@ -597,7 +598,7 @@ class TestS3GateObject: assert got_tags_3, f"Expected tags, got {got_tags_3}" assert got_tags_3 == [{"Key": tag_key_3, "Value": str(tag_value_3)}], "Tags must be the same" - with allure.step("Put new version of file into bucket"): + with reporter.step("Put new version of file into bucket"): file_path_4 = generate_file_with_content(simple_object_size.value, file_path=file_path_3) version_id_2 = s3_client.put_object(bucket, file_path_4) versions = s3_client.list_objects_versions(bucket) @@ -609,13 +610,13 @@ class TestS3GateObject: got_tags_4 = s3_client.get_object_tagging(bucket, file_name_3) assert not got_tags_4, "No tags expected" - with allure.step("Get object"): + with reporter.step("Get object"): object_3 = s3_client.get_object(bucket, file_name_3, full_output=True) assert object_3.get("VersionId") == version_id_2, f"get object with version {version_id_2}" object_3 = s3_client.get_object(bucket, file_name_3) assert get_file_hash(file_path_4) == get_file_hash(object_3), "Hashes must be the same" - with allure.step("Get first version of object"): + with reporter.step("Get first version of object"): object_4 = s3_client.get_object(bucket, file_name_3, version_id_1, full_output=True) assert object_4.get("VersionId") == version_id_1, f"get object with version {version_id_1}" object_4 = s3_client.get_object(bucket, file_name_3, version_id_1) @@ -645,14 +646,14 @@ class TestS3GateObject: status = VersioningStatus.SUSPENDED s3_helper.set_bucket_versioning(s3_client, bucket, status) - with allure.step("Put object with acl private"): + with reporter.step("Put object with acl private"): s3_client.put_object(bucket, file_path_1, acl="private") obj_acl = s3_client.get_object_acl(bucket, file_name) s3_helper.assert_s3_acl(acl_grants=obj_acl, permitted_users="CanonicalUser") object_1 = s3_client.get_object(bucket, file_name) assert get_file_hash(file_path_1) == get_file_hash(object_1), "Hashes must be the same" - with allure.step("Put object with acl public-read"): + with reporter.step("Put object with acl public-read"): file_path_2 = generate_file_with_content(simple_object_size.value, file_path=file_path_1) s3_client.put_object(bucket, file_path_2, acl="public-read") obj_acl = s3_client.get_object_acl(bucket, file_name) @@ -660,7 +661,7 @@ class TestS3GateObject: object_2 = s3_client.get_object(bucket, file_name) assert get_file_hash(file_path_2) == get_file_hash(object_2), "Hashes must be the same" - with allure.step("Put object with acl public-read-write"): + with reporter.step("Put object with acl public-read-write"): file_path_3 = generate_file_with_content(simple_object_size.value, file_path=file_path_1) s3_client.put_object(bucket, file_path_3, acl="public-read-write") obj_acl = s3_client.get_object_acl(bucket, file_name) @@ -668,7 +669,7 @@ class TestS3GateObject: object_3 = s3_client.get_object(bucket, file_name) assert get_file_hash(file_path_3) == get_file_hash(object_3), "Hashes must be the same" - with allure.step("Put object with acl authenticated-read"): + with reporter.step("Put object with acl authenticated-read"): file_path_4 = generate_file_with_content(simple_object_size.value, file_path=file_path_1) s3_client.put_object(bucket, file_path_4, acl="authenticated-read") obj_acl = s3_client.get_object_acl(bucket, file_name) @@ -679,7 +680,7 @@ class TestS3GateObject: file_path_5 = generate_file(complex_object_size.value) file_name_5 = s3_helper.object_key_from_file_path(file_path_5) - with allure.step("Put object with --grant-full-control id=mycanonicaluserid"): + with reporter.step("Put object with --grant-full-control id=mycanonicaluserid"): generate_file_with_content(simple_object_size.value, file_path=file_path_5) s3_client.put_object( bucket, @@ -691,7 +692,7 @@ class TestS3GateObject: object_5 = s3_client.get_object(bucket, file_name_5) assert get_file_hash(file_path_5) == get_file_hash(object_5), "Hashes must be the same" - with allure.step("Put object with --grant-read uri=http://acs.amazonaws.com/groups/global/AllUsers"): + with reporter.step("Put object with --grant-read uri=http://acs.amazonaws.com/groups/global/AllUsers"): generate_file_with_content(simple_object_size.value, file_path=file_path_5) s3_client.put_object( bucket, @@ -716,7 +717,7 @@ class TestS3GateObject: bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=True) s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put object with lock-mode GOVERNANCE lock-retain-until-date +1day, lock-legal-hold-status"): + with reporter.step("Put object with lock-mode GOVERNANCE lock-retain-until-date +1day, lock-legal-hold-status"): date_obj = datetime.utcnow() + timedelta(days=1) s3_client.put_object( bucket, @@ -727,7 +728,7 @@ class TestS3GateObject: ) s3_helper.assert_object_lock_mode(s3_client, bucket, file_name, "GOVERNANCE", date_obj, "OFF") - with allure.step( + with reporter.step( "Put new version of object with [--object-lock-mode COMPLIANCE] и [--object-lock-retain-until-date +3days]" ): date_obj = datetime.utcnow() + timedelta(days=2) @@ -740,7 +741,7 @@ class TestS3GateObject: ) s3_helper.assert_object_lock_mode(s3_client, bucket, file_name, "COMPLIANCE", date_obj, "OFF") - with allure.step( + with reporter.step( "Put new version of object with [--object-lock-mode COMPLIANCE] и [--object-lock-retain-until-date +2days]" ): date_obj = datetime.utcnow() + timedelta(days=3) @@ -754,7 +755,7 @@ class TestS3GateObject: ) s3_helper.assert_object_lock_mode(s3_client, bucket, file_name, "COMPLIANCE", date_obj, "ON") - with allure.step("Put object with lock-mode"): + with reporter.step("Put object with lock-mode"): with pytest.raises( Exception, match=r".*must both be supplied*", @@ -762,7 +763,7 @@ class TestS3GateObject: # x-amz-object-lock-retain-until-date and x-amz-object-lock-mode must both be supplied s3_client.put_object(bucket, file_path_1, object_lock_mode="COMPLIANCE") - with allure.step("Put object with lock-mode and past date"): + with reporter.step("Put object with lock-mode and past date"): date_obj = datetime.utcnow() - timedelta(days=3) with pytest.raises( Exception, @@ -810,11 +811,11 @@ class TestS3GateObject: metadata=object_metadata, ) - with allure.step("Check objects are synced"): + with reporter.step("Check objects are synced"): objects = s3_client.list_objects(bucket) assert set(key_to_path.keys()) == set(objects), f"Expected all abjects saved. Got {objects}" - with allure.step("Check these are the same objects"): + with reporter.step("Check these are the same objects"): for obj_key in objects: got_object = s3_client.get_object(bucket, obj_key) assert get_file_hash(got_object) == get_file_hash( @@ -841,7 +842,7 @@ class TestS3GateObject: objects_list = s3_client.list_objects(bucket) assert not objects_list, f"Expected empty bucket, got {objects_list}" - with allure.step("Put object"): + with reporter.step("Put object"): s3_client.put_object(bucket, file_path_1) s3_helper.check_objects_in_bucket(s3_client, bucket, [file_name]) @@ -850,12 +851,12 @@ class TestS3GateObject: s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) objects_list = s3_client.list_objects_versions(bucket) - with allure.step("Check that bucket is empty"): + with reporter.step("Check that bucket is empty"): assert not objects_list, f"Expected empty bucket, got {objects_list}" obj_key = "fake_object_key" - with allure.step("Delete non-existing object"): + with reporter.step("Delete non-existing object"): delete_obj = s3_client.delete_object(bucket, obj_key) # there should be no objects or delete markers in the bucket assert "DeleteMarker" not in delete_obj.keys(), "Delete markers should not be created" @@ -866,16 +867,16 @@ class TestS3GateObject: def test_s3_delete_twice(self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize): s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) objects_list = s3_client.list_objects(bucket) - with allure.step("Check that bucket is empty"): + with reporter.step("Check that bucket is empty"): assert not objects_list, f"Expected empty bucket, got {objects_list}" file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) - with allure.step("Put object into one bucket"): + with reporter.step("Put object into one bucket"): s3_client.put_object(bucket, file_path) - with allure.step("Delete the object from the bucket"): + with reporter.step("Delete the object from the bucket"): delete_object = s3_client.delete_object(bucket, file_name) versions = s3_client.list_objects_versions(bucket) @@ -883,7 +884,7 @@ class TestS3GateObject: assert obj_versions, f"Object versions were not found {objects_list}" assert "DeleteMarker" in delete_object.keys(), "Delete markers not found" - with allure.step("Delete the object from the bucket again"): + with reporter.step("Delete the object from the bucket again"): delete_object_2nd_attempt = s3_client.delete_object(bucket, file_name) versions_2nd_attempt = s3_client.list_objects_versions(bucket) diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_policy.py b/pytest_tests/testsuites/services/s3_gate/test_s3_policy.py index 387cdfa..0c1e11e 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_policy.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_policy.py @@ -2,6 +2,7 @@ import os import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.s3 import S3ClientWrapper, VersioningStatus from frostfs_testlib.steps.cli.container import search_container_by_name from frostfs_testlib.steps.s3 import s3_helper @@ -22,7 +23,7 @@ class TestS3GatePolicy(ClusterTestBase): file_path_2 = generate_file(simple_object_size.value) file_name_2 = s3_helper.object_key_from_file_path(file_path_2) - with allure.step("Create two buckets with different bucket configuration"): + with reporter.step("Create two buckets with different bucket configuration"): bucket_1 = s3_client.create_bucket(location_constraint="complex") s3_helper.set_bucket_versioning(s3_client, bucket_1, VersioningStatus.ENABLED) bucket_2 = s3_client.create_bucket(location_constraint="rep-3") @@ -32,24 +33,24 @@ class TestS3GatePolicy(ClusterTestBase): bucket_1 in list_buckets and bucket_2 in list_buckets ), f"Expected two buckets {bucket_1, bucket_2}, got {list_buckets}" - with allure.step("Check head buckets"): + with reporter.step("Check head buckets"): with expect_not_raises(): s3_client.head_bucket(bucket_1) s3_client.head_bucket(bucket_2) - with allure.step("Put objects into buckets"): + with reporter.step("Put objects into buckets"): version_id_1 = s3_client.put_object(bucket_1, file_path_1) version_id_2 = s3_client.put_object(bucket_2, file_path_2) s3_helper.check_objects_in_bucket(s3_client, bucket_1, [file_name_1]) s3_helper.check_objects_in_bucket(s3_client, bucket_2, [file_name_2]) - with allure.step("Check bucket location"): + with reporter.step("Check bucket location"): bucket_loc_1 = s3_client.get_bucket_location(bucket_1) bucket_loc_2 = s3_client.get_bucket_location(bucket_2) assert bucket_loc_1 == "complex" assert bucket_loc_2 == "rep-3" - with allure.step("Check object policy"): + with reporter.step("Check object policy"): cid_1 = search_container_by_name( default_wallet, bucket_1, @@ -81,20 +82,20 @@ class TestS3GatePolicy(ClusterTestBase): @allure.title("Bucket with unexisting location constraint (s3_client={s3_client})") def test_s3_bucket_wrong_location(self, s3_client: S3ClientWrapper): - with allure.step("Create bucket with unenxisting location constraint policy"): + with reporter.step("Create bucket with unenxisting location constraint policy"): with pytest.raises(Exception): s3_client.create_bucket(location_constraint="UNEXISTING LOCATION CONSTRAINT") @allure.title("Bucket policy (s3_client={s3_client})") def test_s3_bucket_policy(self, s3_client: S3ClientWrapper): - with allure.step("Create bucket with default policy"): + with reporter.step("Create bucket with default policy"): bucket = s3_client.create_bucket() s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("GetBucketPolicy"): + with reporter.step("GetBucketPolicy"): s3_client.get_bucket_policy(bucket) - with allure.step("Put new policy"): + with reporter.step("Put new policy"): custom_policy = f"file://{os.getcwd()}/pytest_tests/resources/files/bucket_policy.json" custom_policy = { "Version": "2008-10-17", @@ -111,20 +112,20 @@ class TestS3GatePolicy(ClusterTestBase): } s3_client.put_bucket_policy(bucket, custom_policy) - with allure.step("GetBucketPolicy"): + with reporter.step("GetBucketPolicy"): policy_1 = s3_client.get_bucket_policy(bucket) print(policy_1) @allure.title("Bucket CORS (s3_client={s3_client})") def test_s3_cors(self, s3_client: S3ClientWrapper): - with allure.step("Create bucket without cors"): + with reporter.step("Create bucket without cors"): bucket = s3_client.create_bucket() s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) with pytest.raises(Exception): bucket_cors = s3_client.get_bucket_cors(bucket) - with allure.step("Put bucket cors"): + with reporter.step("Put bucket cors"): cors = { "CORSRules": [ { @@ -146,7 +147,7 @@ class TestS3GatePolicy(ClusterTestBase): bucket_cors = s3_client.get_bucket_cors(bucket) assert bucket_cors == cors.get("CORSRules"), f"Expected CORSRules must be {cors.get('CORSRules')}" - with allure.step("delete bucket cors"): + with reporter.step("delete bucket cors"): s3_client.delete_bucket_cors(bucket) with pytest.raises(Exception): diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_tagging.py b/pytest_tests/testsuites/services/s3_gate/test_s3_tagging.py index fb3f44e..f36ed6e 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_tagging.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_tagging.py @@ -4,6 +4,7 @@ from typing import Tuple import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.s3 import S3ClientWrapper from frostfs_testlib.steps.s3 import s3_helper from frostfs_testlib.storage.dataclasses.object_size import ObjectSize @@ -27,76 +28,76 @@ class TestS3GateTagging: file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) - with allure.step("Put with 3 tags object into bucket"): + with reporter.step("Put with 3 tags object into bucket"): tag_1 = "Tag1=Value1" s3_client.put_object(bucket, file_path, tagging=tag_1) got_tags = s3_client.get_object_tagging(bucket, file_name) assert got_tags, f"Expected tags, got {got_tags}" assert got_tags == [{"Key": "Tag1", "Value": "Value1"}], "Tags must be the same" - with allure.step("Put 10 new tags for object"): + with reporter.step("Put 10 new tags for object"): tags_2 = self.create_tags(10) s3_client.put_object_tagging(bucket, file_name, tags=tags_2) s3_helper.check_tags_by_object(s3_client, bucket, file_name, tags_2, [("Tag1", "Value1")]) - with allure.step("Put 10 extra new tags for object"): + with reporter.step("Put 10 extra new tags for object"): tags_3 = self.create_tags(10) s3_client.put_object_tagging(bucket, file_name, tags=tags_3) s3_helper.check_tags_by_object(s3_client, bucket, file_name, tags_3, tags_2) - with allure.step("Copy one object with tag"): + with reporter.step("Copy one object with tag"): copy_obj_path_1 = s3_client.copy_object(bucket, file_name, tagging_directive="COPY") s3_helper.check_tags_by_object(s3_client, bucket, copy_obj_path_1, tags_3, tags_2) - with allure.step("Put 11 new tags to object and expect an error"): + with reporter.step("Put 11 new tags to object and expect an error"): tags_4 = self.create_tags(11) with pytest.raises(Exception, match=r".*Object tags cannot be greater than 10*"): # An error occurred (BadRequest) when calling the PutObjectTagging operation: Object tags cannot be greater than 10 s3_client.put_object_tagging(bucket, file_name, tags=tags_4) - with allure.step("Put empty tag"): + with reporter.step("Put empty tag"): tags_5 = [] s3_client.put_object_tagging(bucket, file_name, tags=tags_5) s3_helper.check_tags_by_object(s3_client, bucket, file_name, []) - with allure.step("Put 10 object tags"): + with reporter.step("Put 10 object tags"): tags_6 = self.create_tags(10) s3_client.put_object_tagging(bucket, file_name, tags=tags_6) s3_helper.check_tags_by_object(s3_client, bucket, file_name, tags_6) - with allure.step("Delete tags by delete-object-tagging"): + with reporter.step("Delete tags by delete-object-tagging"): s3_client.delete_object_tagging(bucket, file_name) s3_helper.check_tags_by_object(s3_client, bucket, file_name, []) @allure.title("Bucket tagging (s3_client={s3_client})") def test_s3_bucket_tagging(self, s3_client: S3ClientWrapper, bucket: str): - with allure.step("Put 10 bucket tags"): + with reporter.step("Put 10 bucket tags"): tags_1 = self.create_tags(10) s3_client.put_bucket_tagging(bucket, tags_1) s3_helper.check_tags_by_bucket(s3_client, bucket, tags_1) - with allure.step("Put new 10 bucket tags"): + with reporter.step("Put new 10 bucket tags"): tags_2 = self.create_tags(10) s3_client.put_bucket_tagging(bucket, tags_2) s3_helper.check_tags_by_bucket(s3_client, bucket, tags_2, tags_1) - with allure.step("Put 11 new tags to bucket and expect an error"): + with reporter.step("Put 11 new tags to bucket and expect an error"): tags_3 = self.create_tags(11) with pytest.raises(Exception, match=r".*Object tags cannot be greater than 10.*"): # An error occurred (BadRequest) when calling the PutBucketTagging operation (reached max retries: 0): Object tags cannot be greater than 10 s3_client.put_bucket_tagging(bucket, tags_3) - with allure.step("Put empty tag"): + with reporter.step("Put empty tag"): tags_4 = [] s3_client.put_bucket_tagging(bucket, tags_4) s3_helper.check_tags_by_bucket(s3_client, bucket, tags_4) - with allure.step("Put new 10 bucket tags"): + with reporter.step("Put new 10 bucket tags"): tags_5 = self.create_tags(10) s3_client.put_bucket_tagging(bucket, tags_5) s3_helper.check_tags_by_bucket(s3_client, bucket, tags_5, tags_2) - with allure.step("Delete tags by delete-bucket-tagging"): + with reporter.step("Delete tags by delete-bucket-tagging"): s3_client.delete_bucket_tagging(bucket) s3_helper.check_tags_by_bucket(s3_client, bucket, []) diff --git a/pytest_tests/testsuites/services/s3_gate/test_s3_versioning.py b/pytest_tests/testsuites/services/s3_gate/test_s3_versioning.py index 57fc3c0..df450d8 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_versioning.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_versioning.py @@ -1,5 +1,6 @@ import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.s3 import S3ClientWrapper, VersioningStatus from frostfs_testlib.steps.s3 import s3_helper from frostfs_testlib.storage.dataclasses.object_size import ObjectSize @@ -23,7 +24,7 @@ class TestS3GateVersioning: bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=False) s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.SUSPENDED) - with allure.step("Put object into bucket"): + with reporter.step("Put object into bucket"): s3_client.put_object(bucket, file_path) objects_list = s3_client.list_objects(bucket) assert objects_list == bucket_objects, f"Expected list with single objects in bucket, got {objects_list}" @@ -37,26 +38,26 @@ class TestS3GateVersioning: s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) - with allure.step("Put several versions of object into bucket"): + with reporter.step("Put several versions of object into bucket"): version_id_1 = s3_client.put_object(bucket, file_path) file_name_1 = generate_file_with_content(simple_object_size.value, file_path=file_path) version_id_2 = s3_client.put_object(bucket, file_name_1) - with allure.step("Check bucket shows all versions"): + with reporter.step("Check bucket shows all versions"): versions = s3_client.list_objects_versions(bucket) obj_versions = [version.get("VersionId") for version in versions if version.get("Key") == file_name] assert ( obj_versions.sort() == [version_id_1, version_id_2, "null"].sort() ), f"Expected object has versions: {version_id_1, version_id_2, 'null'}" - with allure.step("Get object"): + with reporter.step("Get object"): object_1 = s3_client.get_object(bucket, file_name, full_output=True) assert object_1.get("VersionId") == version_id_2, f"Get object with version {version_id_2}" - with allure.step("Get first version of object"): + with reporter.step("Get first version of object"): object_2 = s3_client.get_object(bucket, file_name, version_id_1, full_output=True) assert object_2.get("VersionId") == version_id_1, f"Get object with version {version_id_1}" - with allure.step("Get second version of object"): + with reporter.step("Get second version of object"): object_3 = s3_client.get_object(bucket, file_name, version_id_2, full_output=True) assert object_3.get("VersionId") == version_id_2, f"Get object with version {version_id_2}" diff --git a/pytest_tests/testsuites/services/test_binaries.py b/pytest_tests/testsuites/services/test_binaries.py index cf12f99..3ff6072 100644 --- a/pytest_tests/testsuites/services/test_binaries.py +++ b/pytest_tests/testsuites/services/test_binaries.py @@ -6,6 +6,7 @@ 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 @@ -21,7 +22,7 @@ def test_binaries_versions(request: FixtureRequest, hosting: Hosting): """ Compare binaries versions from external source (url) and deployed on servers. """ - with allure.step("Get binaries versions from servers"): + with reporter.step("Get binaries versions from servers"): got_versions = get_remote_binaries_versions(hosting) environment_dir = request.config.getoption("--alluredir") or ASSETS_DIR @@ -52,7 +53,7 @@ def test_binaries_versions(request: FixtureRequest, hosting: Hosting): raise AssertionError(f"Found binaries with unexpected versions:\n{msg}") -@allure.step("Download versions info from {url}") +@reporter.step("Download versions info from {url}") def download_versions_info(url: str) -> dict: binaries_to_version = {} diff --git a/pytest_tests/testsuites/session_token/test_object_session_token.py b/pytest_tests/testsuites/session_token/test_object_session_token.py index db32033..c49a0a8 100644 --- a/pytest_tests/testsuites/session_token/test_object_session_token.py +++ b/pytest_tests/testsuites/session_token/test_object_session_token.py @@ -2,6 +2,7 @@ import random import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.common import DEFAULT_WALLET_PASS from frostfs_testlib.resources.error_patterns import SESSION_NOT_FOUND from frostfs_testlib.steps.cli.container import create_container @@ -31,16 +32,14 @@ class TestDynamicObjectSession(ClusterTestBase): with a session token """ - with allure.step("Init wallet"): + with reporter.step("Init wallet"): wallet = default_wallet address = wallet_utils.get_last_address_from_wallet(wallet, "") - with allure.step("Nodes Settlements"): - session_token_node, container_node, non_container_node = random.sample( - self.cluster.storage_nodes, 3 - ) + with reporter.step("Nodes Settlements"): + session_token_node, container_node, non_container_node = random.sample(self.cluster.storage_nodes, 3) - with allure.step("Create Session Token"): + with reporter.step("Create Session Token"): session_token = create_session_token( shell=self.shell, owner=address, @@ -49,7 +48,7 @@ class TestDynamicObjectSession(ClusterTestBase): rpc_endpoint=session_token_node.get_rpc_endpoint(), ) - with allure.step("Create Private Container"): + with reporter.step("Create Private Container"): un_locode = container_node.get_un_locode() locode = "SPB" if un_locode == "RU LED" else un_locode.split()[1] placement_policy = ( @@ -64,7 +63,7 @@ class TestDynamicObjectSession(ClusterTestBase): rule=placement_policy, ) - with allure.step("Put Objects"): + with reporter.step("Put Objects"): file_path = generate_file(object_size.value) oid = put_object_to_random_node( wallet=wallet, @@ -81,7 +80,7 @@ class TestDynamicObjectSession(ClusterTestBase): cluster=self.cluster, ) - with allure.step("Node not in container but granted a session token"): + with reporter.step("Node not in container but granted a session token"): put_object( wallet=wallet, path=file_path, @@ -99,7 +98,7 @@ class TestDynamicObjectSession(ClusterTestBase): session=session_token, ) - with allure.step("Node in container and not granted a session token"): + with reporter.step("Node in container and not granted a session token"): with pytest.raises(Exception, match=SESSION_NOT_FOUND): put_object( wallet=wallet, @@ -119,7 +118,7 @@ class TestDynamicObjectSession(ClusterTestBase): session=session_token, ) - with allure.step("Node not in container and not granted a session token"): + with reporter.step("Node not in container and not granted a session token"): with pytest.raises(Exception, match=SESSION_NOT_FOUND): put_object( wallet=wallet, diff --git a/pytest_tests/testsuites/session_token/test_static_object_session_token.py b/pytest_tests/testsuites/session_token/test_static_object_session_token.py index 019502b..7c8e2ac 100644 --- a/pytest_tests/testsuites/session_token/test_static_object_session_token.py +++ b/pytest_tests/testsuites/session_token/test_static_object_session_token.py @@ -2,6 +2,7 @@ import logging import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.error_patterns import ( EXPIRED_SESSION_TOKEN, MALFORMED_REQUEST, @@ -69,7 +70,7 @@ def storage_objects( file_path = generate_file(object_size.value) storage_objects = [] - with allure.step("Put objects"): + with reporter.step("Put objects"): # upload couple objects for _ in range(3): storage_object_id = put_object_to_random_node( @@ -92,7 +93,7 @@ def storage_objects( delete_objects(storage_objects, client_shell, cluster) -@allure.step("Get ranges for test") +@reporter.step("Get ranges for test") def get_ranges(storage_object: StorageObjectInfo, max_object_size: int, shell: Shell, endpoint: str) -> list[str]: """ Returns ranges to test range/hash methods via static session @@ -192,7 +193,7 @@ class TestObjectStaticSession(ClusterTestBase): ranges_to_test = get_ranges(storage_object, max_object_size, self.shell, self.cluster.default_rpc_endpoint) for range_to_test in ranges_to_test: - with allure.step(f"Check range {range_to_test}"): + with reporter.step(f"Check range {range_to_test}"): with expect_not_raises(): method_under_test( user_wallet.path, @@ -432,7 +433,7 @@ class TestObjectStaticSession(ClusterTestBase): object_id = storage_objects[0].oid expiration = Lifetime(epoch + 1, epoch, epoch) - with allure.step("Create session token"): + with reporter.step("Create session token"): token_expire_at_next_epoch = get_object_signed_token( owner_wallet, user_wallet, @@ -444,7 +445,7 @@ class TestObjectStaticSession(ClusterTestBase): expiration, ) - with allure.step("Object should be available with session token after token creation"): + with reporter.step("Object should be available with session token after token creation"): with expect_not_raises(): head_object( user_wallet.path, @@ -455,7 +456,7 @@ class TestObjectStaticSession(ClusterTestBase): session=token_expire_at_next_epoch, ) - with allure.step("Object should be available at last epoch before session token expiration"): + with reporter.step("Object should be available at last epoch before session token expiration"): self.tick_epoch() with expect_not_raises(): head_object( @@ -467,7 +468,7 @@ class TestObjectStaticSession(ClusterTestBase): session=token_expire_at_next_epoch, ) - with allure.step("Object should NOT be available after session token expiration epoch"): + with reporter.step("Object should NOT be available after session token expiration epoch"): self.tick_epoch() with pytest.raises(Exception, match=EXPIRED_SESSION_TOKEN): head_object( @@ -498,7 +499,7 @@ class TestObjectStaticSession(ClusterTestBase): object_id = storage_objects[0].oid expiration = Lifetime(epoch + 2, epoch + 1, epoch) - with allure.step("Create session token"): + with reporter.step("Create session token"): token_start_at_next_epoch = get_object_signed_token( owner_wallet, user_wallet, @@ -510,7 +511,7 @@ class TestObjectStaticSession(ClusterTestBase): expiration, ) - with allure.step("Object should NOT be available with session token after token creation"): + with reporter.step("Object should NOT be available with session token after token creation"): with pytest.raises(Exception, match=MALFORMED_REQUEST): head_object( user_wallet.path, @@ -521,7 +522,7 @@ class TestObjectStaticSession(ClusterTestBase): session=token_start_at_next_epoch, ) - with allure.step("Object should be available with session token starting from token nbf epoch"): + with reporter.step("Object should be available with session token starting from token nbf epoch"): self.tick_epoch() with expect_not_raises(): head_object( @@ -533,7 +534,7 @@ class TestObjectStaticSession(ClusterTestBase): session=token_start_at_next_epoch, ) - with allure.step("Object should be available at last epoch before session token expiration"): + with reporter.step("Object should be available at last epoch before session token expiration"): self.tick_epoch() with expect_not_raises(): head_object( @@ -545,7 +546,7 @@ class TestObjectStaticSession(ClusterTestBase): session=token_start_at_next_epoch, ) - with allure.step("Object should NOT be available after session token expiration epoch"): + with reporter.step("Object should NOT be available after session token expiration epoch"): self.tick_epoch() with pytest.raises(Exception, match=EXPIRED_SESSION_TOKEN): head_object( diff --git a/pytest_tests/testsuites/session_token/test_static_session_token_container.py b/pytest_tests/testsuites/session_token/test_static_session_token_container.py index 58a27d5..c6cc259 100644 --- a/pytest_tests/testsuites/session_token/test_static_session_token_container.py +++ b/pytest_tests/testsuites/session_token/test_static_session_token_container.py @@ -1,5 +1,5 @@ -import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL from frostfs_testlib.shell import Shell from frostfs_testlib.steps.acl import create_eacl, set_eacl, wait_for_cache_expired @@ -41,7 +41,7 @@ class TestSessionTokenContainer(ClusterTestBase): """ Validate static session with create operation """ - with allure.step("Create container with static session token"): + with reporter.step("Create container with static session token"): cid = create_container( user_wallet.path, session_token=static_sessions[ContainerVerb.CREATE], @@ -68,7 +68,7 @@ class TestSessionTokenContainer(ClusterTestBase): """ Validate static session without create operation """ - with allure.step("Try create container with static session token without PUT rule"): + with reporter.step("Try create container with static session token without PUT rule"): for verb in [verb for verb in ContainerVerb if verb != ContainerVerb.CREATE]: with pytest.raises(Exception): create_container( @@ -87,7 +87,7 @@ class TestSessionTokenContainer(ClusterTestBase): """ Validate static session with create operation for other wallet """ - with allure.step("Try create container with static session token without PUT rule"): + with reporter.step("Try create container with static session token without PUT rule"): with pytest.raises(Exception): create_container( stranger_wallet.path, @@ -106,14 +106,14 @@ class TestSessionTokenContainer(ClusterTestBase): """ Validate static session with delete operation """ - with allure.step("Create container"): + with reporter.step("Create container"): cid = create_container( owner_wallet.path, shell=self.shell, endpoint=self.cluster.default_rpc_endpoint, wait_for_creation=False, ) - with allure.step("Delete container with static session token"): + with reporter.step("Delete container with static session token"): delete_container( wallet=user_wallet.path, cid=cid, @@ -139,7 +139,7 @@ class TestSessionTokenContainer(ClusterTestBase): """ Validate static session with set eacl operation """ - with allure.step("Create container"): + with reporter.step("Create container"): cid = create_container( owner_wallet.path, basic_acl=PUBLIC_ACL, @@ -149,7 +149,7 @@ class TestSessionTokenContainer(ClusterTestBase): file_path = generate_file(simple_object_size.value) assert can_put_object(stranger_wallet.path, cid, file_path, self.shell, self.cluster) - with allure.step("Deny all operations for other via eACL"): + with reporter.step("Deny all operations for other via eACL"): eacl_deny = [EACLRule(access=EACLAccess.DENY, role=EACLRole.OTHERS, operation=op) for op in EACLOperation] set_eacl( user_wallet.path, diff --git a/pytest_tests/testsuites/special/test_logs.py b/pytest_tests/testsuites/special/test_logs.py index f83cb51..fd3a37a 100644 --- a/pytest_tests/testsuites/special/test_logs.py +++ b/pytest_tests/testsuites/special/test_logs.py @@ -4,6 +4,7 @@ from datetime import datetime import allure import pytest +from frostfs_testlib import reporter from frostfs_testlib.hosting import Host from frostfs_testlib.testing.cluster_test_base import Cluster from frostfs_testlib.testing.parallel import parallel @@ -51,7 +52,7 @@ class TestLogs: ), f"The following hosts contains contain critical errors in system logs: {', '.join(hosts_with_problems)}" def _collect_logs_on_host(self, host: Host, logs_dir: str, regex: str, since: datetime, until: datetime): - with allure.step(f"Get logs from {host.config.address}"): + with reporter.step(f"Get logs from {host.config.address}"): logs = host.get_filtered_logs(regex, since, until) if not logs: @@ -66,4 +67,4 @@ class TestLogs: # Zip all files and attach to Allure because it is more convenient to download a single # zip with all logs rather than mess with individual logs files per service or node logs_zip_file_path = shutil.make_archive(logs_dir, "zip", logs_dir) - allure.attach.file(logs_zip_file_path, name="logs.zip", extension="zip") + reporter.attach(logs_zip_file_path, "logs.zip")