Reduce number of sanity tests #146
6 changed files with 76 additions and 194 deletions
|
@ -9,10 +9,7 @@ from frostfs_testlib.storage.dataclasses.acl import EACLAccess, EACLOperation, E
|
|||
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||
from frostfs_testlib.utils.failover_utils import wait_object_replication
|
||||
|
||||
from pytest_tests.helpers.container_access import (
|
||||
check_full_access_to_container,
|
||||
check_no_access_to_container,
|
||||
)
|
||||
from pytest_tests.helpers.container_access import check_full_access_to_container, check_no_access_to_container
|
||||
from pytest_tests.helpers.object_access import (
|
||||
can_delete_object,
|
||||
can_get_head_object,
|
||||
|
@ -25,7 +22,6 @@ from pytest_tests.helpers.object_access import (
|
|||
from pytest_tests.testsuites.acl.conftest import Wallets
|
||||
|
||||
|
||||
@pytest.mark.sanity
|
||||
@pytest.mark.acl
|
||||
@pytest.mark.acl_extended
|
||||
class TestEACLContainer(ClusterTestBase):
|
||||
|
@ -58,6 +54,7 @@ class TestEACLContainer(ClusterTestBase):
|
|||
|
||||
yield cid, oid, file_path
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Deny operations (role={deny_role.value}, obj_size={object_size})")
|
||||
@pytest.mark.parametrize("deny_role", [EACLRole.USER, EACLRole.OTHERS])
|
||||
def test_extended_acl_deny_all_operations(
|
||||
|
@ -75,10 +72,7 @@ class TestEACLContainer(ClusterTestBase):
|
|||
cid, object_oids, file_path = eacl_container_with_objects
|
||||
|
||||
with allure.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
|
||||
]
|
||||
eacl_deny = [EACLRule(access=EACLAccess.DENY, role=deny_role, operation=op) for op in EACLOperation]
|
||||
set_eacl(
|
||||
user_wallet.wallet_path,
|
||||
cid,
|
||||
|
@ -89,9 +83,7 @@ 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 allure.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,
|
||||
|
@ -101,9 +93,7 @@ class TestEACLContainer(ClusterTestBase):
|
|||
cluster=self.cluster,
|
||||
)
|
||||
|
||||
with allure.step(
|
||||
f"Check {not_deny_role_wallet} has full access to eACL public container"
|
||||
):
|
||||
with allure.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,
|
||||
|
@ -114,10 +104,7 @@ class TestEACLContainer(ClusterTestBase):
|
|||
)
|
||||
|
||||
with allure.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
|
||||
]
|
||||
eacl_deny = [EACLRule(access=EACLAccess.ALLOW, role=deny_role, operation=op) for op in EACLOperation]
|
||||
set_eacl(
|
||||
user_wallet.wallet_path,
|
||||
cid,
|
||||
|
@ -162,10 +149,7 @@ class TestEACLContainer(ClusterTestBase):
|
|||
)
|
||||
for op in EACLOperation
|
||||
]
|
||||
eacl += [
|
||||
EACLRule(access=EACLAccess.DENY, role=EACLRole.OTHERS, operation=op)
|
||||
for op in EACLOperation
|
||||
]
|
||||
eacl += [EACLRule(access=EACLAccess.DENY, role=EACLRole.OTHERS, operation=op) for op in EACLOperation]
|
||||
set_eacl(
|
||||
user_wallet.wallet_path,
|
||||
cid,
|
||||
|
@ -218,14 +202,8 @@ class TestEACLContainer(ClusterTestBase):
|
|||
storage_node = self.cluster.storage_nodes[0]
|
||||
|
||||
with allure.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
|
||||
]
|
||||
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(
|
||||
user_wallet.wallet_path,
|
||||
cid,
|
||||
|
@ -249,9 +227,7 @@ class TestEACLContainer(ClusterTestBase):
|
|||
)
|
||||
|
||||
@allure.title("Operations with extended ACL for SYSTEM (obj_size={object_size})")
|
||||
def test_extended_actions_system(
|
||||
self, wallets: Wallets, eacl_container_with_objects: tuple[str, list[str], str]
|
||||
):
|
||||
def test_extended_actions_system(self, wallets: Wallets, eacl_container_with_objects: tuple[str, list[str], str]):
|
||||
user_wallet = wallets.get_wallet()
|
||||
ir_wallet, storage_wallet = wallets.get_wallets_list(role=EACLRole.SYSTEM)[:2]
|
||||
|
||||
|
@ -392,8 +368,7 @@ class TestEACLContainer(ClusterTestBase):
|
|||
create_eacl(
|
||||
cid=cid,
|
||||
rules_list=[
|
||||
EACLRule(access=EACLAccess.DENY, role=EACLRole.SYSTEM, operation=op)
|
||||
for op in EACLOperation
|
||||
EACLRule(access=EACLAccess.DENY, role=EACLRole.SYSTEM, operation=op) for op in EACLOperation
|
||||
],
|
||||
shell=self.shell,
|
||||
),
|
||||
|
@ -543,8 +518,7 @@ class TestEACLContainer(ClusterTestBase):
|
|||
create_eacl(
|
||||
cid=cid,
|
||||
rules_list=[
|
||||
EACLRule(access=EACLAccess.ALLOW, role=EACLRole.SYSTEM, operation=op)
|
||||
for op in EACLOperation
|
||||
EACLRule(access=EACLAccess.ALLOW, role=EACLRole.SYSTEM, operation=op) for op in EACLOperation
|
||||
],
|
||||
shell=self.shell,
|
||||
),
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import allure
|
||||
import pytest
|
||||
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.acl import create_eacl, form_bearertoken_file, set_eacl, wait_for_cache_expired
|
||||
from frostfs_testlib.steps.cli.container import create_container, delete_container
|
||||
from frostfs_testlib.steps.cli.object import put_object_to_random_node
|
||||
from frostfs_testlib.storage.dataclasses.acl import (
|
||||
|
@ -21,15 +16,11 @@ from frostfs_testlib.storage.dataclasses.acl import (
|
|||
)
|
||||
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||
|
||||
from pytest_tests.helpers.container_access import (
|
||||
check_full_access_to_container,
|
||||
check_no_access_to_container,
|
||||
)
|
||||
from pytest_tests.helpers.container_access import check_full_access_to_container, check_no_access_to_container
|
||||
from pytest_tests.helpers.object_access import can_get_head_object, can_get_object, can_put_object
|
||||
from pytest_tests.testsuites.acl.conftest import Wallets
|
||||
|
||||
|
||||
@pytest.mark.sanity
|
||||
@pytest.mark.acl
|
||||
@pytest.mark.acl_filters
|
||||
class TestEACLFilters(ClusterTestBase):
|
||||
|
@ -46,18 +37,14 @@ class TestEACLFilters(ClusterTestBase):
|
|||
"x_key": "other_value",
|
||||
"check_key": "other_value",
|
||||
}
|
||||
REQ_EQUAL_FILTER = EACLFilter(
|
||||
key="check_key", value="check_value", header_type=EACLHeaderType.REQUEST
|
||||
)
|
||||
REQ_EQUAL_FILTER = EACLFilter(key="check_key", value="check_value", header_type=EACLHeaderType.REQUEST)
|
||||
NOT_REQ_EQUAL_FILTER = EACLFilter(
|
||||
key="check_key",
|
||||
value="other_value",
|
||||
match_type=EACLMatchType.STRING_NOT_EQUAL,
|
||||
header_type=EACLHeaderType.REQUEST,
|
||||
)
|
||||
OBJ_EQUAL_FILTER = EACLFilter(
|
||||
key="check_key", value="check_value", header_type=EACLHeaderType.OBJECT
|
||||
)
|
||||
OBJ_EQUAL_FILTER = EACLFilter(key="check_key", value="check_value", header_type=EACLHeaderType.OBJECT)
|
||||
NOT_OBJ_EQUAL_FILTER = EACLFilter(
|
||||
key="check_key",
|
||||
value="other_value",
|
||||
|
@ -128,12 +115,9 @@ class TestEACLFilters(ClusterTestBase):
|
|||
endpoint=self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
|
||||
@allure.title(
|
||||
"Operations with request filter (match_type={match_type}, obj_size={object_size})"
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"match_type", [EACLMatchType.STRING_EQUAL, EACLMatchType.STRING_NOT_EQUAL]
|
||||
)
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Operations with request filter (match_type={match_type}, obj_size={object_size})")
|
||||
@pytest.mark.parametrize("match_type", [EACLMatchType.STRING_EQUAL, EACLMatchType.STRING_NOT_EQUAL])
|
||||
def test_extended_acl_filters_request(
|
||||
self,
|
||||
wallets: Wallets,
|
||||
|
@ -174,12 +158,8 @@ class TestEACLFilters(ClusterTestBase):
|
|||
# Filter denies requests where "check_key {match_type} ATTRIBUTE", so when match_type
|
||||
# is STRING_EQUAL, then requests with "check_key=OTHER_ATTRIBUTE" will be allowed while
|
||||
# requests with "check_key=ATTRIBUTE" will be denied, and vice versa
|
||||
allow_headers = (
|
||||
self.OTHER_ATTRIBUTE if match_type == EACLMatchType.STRING_EQUAL else self.ATTRIBUTE
|
||||
)
|
||||
deny_headers = (
|
||||
self.ATTRIBUTE if match_type == EACLMatchType.STRING_EQUAL else self.OTHER_ATTRIBUTE
|
||||
)
|
||||
allow_headers = self.OTHER_ATTRIBUTE if match_type == EACLMatchType.STRING_EQUAL else self.ATTRIBUTE
|
||||
deny_headers = self.ATTRIBUTE if match_type == EACLMatchType.STRING_EQUAL else self.OTHER_ATTRIBUTE
|
||||
# We test on 3 groups of objects with various headers,
|
||||
# but eACL rule should ignore object headers and
|
||||
# work only based on request headers
|
||||
|
@ -198,9 +178,7 @@ class TestEACLFilters(ClusterTestBase):
|
|||
cluster=self.cluster,
|
||||
)
|
||||
|
||||
with allure.step(
|
||||
"Check other has full access when sending request with allowed headers"
|
||||
):
|
||||
with allure.step("Check other has full access when sending request with allowed headers"):
|
||||
check_full_access_to_container(
|
||||
other_wallet.wallet_path,
|
||||
cid,
|
||||
|
@ -223,16 +201,12 @@ class TestEACLFilters(ClusterTestBase):
|
|||
)
|
||||
|
||||
with allure.step(
|
||||
"Check other has full access when sending request "
|
||||
"with denied headers and using bearer token"
|
||||
"Check other has full access when sending request " "with denied headers and using bearer token"
|
||||
):
|
||||
bearer_other = form_bearertoken_file(
|
||||
user_wallet.wallet_path,
|
||||
cid,
|
||||
[
|
||||
EACLRule(operation=op, access=EACLAccess.ALLOW, role=EACLRole.OTHERS)
|
||||
for op in EACLOperation
|
||||
],
|
||||
[EACLRule(operation=op, access=EACLAccess.ALLOW, role=EACLRole.OTHERS) for op in EACLOperation],
|
||||
shell=self.shell,
|
||||
endpoint=self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
|
@ -247,12 +221,8 @@ class TestEACLFilters(ClusterTestBase):
|
|||
bearer=bearer_other,
|
||||
)
|
||||
|
||||
@allure.title(
|
||||
"Operations with deny user headers filter (match_type={match_type}, obj_size={object_size})"
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"match_type", [EACLMatchType.STRING_EQUAL, EACLMatchType.STRING_NOT_EQUAL]
|
||||
)
|
||||
@allure.title("Operations with deny user headers filter (match_type={match_type}, obj_size={object_size})")
|
||||
@pytest.mark.parametrize("match_type", [EACLMatchType.STRING_EQUAL, EACLMatchType.STRING_NOT_EQUAL])
|
||||
def test_extended_acl_deny_filters_object(
|
||||
self,
|
||||
wallets: Wallets,
|
||||
|
@ -290,16 +260,8 @@ class TestEACLFilters(ClusterTestBase):
|
|||
)
|
||||
wait_for_cache_expired()
|
||||
|
||||
allow_objects = (
|
||||
objects_with_other_header
|
||||
if match_type == EACLMatchType.STRING_EQUAL
|
||||
else objects_with_header
|
||||
)
|
||||
deny_objects = (
|
||||
objects_with_header
|
||||
if match_type == EACLMatchType.STRING_EQUAL
|
||||
else objects_with_other_header
|
||||
)
|
||||
allow_objects = objects_with_other_header if match_type == EACLMatchType.STRING_EQUAL else objects_with_header
|
||||
deny_objects = objects_with_header if match_type == EACLMatchType.STRING_EQUAL else objects_with_other_header
|
||||
|
||||
# We will attempt requests with various headers,
|
||||
# but eACL rule should ignore request headers and validate
|
||||
|
@ -348,9 +310,7 @@ class TestEACLFilters(ClusterTestBase):
|
|||
xhdr=xhdr,
|
||||
)
|
||||
|
||||
with allure.step(
|
||||
"Check other have access to objects with deny attribute and using bearer token"
|
||||
):
|
||||
with allure.step("Check other have access to objects with deny attribute and using bearer token"):
|
||||
bearer_other = form_bearertoken_file(
|
||||
user_wallet.wallet_path,
|
||||
cid,
|
||||
|
@ -376,9 +336,7 @@ class TestEACLFilters(ClusterTestBase):
|
|||
bearer=bearer_other,
|
||||
)
|
||||
|
||||
allow_attribute = (
|
||||
self.OTHER_ATTRIBUTE if match_type == EACLMatchType.STRING_EQUAL else self.ATTRIBUTE
|
||||
)
|
||||
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"):
|
||||
assert can_put_object(
|
||||
other_wallet.wallet_path,
|
||||
|
@ -388,13 +346,9 @@ class TestEACLFilters(ClusterTestBase):
|
|||
cluster=self.cluster,
|
||||
attributes=allow_attribute,
|
||||
)
|
||||
assert can_put_object(
|
||||
other_wallet.wallet_path, cid, file_path, shell=self.shell, cluster=self.cluster
|
||||
)
|
||||
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
|
||||
)
|
||||
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 pytest.raises(AssertionError):
|
||||
assert can_put_object(
|
||||
|
@ -406,9 +360,7 @@ class TestEACLFilters(ClusterTestBase):
|
|||
attributes=deny_attribute,
|
||||
)
|
||||
|
||||
with allure.step(
|
||||
"Check other can PUT objects with denied attribute and using bearer token"
|
||||
):
|
||||
with allure.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,
|
||||
|
@ -432,12 +384,8 @@ class TestEACLFilters(ClusterTestBase):
|
|||
bearer=bearer_other_for_put,
|
||||
)
|
||||
|
||||
@allure.title(
|
||||
"Operations with allow eACL user headers filters (match_type={match_type}, obj_size={object_size})"
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"match_type", [EACLMatchType.STRING_EQUAL, EACLMatchType.STRING_NOT_EQUAL]
|
||||
)
|
||||
@allure.title("Operations with allow eACL user headers filters (match_type={match_type}, obj_size={object_size})")
|
||||
@pytest.mark.parametrize("match_type", [EACLMatchType.STRING_EQUAL, EACLMatchType.STRING_NOT_EQUAL])
|
||||
def test_extended_acl_allow_filters_object(
|
||||
self,
|
||||
wallets: Wallets,
|
||||
|
@ -454,9 +402,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 allure.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 = [
|
||||
|
@ -511,13 +457,9 @@ class TestEACLFilters(ClusterTestBase):
|
|||
cluster=self.cluster,
|
||||
)
|
||||
with pytest.raises(AssertionError):
|
||||
assert can_put_object(
|
||||
other_wallet.wallet_path, cid, file_path, shell=self.shell, cluster=self.cluster
|
||||
)
|
||||
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 allure.step("Check other can get and put objects without attributes and using bearer token"):
|
||||
bearer_other = form_bearertoken_file(
|
||||
user_wallet.wallet_path,
|
||||
cid,
|
||||
|
@ -613,8 +555,7 @@ class TestEACLFilters(ClusterTestBase):
|
|||
)
|
||||
|
||||
with allure.step(
|
||||
"Check other can get objects without attributes matching the filter "
|
||||
"and using bearer token"
|
||||
"Check other can get objects without attributes matching the filter " "and using bearer token"
|
||||
):
|
||||
oid = deny_objects.pop()
|
||||
assert can_get_head_object(
|
||||
|
|
|
@ -21,7 +21,6 @@ from pytest_tests.resources.policy_error_patterns import (
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.sanity
|
||||
@pytest.mark.container
|
||||
@pytest.mark.policy
|
||||
class TestPolicy(ClusterTestBase):
|
||||
|
@ -93,6 +92,7 @@ class TestPolicy(ClusterTestBase):
|
|||
endpoint=endpoint,
|
||||
)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Simple policy results with one node")
|
||||
def test_simple_policy_results_with_one_node(
|
||||
self,
|
||||
|
@ -167,6 +167,7 @@ class TestPolicy(ClusterTestBase):
|
|||
with allure.step(f"Delete the container"):
|
||||
delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Policy with SELECT and FILTER results with one node")
|
||||
def test_policy_with_select_and_filter_results_with_one_node(
|
||||
self,
|
||||
|
@ -263,6 +264,7 @@ class TestPolicy(ClusterTestBase):
|
|||
with allure.step(f"Delete the container"):
|
||||
delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Policy with Multi SELECTs and FILTERs results with one node")
|
||||
def test_policy_with_multi_selects_and_filters_results_with_one_node(
|
||||
self,
|
||||
|
@ -313,6 +315,7 @@ class TestPolicy(ClusterTestBase):
|
|||
with allure.step(f"Delete the container"):
|
||||
delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Policy with SELECT and FILTER results with UNIQUE nodes")
|
||||
def test_policy_with_select_and_filter_results_with_unique_nodes(
|
||||
self,
|
||||
|
@ -819,6 +822,7 @@ class TestPolicy(ClusterTestBase):
|
|||
with allure.step(f"Delete the container"):
|
||||
delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Simple policy results with 75% of available nodes")
|
||||
def test_simple_policy_results_with_75_of_available_nodes(
|
||||
self,
|
||||
|
@ -1050,6 +1054,7 @@ class TestPolicy(ClusterTestBase):
|
|||
with allure.step(f"Delete the container"):
|
||||
delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Simple policy results with 100% of available nodes")
|
||||
def test_simple_policy_results_with_100_of_available_nodes(
|
||||
self,
|
||||
|
@ -1268,6 +1273,7 @@ class TestPolicy(ClusterTestBase):
|
|||
with allure.step(f"Delete the container"):
|
||||
delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Simple policy results with UNIQUE nodes")
|
||||
def test_simple_policy_results_with_unique_nodes(
|
||||
self,
|
||||
|
@ -1349,6 +1355,7 @@ class TestPolicy(ClusterTestBase):
|
|||
with allure.step(f"Delete the container"):
|
||||
delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Policy with SELECT and Complex FILTER results with UNIQUE nodes")
|
||||
def test_policy_with_select_and_complex_filter_results_with_unique_nodes(
|
||||
self,
|
||||
|
@ -1400,6 +1407,7 @@ class TestPolicy(ClusterTestBase):
|
|||
with allure.step(f"Delete the container"):
|
||||
delete_container(wallet=default_wallet, cid=cid, shell=self.shell, endpoint=endpoint)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Policy with Multi SELECTs and FILTERs results with UNIQUE nodes")
|
||||
def test_policy_with_multi_selects_and_filters_results_with_unique_nodes(
|
||||
self,
|
||||
|
|
|
@ -14,11 +14,7 @@ from frostfs_testlib.resources.error_patterns import (
|
|||
OBJECT_NOT_FOUND,
|
||||
)
|
||||
from frostfs_testlib.shell import Shell
|
||||
from frostfs_testlib.steps.cli.container import (
|
||||
StorageContainer,
|
||||
StorageContainerInfo,
|
||||
create_container,
|
||||
)
|
||||
from frostfs_testlib.steps.cli.container import StorageContainer, StorageContainerInfo, create_container
|
||||
from frostfs_testlib.steps.cli.object import delete_object, head_object, lock_object
|
||||
from frostfs_testlib.steps.complex_object_actions import get_link_object, get_storage_object_chunks
|
||||
from frostfs_testlib.steps.epoch import ensure_fresh_epoch, get_epoch, tick_epoch
|
||||
|
@ -27,10 +23,7 @@ from frostfs_testlib.steps.storage_object import delete_objects
|
|||
from frostfs_testlib.steps.storage_policy import get_nodes_with_object
|
||||
from frostfs_testlib.storage.cluster import Cluster
|
||||
from frostfs_testlib.storage.dataclasses.object_size import ObjectSize
|
||||
from frostfs_testlib.storage.dataclasses.storage_object_info import (
|
||||
LockObjectInfo,
|
||||
StorageObjectInfo,
|
||||
)
|
||||
from frostfs_testlib.storage.dataclasses.storage_object_info import LockObjectInfo, StorageObjectInfo
|
||||
from frostfs_testlib.storage.dataclasses.wallet import WalletFactory, WalletInfo
|
||||
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||
from frostfs_testlib.testing.test_control import expect_not_raises, wait_for_success
|
||||
|
@ -57,9 +50,7 @@ def user_wallet(wallet_factory: WalletFactory):
|
|||
scope="module",
|
||||
)
|
||||
def user_container(user_wallet: WalletInfo, client_shell: Shell, cluster: Cluster):
|
||||
container_id = create_container(
|
||||
user_wallet.path, shell=client_shell, endpoint=cluster.default_rpc_endpoint
|
||||
)
|
||||
container_id = create_container(user_wallet.path, shell=client_shell, endpoint=cluster.default_rpc_endpoint)
|
||||
return StorageContainer(StorageContainerInfo(container_id, user_wallet), client_shell, cluster)
|
||||
|
||||
|
||||
|
@ -91,9 +82,7 @@ def locked_storage_object(
|
|||
lifetime=FIXTURE_LOCK_LIFETIME,
|
||||
)
|
||||
storage_object.locks = [
|
||||
LockObjectInfo(
|
||||
storage_object.cid, lock_object_id, FIXTURE_LOCK_LIFETIME, expiration_epoch
|
||||
)
|
||||
LockObjectInfo(storage_object.cid, lock_object_id, FIXTURE_LOCK_LIFETIME, expiration_epoch)
|
||||
]
|
||||
|
||||
yield storage_object
|
||||
|
@ -117,17 +106,13 @@ def locked_storage_object(
|
|||
except Exception as ex:
|
||||
ex_message = str(ex)
|
||||
# It's okay if object already removed
|
||||
if not re.search(OBJECT_NOT_FOUND, ex_message) and not re.search(
|
||||
OBJECT_ALREADY_REMOVED, ex_message
|
||||
):
|
||||
if not re.search(OBJECT_NOT_FOUND, ex_message) and not re.search(OBJECT_ALREADY_REMOVED, ex_message):
|
||||
raise ex
|
||||
logger.debug(ex_message)
|
||||
|
||||
|
||||
@wait_for_success(datetime_utils.parse_time(STORAGE_GC_TIME))
|
||||
def check_object_not_found(
|
||||
wallet_file_path: str, cid: str, oid: str, shell: Shell, rpc_endpoint: str
|
||||
):
|
||||
def check_object_not_found(wallet_file_path: str, cid: str, oid: str, shell: Shell, rpc_endpoint: str):
|
||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||
head_object(
|
||||
wallet_file_path,
|
||||
|
@ -138,9 +123,7 @@ def check_object_not_found(
|
|||
)
|
||||
|
||||
|
||||
def verify_object_available(
|
||||
wallet_file_path: str, cid: str, oid: str, shell: Shell, rpc_endpoint: str
|
||||
):
|
||||
def verify_object_available(wallet_file_path: str, cid: str, oid: str, shell: Shell, rpc_endpoint: str):
|
||||
with expect_not_raises():
|
||||
head_object(
|
||||
wallet_file_path,
|
||||
|
@ -151,13 +134,10 @@ def verify_object_available(
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.sanity
|
||||
@pytest.mark.grpc_object_lock
|
||||
class TestObjectLockWithGrpc(ClusterTestBase):
|
||||
@pytest.fixture()
|
||||
def new_locked_storage_object(
|
||||
self, user_container: StorageContainer, object_size: ObjectSize
|
||||
) -> StorageObjectInfo:
|
||||
def new_locked_storage_object(self, user_container: StorageContainer, object_size: ObjectSize) -> StorageObjectInfo:
|
||||
"""
|
||||
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
|
||||
|
@ -284,6 +264,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
expire_at=wrong_expire_at,
|
||||
)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Expired object is deleted when locks are expired (obj_size={object_size})")
|
||||
def test_expired_object_should_be_deleted_after_locks_are_expired(
|
||||
self,
|
||||
|
@ -295,9 +276,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
"""
|
||||
|
||||
current_epoch = self.ensure_fresh_epoch()
|
||||
storage_object = user_container.generate_object(
|
||||
object_size.value, expire_at=current_epoch + 1
|
||||
)
|
||||
storage_object = user_container.generate_object(object_size.value, expire_at=current_epoch + 1)
|
||||
|
||||
with allure.step("Lock object for couple epochs"):
|
||||
lock_object(
|
||||
|
@ -355,9 +334,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
|
||||
with allure.step("Generate three objects"):
|
||||
for _ in range(3):
|
||||
storage_objects.append(
|
||||
user_container.generate_object(object_size.value, expire_at=current_epoch + 5)
|
||||
)
|
||||
storage_objects.append(user_container.generate_object(object_size.value, expire_at=current_epoch + 5))
|
||||
|
||||
lock_object(
|
||||
storage_objects[0].wallet_file_path,
|
||||
|
@ -398,16 +375,12 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
|
||||
current_epoch = self.ensure_fresh_epoch()
|
||||
|
||||
storage_object = user_container.generate_object(
|
||||
object_size.value, expire_at=current_epoch + 1
|
||||
)
|
||||
storage_object = user_container.generate_object(object_size.value, expire_at=current_epoch + 1)
|
||||
|
||||
expiration_epoch = current_epoch - 1
|
||||
with pytest.raises(
|
||||
Exception,
|
||||
match=LOCK_OBJECT_EXPIRATION.format(
|
||||
expiration_epoch=expiration_epoch, current_epoch=current_epoch
|
||||
),
|
||||
match=LOCK_OBJECT_EXPIRATION.format(expiration_epoch=expiration_epoch, current_epoch=current_epoch),
|
||||
):
|
||||
lock_object(
|
||||
storage_object.wallet_file_path,
|
||||
|
@ -418,6 +391,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
expire_at=expiration_epoch,
|
||||
)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Delete object when lock is expired by lifetime (obj_size={object_size})")
|
||||
@expect_not_raises()
|
||||
def test_after_lock_expiration_with_lifetime_user_should_be_able_to_delete_object(
|
||||
|
@ -430,9 +404,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
"""
|
||||
|
||||
current_epoch = self.ensure_fresh_epoch()
|
||||
storage_object = user_container.generate_object(
|
||||
object_size.value, expire_at=current_epoch + 5
|
||||
)
|
||||
storage_object = user_container.generate_object(object_size.value, expire_at=current_epoch + 5)
|
||||
|
||||
lock_object(
|
||||
storage_object.wallet_file_path,
|
||||
|
@ -466,9 +438,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
|
||||
current_epoch = self.ensure_fresh_epoch()
|
||||
|
||||
storage_object = user_container.generate_object(
|
||||
object_size.value, expire_at=current_epoch + 5
|
||||
)
|
||||
storage_object = user_container.generate_object(object_size.value, expire_at=current_epoch + 5)
|
||||
|
||||
lock_object(
|
||||
storage_object.wallet_file_path,
|
||||
|
@ -505,9 +475,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
Complex object chunks should also be protected from deletion
|
||||
"""
|
||||
|
||||
chunk_object_ids = get_storage_object_chunks(
|
||||
locked_storage_object, self.shell, self.cluster
|
||||
)
|
||||
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 pytest.raises(Exception, match=OBJECT_IS_LOCKED):
|
||||
|
@ -527,9 +495,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
["complex"],
|
||||
indirect=True,
|
||||
)
|
||||
def test_link_object_of_locked_complex_object_can_be_dropped(
|
||||
self, new_locked_storage_object: StorageObjectInfo
|
||||
):
|
||||
def test_link_object_of_locked_complex_object_can_be_dropped(self, new_locked_storage_object: StorageObjectInfo):
|
||||
link_object_id = get_link_object(
|
||||
new_locked_storage_object.wallet_file_path,
|
||||
new_locked_storage_object.cid,
|
||||
|
@ -557,12 +523,8 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
["complex"],
|
||||
indirect=True,
|
||||
)
|
||||
def test_chunks_of_locked_complex_object_can_be_dropped(
|
||||
self, new_locked_storage_object: StorageObjectInfo
|
||||
):
|
||||
chunk_objects = get_storage_object_chunks(
|
||||
new_locked_storage_object, self.shell, self.cluster
|
||||
)
|
||||
def test_chunks_of_locked_complex_object_can_be_dropped(self, new_locked_storage_object: StorageObjectInfo):
|
||||
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"):
|
||||
|
@ -630,9 +592,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
object_size: ObjectSize,
|
||||
):
|
||||
current_epoch = self.ensure_fresh_epoch()
|
||||
storage_object = user_container.generate_object(
|
||||
object_size.value, expire_at=current_epoch + 1
|
||||
)
|
||||
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"):
|
||||
lock_object_id_0 = lock_object(
|
||||
|
@ -705,9 +665,8 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
|
||||
@allure.title(
|
||||
"Two expired objects with one lock are deleted after lock expiration (obj_size={object_size})"
|
||||
)
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Two expired objects with one lock are deleted after lock expiration (obj_size={object_size})")
|
||||
def test_two_objects_expiration_with_one_lock(
|
||||
self,
|
||||
user_container: StorageContainer,
|
||||
|
@ -720,9 +679,7 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
with allure.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
|
||||
)
|
||||
user_container.generate_object(object_size.value, expire_at=current_epoch + epoch_i + 3)
|
||||
)
|
||||
|
||||
self.tick_epoch()
|
||||
|
|
|
@ -137,7 +137,6 @@ def static_sessions(
|
|||
}
|
||||
|
||||
|
||||
@pytest.mark.sanity
|
||||
@pytest.mark.static_session
|
||||
class TestObjectStaticSession(ClusterTestBase):
|
||||
@allure.title("Read operations with static session (method={method_under_test.__name__}, obj_size={object_size})")
|
||||
|
@ -176,6 +175,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
|||
"method_under_test,verb",
|
||||
[(get_range, ObjectVerb.RANGE), (get_range_hash, ObjectVerb.RANGEHASH)],
|
||||
)
|
||||
@pytest.mark.sanity
|
||||
def test_static_session_range(
|
||||
self,
|
||||
user_wallet: WalletInfo,
|
||||
|
@ -479,6 +479,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
|||
session=token_expire_at_next_epoch,
|
||||
)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Static session which is valid since next epoch (obj_size={object_size})")
|
||||
def test_static_session_start_at_next(
|
||||
self,
|
||||
|
@ -616,6 +617,7 @@ class TestObjectStaticSession(ClusterTestBase):
|
|||
session=static_sessions[ObjectVerb.DELETE],
|
||||
)
|
||||
|
||||
@pytest.mark.sanity
|
||||
@allure.title("Put verb is restricted for static session (obj_size={object_size})")
|
||||
def test_static_session_put_verb(
|
||||
self,
|
||||
|
|
|
@ -14,7 +14,6 @@ from frostfs_testlib.utils.file_utils import generate_file
|
|||
from pytest_tests.helpers.object_access import can_put_object
|
||||
|
||||
|
||||
@pytest.mark.sanity
|
||||
@pytest.mark.static_session_container
|
||||
class TestSessionTokenContainer(ClusterTestBase):
|
||||
@pytest.fixture(scope="module")
|
||||
|
@ -128,6 +127,7 @@ class TestSessionTokenContainer(ClusterTestBase):
|
|||
owner_wallet.path, shell=self.shell, endpoint=self.cluster.default_rpc_endpoint
|
||||
)
|
||||
|
||||
@pytest.mark.sanity
|
||||
def test_static_session_token_container_set_eacl(
|
||||
self,
|
||||
owner_wallet: WalletInfo,
|
||||
|
|
Loading…
Reference in a new issue