forked from TrueCloudLab/frostfs-testcases
Compare commits
1 commit
master
...
object-loc
Author | SHA1 | Date | |
---|---|---|---|
9c5fe134bc |
1 changed files with 180 additions and 12 deletions
|
@ -126,6 +126,20 @@ def locked_storage_object(
|
|||
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, default_rpc_endpoint: str
|
||||
):
|
||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||
head_object(
|
||||
wallet_file_path,
|
||||
cid,
|
||||
oid,
|
||||
shell,
|
||||
default_rpc_endpoint,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.sanity
|
||||
@pytest.mark.grpc_object_lock
|
||||
class TestObjectLockWithGrpc(ClusterTestBase):
|
||||
|
@ -328,20 +342,15 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
|
||||
@wait_for_success(datetime_utils.parse_time(STORAGE_GC_TIME))
|
||||
def check_object_not_found():
|
||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||
head_object(
|
||||
storage_object.wallet_file_path,
|
||||
storage_object.cid,
|
||||
storage_object.oid,
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
|
||||
with allure.step("Wait for object to be deleted after third epoch"):
|
||||
self.tick_epoch()
|
||||
check_object_not_found()
|
||||
check_object_not_found(
|
||||
storage_object.wallet_file_path,
|
||||
storage_object.cid,
|
||||
storage_object.oid,
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
|
||||
@allure.title("Should be possible to lock multiple objects at once for {object_size}")
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -658,3 +667,162 @@ class TestObjectLockWithGrpc(ClusterTestBase):
|
|||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
|
||||
@allure.title("Expired object should be removes after relocks")
|
||||
@pytest.mark.parametrize(
|
||||
"object_size",
|
||||
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||
ids=["simple object", "complex object"],
|
||||
)
|
||||
def test_expired_object_should_be_removed_after_relocks_expare_at(
|
||||
self,
|
||||
request: FixtureRequest,
|
||||
user_container: StorageContainer,
|
||||
object_size: int,
|
||||
):
|
||||
|
||||
allure.dynamic.title(
|
||||
f"Expired object should be removes after relocks are expired for {request.node.callspec.id}"
|
||||
)
|
||||
|
||||
current_epoch = self.ensure_fresh_epoch()
|
||||
storage_object = user_container.generate_object(object_size, expire_at=current_epoch + 1)
|
||||
|
||||
with allure.step("Lock object for couple epochs"):
|
||||
lock_object_id_0 = lock_object(
|
||||
storage_object.wallet_file_path,
|
||||
storage_object.cid,
|
||||
storage_object.oid,
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
expire_at=current_epoch + 3,
|
||||
)
|
||||
|
||||
def check_lock_object(lock_object_id: str):
|
||||
try:
|
||||
head_object(
|
||||
storage_object.wallet_file_path,
|
||||
storage_object.cid,
|
||||
lock_object_id,
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
except Exception as ex:
|
||||
ex_message = str(ex)
|
||||
if not re.search(OBJECT_NOT_FOUND, ex_message) and not re.search(
|
||||
OBJECT_ALREADY_REMOVED, ex_message
|
||||
):
|
||||
raise ex
|
||||
logger.debug(ex_message)
|
||||
|
||||
self.tick_epochs(2)
|
||||
|
||||
with allure.step("Check previous lock"):
|
||||
check_lock_object(lock_object_id_0)
|
||||
|
||||
with allure.step("Lock object for couple epochs"):
|
||||
lock_object_id_1 = lock_object(
|
||||
storage_object.wallet_file_path,
|
||||
storage_object.cid,
|
||||
storage_object.oid,
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
expire_at=current_epoch + 5,
|
||||
)
|
||||
|
||||
self.tick_epochs(2)
|
||||
|
||||
with allure.step("Check previous locks"):
|
||||
check_object_not_found(
|
||||
storage_object.wallet_file_path,
|
||||
storage_object.cid,
|
||||
lock_object_id_0,
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
check_lock_object(lock_object_id_1)
|
||||
|
||||
with allure.step("Lock object for couple epochs"):
|
||||
lock_object(
|
||||
storage_object.wallet_file_path,
|
||||
storage_object.cid,
|
||||
storage_object.oid,
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
expire_at=current_epoch + 7,
|
||||
)
|
||||
|
||||
with allure.step("Wait for object to be deleted"):
|
||||
self.tick_epochs(4)
|
||||
check_object_not_found(
|
||||
storage_object.wallet_file_path,
|
||||
storage_object.cid,
|
||||
storage_object.oid,
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
|
||||
@allure.title("Expired two objects with one lock should be deleted after locks")
|
||||
@pytest.mark.parametrize(
|
||||
"object_size",
|
||||
[pytest.lazy_fixture("simple_object_size"), pytest.lazy_fixture("complex_object_size")],
|
||||
ids=["simple object", "complex object"],
|
||||
)
|
||||
def test_two_objects_expiration_with_one_lock(
|
||||
self,
|
||||
request: FixtureRequest,
|
||||
user_container: StorageContainer,
|
||||
object_size: int,
|
||||
):
|
||||
|
||||
allure.dynamic.title(
|
||||
f"Expired two objects with one lock should be deleted after locks are expired for {request.node.callspec.id}"
|
||||
)
|
||||
|
||||
current_epoch = self.ensure_fresh_epoch()
|
||||
storage_objects: list[StorageObjectInfo] = []
|
||||
|
||||
with allure.step("Generate two objects"):
|
||||
for epoch_i in range(2):
|
||||
storage_objects.append(
|
||||
user_container.generate_object(
|
||||
object_size, expire_at=current_epoch + epoch_i + 3
|
||||
)
|
||||
)
|
||||
|
||||
self.tick_epoch()
|
||||
|
||||
with allure.step("Lock object for couple epochs"):
|
||||
lock_object(
|
||||
storage_objects[0].wallet_file_path,
|
||||
storage_objects[0].cid,
|
||||
",".join([storage_object.oid for storage_object in storage_objects]),
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
expire_at=current_epoch + 4,
|
||||
)
|
||||
|
||||
with allure.step("Check object is available at expiration time"):
|
||||
for epoch_i in range(3):
|
||||
self.tick_epoch()
|
||||
with allure.step(f"Check objects at epoch {current_epoch + epoch_i + 2}"):
|
||||
for storage_object in storage_objects:
|
||||
with expect_not_raises():
|
||||
head_object(
|
||||
storage_object.wallet_file_path,
|
||||
storage_object.cid,
|
||||
storage_object.oid,
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
|
||||
with allure.step("Wait for object to be deleted"):
|
||||
self.tick_epoch()
|
||||
for storage_object in storage_objects:
|
||||
check_object_not_found(
|
||||
storage_object.wallet_file_path,
|
||||
storage_object.cid,
|
||||
storage_object.oid,
|
||||
self.shell,
|
||||
self.cluster.default_rpc_endpoint,
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue