[#368] Extend test_object_api_lifetime
test with EC 3.1
policy
Signed-off-by: Kirill Sosnovskikh <k.sosnovskikh@yadro.com>
This commit is contained in:
parent
b03f5f46b2
commit
f8785fa299
1 changed files with 38 additions and 35 deletions
|
@ -1,58 +1,61 @@
|
|||
import logging
|
||||
|
||||
import allure
|
||||
import pytest
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.resources.error_patterns import OBJECT_NOT_FOUND
|
||||
from frostfs_testlib.steps.cli.object import get_object_from_random_node, head_object, put_object_to_random_node
|
||||
from frostfs_testlib.steps.epoch import get_epoch
|
||||
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||
from frostfs_testlib.resources.common import STORAGE_GC_TIME
|
||||
from frostfs_testlib.resources.error_patterns import OBJECT_ALREADY_REMOVED, OBJECT_NOT_FOUND
|
||||
from frostfs_testlib.steps.cli.container import DEFAULT_EC_PLACEMENT_RULE, DEFAULT_PLACEMENT_RULE
|
||||
from frostfs_testlib.storage.grpc_operations.interfaces_wrapper import GrpcClientWrapper
|
||||
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||
from frostfs_testlib.testing.test_control import expect_not_raises
|
||||
from frostfs_testlib.testing.test_control import wait_for_success
|
||||
from frostfs_testlib.utils import datetime_utils
|
||||
from frostfs_testlib.utils.file_utils import TestFile
|
||||
|
||||
from ...helpers.utility import wait_for_gc_pass_on_storage_nodes
|
||||
from ...helpers.container_request import APE_EVERYONE_ALLOW_ALL, ContainerRequest
|
||||
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
@wait_for_success(datetime_utils.parse_time(STORAGE_GC_TIME) * 5, datetime_utils.parse_time(STORAGE_GC_TIME))
|
||||
def wait_for_object_status_change_to(status: str, grpc_client: GrpcClientWrapper, cid: str, oid: str, endpoint: str) -> None:
|
||||
with pytest.raises(Exception, match=status):
|
||||
grpc_client.object.head(cid, oid, endpoint)
|
||||
|
||||
|
||||
@pytest.mark.nightly
|
||||
@pytest.mark.sanity
|
||||
@pytest.mark.grpc_api
|
||||
class TestObjectApiLifetime(ClusterTestBase):
|
||||
@allure.title("Object is removed when lifetime expired (obj_size={object_size})")
|
||||
def test_object_api_lifetime(self, container: str, test_file: TestFile, default_wallet: WalletInfo):
|
||||
@allure.title("Object is removed when lifetime expired (obj_size={object_size}, policy={container_request.short_name})")
|
||||
@pytest.mark.parametrize(
|
||||
"container_request",
|
||||
[
|
||||
ContainerRequest(DEFAULT_PLACEMENT_RULE, APE_EVERYONE_ALLOW_ALL, "REP 2"),
|
||||
ContainerRequest(DEFAULT_EC_PLACEMENT_RULE, APE_EVERYONE_ALLOW_ALL, "EC 3.1"),
|
||||
],
|
||||
)
|
||||
def test_object_api_lifetime(self, grpc_client: GrpcClientWrapper, container: str, test_file: TestFile):
|
||||
"""
|
||||
Test object deleted after expiration epoch.
|
||||
"""
|
||||
|
||||
wallet = default_wallet
|
||||
with reporter.step("Get current epoch"):
|
||||
current_epoch = self.get_epoch()
|
||||
last_active_epoch = current_epoch + 1
|
||||
|
||||
epoch = get_epoch(self.shell, self.cluster)
|
||||
with reporter.step("Put object to random node"):
|
||||
oid = grpc_client.object.put_to_random_node(test_file, container, self.cluster, expire_at=last_active_epoch)
|
||||
|
||||
oid = put_object_to_random_node(wallet, test_file.path, container, self.shell, self.cluster, expire_at=epoch + 1)
|
||||
with expect_not_raises():
|
||||
head_object(wallet, container, oid, self.shell, self.cluster.default_rpc_endpoint)
|
||||
with reporter.step("Ensure that expiration of object has expected value"):
|
||||
object_info: dict = grpc_client.object.head(container, oid, self.cluster.default_rpc_endpoint)
|
||||
expiration_epoch = int(object_info["header"]["attributes"]["__SYSTEM__EXPIRATION_EPOCH"])
|
||||
assert expiration_epoch == last_active_epoch, f"Expiration time set for object is not expected: {expiration_epoch}"
|
||||
|
||||
with reporter.step("Tick two epochs"):
|
||||
with reporter.step("Tick two epoch for object expiration"):
|
||||
self.tick_epochs(2)
|
||||
|
||||
# Wait for GC, because object with expiration is counted as alive until GC removes it
|
||||
wait_for_gc_pass_on_storage_nodes()
|
||||
with reporter.step("Wait until GC marks object as 'already removed' or 'not found'"):
|
||||
wait_for_object_status_change_to(
|
||||
f"{OBJECT_ALREADY_REMOVED}|{OBJECT_NOT_FOUND}", grpc_client, container, oid, self.cluster.default_rpc_endpoint
|
||||
)
|
||||
|
||||
with reporter.step("Check object deleted because it expires on epoch"):
|
||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||
head_object(wallet, container, oid, self.shell, self.cluster.default_rpc_endpoint)
|
||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||
get_object_from_random_node(wallet, container, oid, self.shell, self.cluster)
|
||||
|
||||
with reporter.step("Tick additional epoch"):
|
||||
self.tick_epoch()
|
||||
|
||||
wait_for_gc_pass_on_storage_nodes()
|
||||
|
||||
with reporter.step("Check object deleted because it expires on previous epoch"):
|
||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||
head_object(wallet, container, oid, self.shell, self.cluster.default_rpc_endpoint)
|
||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||
get_object_from_random_node(wallet, container, oid, self.shell, self.cluster)
|
||||
with reporter.step("Try to get object from random node and make sure it is really deleted"):
|
||||
with pytest.raises(Exception, match=f"{OBJECT_ALREADY_REMOVED}|{OBJECT_NOT_FOUND}"):
|
||||
grpc_client.object.get_from_random_node(container, oid, self.cluster)
|
||||
|
|
Loading…
Add table
Reference in a new issue