forked from TrueCloudLab/frostfs-testcases
[#321] Add tombstone expiration test
Signed-off-by: a.berezin <a.berezin@yadro.com>
This commit is contained in:
parent
aef9d43979
commit
1ee5f73243
5 changed files with 228 additions and 121 deletions
|
@ -1,7 +1,9 @@
|
|||
import json
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import shutil
|
||||
import time
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Optional
|
||||
|
||||
|
@ -14,15 +16,24 @@ from frostfs_testlib.credentials.interfaces import CredentialsProvider, User
|
|||
from frostfs_testlib.healthcheck.interfaces import Healthcheck
|
||||
from frostfs_testlib.hosting import Hosting
|
||||
from frostfs_testlib.resources import optionals
|
||||
from frostfs_testlib.resources.common import COMPLEX_OBJECT_CHUNKS_COUNT, COMPLEX_OBJECT_TAIL_SIZE, 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.interfaces import BucketContainerResolver
|
||||
from frostfs_testlib.shell import LocalShell, Shell
|
||||
from frostfs_testlib.steps.cli.container import DEFAULT_EC_PLACEMENT_RULE, DEFAULT_PLACEMENT_RULE, FROSTFS_CLI_EXEC
|
||||
from frostfs_testlib.steps.cli.container import (
|
||||
DEFAULT_EC_PLACEMENT_RULE,
|
||||
DEFAULT_PLACEMENT_RULE,
|
||||
FROSTFS_CLI_EXEC,
|
||||
create_container,
|
||||
search_nodes_with_container,
|
||||
)
|
||||
from frostfs_testlib.steps.cli.object import get_netmap_netinfo
|
||||
from frostfs_testlib.steps.epoch import ensure_fresh_epoch
|
||||
from frostfs_testlib.steps.s3 import s3_helper
|
||||
from frostfs_testlib.storage.cluster import Cluster, ClusterNode
|
||||
from frostfs_testlib.storage.controllers.cluster_state_controller import ClusterStateController
|
||||
from frostfs_testlib.storage.dataclasses import ape
|
||||
from frostfs_testlib.storage.dataclasses.frostfs_services import StorageNode
|
||||
from frostfs_testlib.storage.dataclasses.object_size import ObjectSize
|
||||
from frostfs_testlib.storage.dataclasses.policy import PlacementPolicy
|
||||
|
@ -32,8 +43,9 @@ from frostfs_testlib.storage.grpc_operations.interfaces import GrpcClientWrapper
|
|||
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||
from frostfs_testlib.testing.parallel import parallel
|
||||
from frostfs_testlib.testing.test_control import run_optionally, wait_for_success
|
||||
from frostfs_testlib.utils import 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 workspace.frostfs_testcases.pytest_tests.helpers.container_spec import ContainerSpec
|
||||
|
||||
from ..resources.common import TEST_CYCLES_COUNT
|
||||
|
||||
|
@ -158,11 +170,6 @@ def simple_object_size(max_object_size: int) -> ObjectSize:
|
|||
return ObjectSize("simple", size)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def file_path(object_size: ObjectSize) -> TestFile:
|
||||
return generate_file(object_size.value)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def complex_object_size(max_object_size: int) -> ObjectSize:
|
||||
size = max_object_size * int(COMPLEX_OBJECT_CHUNKS_COUNT) + int(COMPLEX_OBJECT_TAIL_SIZE)
|
||||
|
@ -181,6 +188,17 @@ def object_size(simple_object_size: ObjectSize, complex_object_size: ObjectSize,
|
|||
return complex_object_size
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def test_file(object_size: ObjectSize) -> TestFile:
|
||||
return generate_file(object_size.value)
|
||||
|
||||
|
||||
# Deprecated. Please migrate all to test_file
|
||||
@pytest.fixture()
|
||||
def file_path(test_file: TestFile) -> TestFile:
|
||||
return test_file
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def rep_placement_policy() -> PlacementPolicy:
|
||||
return PlacementPolicy("rep", DEFAULT_PLACEMENT_RULE)
|
||||
|
@ -469,3 +487,108 @@ def bucket_container_resolver(node_under_test: ClusterNode) -> BucketContainerRe
|
|||
resolver_cls = plugins.load_plugin("frostfs.testlib.bucket_cid_resolver", node_under_test.host.config.product)
|
||||
resolver: BucketContainerResolver = resolver_cls()
|
||||
return resolver
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def container(
|
||||
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)
|
||||
|
||||
return cid
|
||||
|
||||
|
||||
def _apply_ape_rules(frostfs_cli: FrostfsCli, cluster: Cluster, container: str, ape_rules: list[ape.Rule]):
|
||||
for ape_rule in ape_rules:
|
||||
rule_str = ape_rule.as_string()
|
||||
with reporter.step(f"Apply APE rule '{rule_str}' for container {container}"):
|
||||
frostfs_cli.ape_manager.add(
|
||||
cluster.default_rpc_endpoint,
|
||||
ape_rule.chain_id,
|
||||
target_name=container,
|
||||
target_type="container",
|
||||
rule=rule_str,
|
||||
)
|
||||
|
||||
with reporter.step("Wait for one block"):
|
||||
time.sleep(datetime_utils.parse_time(MORPH_BLOCK_TIME))
|
||||
|
||||
|
||||
def _create_container_by_spec(
|
||||
default_wallet: WalletInfo, client_shell: Shell, cluster: Cluster, rpc_endpoint: str, container_spec: ContainerSpec
|
||||
) -> str:
|
||||
# TODO: add container spec to step message
|
||||
with reporter.step("Create container"):
|
||||
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"):
|
||||
container_holder_nodes = search_nodes_with_container(default_wallet, cid, client_shell, cluster.default_rpc_endpoint, cluster)
|
||||
report_data = {node.id: node.host_ip for node in container_holder_nodes}
|
||||
|
||||
reporter.attach(json.dumps(report_data, indent=2), "container_nodes.json")
|
||||
|
||||
return cid
|
||||
|
||||
|
||||
def _get_container_spec(request: pytest.FixtureRequest) -> ContainerSpec:
|
||||
container_marker = request.node.get_closest_marker("container")
|
||||
# let default container to be public at the moment
|
||||
container_spec = ContainerSpec(basic_acl=PUBLIC_ACL)
|
||||
|
||||
if container_marker:
|
||||
if len(container_marker.args) != 1:
|
||||
raise RuntimeError(f"Something wrong with container marker: {container_marker}")
|
||||
container_spec = container_marker.args[0]
|
||||
|
||||
if "param" in request.__dict__:
|
||||
container_spec = request.param
|
||||
|
||||
if not container_spec:
|
||||
raise RuntimeError(
|
||||
f"""Container specification is empty.
|
||||
Either add @pytest.mark.container(ContainerSpec(...)) or
|
||||
@pytest.mark.parametrize(\"container\", [ContainerSpec(...)], indirect=True) decorator"""
|
||||
)
|
||||
|
||||
return container_spec
|
||||
|
||||
|
||||
def _allow_owner_via_ape(frostfs_cli: FrostfsCli, cluster: Cluster, container: str):
|
||||
with reporter.step("Create allow APE rule for container owner"):
|
||||
role_condition = ape.Condition.by_role(ape.Role.OWNER)
|
||||
ape_rule = ape.Rule(ape.Verb.ALLOW, ape.ObjectOperations.WILDCARD_ALL, role_condition)
|
||||
|
||||
frostfs_cli.ape_manager.add(
|
||||
cluster.default_rpc_endpoint,
|
||||
ape_rule.chain_id,
|
||||
target_name=container,
|
||||
target_type="container",
|
||||
rule=ape_rule.as_string(),
|
||||
)
|
||||
|
||||
with reporter.step("Wait for one block"):
|
||||
time.sleep(datetime_utils.parse_time(MORPH_BLOCK_TIME))
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def new_epoch(client_shell: Shell, cluster: Cluster) -> int:
|
||||
return ensure_fresh_epoch(client_shell, cluster)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue