diff --git a/pytest_tests/testsuites/acl/test_bearer.py b/pytest_tests/testsuites/acl/test_bearer.py index 726a41b..d16b752 100644 --- a/pytest_tests/testsuites/acl/test_bearer.py +++ b/pytest_tests/testsuites/acl/test_bearer.py @@ -21,6 +21,7 @@ from pytest_tests.testsuites.acl.conftest import Wallets @pytest.mark.acl @pytest.mark.acl_bearer class TestACLBearer(ClusterTestBase): + @allure.title("Validate FrostFS operations with {role.value} BearerToken") @pytest.mark.parametrize("role", [EACLRole.USER, EACLRole.OTHERS]) def test_bearer_token_operations( self, @@ -28,9 +29,6 @@ class TestACLBearer(ClusterTestBase): eacl_container_with_objects: tuple[str, list[str], str], role: EACLRole, ): - allure.dynamic.title( - f"Testcase to validate FrostFS operations with {role.value} BearerToken" - ) cid, objects_oids, file_path = eacl_container_with_objects user_wallet = wallets.get_wallet() deny_wallet = wallets.get_wallet(role) diff --git a/pytest_tests/testsuites/acl/test_eacl.py b/pytest_tests/testsuites/acl/test_eacl.py index 26e8834..c56eafa 100644 --- a/pytest_tests/testsuites/acl/test_eacl.py +++ b/pytest_tests/testsuites/acl/test_eacl.py @@ -58,6 +58,7 @@ class TestEACLContainer(ClusterTestBase): yield cid, oid, file_path + @allure.title("Deny FrostFS operations for {deny_role.value}") @pytest.mark.parametrize("deny_role", [EACLRole.USER, EACLRole.OTHERS]) def test_extended_acl_deny_all_operations( self, @@ -71,7 +72,6 @@ class TestEACLContainer(ClusterTestBase): not_deny_role_wallet = user_wallet if deny_role == EACLRole.OTHERS else other_wallet deny_role_str = "all others" if deny_role == EACLRole.OTHERS else "user" not_deny_role_str = "user" if deny_role == EACLRole.OTHERS else "all others" - allure.dynamic.title(f"Testcase to deny FrostFS operations for {deny_role_str}.") cid, object_oids, file_path = eacl_container_with_objects with allure.step(f"Deny all operations for {deny_role_str} via eACL"): @@ -145,7 +145,7 @@ class TestEACLContainer(ClusterTestBase): cluster=self.cluster, ) - @allure.title("Testcase to allow FrostFS operations for only one other pubkey.") + @allure.title("Allow FrostFS operations for only one other pubkey") def test_extended_acl_deny_all_operations_exclude_pubkey( self, wallets: Wallets, eacl_container_with_objects: tuple[str, list[str], str] ): @@ -206,7 +206,7 @@ class TestEACLContainer(ClusterTestBase): cluster=self.cluster, ) - @allure.title("Testcase to validate FrostFS replication with eACL deny rules.") + @allure.title("Replication with eACL deny rules") def test_extended_acl_deny_replication( self, wallets: Wallets, @@ -248,7 +248,7 @@ class TestEACLContainer(ClusterTestBase): storage_nodes, ) - @allure.title("Testcase to validate FrostFS system operations with extended ACL") + @allure.title("System operations with extended ACL") def test_extended_actions_system( self, wallets: Wallets, eacl_container_with_objects: tuple[str, list[str], str] ): diff --git a/pytest_tests/testsuites/acl/test_eacl_filters.py b/pytest_tests/testsuites/acl/test_eacl_filters.py index d4faf39..99a1091 100644 --- a/pytest_tests/testsuites/acl/test_eacl_filters.py +++ b/pytest_tests/testsuites/acl/test_eacl_filters.py @@ -128,6 +128,7 @@ class TestEACLFilters(ClusterTestBase): endpoint=self.cluster.default_rpc_endpoint, ) + @allure.title("Validate FrostFS operations with request filter: {match_type}") @pytest.mark.parametrize( "match_type", [EACLMatchType.STRING_EQUAL, EACLMatchType.STRING_NOT_EQUAL] ) @@ -137,7 +138,6 @@ class TestEACLFilters(ClusterTestBase): eacl_container_with_objects: tuple[str, list[str], str], match_type: EACLMatchType, ): - allure.dynamic.title(f"Validate FrostFS operations with request filter: {match_type.name}") user_wallet = wallets.get_wallet() other_wallet = wallets.get_wallet(EACLRole.OTHERS) ( @@ -245,6 +245,7 @@ class TestEACLFilters(ClusterTestBase): bearer=bearer_other, ) + @allure.title("Validate FrostFS operations with deny user headers filter: {match_type}") @pytest.mark.parametrize( "match_type", [EACLMatchType.STRING_EQUAL, EACLMatchType.STRING_NOT_EQUAL] ) @@ -254,9 +255,6 @@ class TestEACLFilters(ClusterTestBase): eacl_container_with_objects: tuple[str, list[str], str], match_type: EACLMatchType, ): - allure.dynamic.title( - f"Validate FrostFS operations with deny user headers filter: {match_type.name}" - ) user_wallet = wallets.get_wallet() other_wallet = wallets.get_wallet(EACLRole.OTHERS) ( @@ -430,6 +428,7 @@ class TestEACLFilters(ClusterTestBase): bearer=bearer_other_for_put, ) + @allure.title("Validate FrostFS operation with allow eACL user headers filters: {match_type}") @pytest.mark.parametrize( "match_type", [EACLMatchType.STRING_EQUAL, EACLMatchType.STRING_NOT_EQUAL] ) @@ -439,10 +438,6 @@ class TestEACLFilters(ClusterTestBase): eacl_container_with_objects: tuple[str, list[str], str], match_type: EACLMatchType, ): - allure.dynamic.title( - "Testcase to validate FrostFS operation with allow eACL user headers filters:" - f"{match_type.name}" - ) user_wallet = wallets.get_wallet() other_wallet = wallets.get_wallet(EACLRole.OTHERS) ( diff --git a/pytest_tests/testsuites/failovers/test_failover_storage.py b/pytest_tests/testsuites/failovers/test_failover_storage.py index c378321..5807f51 100644 --- a/pytest_tests/testsuites/failovers/test_failover_storage.py +++ b/pytest_tests/testsuites/failovers/test_failover_storage.py @@ -97,7 +97,7 @@ def return_stopped_hosts(shell: Shell, cluster: Cluster) -> None: @pytest.mark.failover class TestFailoverStorage(ClusterTestBase): - @allure.title("Lose and return storage node's host") + @allure.title("Lose and return storage node's host ({stop_mode} stop)") @pytest.mark.parametrize("stop_mode", ["hard", "soft"]) @pytest.mark.failover_reboot def test_lose_storage_node_host( @@ -157,7 +157,7 @@ class TestFailoverStorage(ClusterTestBase): ) assert get_file_hash(source_file_path) == get_file_hash(got_file_path) - @allure.title("Panic storage node's host") + @allure.title("Panic storage node's host (sequenced_reboots={sequence})") @pytest.mark.parametrize("sequence", [True, False]) @pytest.mark.failover_panic def test_panic_storage_node_host( @@ -229,7 +229,7 @@ class TestFailoverStorage(ClusterTestBase): ) assert get_file_hash(source_file_path) == get_file_hash(got_file_path) - @allure.title("Do not ignore unhealthy tree endpoints") + @allure.title("{s3_client}: Do not ignore unhealthy tree endpoints") def test_unhealthy_tree( self, s3_client: S3ClientWrapper, @@ -294,7 +294,7 @@ class TestEmptyMap(ClusterTestBase): @test_case.suite_name("failovers") @test_case.suite_section("test_failover_storage") @pytest.mark.failover_empty_map_offlne - @allure.title("Test makes network map empty (offline all storage nodes)") + @allure.title("{s3_client}: empty network map (offline all storage nodes)") def test_offline_all_storage_nodes( self, s3_client: S3ClientWrapper, @@ -364,7 +364,7 @@ class TestEmptyMap(ClusterTestBase): @test_case.suite_name("failovers") @test_case.suite_section("test_failover_storage") @pytest.mark.failover_empty_map_stop_service - @allure.title("Test makes network map empty (stop storage service on all nodes)") + @allure.title("{s3_client}: empty network map (stop storage service on all nodes)") def test_stop_all_storage_nodes( self, s3_client: S3ClientWrapper, @@ -439,7 +439,7 @@ class TestEmptyMap(ClusterTestBase): check_node_in_map(node, shell=self.shell, alive_node=node) stopped_nodes.remove(node) - @allure.title("Test S3 Object loss from fstree/blobovnicza, versioning is enabled") + @allure.title("{s3_client}: Object loss from fstree/blobovnicza, versioning is enabled") def test_s3_fstree_blobovnicza_loss_versioning_on( self, s3_client: S3ClientWrapper, @@ -484,7 +484,7 @@ class TestEmptyMap(ClusterTestBase): with allure.step("Delete bucket"): s3_client.delete_bucket(bucket) - @allure.title("Test S3 Object loss from fstree/blobovnicza, versioning is disabled") + @allure.title("{s3_client}: Object loss from fstree/blobovnicza, versioning is disabled") def test_s3_fstree_blobovnicza_loss_versioning_off( self, s3_client: S3ClientWrapper, @@ -523,10 +523,10 @@ class TestEmptyMap(ClusterTestBase): @pytest.mark.parametrize( # versioning should NOT be VersioningStatus.SUSPENDED, it needs to be undefined "versioning_status", - [VersioningStatus.ENABLED, None], + [VersioningStatus.ENABLED, VersioningStatus.UNDEFINED], ) @allure.title( - "After Pilorama.db loss on all nodes list objects should return nothing in second listing" + "{s3_client}: After Pilorama.db loss on all nodes list objects should return nothing in second listing (versioning_status {versioning_status})" ) def test_s3_pilorama_loss( self, @@ -536,8 +536,7 @@ class TestEmptyMap(ClusterTestBase): cluster_state_controller: ClusterStateController, ): bucket = s3_client.create_bucket() - if versioning_status: - s3_helper.set_bucket_versioning(s3_client, bucket, versioning_status) + s3_helper.set_bucket_versioning(s3_client, bucket, versioning_status) file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) @@ -585,7 +584,7 @@ class TestStorageDataLoss(ClusterTestBase): return piloramas @allure.title( - "After metabase loss on all nodes operations on objects and buckets should be still available via S3" + "{s3_client}: After metabase loss on all nodes operations on objects and buckets should be still available via S3" ) @pytest.mark.metabase_loss def test_metabase_loss( @@ -738,7 +737,7 @@ class TestStorageDataLoss(ClusterTestBase): assert not exception_messages, "\n".join(exception_messages) @allure.title( - "Test S3 Loss of one node should trigger use of tree and storage service in another node" + "{s3_client}: Loss of one node should trigger use of tree and storage service in another node" ) def test_s3_one_endpoint_loss( self, @@ -764,7 +763,7 @@ class TestStorageDataLoss(ClusterTestBase): put_object = s3_client.put_object(bucket, file_path) s3_helper.check_objects_in_bucket(s3_client, bucket, expected_objects=[file_name]) - @allure.title("After Pilorama.db loss on one node object are retrievable") + @allure.title("{s3_client}: After Pilorama.db loss on one node object are retrievable") def test_s3_one_pilorama_loss( self, s3_client: S3ClientWrapper, diff --git a/pytest_tests/testsuites/network/test_node_management.py b/pytest_tests/testsuites/network/test_node_management.py index 97a8f1e..844bd9c 100644 --- a/pytest_tests/testsuites/network/test_node_management.py +++ b/pytest_tests/testsuites/network/test_node_management.py @@ -225,7 +225,7 @@ class TestNodeManagement(ClusterTestBase): ], ) @pytest.mark.node_mgmt - @allure.title("Test object copies based on placement policy") + @allure.title("Object should have {expected_copies} copies with policy {placement_rule}") def test_placement_policy( self, default_wallet, placement_rule, expected_copies, simple_object_size: ObjectSize ): @@ -286,7 +286,9 @@ class TestNodeManagement(ClusterTestBase): ], ) @pytest.mark.node_mgmt - @allure.title("Test object copies and storage nodes based on placement policy") + @allure.title( + "Object should have copies on nodes {expected_nodes_id} with policy {placement_rule}" + ) def test_placement_policy_with_nodes( self, default_wallet, @@ -316,7 +318,7 @@ class TestNodeManagement(ClusterTestBase): ], ) @pytest.mark.node_mgmt - @allure.title("Negative cases for placement policy") + @allure.title("[NEGATIVE] Placement policy: {placement_rule}") def test_placement_policy_negative( self, default_wallet, placement_rule, expected_copies, simple_object_size: ObjectSize ): diff --git a/pytest_tests/testsuites/object/test_object_api.py b/pytest_tests/testsuites/object/test_object_api.py index aefafae..16e9f7f 100755 --- a/pytest_tests/testsuites/object/test_object_api.py +++ b/pytest_tests/testsuites/object/test_object_api.py @@ -138,7 +138,7 @@ def storage_objects( @pytest.mark.sanity @pytest.mark.grpc_api class TestObjectApi(ClusterTestBase): - @allure.title("Validate object storage policy by native API") + @allure.title("Validate object storage policy by native API for {storage_objects}") def test_object_storage_policies( self, request: FixtureRequest, @@ -172,7 +172,7 @@ class TestObjectApi(ClusterTestBase): ) assert copies == 2, "Expected 2 copies" - @allure.title("Validate get object native API") + @allure.title("Validate get object native API for {storage_objects}") def test_get_object_api( self, request: FixtureRequest, storage_objects: list[StorageObjectInfo] ): @@ -193,7 +193,7 @@ class TestObjectApi(ClusterTestBase): file_hash = get_file_hash(file_path) assert storage_object.file_hash == file_hash - @allure.title("Validate head object native API") + @allure.title("Validate head object native API for {storage_objects}") def test_head_object_api( self, request: FixtureRequest, storage_objects: list[StorageObjectInfo] ): @@ -222,7 +222,7 @@ class TestObjectApi(ClusterTestBase): ) self.check_header_is_presented(head_info, storage_object_2.attributes) - @allure.title("Validate object search by native API") + @allure.title("Validate object search by native API for {storage_objects}") def test_search_object_api( self, request: FixtureRequest, storage_objects: list[StorageObjectInfo] ): @@ -266,21 +266,18 @@ class TestObjectApi(ClusterTestBase): ) assert sorted(expected_oids) == sorted(result) - @allure.title("Validate object search with removed items") + @allure.title("Validate object search with removed items for {object_size}") @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], ids=["simple object size", "complex object size"], ) def test_object_search_should_return_tombstone_items( - self, default_wallet: str, request: FixtureRequest, object_size: ObjectSize + self, default_wallet: str, object_size: ObjectSize ): """ Validate object search with removed items """ - allure.dynamic.title( - f"Validate object search with removed items for {request.node.callspec.id}" - ) wallet = default_wallet cid = create_container(wallet, self.shell, self.cluster.default_rpc_endpoint) @@ -339,7 +336,7 @@ class TestObjectApi(ClusterTestBase): object_type == "TOMBSTONE" ), f"Object wasn't deleted properly. Found object {tombstone_oid} with type {object_type}" - @allure.title("Validate native object API get_range_hash") + @allure.title("Validate native get_range_hash object API for {storage_objects}") @pytest.mark.sanity @pytest.mark.grpc_api def test_object_get_range_hash( @@ -378,7 +375,7 @@ class TestObjectApi(ClusterTestBase): get_file_hash(file_path, range_len, range_start) == range_hash ), f"Expected range hash to match {range_cut} slice of file payload" - @allure.title("Validate native object API get_range") + @allure.title("Validate native get_range object API for {storage_objects}") @pytest.mark.sanity @pytest.mark.grpc_api def test_object_get_range( @@ -418,7 +415,9 @@ class TestObjectApi(ClusterTestBase): == range_content ), f"Expected range content to match {range_cut} slice of file payload" - @allure.title("Validate native object API get_range negative cases") + @allure.title( + "[NEGATIVE] Invalid range in get_range native object API should return error for {storage_objects}" + ) @pytest.mark.sanity @pytest.mark.grpc_api def test_object_get_range_negatives( @@ -430,7 +429,7 @@ class TestObjectApi(ClusterTestBase): Validate get_range negative for object by native gRPC API """ allure.dynamic.title( - f"Validate native get_range negative object API for {request.node.callspec.id}" + f"[NEGATIVE] Invalid range in get_range native object API should return error for {request.node.callspec.id}" ) wallet = storage_objects[0].wallet_file_path @@ -475,7 +474,9 @@ class TestObjectApi(ClusterTestBase): range_cut=range_cut, ) - @allure.title("Validate native object API get_range_hash negative cases") + @allure.title( + "[NEGATIVE] Invalid range in get_range_hash native object API should return error for {storage_objects}" + ) def test_object_get_range_hash_negatives( self, request: FixtureRequest, @@ -485,7 +486,7 @@ class TestObjectApi(ClusterTestBase): Validate get_range_hash negative for object by native gRPC API """ allure.dynamic.title( - f"Validate native get_range_hash negative object API for {request.node.callspec.id}" + f"[NEGATIVE] Invalid range in get_range_hash native object API should return error for {request.node.callspec.id}" ) wallet = storage_objects[0].wallet_file_path diff --git a/pytest_tests/testsuites/object/test_object_api_bearer.py b/pytest_tests/testsuites/object/test_object_api_bearer.py index 39c35e6..e62f4ed 100644 --- a/pytest_tests/testsuites/object/test_object_api_bearer.py +++ b/pytest_tests/testsuites/object/test_object_api_bearer.py @@ -86,15 +86,15 @@ def storage_objects( @pytest.mark.smoke @pytest.mark.bearer class TestObjectApiWithBearerToken(ClusterTestBase): - @pytest.mark.parametrize( - "user_container", - [SINGLE_PLACEMENT_RULE], - ids=["single replica for all nodes placement rule"], - indirect=True, + @allure.title( + "Object can be deleted from any node using s3gate wallet with bearer token for {storage_objects}" ) @pytest.mark.parametrize( - "storage_objects", - [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], + "storage_objects,user_container", + [ + (pytest.lazy_fixture("simple_object_size"), SINGLE_PLACEMENT_RULE), + (pytest.lazy_fixture("complex_object_size"), SINGLE_PLACEMENT_RULE), + ], ids=["simple object size", "complex object size"], indirect=True, ) @@ -122,28 +122,24 @@ class TestObjectApiWithBearerToken(ClusterTestBase): wallet_config=s3_gate_wallet.get_wallet_config_path(), ) - @pytest.mark.parametrize( - "user_container", - [REP_2_FOR_3_NODES_PLACEMENT_RULE], - ids=["2 replicas for 3 nodes placement rule"], - indirect=True, + @allure.title( + "Object can be fetched from any node using s3gate wallet with bearer token for {object_size}" ) @pytest.mark.parametrize( - "object_size", - [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], + "object_size, user_container", + [ + (pytest.lazy_fixture("simple_object_size"), REP_2_FOR_3_NODES_PLACEMENT_RULE), + (pytest.lazy_fixture("complex_object_size"), REP_2_FOR_3_NODES_PLACEMENT_RULE), + ], ids=["simple object size", "complex object size"], + indirect=["user_container"], ) def test_get_object_with_s3_wallet_bearer_from_all_nodes( self, user_container: StorageContainer, object_size: ObjectSize, bearer_token_file_all_allow: str, - request: FixtureRequest, ): - allure.dynamic.title( - f"Object can be fetched from any node using s3gate wallet with bearer token for {request.node.callspec.id}" - ) - s3_gate_wallet = self.cluster.s3_gates[0] with allure.step("Put one object to container"): epoch = self.get_epoch() diff --git a/pytest_tests/testsuites/object/test_object_lifetime.py b/pytest_tests/testsuites/object/test_object_lifetime.py index a736cab..7bbec9a 100644 --- a/pytest_tests/testsuites/object/test_object_lifetime.py +++ b/pytest_tests/testsuites/object/test_object_lifetime.py @@ -13,7 +13,6 @@ 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 from frostfs_testlib.utils.file_utils import generate_file, get_file_hash -from pytest import FixtureRequest from pytest_tests.helpers.utility import wait_for_gc_pass_on_storage_nodes @@ -23,21 +22,17 @@ logger = logging.getLogger("NeoLogger") @pytest.mark.sanity @pytest.mark.grpc_api class TestObjectApiLifetime(ClusterTestBase): - @allure.title("Test object life time") + @allure.title("Object should be removed when lifetime expired for {object_size}") @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], ids=["simple object size", "complex object size"], ) - def test_object_api_lifetime( - self, default_wallet: str, request: FixtureRequest, object_size: ObjectSize - ): + def test_object_api_lifetime(self, default_wallet: str, object_size: ObjectSize): """ Test object deleted after expiration epoch. """ - allure.dynamic.title(f"Test object life time for {request.node.callspec.id}") - wallet = default_wallet endpoint = self.cluster.default_rpc_endpoint cid = create_container(wallet, self.shell, endpoint) diff --git a/pytest_tests/testsuites/object/test_object_lock.py b/pytest_tests/testsuites/object/test_object_lock.py index 648ade0..91bcb7e 100755 --- a/pytest_tests/testsuites/object/test_object_lock.py +++ b/pytest_tests/testsuites/object/test_object_lock.py @@ -155,7 +155,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): return storage_object - @allure.title("Locked object should be protected from deletion") + @allure.title("Locked object should be protected from deletion for {locked_storage_object}") @pytest.mark.parametrize( "locked_storage_object", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], @@ -234,7 +234,9 @@ class TestObjectLockWithGrpc(ClusterTestBase): 1, ) - @allure.title("Cannot lock object without lifetime and expire_at fields") + @allure.title( + "Lock must contain valid lifetime or expire_at field: (lifetime={wrong_lifetime}, expire-at={wrong_expire_at})" + ) # We operate with only lock object here so no complex object needed in this test @pytest.mark.parametrize( "locked_storage_object", [pytest.lazy_fixture("simple_object_size")], indirect=True @@ -260,9 +262,6 @@ class TestObjectLockWithGrpc(ClusterTestBase): """ Cannot lock object without lifetime and expire_at fields """ - allure.dynamic.title( - f"Cannot lock object without lifetime and expire_at fields: (lifetime={wrong_lifetime}, expire-at={wrong_expire_at})" - ) lock_object_info = locked_storage_object.locks[0] wallet_path = locked_storage_object.wallet_file_path @@ -278,7 +277,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): expire_at=wrong_expire_at, ) - @allure.title("Expired object should be deleted after locks are expired") + @allure.title("Expired object should be deleted after locks are expired for {object_size}") @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], @@ -286,16 +285,12 @@ class TestObjectLockWithGrpc(ClusterTestBase): ) def test_expired_object_should_be_deleted_after_locks_are_expired( self, - request: FixtureRequest, user_container: StorageContainer, object_size: ObjectSize, ): """ Expired object should be deleted after locks are expired """ - allure.dynamic.title( - f"Expired object should be deleted after locks are expired for {request.node.callspec.id}" - ) current_epoch = self.ensure_fresh_epoch() storage_object = user_container.generate_object( @@ -348,7 +343,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.tick_epoch() check_object_not_found() - @allure.title("Should be possible to lock multiple objects at once") + @allure.title("Should be possible to lock multiple objects at once for {object_size}") @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], @@ -356,16 +351,12 @@ class TestObjectLockWithGrpc(ClusterTestBase): ) def test_should_be_possible_to_lock_multiple_objects_at_once( self, - request: FixtureRequest, user_container: StorageContainer, object_size: ObjectSize, ): """ Should be possible to lock multiple objects at once """ - allure.dynamic.title( - f"Should be possible to lock multiple objects at once for {request.node.callspec.id}" - ) current_epoch = ensure_fresh_epoch(self.shell, self.cluster) storage_objects: list[StorageObjectInfo] = [] @@ -403,7 +394,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): with expect_not_raises(): delete_objects(storage_objects, self.shell, self.cluster) - @allure.title("Already outdated lock should not be applied") + @allure.title("Already outdated lock should not be applied for {object_size}") @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], @@ -411,16 +402,12 @@ class TestObjectLockWithGrpc(ClusterTestBase): ) def test_already_outdated_lock_should_not_be_applied( self, - request: FixtureRequest, user_container: StorageContainer, object_size: ObjectSize, ): """ Already outdated lock should not be applied """ - allure.dynamic.title( - f"Already outdated lock should not be applied for {request.node.callspec.id}" - ) current_epoch = self.ensure_fresh_epoch() @@ -444,7 +431,9 @@ class TestObjectLockWithGrpc(ClusterTestBase): expire_at=expiration_epoch, ) - @allure.title("After lock expiration with lifetime user should be able to delete object") + @allure.title( + "After lock expiration with lifetime user should be able to delete object for {object_size}" + ) @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], @@ -453,16 +442,12 @@ class TestObjectLockWithGrpc(ClusterTestBase): @expect_not_raises() def test_after_lock_expiration_with_lifetime_user_should_be_able_to_delete_object( self, - request: FixtureRequest, user_container: StorageContainer, object_size: ObjectSize, ): """ After lock expiration with lifetime user should be able to delete object """ - allure.dynamic.title( - f"After lock expiration with lifetime user should be able to delete object for {request.node.callspec.id}" - ) current_epoch = self.ensure_fresh_epoch() storage_object = user_container.generate_object( @@ -488,7 +473,9 @@ class TestObjectLockWithGrpc(ClusterTestBase): self.cluster.default_rpc_endpoint, ) - @allure.title("After lock expiration with expire_at user should be able to delete object") + @allure.title( + "After lock expiration with expire_at user should be able to delete object for {object_size}" + ) @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], @@ -497,16 +484,12 @@ class TestObjectLockWithGrpc(ClusterTestBase): @expect_not_raises() def test_after_lock_expiration_with_expire_at_user_should_be_able_to_delete_object( self, - request: FixtureRequest, user_container: StorageContainer, object_size: ObjectSize, ): """ After lock expiration with expire_at user should be able to delete object """ - allure.dynamic.title( - f"After lock expiration with expire_at user should be able to delete object for {request.node.callspec.id}" - ) current_epoch = self.ensure_fresh_epoch() @@ -620,6 +603,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): with expect_not_raises(): drop_object(node, new_locked_storage_object.cid, chunk_object_id) + @allure.title("Locked object with {new_locked_storage_object} can be dropped") @pytest.mark.grpc_control @pytest.mark.parametrize( "new_locked_storage_object", @@ -628,7 +612,7 @@ class TestObjectLockWithGrpc(ClusterTestBase): indirect=True, ) def test_locked_object_can_be_dropped( - self, new_locked_storage_object: StorageObjectInfo, request: FixtureRequest + self, new_locked_storage_object: StorageObjectInfo, request: pytest.FixtureRequest ): allure.dynamic.title(f"Locked {request.node.callspec.id} can be dropped") nodes_with_object = get_nodes_with_object( diff --git a/pytest_tests/testsuites/replication/test_replication.py b/pytest_tests/testsuites/replication/test_replication.py index 83f352f..a7ca890 100644 --- a/pytest_tests/testsuites/replication/test_replication.py +++ b/pytest_tests/testsuites/replication/test_replication.py @@ -32,7 +32,7 @@ class TestReplication(ClusterTestBase): [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], ids=["simple object size", "complex object size"], ) - @allure.title("Test replication") + @allure.title("Test replication for {object_size}") def test_replication( self, default_wallet: str, 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 e772cad..bfa88c6 100644 --- a/pytest_tests/testsuites/services/http_gate/test_http_bearer.py +++ b/pytest_tests/testsuites/services/http_gate/test_http_bearer.py @@ -81,7 +81,7 @@ class Test_http_bearer(ClusterTestBase): ) return bearer_token_base64_from_file(bearer_signed) - @allure.title(f"[negative] Put object without bearer token for {EACLRole.OTHERS}") + @allure.title(f"[NEGATIVE] Put object without bearer token for {EACLRole.OTHERS}") def test_unable_put_without_bearer_token( self, simple_object_size: ObjectSize, user_container: str, eacl_deny_for_others ): 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 b1642f1..6e7653d 100644 --- a/pytest_tests/testsuites/services/http_gate/test_http_gate.py +++ b/pytest_tests/testsuites/services/http_gate/test_http_gate.py @@ -43,7 +43,7 @@ class TestHttpGate(ClusterTestBase): def prepare_wallet(self, default_wallet): TestHttpGate.wallet = default_wallet - @allure.title("Test Put over gRPC, Get over HTTP") + @allure.title("Put over gRPC, Get over HTTP") def test_put_grpc_get_http( self, complex_object_size: ObjectSize, simple_object_size: ObjectSize ): @@ -101,7 +101,7 @@ class TestHttpGate(ClusterTestBase): @allure.link("https://github.com/TrueCloudLab/frostfs-http-gw#uploading", name="uploading") @allure.link("https://github.com/TrueCloudLab/frostfs-http-gw#downloading", name="downloading") - @allure.title("Test Put over HTTP, Get over HTTP") + @allure.title("Put over HTTP, Get over HTTP") @pytest.mark.skip("Skipped due to deprecated PUT via http") @pytest.mark.smoke def test_put_http_get_http( @@ -154,7 +154,7 @@ class TestHttpGate(ClusterTestBase): name="download by attributes", ) @pytest.mark.skip("Skipped due to deprecated PUT via http") - @allure.title("Test Put over HTTP, Get over HTTP with headers") + @allure.title("Put over HTTP, Get over HTTP with header") @pytest.mark.parametrize( "attributes", [ @@ -164,7 +164,9 @@ class TestHttpGate(ClusterTestBase): ], ids=["simple", "hyphen", "percent"], ) - def test_put_http_get_http_with_headers(self, attributes: dict, simple_object_size: ObjectSize): + def test_put_http_get_http_with_headers( + self, attributes: dict, simple_object_size: ObjectSize, request: pytest.FixtureRequest + ): """ Test that object can be downloaded using different attributes in HTTP header. @@ -177,6 +179,7 @@ class TestHttpGate(ClusterTestBase): Expected result: Hashes must be the same. """ + allure.dynamic.title(f"Put over HTTP, Get over HTTP with {request.node.callspec.id} header") cid = create_container( self.wallet, shell=self.shell, @@ -205,7 +208,7 @@ class TestHttpGate(ClusterTestBase): ) @pytest.mark.skip("Skipped due to deprecated PUT via http") - @allure.title("Test Expiration-Epoch in HTTP header") + @allure.title("Test Expiration-Epoch in HTTP header with epoch_gap={epoch_gap}") @pytest.mark.parametrize("epoch_gap", [0, 1]) def test_expiration_epoch_in_http(self, simple_object_size: ObjectSize, epoch_gap: int): endpoint = self.cluster.default_rpc_endpoint @@ -313,7 +316,7 @@ class TestHttpGate(ClusterTestBase): @pytest.mark.long @pytest.mark.skip("Skipped due to deprecated PUT via http") - @allure.title("Test Put over HTTP/Curl, Get over HTTP/Curl for large object") + @allure.title("Put over HTTP/Curl, Get over HTTP/Curl for large object") def test_put_http_get_http_large_file(self, complex_object_size: ObjectSize): """ This test checks upload and download using curl with 'large' object. @@ -362,7 +365,7 @@ class TestHttpGate(ClusterTestBase): ) @pytest.mark.skip("Skipped due to deprecated PUT via http") - @allure.title("Test Put/Get over HTTP using Curl utility") + @allure.title("Put/Get over HTTP using Curl utility") def test_put_http_get_http_curl( self, complex_object_size: ObjectSize, simple_object_size: ObjectSize ): 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 98d44a0..a03d3da 100644 --- a/pytest_tests/testsuites/services/http_gate/test_http_headers.py +++ b/pytest_tests/testsuites/services/http_gate/test_http_headers.py @@ -110,7 +110,7 @@ class Test_http_headers(ClusterTestBase): http_hostname=self.cluster.default_http_hostname, ) - @allure.title("Test get object2 with different attributes, then delete object2 and get object1") + @allure.title("Get object2 with different attributes, then delete object2 and get object1") def test_object2_can_be_get_by_attr( self, storage_objects_with_attributes: list[StorageObjectInfo] ): @@ -173,7 +173,7 @@ class Test_http_headers(ClusterTestBase): http_hostname=self.cluster.default_http_hostname, ) - @allure.title("[Negative] Try to put object and get right after container is deleted") + @allure.title("[NEGATIVE] Put object and get right after container is deleted") @pytest.mark.skip("Skipped due to deprecated PUT via http") def test_negative_put_and_get_object3( self, storage_objects_with_attributes: list[StorageObjectInfo] 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 15a4318..fb5477d 100644 --- a/pytest_tests/testsuites/services/http_gate/test_http_object.py +++ b/pytest_tests/testsuites/services/http_gate/test_http_object.py @@ -27,7 +27,7 @@ class Test_http_object(ClusterTestBase): def prepare_wallet(self, default_wallet): Test_http_object.wallet = default_wallet - @allure.title("Test Put over gRPC, Get over HTTP") + @allure.title("Put over gRPC, Get over HTTP for {object_size}") @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], 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 cc40358..203a2b5 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 @@ -142,7 +142,7 @@ class Test_http_system_header(ClusterTestBase): ) return oid, head - @allure.title("[negative] attempt to put object with expired epoch") + @allure.title("[NEGATIVE] Put object with expired epoch") 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)} @@ -159,7 +159,7 @@ class Test_http_system_header(ClusterTestBase): error_pattern="must be greater than current epoch", ) - @allure.title("[negative] attempt to put object with negative System-Expiration-Duration") + @allure.title("[NEGATIVE] Put object with negative System-Expiration-Duration") def test_unable_put_negative_duration( self, user_container: str, simple_object_size: ObjectSize ): @@ -176,9 +176,7 @@ class Test_http_system_header(ClusterTestBase): error_pattern=f"{EXPIRATION_DURATION_HEADER} must be positive", ) - @allure.title( - "[negative] attempt to put object with System-Expiration-Timestamp value in the past" - ) + @allure.title("[NEGATIVE] Put object with System-Expiration-Timestamp value in the past") def test_unable_put_expired_timestamp( self, user_container: str, simple_object_size: ObjectSize ): @@ -196,7 +194,7 @@ class Test_http_system_header(ClusterTestBase): ) @allure.title( - "[negative] Put object using HTTP with attribute System-Expiration-RFC3339 where duration is in the past" + "[NEGATIVE] Put object using HTTP with attribute System-Expiration-RFC3339 where duration is in the past" ) def test_unable_put_expired_rfc(self, user_container: str, simple_object_size: ObjectSize): headers = attr_into_str_header_curl({"System-Expiration-RFC3339": "2021-11-22T09:55:49Z"}) @@ -209,7 +207,7 @@ class Test_http_system_header(ClusterTestBase): error_pattern=f"{EXPIRATION_EXPIRATION_RFC} must be in the future", ) - @allure.title("priority of attributes epoch>duration") + @allure.title("Priority of attributes epoch>duration for {object_size}") @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], @@ -256,9 +254,7 @@ class Test_http_system_header(ClusterTestBase): self.wallet, user_container, oid, self.shell, self.cluster ) - @allure.title( - f"priority of attributes duration>timestamp, duration time has higher priority and should be converted {EXPIRATION_EPOCH_HEADER}" - ) + @allure.title("Priority of attributes duration>timestamp for {object_size}") @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], @@ -312,9 +308,7 @@ class Test_http_system_header(ClusterTestBase): self.wallet, user_container, oid, self.shell, self.cluster ) - @allure.title( - f"priority of attributes timestamp>Expiration-RFC, timestamp has higher priority and should be converted {EXPIRATION_EPOCH_HEADER}" - ) + @allure.title("Priority of attributes timestamp>Expiration-RFC for {object_size}") @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], @@ -368,7 +362,7 @@ class Test_http_system_header(ClusterTestBase): self.wallet, user_container, oid, self.shell, self.cluster ) - @allure.title("Test that object is automatically delete when expiration passed") + @allure.title("Object should be deleted when expiration passed for {object_size}") @pytest.mark.parametrize( "object_size", # TODO: Temp disabled for v0.37 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 de68587..f576ec4 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_ACL.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_ACL.py @@ -10,7 +10,7 @@ from frostfs_testlib.utils.file_utils import generate_file @pytest.mark.acl @pytest.mark.s3_gate class TestS3GateACL: - @allure.title("Test S3: Object ACL") + @allure.title("{s3_client}: Object ACL") @pytest.mark.parametrize("s3_client", [AwsCliClient], indirect=True) def test_s3_object_ACL( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize @@ -44,7 +44,7 @@ class TestS3GateACL: obj_acl = s3_client.get_object_acl(bucket, file_name) s3_helper.assert_s3_acl(acl_grants=obj_acl, permitted_users="AllUsers") - @allure.title("Test S3: Bucket ACL") + @allure.title("{s3_client}: Bucket ACL") @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"): 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 7a6e0d6..3f22789 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_bucket.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_bucket.py @@ -17,7 +17,7 @@ def pytest_generate_tests(metafunc: pytest.Metafunc): @pytest.mark.s3_gate @pytest.mark.s3_gate_bucket class TestS3GateBucket: - @allure.title("Test S3: Create Bucket with different ACL") + @allure.title("{s3_client}: Create Bucket with different ACL") def test_s3_create_bucket_with_ACL(self, s3_client: S3ClientWrapper): with allure.step("Create bucket with ACL private"): @@ -46,7 +46,7 @@ class TestS3GateBucket: bucket_acl_3 = s3_client.get_bucket_acl(bucket_3) s3_helper.assert_s3_acl(acl_grants=bucket_acl_3, permitted_users="AllUsers") - @allure.title("Test S3: Create Bucket with different ACL by grand") + @allure.title("{s3_client}: Create Bucket with different ACL by grant") def test_s3_create_bucket_with_grands(self, s3_client: S3ClientWrapper): with allure.step("Create bucket with --grant-read"): @@ -73,7 +73,7 @@ class TestS3GateBucket: bucket_acl_2 = s3_client.get_bucket_acl(bucket_2) s3_helper.assert_s3_acl(acl_grants=bucket_acl_2, permitted_users="AllUsers") - @allure.title("Test S3: create bucket with object lock") + @allure.title("{s3_client}: create bucket with object lock") def test_s3_bucket_object_lock( self, s3_client: S3ClientWrapper, simple_object_size: ObjectSize ): @@ -108,7 +108,7 @@ class TestS3GateBucket: s3_client, bucket_1, file_name, "COMPLIANCE", date_obj_1, "ON" ) - @allure.title("Test S3: delete bucket") + @allure.title("{s3_client}: delete bucket") def test_s3_delete_bucket(self, s3_client: S3ClientWrapper, simple_object_size: ObjectSize): file_path_1 = generate_file(simple_object_size.value) file_name_1 = s3_helper.object_key_from_file_path(file_path_1) 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 d6e3538..2667197 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_gate.py @@ -34,7 +34,7 @@ def pytest_generate_tests(metafunc: pytest.Metafunc): @pytest.mark.s3_gate @pytest.mark.s3_gate_base class TestS3Gate: - @allure.title("Test S3 Bucket API") + @allure.title("{s3_client}: Bucket API") def test_s3_buckets( self, s3_client: S3ClientWrapper, @@ -107,7 +107,7 @@ class TestS3Gate: with pytest.raises(Exception, match=r".*Not Found.*"): s3_client.head_bucket(bucket_1) - @allure.title("Test S3 Object API") + @allure.title("{s3_client}: Object API for {object_size}") @pytest.mark.parametrize( "object_size", ["simple object size", "complex object size"], @@ -147,7 +147,7 @@ class TestS3Gate: for attrs in (["ETag"], ["ObjectSize", "StorageClass"]): s3_client.get_object_attributes(bucket, file_name, attrs) - @allure.title("Test S3 Sync directory") + @allure.title("{s3_client}: Sync directory") def test_s3_sync_dir( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize ): @@ -179,7 +179,7 @@ class TestS3Gate: key_to_path.get(obj_key) ), "Expected hashes are the same" - @allure.title("Test S3 Object versioning") + @allure.title("{s3_client}: Object versioning") def test_s3_api_versioning( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize ): @@ -259,7 +259,7 @@ class TestS3Gate: ), f"Expected object content is\n{version_2_content}\nGot\n{got_content}" @pytest.mark.s3_gate_multipart - @allure.title("Test S3 Object Multipart API") + @allure.title("{s3_client}: Object Multipart API") def test_s3_api_multipart( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize ): @@ -316,7 +316,7 @@ class TestS3Gate: self.check_object_attributes(s3_client, bucket, object_key, parts_count) - @allure.title("Test S3 Bucket tagging API") + @allure.title("{s3_client}: Bucket tagging API") def test_s3_api_bucket_tagging(self, s3_client: S3ClientWrapper, bucket: str): """ Test checks S3 Bucket tagging API (Put tag/Get tag). @@ -329,7 +329,7 @@ class TestS3Gate: s3_client.delete_bucket_tagging(bucket) s3_helper.check_tags_by_bucket(s3_client, bucket, []) - @allure.title("Test S3 Object tagging API") + @allure.title("{s3_client}: Object tagging API") def test_s3_api_object_tagging( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize ): @@ -361,7 +361,7 @@ class TestS3Gate: s3_client.delete_object_tagging(bucket, obj_key) s3_helper.check_tags_by_object(s3_client, bucket, obj_key, []) - @allure.title("Test S3: Delete object & delete objects S3 API") + @allure.title("{s3_client}: Delete object & delete objects") def test_s3_api_delete( self, s3_client: S3ClientWrapper, @@ -427,7 +427,7 @@ class TestS3Gate: with pytest.raises(Exception, match="The specified key does not exist"): s3_client.get_object(bucket_2, object_key) - @allure.title("Test S3: Copy object to the same bucket") + @allure.title("{s3_client}: Copy object to the same bucket") def test_s3_copy_same_bucket( self, s3_client: S3ClientWrapper, @@ -476,7 +476,7 @@ class TestS3Gate: unexpected_objects=[file_name_simple], ) - @allure.title("Test S3: Copy object to another bucket") + @allure.title("{s3_client}: Copy object to another bucket") def test_s3_copy_to_another_bucket( self, s3_client: S3ClientWrapper, 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 cad4e13..925f5e0 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_locking.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_locking.py @@ -19,7 +19,9 @@ def pytest_generate_tests(metafunc: pytest.Metafunc): @pytest.mark.s3_gate_locking @pytest.mark.parametrize("version_id", [None, "second"]) class TestS3GateLocking: - @allure.title("Test S3: Checking the operation of retention period & legal lock on the object") + @allure.title( + "{s3_client}: Retention period & legal lock on the object with version_id={version_id}" + ) def test_s3_object_locking( self, s3_client: S3ClientWrapper, version_id: str, simple_object_size: ObjectSize ): @@ -74,7 +76,9 @@ class TestS3GateLocking: else: s3_client.delete_object(bucket, file_name, version_id) - @allure.title("Test S3: Checking the impossibility to change the retention mode COMPLIANCE") + @allure.title( + "{s3_client}: Impossible to change the retention mode COMPLIANCE with version_id={version_id}" + ) def test_s3_mode_compliance( self, s3_client: S3ClientWrapper, version_id: str, simple_object_size: ObjectSize ): @@ -113,7 +117,7 @@ class TestS3GateLocking: with pytest.raises(Exception): s3_client.put_object_retention(bucket, file_name, retention, version_id) - @allure.title("Test S3: Checking the ability to change retention mode GOVERNANCE") + @allure.title("{s3_client}: Change retention mode GOVERNANCE with version_id={version_id}") def test_s3_mode_governance( self, s3_client: S3ClientWrapper, version_id: str, simple_object_size: ObjectSize ): @@ -175,7 +179,7 @@ class TestS3GateLocking: s3_client, bucket, file_name, "GOVERNANCE", date_obj, "OFF" ) - @allure.title("Test S3: Checking if an Object Cannot Be Locked") + @allure.title("{s3_client}: Object Cannot Be Locked with version_id={version_id}") def test_s3_legal_hold( self, s3_client: S3ClientWrapper, version_id: str, simple_object_size: ObjectSize ): @@ -197,7 +201,7 @@ class TestS3GateLocking: @pytest.mark.s3_gate class TestS3GateLockingBucket: - @allure.title("Test S3: Bucket Lock") + @allure.title("{s3_client}: Bucket Lock") def test_s3_bucket_lock(self, s3_client: S3ClientWrapper, simple_object_size: ObjectSize): file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) 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 e184b16..7bcf9a7 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_multipart.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_multipart.py @@ -23,7 +23,7 @@ class TestS3GateMultipart(ClusterTestBase): "The upload ID may be invalid, or the upload may have been aborted or completed." ) - @allure.title("Test S3 Object Multipart API") + @allure.title("{s3_client}: Object Multipart API") @pytest.mark.parametrize("bucket", [VersioningStatus.ENABLED], indirect=True) def test_s3_object_multipart(self, s3_client: S3ClientWrapper, bucket: str): parts_count = 5 @@ -58,7 +58,7 @@ class TestS3GateMultipart(ClusterTestBase): got_object = s3_client.get_object(bucket, object_key) assert get_file_hash(got_object) == get_file_hash(file_name_large) - @allure.title("Test S3 Multipart abort") + @allure.title("{s3_client}: Multipart abort with") @pytest.mark.parametrize("bucket", [VersioningStatus.ENABLED], indirect=True) def test_s3_abort_multipart( self, @@ -113,7 +113,7 @@ class TestS3GateMultipart(ClusterTestBase): ) assert len(objects) == 0, f"Expected no objects in container, got\n{objects}" - @allure.title("Test S3 Upload Part Copy") + @allure.title("{s3_client}: Upload Part Copy") @pytest.mark.parametrize("bucket", [VersioningStatus.ENABLED], indirect=True) def test_s3_multipart_copy(self, s3_client: S3ClientWrapper, bucket: str): parts_count = 3 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 cb75178..54ed8f1 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_object.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_object.py @@ -67,7 +67,7 @@ class TestS3GateObject: public_key = wallet_utils.get_wallet_public_key(second_wallet, DEFAULT_WALLET_PASS) yield public_key - @allure.title("Test S3: Copy object") + @allure.title("{s3_client}: Copy object") def test_s3_copy_object( self, s3_client: S3ClientWrapper, @@ -123,7 +123,7 @@ class TestS3GateObject: with pytest.raises(Exception): s3_client.copy_object(bucket_1, file_name) - @allure.title("Test S3: Copy version of object") + @allure.title("{s3_client}: Copy version of object") def test_s3_copy_version_object( self, s3_client: S3ClientWrapper, @@ -191,7 +191,7 @@ class TestS3GateObject: obj_acl = s3_client.get_object_acl(bucket, copy_obj_path) s3_helper.assert_s3_acl(acl_grants=obj_acl, permitted_users="CanonicalUser") - @allure.title("Test S3: Copy object with metadata") + @allure.title("{s3_client}: Copy object with metadata") def test_s3_copy_metadate( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize ): @@ -238,7 +238,7 @@ class TestS3GateObject: obj_head.get("Metadata") == object_metadata_1 ), f"Metadata must be {object_metadata_1}" - @allure.title("Test S3: Copy object with tagging") + @allure.title("{s3_client}: Copy object with tagging") def test_s3_copy_tagging( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize ): @@ -289,7 +289,7 @@ class TestS3GateObject: for tag in expected_tags: assert tag in got_tags, f"Expected tag {tag} in {got_tags}" - @allure.title("Test S3: Delete version of object") + @allure.title("{s3_client}: Delete version of object") def test_s3_delete_versioning( self, s3_client: S3ClientWrapper, @@ -352,7 +352,7 @@ class TestS3GateObject: assert versions.get("DeleteMarkers", None), "Expected delete Marker" assert "DeleteMarker" in delete_obj.keys(), "Expected delete Marker" - @allure.title("Test S3: bulk delete version of object") + @allure.title("{s3_client}: bulk delete version of object") def test_s3_bulk_delete_versioning( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize ): @@ -407,7 +407,7 @@ class TestS3GateObject: obj_versions.sort() == version_to_save.sort() ), f"Object should have versions: {version_to_save}" - @allure.title("Test S3: Get versions of object") + @allure.title("{s3_client}: Get versions of object") def test_s3_get_versioning( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize ): @@ -444,7 +444,7 @@ class TestS3GateObject: object_3.get("VersionId") == version_id_2 ), f"Get object with version {version_id_2}" - @allure.title("Test S3: Get range") + @allure.title("{s3_client}: Get range") def test_s3_get_range( self, s3_client: S3ClientWrapper, @@ -546,7 +546,7 @@ class TestS3GateObject: return result_list - @allure.title("Test S3: Bulk deletion should be limited to 1000 objects") + @allure.title("{s3_client}: Bulk deletion should be limited to 1000 objects") @pytest.mark.parametrize( "objects_in_bucket, object_size", [(3, 10)], @@ -565,7 +565,7 @@ class TestS3GateObject: with expect_not_raises(): s3_client.delete_objects(bucket, objects_to_delete[:1000]) - @allure.title("Test S3: Copy object with metadata") + @allure.title("{s3_client}: Copy object with metadata") @pytest.mark.smoke def test_s3_head_object( self, @@ -606,7 +606,7 @@ class TestS3GateObject: ), f"Expected VersionId is {version_id_1}" assert response.get("ContentLength") != 0, "Expected ContentLength is not zero" - @allure.title("Test S3: list of object with versions") + @allure.title("{s3_client}: list of objects with version {list_type}") @pytest.mark.parametrize("list_type", ["v1", "v2"]) def test_s3_list_object( self, @@ -648,7 +648,7 @@ class TestS3GateObject: ), f"bucket should have object key {file_name_2}" assert "DeleteMarker" in delete_obj.keys(), "Expected delete Marker" - @allure.title("Test S3: put object") + @allure.title("{s3_client}: put object") def test_s3_put_object( self, s3_client: S3ClientWrapper, @@ -754,7 +754,7 @@ class TestS3GateObject: {"Key": tag_key_3, "Value": str(tag_value_3)} ], "Tags must be the same" - @allure.title("Test S3: put object with ACL") + @allure.title("{s3_client}: put object with ACL and versioning is {bucket_versioning}") @pytest.mark.parametrize("bucket_versioning", ["ENABLED", "SUSPENDED"]) def test_s3_put_object_acl( self, @@ -839,7 +839,7 @@ class TestS3GateObject: object_6 = s3_client.get_object(bucket, file_name_5) assert get_file_hash(file_path_5) == get_file_hash(object_6), "Hashes must be the same" - @allure.title("Test S3: put object with lock-mode") + @allure.title("{s3_client}: put object with lock-mode") def test_s3_put_object_lock_mode( self, s3_client: S3ClientWrapper, @@ -920,7 +920,7 @@ class TestS3GateObject: object_lock_retain_until_date=date_obj, ) - @allure.title("Test S3 Sync directory") + @allure.title("{s3_client}: Sync directory with sync type {sync_type}") @pytest.mark.parametrize("sync_type", ["sync", "cp"]) def test_s3_sync_dir( self, @@ -976,7 +976,7 @@ class TestS3GateObject: # obj_acl = s3_client.get_object_acl(bucket, obj_key) # s3_helper.assert_s3_acl(acl_grants = obj_acl, permitted_users = "AllUsers") - @allure.title("Test S3 Put 10 nested level object") + @allure.title("{s3_client}: Put 10 nested level object") def test_s3_put_10_folder( self, s3_client: S3ClientWrapper, @@ -995,7 +995,7 @@ class TestS3GateObject: s3_client.put_object(bucket, file_path_1) s3_helper.check_objects_in_bucket(s3_client, bucket, [file_name]) - @allure.title("Test S3: Delete non-existing object from empty bucket") + @allure.title("{s3_client}: Delete non-existing object from empty bucket") def test_s3_delete_non_existing_object(self, s3_client: S3ClientWrapper, bucket: str): s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.ENABLED) @@ -1012,7 +1012,7 @@ class TestS3GateObject: objects_list = s3_client.list_objects_versions(bucket) assert not objects_list, f"Expected empty bucket, got {objects_list}" - @allure.title("Test S3: Delete the same object twice") + @allure.title("{s3_client}: Delete the same object twice") def test_s3_delete_twice( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize ): 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 d1dc766..c94792b 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_policy.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_policy.py @@ -25,7 +25,7 @@ def pytest_generate_tests(metafunc: pytest.Metafunc): @pytest.mark.s3_gate class TestS3GatePolicy(ClusterTestBase): - @allure.title("Test S3: Verify bucket creation with retention policy applied") + @allure.title("{s3_client}: bucket creation with retention policy applied") def test_s3_bucket_location( self, default_wallet: str, s3_client: S3ClientWrapper, simple_object_size: ObjectSize ): @@ -91,13 +91,13 @@ class TestS3GatePolicy(ClusterTestBase): ) assert copies_2 == 3 - @allure.title("Test S3: bucket with unexisting location constraint") + @allure.title("{s3_client}: bucket with unexisting location constraint") def test_s3_bucket_wrong_location(self, s3_client: S3ClientWrapper): with allure.step("Create bucket with unenxisting location constraint policy"): with pytest.raises(Exception): s3_client.create_bucket(location_constraint="UNEXISTING LOCATION CONSTRAINT") - @allure.title("Test S3: bucket policy ") + @allure.title("{s3_client}: bucket policy") def test_s3_bucket_policy(self, s3_client: S3ClientWrapper): with allure.step("Create bucket with default policy"): bucket = s3_client.create_bucket() @@ -127,7 +127,7 @@ class TestS3GatePolicy(ClusterTestBase): policy_1 = s3_client.get_bucket_policy(bucket) print(policy_1) - @allure.title("Test S3: bucket CORS") + @allure.title("{s3_client}: bucket CORS") def test_s3_cors(self, s3_client: S3ClientWrapper): with allure.step("Create bucket without cors"): bucket = s3_client.create_bucket() 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 448a3e6..1032004 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_tagging.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_tagging.py @@ -28,7 +28,7 @@ class TestS3GateTagging: tags.append((tag_key, tag_value)) return tags - @allure.title("Test S3: Object tagging") + @allure.title("{s3_client}: Object tagging") def test_s3_object_tagging( self, s3_client: S3ClientWrapper, bucket: str, simple_object_size: ObjectSize ): @@ -78,7 +78,7 @@ class TestS3GateTagging: s3_client.delete_object_tagging(bucket, file_name) s3_helper.check_tags_by_object(s3_client, bucket, file_name, []) - @allure.title("Test S3: bucket tagging") + @allure.title("{s3_client}: bucket tagging") def test_s3_bucket_tagging(self, s3_client: S3ClientWrapper, bucket: str): with allure.step("Put 10 bucket tags"): 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 108ae63..3a14ca5 100644 --- a/pytest_tests/testsuites/services/s3_gate/test_s3_versioning.py +++ b/pytest_tests/testsuites/services/s3_gate/test_s3_versioning.py @@ -17,13 +17,13 @@ def pytest_generate_tests(metafunc: pytest.Metafunc): @pytest.mark.s3_gate @pytest.mark.s3_gate_versioning class TestS3GateVersioning: - @allure.title("Test S3: try to disable versioning") + @allure.title("{s3_client}: Impossible to disable versioning with object_lock") def test_s3_version_off(self, s3_client: S3ClientWrapper): bucket = s3_client.create_bucket(object_lock_enabled_for_bucket=True) with pytest.raises(Exception): s3_helper.set_bucket_versioning(s3_client, bucket, VersioningStatus.SUSPENDED) - @allure.title("Test S3: Enable and disable versioning") + @allure.title("{s3_client}: Enable and disable versioning without object_lock") def test_s3_version(self, s3_client: S3ClientWrapper, simple_object_size: ObjectSize): file_path = generate_file(simple_object_size.value) file_name = s3_helper.object_key_from_file_path(file_path) 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 a815934..7712f74 100644 --- a/pytest_tests/testsuites/session_token/test_object_session_token.py +++ b/pytest_tests/testsuites/session_token/test_object_session_token.py @@ -16,7 +16,7 @@ from frostfs_testlib.utils.file_utils import generate_file @pytest.mark.sanity @pytest.mark.session_token class TestDynamicObjectSession(ClusterTestBase): - @allure.title("Test Object Operations with Session Token") + @allure.title("Object Operations with Session Token for {object_size}") @pytest.mark.parametrize( "object_size", [pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")], 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 2ae5f81..decdde7 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 @@ -152,13 +152,14 @@ def static_sessions( @pytest.mark.static_session class TestObjectStaticSession(ClusterTestBase): - @allure.title("Validate static session with read operations") + @allure.title("Read operations with static session: {storage_objects} {verb.value}") @pytest.mark.parametrize( "method_under_test,verb", [ (head_object, ObjectVerb.HEAD), (get_object, ObjectVerb.GET), ], + ids=["head", "get"], ) def test_static_session_read( self, @@ -173,7 +174,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session with read operations """ allure.dynamic.title( - f"Validate static session with read operations for {request.node.callspec.id}" + f"Read operation with static session: {request.node.callspec.id.replace('-', ' ')}" ) for node in self.cluster.storage_nodes: @@ -187,10 +188,11 @@ class TestObjectStaticSession(ClusterTestBase): session=static_sessions[verb], ) - @allure.title("Validate static session with range operations") + @allure.title("Range operations with static session for: {storage_objects} {verb.value}") @pytest.mark.parametrize( "method_under_test,verb", [(get_range, ObjectVerb.RANGE), (get_range_hash, ObjectVerb.RANGEHASH)], + ids=["range", "rangehash"], ) def test_static_session_range( self, @@ -206,7 +208,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session with range operations """ allure.dynamic.title( - f"Validate static session with range operations for {request.node.callspec.id}" + f"Range operation with static session: {request.node.callspec.id.replace('-', ' ')}" ) storage_object = storage_objects[0] ranges_to_test = get_ranges( @@ -226,7 +228,7 @@ class TestObjectStaticSession(ClusterTestBase): range_cut=range_to_test, ) - @allure.title("Validate static session with search operation") + @allure.title("Search operation with static session for {storage_objects}") def test_static_session_search( self, user_wallet: WalletInfo, @@ -237,7 +239,7 @@ class TestObjectStaticSession(ClusterTestBase): """ Validate static session with search operations """ - allure.dynamic.title(f"Validate static session with search for {request.node.callspec.id}") + allure.dynamic.title(f"Search operation with static session for {request.node.callspec.id}") cid = storage_objects[0].cid expected_object_ids = [storage_object.oid for storage_object in storage_objects[0:2]] @@ -251,7 +253,7 @@ class TestObjectStaticSession(ClusterTestBase): ) assert sorted(expected_object_ids) == sorted(actual_object_ids) - @allure.title("Validate static session with object id not in session") + @allure.title("Static session with object id not in session for {storage_objects}") def test_static_session_unrelated_object( self, user_wallet: WalletInfo, @@ -263,7 +265,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session with object id not in session """ allure.dynamic.title( - f"Validate static session with object id not in session for {request.node.callspec.id}" + f"Static session with object id not in session for {request.node.callspec.id}" ) with pytest.raises(Exception, match=UNRELATED_OBJECT): head_object( @@ -275,7 +277,7 @@ class TestObjectStaticSession(ClusterTestBase): session=static_sessions[ObjectVerb.HEAD], ) - @allure.title("Validate static session with user id not in session") + @allure.title("Static session with user id not in session for {storage_objects}") def test_static_session_head_unrelated_user( self, stranger_wallet: WalletInfo, @@ -287,7 +289,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session with user id not in session """ allure.dynamic.title( - f"Validate static session with user id not in session for {request.node.callspec.id}" + f"Static session with user id not in session for {request.node.callspec.id}" ) storage_object = storage_objects[0] @@ -301,7 +303,7 @@ class TestObjectStaticSession(ClusterTestBase): session=static_sessions[ObjectVerb.HEAD], ) - @allure.title("Validate static session with wrong verb in session") + @allure.title("Static session with wrong verb in session for {storage_objects}") def test_static_session_head_wrong_verb( self, user_wallet: WalletInfo, @@ -313,7 +315,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session with wrong verb in session """ allure.dynamic.title( - f"Validate static session with wrong verb in session for {request.node.callspec.id}" + f"Static session with wrong verb in session for {request.node.callspec.id}" ) storage_object = storage_objects[0] @@ -327,7 +329,7 @@ class TestObjectStaticSession(ClusterTestBase): session=static_sessions[ObjectVerb.HEAD], ) - @allure.title("Validate static session with container id not in session") + @allure.title("Static session with container id not in session for {storage_objects}") def test_static_session_unrelated_container( self, user_wallet: WalletInfo, @@ -340,7 +342,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session with container id not in session """ allure.dynamic.title( - f"Validate static session with container id not in session for {request.node.callspec.id}" + f"Static session with container id not in session for {request.node.callspec.id}" ) storage_object = storage_objects[0] @@ -354,7 +356,7 @@ class TestObjectStaticSession(ClusterTestBase): session=static_sessions[ObjectVerb.GET], ) - @allure.title("Validate static session which signed by another wallet") + @allure.title("Static session which signed by another wallet for {storage_objects}") def test_static_session_signed_by_other( self, owner_wallet: WalletInfo, @@ -369,7 +371,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session which signed by another wallet """ allure.dynamic.title( - f"Validate static session which signed by another wallet for {request.node.callspec.id}" + f"Static session which signed by another wallet for {request.node.callspec.id}" ) storage_object = storage_objects[0] @@ -392,7 +394,7 @@ class TestObjectStaticSession(ClusterTestBase): session=signed_token_file, ) - @allure.title("Validate static session which signed for another container") + @allure.title("Static session which signed for another container for {storage_objects}") def test_static_session_signed_for_other_container( self, owner_wallet: WalletInfo, @@ -406,7 +408,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session which signed for another container """ allure.dynamic.title( - f"Validate static session which signed for another container for {request.node.callspec.id}" + f"Static session which signed for another container for {request.node.callspec.id}" ) storage_object = storage_objects[0] container = storage_containers[1] @@ -430,7 +432,7 @@ class TestObjectStaticSession(ClusterTestBase): session=signed_token_file, ) - @allure.title("Validate static session which wasn't signed") + @allure.title("Static session which wasn't signed for {storage_objects}") def test_static_session_without_sign( self, owner_wallet: WalletInfo, @@ -443,9 +445,7 @@ class TestObjectStaticSession(ClusterTestBase): """ Validate static session which wasn't signed """ - allure.dynamic.title( - f"Validate static session which wasn't signed for {request.node.callspec.id}" - ) + allure.dynamic.title(f"Static session which wasn't signed for {request.node.callspec.id}") storage_object = storage_objects[0] session_token_file = generate_object_session_token( @@ -466,7 +466,7 @@ class TestObjectStaticSession(ClusterTestBase): session=session_token_file, ) - @allure.title("Validate static session which expires at next epoch") + @allure.title("Static session which expires at next epoch for {storage_objects}") def test_static_session_expiration_at_next( self, owner_wallet: WalletInfo, @@ -480,7 +480,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session which expires at next epoch """ allure.dynamic.title( - f"Validate static session which expires at next epoch for {request.node.callspec.id}" + f"Static session which expires at next epoch for {request.node.callspec.id}" ) epoch = ensure_fresh_epoch(self.shell, self.cluster) @@ -537,7 +537,7 @@ class TestObjectStaticSession(ClusterTestBase): session=token_expire_at_next_epoch, ) - @allure.title("Validate static session which is valid starting from next epoch") + @allure.title("Static session which is valid starting from next epoch for {storage_objects}") def test_static_session_start_at_next( self, owner_wallet: WalletInfo, @@ -551,7 +551,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session which is valid starting from next epoch """ allure.dynamic.title( - f"Validate static session which is valid starting from next epoch for {request.node.callspec.id}" + f"Static session which is valid starting from next epoch for {request.node.callspec.id}" ) epoch = ensure_fresh_epoch(self.shell, self.cluster) @@ -622,7 +622,7 @@ class TestObjectStaticSession(ClusterTestBase): session=token_start_at_next_epoch, ) - @allure.title("Validate static session which is already expired") + @allure.title("Static session which is already expired for {storage_objects}") def test_static_session_already_expired( self, owner_wallet: WalletInfo, @@ -636,7 +636,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session which is already expired """ allure.dynamic.title( - f"Validate static session which is already expired for {request.node.callspec.id}" + f"Static session which is already expired for {request.node.callspec.id}" ) epoch = ensure_fresh_epoch(self.shell, self.cluster) @@ -665,7 +665,7 @@ class TestObjectStaticSession(ClusterTestBase): session=token_already_expired, ) - @allure.title("Delete verb should be restricted for static session") + @allure.title("Delete verb should be restricted for static session for {storage_objects}") def test_static_session_delete_verb( self, user_wallet: WalletInfo, @@ -690,7 +690,7 @@ class TestObjectStaticSession(ClusterTestBase): session=static_sessions[ObjectVerb.DELETE], ) - @allure.title("Put verb should be restricted for static session") + @allure.title("Put verb should be restricted for static session for {storage_objects}") def test_static_session_put_verb( self, user_wallet: WalletInfo, @@ -715,7 +715,7 @@ class TestObjectStaticSession(ClusterTestBase): session=static_sessions[ObjectVerb.PUT], ) - @allure.title("Validate static session which is issued in future epoch") + @allure.title("Static session which is issued in future epoch for {storage_objects}") def test_static_session_invalid_issued_epoch( self, owner_wallet: WalletInfo, @@ -729,7 +729,7 @@ class TestObjectStaticSession(ClusterTestBase): Validate static session which is issued in future epoch """ allure.dynamic.title( - f"Validate static session which is issued in future epoch for {request.node.callspec.id}" + f"Static session which is issued in future epoch for {request.node.callspec.id}" ) epoch = ensure_fresh_epoch(self.shell, self.cluster)