[#322] Remove basic acl part one #322
4 changed files with 73 additions and 61 deletions
|
@ -42,3 +42,7 @@ class ContainerSpec:
|
||||||
spec_info.append(f"ape_rules=[{ape_rules_list}]")
|
spec_info.append(f"ape_rules=[{ape_rules_list}]")
|
||||||
|
|
||||||
return f"ContainerSpec({', '.join(spec_info)})"
|
return f"ContainerSpec({', '.join(spec_info)})"
|
||||||
|
|
||||||
|
|
||||||
|
class ContainerSpecs:
|
||||||
|
PublicReadWrite = ContainerSpec(ape_rules=APE_PUBLIC_READ_WRITE)
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import random
|
import random
|
||||||
import shutil
|
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
@ -17,7 +15,6 @@ from frostfs_testlib.healthcheck.interfaces import Healthcheck
|
||||||
from frostfs_testlib.hosting import Hosting
|
from frostfs_testlib.hosting import Hosting
|
||||||
from frostfs_testlib.resources import optionals
|
from frostfs_testlib.resources import optionals
|
||||||
from frostfs_testlib.resources.common import COMPLEX_OBJECT_CHUNKS_COUNT, COMPLEX_OBJECT_TAIL_SIZE, MORPH_BLOCK_TIME, SIMPLE_OBJECT_SIZE
|
from frostfs_testlib.resources.common import COMPLEX_OBJECT_CHUNKS_COUNT, COMPLEX_OBJECT_TAIL_SIZE, MORPH_BLOCK_TIME, SIMPLE_OBJECT_SIZE
|
||||||
from frostfs_testlib.resources.wellknown_acl import PUBLIC_ACL
|
|
||||||
from frostfs_testlib.s3 import AwsCliClient, Boto3ClientWrapper, S3ClientWrapper, VersioningStatus
|
from frostfs_testlib.s3 import AwsCliClient, Boto3ClientWrapper, S3ClientWrapper, VersioningStatus
|
||||||
from frostfs_testlib.s3.interfaces import BucketContainerResolver
|
from frostfs_testlib.s3.interfaces import BucketContainerResolver
|
||||||
from frostfs_testlib.shell import LocalShell, Shell
|
from frostfs_testlib.shell import LocalShell, Shell
|
||||||
|
@ -42,11 +39,11 @@ from frostfs_testlib.storage.grpc_operations.client_wrappers import CliClientWra
|
||||||
from frostfs_testlib.storage.grpc_operations.interfaces import GrpcClientWrapper
|
from frostfs_testlib.storage.grpc_operations.interfaces import GrpcClientWrapper
|
||||||
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||||
from frostfs_testlib.testing.parallel import parallel
|
from frostfs_testlib.testing.parallel import parallel
|
||||||
from frostfs_testlib.testing.test_control import run_optionally, wait_for_success
|
from frostfs_testlib.testing.test_control import cached_fixture, run_optionally, wait_for_success
|
||||||
from frostfs_testlib.utils import datetime_utils, env_utils, string_utils, version_utils
|
from frostfs_testlib.utils import datetime_utils, env_utils, string_utils, version_utils
|
||||||
from frostfs_testlib.utils.file_utils import TestFile, generate_file
|
from frostfs_testlib.utils.file_utils import TestFile, generate_file
|
||||||
from workspace.frostfs_testcases.pytest_tests.helpers.container_spec import ContainerSpec
|
|
||||||
|
|
||||||
|
from ..helpers.container_spec import ContainerSpec, ContainerSpecs
|
||||||
from ..resources.common import TEST_CYCLES_COUNT
|
from ..resources.common import TEST_CYCLES_COUNT
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
@ -153,15 +150,16 @@ def require_multiple_interfaces(cluster: Cluster):
|
||||||
interfaces = cluster.cluster_nodes[0].host.config.interfaces
|
interfaces = cluster.cluster_nodes[0].host.config.interfaces
|
||||||
if "internal1" not in interfaces or "data1" not in interfaces:
|
if "internal1" not in interfaces or "data1" not in interfaces:
|
||||||
pytest.skip("This test requires multiple internal and data interfaces")
|
pytest.skip("This test requires multiple internal and data interfaces")
|
||||||
yield
|
return
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
|
@cached_fixture(optionals.OPTIONAL_CACHE_FIXTURES)
|
||||||
def max_object_size(cluster: Cluster, client_shell: Shell) -> int:
|
def max_object_size(cluster: Cluster, client_shell: Shell) -> int:
|
||||||
storage_node = cluster.storage_nodes[0]
|
storage_node = cluster.storage_nodes[0]
|
||||||
wallet = WalletInfo.from_node(storage_node)
|
wallet = WalletInfo.from_node(storage_node)
|
||||||
net_info = get_netmap_netinfo(wallet=wallet, endpoint=storage_node.get_rpc_endpoint(), shell=client_shell)
|
net_info = get_netmap_netinfo(wallet=wallet, endpoint=storage_node.get_rpc_endpoint(), shell=client_shell)
|
||||||
yield net_info["maximum_object_size"]
|
return net_info["maximum_object_size"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
|
@ -436,6 +434,7 @@ def readiness_on_node(cluster_node: ClusterNode):
|
||||||
|
|
||||||
@reporter.step("Prepare default user with wallet")
|
@reporter.step("Prepare default user with wallet")
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
|
@cached_fixture(optionals.OPTIONAL_CACHE_FIXTURES)
|
||||||
def default_user(credentials_provider: CredentialsProvider, cluster: Cluster) -> User:
|
def default_user(credentials_provider: CredentialsProvider, cluster: Cluster) -> User:
|
||||||
user = User(string_utils.unique_name("user-"))
|
user = User(string_utils.unique_name("user-"))
|
||||||
node = cluster.cluster_nodes[0]
|
node = cluster.cluster_nodes[0]
|
||||||
|
@ -512,6 +511,38 @@ def container(
|
||||||
if container_spec.ape_rules:
|
if container_spec.ape_rules:
|
||||||
_apply_ape_rules(frostfs_cli, cluster, cid, container_spec.ape_rules)
|
_apply_ape_rules(frostfs_cli, cluster, cid, container_spec.ape_rules)
|
||||||
|
|
||||||
|
# Add marker if we want to run all tests with container
|
||||||
|
request.node.add_marker("requires_container")
|
||||||
|
|
||||||
|
return cid
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def container_module_scope(
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli: FrostfsCli,
|
||||||
|
client_shell: Shell,
|
||||||
|
cluster: Cluster,
|
||||||
|
request: pytest.FixtureRequest,
|
||||||
|
rpc_endpoint: str,
|
||||||
|
) -> str:
|
||||||
|
with reporter.step("Get container specification for test"):
|
||||||
|
container_spec = _get_container_spec(request)
|
||||||
|
|
||||||
|
with reporter.step("Create container"):
|
||||||
|
cid = _create_container_by_spec(default_wallet, client_shell, cluster, rpc_endpoint, container_spec)
|
||||||
|
# TODO: deprecate this. Use generic ContainerSpec.ape_rule param
|
||||||
|
if container_spec.allow_owner_via_ape:
|
||||||
|
with reporter.step("Allow owner via APE on container"):
|
||||||
|
_allow_owner_via_ape(frostfs_cli, cluster, cid)
|
||||||
|
|
||||||
|
with reporter.step("Apply APE rules for container"):
|
||||||
|
if container_spec.ape_rules:
|
||||||
|
_apply_ape_rules(frostfs_cli, cluster, cid, container_spec.ape_rules)
|
||||||
|
|
||||||
|
# Add marker if we want to run all tests with container
|
||||||
|
request.node.add_marker("requires_container")
|
||||||
|
|
||||||
return cid
|
return cid
|
||||||
|
|
||||||
|
|
||||||
|
@ -534,11 +565,8 @@ def _apply_ape_rules(frostfs_cli: FrostfsCli, cluster: Cluster, container: str,
|
||||||
def _create_container_by_spec(
|
def _create_container_by_spec(
|
||||||
default_wallet: WalletInfo, client_shell: Shell, cluster: Cluster, rpc_endpoint: str, container_spec: ContainerSpec
|
default_wallet: WalletInfo, client_shell: Shell, cluster: Cluster, rpc_endpoint: str, container_spec: ContainerSpec
|
||||||
) -> str:
|
) -> str:
|
||||||
# TODO: add container spec to step message
|
with reporter.step(f"Create container by spec {container_spec}"):
|
||||||
with reporter.step("Create container"):
|
cid = create_container(default_wallet, client_shell, rpc_endpoint, container_spec.parsed_rule(cluster))
|
||||||
cid = create_container(
|
|
||||||
default_wallet, client_shell, rpc_endpoint, basic_acl=container_spec.basic_acl, rule=container_spec.parsed_rule(cluster)
|
|
||||||
)
|
|
||||||
|
|
||||||
with reporter.step("Search nodes holding the container"):
|
with reporter.step("Search nodes holding the container"):
|
||||||
container_holder_nodes = search_nodes_with_container(default_wallet, cid, client_shell, cluster.default_rpc_endpoint, cluster)
|
container_holder_nodes = search_nodes_with_container(default_wallet, cid, client_shell, cluster.default_rpc_endpoint, cluster)
|
||||||
|
@ -552,7 +580,7 @@ def _create_container_by_spec(
|
||||||
def _get_container_spec(request: pytest.FixtureRequest) -> ContainerSpec:
|
def _get_container_spec(request: pytest.FixtureRequest) -> ContainerSpec:
|
||||||
container_marker = request.node.get_closest_marker("container")
|
container_marker = request.node.get_closest_marker("container")
|
||||||
# let default container to be public at the moment
|
# let default container to be public at the moment
|
||||||
container_spec = ContainerSpec(basic_acl=PUBLIC_ACL)
|
container_spec = ContainerSpecs.PublicReadWrite
|
||||||
|
|
||||||
if container_marker:
|
if container_marker:
|
||||||
if len(container_marker.args) != 1:
|
if len(container_marker.args) != 1:
|
||||||
|
@ -592,3 +620,8 @@ def _allow_owner_via_ape(frostfs_cli: FrostfsCli, cluster: Cluster, container: s
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def new_epoch(client_shell: Shell, cluster: Cluster) -> int:
|
def new_epoch(client_shell: Shell, cluster: Cluster) -> int:
|
||||||
return ensure_fresh_epoch(client_shell, cluster)
|
return ensure_fresh_epoch(client_shell, cluster)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def new_epoch_module_scope(client_shell: Shell, cluster: Cluster) -> int:
|
||||||
|
return ensure_fresh_epoch(client_shell, cluster)
|
||||||
|
|
|
@ -4,14 +4,15 @@ import allure
|
||||||
import pytest
|
import pytest
|
||||||
from frostfs_testlib import reporter
|
from frostfs_testlib import reporter
|
||||||
from frostfs_testlib.resources.error_patterns import OBJECT_NOT_FOUND
|
from frostfs_testlib.resources.error_patterns import OBJECT_NOT_FOUND
|
||||||
from frostfs_testlib.steps.cli.container import create_container
|
|
||||||
from frostfs_testlib.steps.cli.object import get_object_from_random_node, head_object, put_object_to_random_node
|
from frostfs_testlib.steps.cli.object import get_object_from_random_node, head_object, put_object_to_random_node
|
||||||
from frostfs_testlib.steps.epoch import get_epoch
|
from frostfs_testlib.steps.epoch import get_epoch
|
||||||
from frostfs_testlib.storage.dataclasses.object_size import ObjectSize
|
from frostfs_testlib.storage.dataclasses.object_size import ObjectSize
|
||||||
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||||
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||||
from frostfs_testlib.utils.file_utils import generate_file, get_file_hash
|
from frostfs_testlib.testing.test_control import expect_not_raises
|
||||||
|
from frostfs_testlib.utils.file_utils import TestFile
|
||||||
|
|
||||||
|
from ...helpers.container_spec import ContainerSpecs
|
||||||
from ...helpers.utility import wait_for_gc_pass_on_storage_nodes
|
from ...helpers.utility import wait_for_gc_pass_on_storage_nodes
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
@ -21,36 +22,32 @@ logger = logging.getLogger("NeoLogger")
|
||||||
@pytest.mark.sanity
|
@pytest.mark.sanity
|
||||||
@pytest.mark.grpc_api
|
@pytest.mark.grpc_api
|
||||||
class TestObjectApiLifetime(ClusterTestBase):
|
class TestObjectApiLifetime(ClusterTestBase):
|
||||||
|
@pytest.mark.container(ContainerSpecs.PublicReadWrite)
|
||||||
@allure.title("Object is removed when lifetime expired (obj_size={object_size})")
|
@allure.title("Object is removed when lifetime expired (obj_size={object_size})")
|
||||||
def test_object_api_lifetime(self, default_wallet: WalletInfo, object_size: ObjectSize):
|
def test_object_api_lifetime(self, container: str, test_file: TestFile, default_wallet: WalletInfo, object_size: ObjectSize):
|
||||||
"""
|
"""
|
||||||
Test object deleted after expiration epoch.
|
Test object deleted after expiration epoch.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
wallet = default_wallet
|
wallet = default_wallet
|
||||||
endpoint = self.cluster.default_rpc_endpoint
|
|
||||||
cid = create_container(wallet, self.shell, endpoint)
|
|
||||||
|
|
||||||
file_path = generate_file(object_size.value)
|
|
||||||
file_hash = get_file_hash(file_path)
|
|
||||||
epoch = get_epoch(self.shell, self.cluster)
|
epoch = get_epoch(self.shell, self.cluster)
|
||||||
|
|
||||||
oid = put_object_to_random_node(wallet, file_path, cid, self.shell, self.cluster, expire_at=epoch + 1)
|
oid = put_object_to_random_node(wallet, test_file.path, container, self.shell, self.cluster, expire_at=epoch + 1)
|
||||||
got_file = get_object_from_random_node(wallet, cid, oid, self.shell, self.cluster)
|
with expect_not_raises():
|
||||||
assert get_file_hash(got_file) == file_hash
|
head_object(wallet, container, oid, self.shell, self.cluster.default_rpc_endpoint)
|
||||||
|
|
||||||
with reporter.step("Tick two epochs"):
|
with reporter.step("Tick two epochs"):
|
||||||
for _ in range(2):
|
self.tick_epochs(2)
|
||||||
self.tick_epoch()
|
|
||||||
|
|
||||||
# Wait for GC, because object with expiration is counted as alive until GC removes it
|
# Wait for GC, because object with expiration is counted as alive until GC removes it
|
||||||
wait_for_gc_pass_on_storage_nodes()
|
wait_for_gc_pass_on_storage_nodes()
|
||||||
|
|
||||||
with reporter.step("Check object deleted because it expires on epoch"):
|
with reporter.step("Check object deleted because it expires on epoch"):
|
||||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||||
head_object(wallet, cid, oid, self.shell, self.cluster.default_rpc_endpoint)
|
head_object(wallet, container, oid, self.shell, self.cluster.default_rpc_endpoint)
|
||||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||||
get_object_from_random_node(wallet, cid, oid, self.shell, self.cluster)
|
get_object_from_random_node(wallet, container, oid, self.shell, self.cluster)
|
||||||
|
|
||||||
with reporter.step("Tick additional epoch"):
|
with reporter.step("Tick additional epoch"):
|
||||||
self.tick_epoch()
|
self.tick_epoch()
|
||||||
|
@ -59,6 +56,6 @@ class TestObjectApiLifetime(ClusterTestBase):
|
||||||
|
|
||||||
with reporter.step("Check object deleted because it expires on previous epoch"):
|
with reporter.step("Check object deleted because it expires on previous epoch"):
|
||||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||||
head_object(wallet, cid, oid, self.shell, self.cluster.default_rpc_endpoint)
|
head_object(wallet, container, oid, self.shell, self.cluster.default_rpc_endpoint)
|
||||||
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
with pytest.raises(Exception, match=OBJECT_NOT_FOUND):
|
||||||
get_object_from_random_node(wallet, cid, oid, self.shell, self.cluster)
|
get_object_from_random_node(wallet, container, oid, self.shell, self.cluster)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import logging
|
import logging
|
||||||
import re
|
|
||||||
|
|
||||||
import allure
|
import allure
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -11,15 +10,14 @@ from frostfs_testlib.resources.error_patterns import (
|
||||||
LOCK_NON_REGULAR_OBJECT,
|
LOCK_NON_REGULAR_OBJECT,
|
||||||
LOCK_OBJECT_EXPIRATION,
|
LOCK_OBJECT_EXPIRATION,
|
||||||
LOCK_OBJECT_REMOVAL,
|
LOCK_OBJECT_REMOVAL,
|
||||||
OBJECT_ALREADY_REMOVED,
|
|
||||||
OBJECT_IS_LOCKED,
|
OBJECT_IS_LOCKED,
|
||||||
OBJECT_NOT_FOUND,
|
OBJECT_NOT_FOUND,
|
||||||
)
|
)
|
||||||
from frostfs_testlib.shell import Shell
|
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
|
||||||
from frostfs_testlib.steps.cli.object import delete_object, head_object, lock_object
|
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.complex_object_actions import get_link_object, get_storage_object_chunks
|
||||||
from frostfs_testlib.steps.epoch import ensure_fresh_epoch, get_epoch, tick_epoch
|
from frostfs_testlib.steps.epoch import ensure_fresh_epoch
|
||||||
from frostfs_testlib.steps.node_management import drop_object
|
from frostfs_testlib.steps.node_management import drop_object
|
||||||
from frostfs_testlib.steps.storage_object import delete_objects
|
from frostfs_testlib.steps.storage_object import delete_objects
|
||||||
from frostfs_testlib.steps.storage_policy import get_nodes_with_object
|
from frostfs_testlib.steps.storage_policy import get_nodes_with_object
|
||||||
|
@ -31,6 +29,7 @@ from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||||
from frostfs_testlib.testing.test_control import expect_not_raises, wait_for_success
|
from frostfs_testlib.testing.test_control import expect_not_raises, wait_for_success
|
||||||
from frostfs_testlib.utils import datetime_utils, string_utils
|
from frostfs_testlib.utils import datetime_utils, string_utils
|
||||||
|
|
||||||
|
from ...helpers.container_spec import ContainerSpecs
|
||||||
from ...helpers.utility import wait_for_gc_pass_on_storage_nodes
|
from ...helpers.utility import wait_for_gc_pass_on_storage_nodes
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
@ -38,6 +37,8 @@ logger = logging.getLogger("NeoLogger")
|
||||||
FIXTURE_LOCK_LIFETIME = 5
|
FIXTURE_LOCK_LIFETIME = 5
|
||||||
FIXTURE_OBJECT_LIFETIME = 10
|
FIXTURE_OBJECT_LIFETIME = 10
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.container(ContainerSpecs.PublicReadWrite)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def user_wallet(credentials_provider: CredentialsProvider, cluster: Cluster) -> WalletInfo:
|
def user_wallet(credentials_provider: CredentialsProvider, cluster: Cluster) -> WalletInfo:
|
||||||
|
@ -47,13 +48,13 @@ def user_wallet(credentials_provider: CredentialsProvider, cluster: Cluster) ->
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def user_container(user_wallet: WalletInfo, client_shell: Shell, cluster: Cluster):
|
def user_container(container_module_scope: str, user_wallet: WalletInfo, client_shell: Shell, cluster: Cluster):
|
||||||
container_id = create_container(user_wallet, shell=client_shell, endpoint=cluster.default_rpc_endpoint)
|
return StorageContainer(StorageContainerInfo(container_module_scope, user_wallet), client_shell, cluster)
|
||||||
return StorageContainer(StorageContainerInfo(container_id, user_wallet), client_shell, cluster)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def locked_storage_object(
|
def locked_storage_object(
|
||||||
|
new_epoch_module_scope: int,
|
||||||
user_container: StorageContainer,
|
user_container: StorageContainer,
|
||||||
client_shell: Shell,
|
client_shell: Shell,
|
||||||
cluster: Cluster,
|
cluster: Cluster,
|
||||||
|
@ -63,7 +64,7 @@ def locked_storage_object(
|
||||||
Intention of this fixture is to provide storage object which is NOT expected to be deleted during test act phase
|
Intention of this fixture is to provide storage object which is NOT expected to be deleted during test act phase
|
||||||
"""
|
"""
|
||||||
with reporter.step("Creating locked object"):
|
with reporter.step("Creating locked object"):
|
||||||
current_epoch = ensure_fresh_epoch(client_shell, cluster)
|
current_epoch = new_epoch_module_scope
|
||||||
expiration_epoch = current_epoch + FIXTURE_LOCK_LIFETIME
|
expiration_epoch = current_epoch + FIXTURE_LOCK_LIFETIME
|
||||||
|
|
||||||
storage_object = user_container.generate_object(object_size.value, expire_at=current_epoch + FIXTURE_OBJECT_LIFETIME)
|
storage_object = user_container.generate_object(object_size.value, expire_at=current_epoch + FIXTURE_OBJECT_LIFETIME)
|
||||||
|
@ -77,30 +78,7 @@ def locked_storage_object(
|
||||||
)
|
)
|
||||||
storage_object.locks = [LockObjectInfo(storage_object.cid, lock_object_id, FIXTURE_LOCK_LIFETIME, expiration_epoch)]
|
storage_object.locks = [LockObjectInfo(storage_object.cid, lock_object_id, FIXTURE_LOCK_LIFETIME, expiration_epoch)]
|
||||||
|
|
||||||
yield storage_object
|
return storage_object
|
||||||
|
|
||||||
with reporter.step("Delete created locked object"):
|
|
||||||
current_epoch = get_epoch(client_shell, cluster)
|
|
||||||
epoch_diff = expiration_epoch - current_epoch + 1
|
|
||||||
|
|
||||||
if epoch_diff > 0:
|
|
||||||
with reporter.step(f"Tick {epoch_diff} epochs"):
|
|
||||||
for _ in range(epoch_diff):
|
|
||||||
tick_epoch(client_shell, cluster)
|
|
||||||
try:
|
|
||||||
delete_object(
|
|
||||||
storage_object.wallet,
|
|
||||||
storage_object.cid,
|
|
||||||
storage_object.oid,
|
|
||||||
client_shell,
|
|
||||||
cluster.default_rpc_endpoint,
|
|
||||||
)
|
|
||||||
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):
|
|
||||||
raise ex
|
|
||||||
logger.debug(ex_message)
|
|
||||||
|
|
||||||
|
|
||||||
@wait_for_success(datetime_utils.parse_time(STORAGE_GC_TIME))
|
@wait_for_success(datetime_utils.parse_time(STORAGE_GC_TIME))
|
||||||
|
|
Loading…
Reference in a new issue