forked from TrueCloudLab/frostfs-testlib
[#133] Change reporter usage
Signed-off-by: Andrey Berezin <a.berezin@yadro.com>
This commit is contained in:
parent
39a17f3634
commit
dc6b0e407f
37 changed files with 478 additions and 678 deletions
|
@ -8,8 +8,8 @@ from typing import List, Optional, Union
|
|||
|
||||
import base58
|
||||
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.cli import FrostfsCli
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.resources.cli import FROSTFS_CLI_EXEC
|
||||
from frostfs_testlib.resources.common import ASSETS_DIR, DEFAULT_WALLET_CONFIG
|
||||
from frostfs_testlib.shell import Shell
|
||||
|
@ -22,11 +22,10 @@ from frostfs_testlib.storage.dataclasses.acl import (
|
|||
)
|
||||
from frostfs_testlib.utils import wallet_utils
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
|
||||
@reporter.step_deco("Get extended ACL")
|
||||
@reporter.step("Get extended ACL")
|
||||
def get_eacl(wallet_path: str, cid: str, shell: Shell, endpoint: str) -> Optional[str]:
|
||||
cli = FrostfsCli(shell, FROSTFS_CLI_EXEC, DEFAULT_WALLET_CONFIG)
|
||||
try:
|
||||
|
@ -40,7 +39,7 @@ def get_eacl(wallet_path: str, cid: str, shell: Shell, endpoint: str) -> Optiona
|
|||
return result.stdout
|
||||
|
||||
|
||||
@reporter.step_deco("Set extended ACL")
|
||||
@reporter.step("Set extended ACL")
|
||||
def set_eacl(
|
||||
wallet_path: str,
|
||||
cid: str,
|
||||
|
@ -165,24 +164,20 @@ def eacl_rules(access: str, verbs: list, user: str) -> list[str]:
|
|||
return rules
|
||||
|
||||
|
||||
def sign_bearer(
|
||||
shell: Shell, wallet_path: str, eacl_rules_file_from: str, eacl_rules_file_to: str, json: bool
|
||||
) -> None:
|
||||
frostfscli = FrostfsCli(
|
||||
shell=shell, frostfs_cli_exec_path=FROSTFS_CLI_EXEC, config_file=DEFAULT_WALLET_CONFIG
|
||||
)
|
||||
def sign_bearer(shell: Shell, wallet_path: str, eacl_rules_file_from: str, eacl_rules_file_to: str, json: bool) -> None:
|
||||
frostfscli = FrostfsCli(shell=shell, frostfs_cli_exec_path=FROSTFS_CLI_EXEC, config_file=DEFAULT_WALLET_CONFIG)
|
||||
frostfscli.util.sign_bearer_token(
|
||||
wallet=wallet_path, from_file=eacl_rules_file_from, to_file=eacl_rules_file_to, json=json
|
||||
)
|
||||
|
||||
|
||||
@reporter.step_deco("Wait for eACL cache expired")
|
||||
@reporter.step("Wait for eACL cache expired")
|
||||
def wait_for_cache_expired():
|
||||
sleep(FROSTFS_CONTRACT_CACHE_TIMEOUT)
|
||||
return
|
||||
|
||||
|
||||
@reporter.step_deco("Return bearer token in base64 to caller")
|
||||
@reporter.step("Return bearer token in base64 to caller")
|
||||
def bearer_token_base64_from_file(
|
||||
bearer_path: str,
|
||||
) -> str:
|
||||
|
|
|
@ -5,8 +5,8 @@ from dataclasses import dataclass
|
|||
from time import sleep
|
||||
from typing import Optional, Union
|
||||
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.cli import FrostfsCli
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.resources.cli import CLI_DEFAULT_TIMEOUT, FROSTFS_CLI_EXEC
|
||||
from frostfs_testlib.resources.common import DEFAULT_WALLET_CONFIG
|
||||
from frostfs_testlib.shell import Shell
|
||||
|
@ -17,7 +17,6 @@ from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
|||
from frostfs_testlib.utils import json_utils
|
||||
from frostfs_testlib.utils.file_utils import generate_file, get_file_hash
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
|
||||
|
@ -47,7 +46,7 @@ class StorageContainer:
|
|||
def get_wallet_config_path(self) -> str:
|
||||
return self.storage_container_info.wallet_file.config_path
|
||||
|
||||
@reporter.step_deco("Generate new object and put in container")
|
||||
@reporter.step("Generate new object and put in container")
|
||||
def generate_object(
|
||||
self,
|
||||
size: int,
|
||||
|
@ -103,7 +102,7 @@ SINGLE_PLACEMENT_RULE = "REP 1 IN X CBF 1 SELECT 4 FROM * AS X"
|
|||
REP_2_FOR_3_NODES_PLACEMENT_RULE = "REP 2 IN X CBF 1 SELECT 3 FROM * AS X"
|
||||
|
||||
|
||||
@reporter.step_deco("Create Container")
|
||||
@reporter.step("Create Container")
|
||||
def create_container(
|
||||
wallet: str,
|
||||
shell: Shell,
|
||||
|
@ -178,9 +177,7 @@ def wait_for_container_creation(
|
|||
return
|
||||
logger.info(f"There is no {cid} in {containers} yet; sleep {sleep_interval} and continue")
|
||||
sleep(sleep_interval)
|
||||
raise RuntimeError(
|
||||
f"After {attempts * sleep_interval} seconds container {cid} hasn't been persisted; exiting"
|
||||
)
|
||||
raise RuntimeError(f"After {attempts * sleep_interval} seconds container {cid} hasn't been persisted; exiting")
|
||||
|
||||
|
||||
def wait_for_container_deletion(
|
||||
|
@ -198,7 +195,7 @@ def wait_for_container_deletion(
|
|||
raise AssertionError(f"Expected container deleted during {attempts * sleep_interval} sec.")
|
||||
|
||||
|
||||
@reporter.step_deco("List Containers")
|
||||
@reporter.step("List Containers")
|
||||
def list_containers(
|
||||
wallet: str, shell: Shell, endpoint: str, timeout: Optional[str] = CLI_DEFAULT_TIMEOUT
|
||||
) -> list[str]:
|
||||
|
@ -219,7 +216,7 @@ def list_containers(
|
|||
return result.stdout.split()
|
||||
|
||||
|
||||
@reporter.step_deco("List Objects in container")
|
||||
@reporter.step("List Objects in container")
|
||||
def list_objects(
|
||||
wallet: str,
|
||||
shell: Shell,
|
||||
|
@ -240,14 +237,12 @@ def list_objects(
|
|||
(list): list of containers
|
||||
"""
|
||||
cli = FrostfsCli(shell, FROSTFS_CLI_EXEC, DEFAULT_WALLET_CONFIG)
|
||||
result = cli.container.list_objects(
|
||||
rpc_endpoint=endpoint, wallet=wallet, cid=container_id, timeout=timeout
|
||||
)
|
||||
result = cli.container.list_objects(rpc_endpoint=endpoint, wallet=wallet, cid=container_id, timeout=timeout)
|
||||
logger.info(f"Container objects: \n{result}")
|
||||
return result.stdout.split()
|
||||
|
||||
|
||||
@reporter.step_deco("Get Container")
|
||||
@reporter.step("Get Container")
|
||||
def get_container(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -271,9 +266,7 @@ def get_container(
|
|||
"""
|
||||
|
||||
cli = FrostfsCli(shell, FROSTFS_CLI_EXEC, DEFAULT_WALLET_CONFIG)
|
||||
result = cli.container.get(
|
||||
rpc_endpoint=endpoint, wallet=wallet, cid=cid, json_mode=json_mode, timeout=timeout
|
||||
)
|
||||
result = cli.container.get(rpc_endpoint=endpoint, wallet=wallet, cid=cid, json_mode=json_mode, timeout=timeout)
|
||||
|
||||
if not json_mode:
|
||||
return result.stdout
|
||||
|
@ -287,7 +280,7 @@ def get_container(
|
|||
return container_info
|
||||
|
||||
|
||||
@reporter.step_deco("Delete Container")
|
||||
@reporter.step("Delete Container")
|
||||
# TODO: make the error message about a non-found container more user-friendly
|
||||
def delete_container(
|
||||
wallet: str,
|
||||
|
@ -350,7 +343,7 @@ def _parse_cid(output: str) -> str:
|
|||
return splitted[1]
|
||||
|
||||
|
||||
@reporter.step_deco("Search container by name")
|
||||
@reporter.step("Search container by name")
|
||||
def search_container_by_name(wallet: str, name: str, shell: Shell, endpoint: str):
|
||||
list_cids = list_containers(wallet, shell, endpoint)
|
||||
for cid in list_cids:
|
||||
|
@ -360,7 +353,7 @@ def search_container_by_name(wallet: str, name: str, shell: Shell, endpoint: str
|
|||
return None
|
||||
|
||||
|
||||
@reporter.step_deco("Search for nodes with a container")
|
||||
@reporter.step("Search for nodes with a container")
|
||||
def search_nodes_with_container(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -370,9 +363,7 @@ def search_nodes_with_container(
|
|||
timeout: Optional[str] = CLI_DEFAULT_TIMEOUT,
|
||||
) -> list[ClusterNode]:
|
||||
cli = FrostfsCli(shell, FROSTFS_CLI_EXEC, DEFAULT_WALLET_CONFIG)
|
||||
result = cli.container.search_node(
|
||||
rpc_endpoint=endpoint, wallet=wallet, cid=cid, timeout=timeout
|
||||
)
|
||||
result = cli.container.search_node(rpc_endpoint=endpoint, wallet=wallet, cid=cid, timeout=timeout)
|
||||
|
||||
pattern = r"[0-9]+(?:\.[0-9]+){3}"
|
||||
nodes_ip = list(set(re.findall(pattern, result.stdout)))
|
||||
|
|
|
@ -5,9 +5,9 @@ import re
|
|||
import uuid
|
||||
from typing import Any, Optional
|
||||
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.cli import FrostfsCli
|
||||
from frostfs_testlib.cli.neogo import NeoGo
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.resources.cli import CLI_DEFAULT_TIMEOUT, FROSTFS_CLI_EXEC, NEOGO_EXECUTABLE
|
||||
from frostfs_testlib.resources.common import ASSETS_DIR, DEFAULT_WALLET_CONFIG
|
||||
from frostfs_testlib.shell import Shell
|
||||
|
@ -16,10 +16,9 @@ from frostfs_testlib.utils import json_utils
|
|||
from frostfs_testlib.utils.cli_utils import parse_cmd_table, parse_netmap_output
|
||||
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
reporter = get_reporter()
|
||||
|
||||
|
||||
@reporter.step_deco("Get object from random node")
|
||||
@reporter.step("Get object from random node")
|
||||
def get_object_from_random_node(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -70,7 +69,7 @@ def get_object_from_random_node(
|
|||
)
|
||||
|
||||
|
||||
@reporter.step_deco("Get object from {endpoint}")
|
||||
@reporter.step("Get object from {endpoint}")
|
||||
def get_object(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -126,7 +125,7 @@ def get_object(
|
|||
return file_path
|
||||
|
||||
|
||||
@reporter.step_deco("Get Range Hash from {endpoint}")
|
||||
@reporter.step("Get Range Hash from {endpoint}")
|
||||
def get_range_hash(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -176,7 +175,7 @@ def get_range_hash(
|
|||
return result.stdout.split(":")[1].strip()
|
||||
|
||||
|
||||
@reporter.step_deco("Put object to random node")
|
||||
@reporter.step("Put object to random node")
|
||||
def put_object_to_random_node(
|
||||
wallet: str,
|
||||
path: str,
|
||||
|
@ -235,7 +234,7 @@ def put_object_to_random_node(
|
|||
)
|
||||
|
||||
|
||||
@reporter.step_deco("Put object at {endpoint} in container {cid}")
|
||||
@reporter.step("Put object at {endpoint} in container {cid}")
|
||||
def put_object(
|
||||
wallet: str,
|
||||
path: str,
|
||||
|
@ -296,7 +295,7 @@ def put_object(
|
|||
return oid.strip()
|
||||
|
||||
|
||||
@reporter.step_deco("Delete object {cid}/{oid} from {endpoint}")
|
||||
@reporter.step("Delete object {cid}/{oid} from {endpoint}")
|
||||
def delete_object(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -344,7 +343,7 @@ def delete_object(
|
|||
return tombstone.strip()
|
||||
|
||||
|
||||
@reporter.step_deco("Get Range")
|
||||
@reporter.step("Get Range")
|
||||
def get_range(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -397,7 +396,7 @@ def get_range(
|
|||
return range_file_path, content
|
||||
|
||||
|
||||
@reporter.step_deco("Lock Object")
|
||||
@reporter.step("Lock Object")
|
||||
def lock_object(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -458,7 +457,7 @@ def lock_object(
|
|||
return oid.strip()
|
||||
|
||||
|
||||
@reporter.step_deco("Search object")
|
||||
@reporter.step("Search object")
|
||||
def search_object(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -503,9 +502,7 @@ def search_object(
|
|||
cid=cid,
|
||||
bearer=bearer,
|
||||
xhdr=xhdr,
|
||||
filters=[f"{filter_key} EQ {filter_val}" for filter_key, filter_val in filters.items()]
|
||||
if filters
|
||||
else None,
|
||||
filters=[f"{filter_key} EQ {filter_val}" for filter_key, filter_val in filters.items()] if filters else None,
|
||||
session=session,
|
||||
phy=phy,
|
||||
root=root,
|
||||
|
@ -517,19 +514,17 @@ def search_object(
|
|||
if expected_objects_list:
|
||||
if sorted(found_objects) == sorted(expected_objects_list):
|
||||
logger.info(
|
||||
f"Found objects list '{found_objects}' "
|
||||
f"is equal for expected list '{expected_objects_list}'"
|
||||
f"Found objects list '{found_objects}' " f"is equal for expected list '{expected_objects_list}'"
|
||||
)
|
||||
else:
|
||||
logger.warning(
|
||||
f"Found object list {found_objects} "
|
||||
f"is not equal to expected list '{expected_objects_list}'"
|
||||
f"Found object list {found_objects} " f"is not equal to expected list '{expected_objects_list}'"
|
||||
)
|
||||
|
||||
return found_objects
|
||||
|
||||
|
||||
@reporter.step_deco("Get netmap netinfo")
|
||||
@reporter.step("Get netmap netinfo")
|
||||
def get_netmap_netinfo(
|
||||
wallet: str,
|
||||
shell: Shell,
|
||||
|
@ -581,7 +576,7 @@ def get_netmap_netinfo(
|
|||
return settings
|
||||
|
||||
|
||||
@reporter.step_deco("Head object")
|
||||
@reporter.step("Head object")
|
||||
def head_object(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -677,7 +672,7 @@ def head_object(
|
|||
return json_utils.decode_simple_header(decoded)
|
||||
|
||||
|
||||
@reporter.step_deco("Run neo-go dump-keys")
|
||||
@reporter.step("Run neo-go dump-keys")
|
||||
def neo_go_dump_keys(shell: Shell, wallet: str) -> dict:
|
||||
"""
|
||||
Run neo-go dump keys command
|
||||
|
@ -702,7 +697,7 @@ def neo_go_dump_keys(shell: Shell, wallet: str) -> dict:
|
|||
return {address_id: wallet_key}
|
||||
|
||||
|
||||
@reporter.step_deco("Run neo-go query height")
|
||||
@reporter.step("Run neo-go query height")
|
||||
def neo_go_query_height(shell: Shell, endpoint: str) -> dict:
|
||||
"""
|
||||
Run neo-go query height command
|
||||
|
@ -734,7 +729,7 @@ def neo_go_query_height(shell: Shell, endpoint: str) -> dict:
|
|||
}
|
||||
|
||||
|
||||
@reporter.step_deco("Search object nodes")
|
||||
@reporter.step("Search object nodes")
|
||||
def get_object_nodes(
|
||||
cluster: Cluster,
|
||||
wallet: str,
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
import logging
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.resources.cli import CLI_DEFAULT_TIMEOUT
|
||||
from frostfs_testlib.resources.common import DEFAULT_WALLET_CONFIG
|
||||
from frostfs_testlib.shell import Shell
|
||||
|
@ -20,7 +20,6 @@ from frostfs_testlib.steps.cli.object import head_object
|
|||
from frostfs_testlib.storage.cluster import Cluster, StorageNode
|
||||
from frostfs_testlib.storage.dataclasses.storage_object_info import StorageObjectInfo
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
|
||||
|
@ -113,7 +112,7 @@ def get_complex_object_split_ranges(
|
|||
return ranges
|
||||
|
||||
|
||||
@reporter.step_deco("Get Link Object")
|
||||
@reporter.step("Get Link Object")
|
||||
def get_link_object(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
@ -166,7 +165,7 @@ def get_link_object(
|
|||
return None
|
||||
|
||||
|
||||
@reporter.step_deco("Get Last Object")
|
||||
@reporter.step("Get Last Object")
|
||||
def get_last_object(
|
||||
wallet: str,
|
||||
cid: str,
|
||||
|
|
|
@ -2,8 +2,8 @@ import logging
|
|||
from time import sleep
|
||||
from typing import Optional
|
||||
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.cli import FrostfsAdm, FrostfsCli, NeoGo
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.resources.cli import (
|
||||
CLI_DEFAULT_TIMEOUT,
|
||||
FROSTFS_ADM_CONFIG_PATH,
|
||||
|
@ -19,11 +19,10 @@ from frostfs_testlib.storage.dataclasses.frostfs_services import InnerRing, Morp
|
|||
from frostfs_testlib.testing.test_control import wait_for_success
|
||||
from frostfs_testlib.utils import datetime_utils, wallet_utils
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
|
||||
@reporter.step_deco("Get epochs from nodes")
|
||||
@reporter.step("Get epochs from nodes")
|
||||
def get_epochs_from_nodes(shell: Shell, cluster: Cluster) -> dict[str, int]:
|
||||
"""
|
||||
Get current epochs on each node.
|
||||
|
@ -41,10 +40,8 @@ def get_epochs_from_nodes(shell: Shell, cluster: Cluster) -> dict[str, int]:
|
|||
return epochs_by_node
|
||||
|
||||
|
||||
@reporter.step_deco("Ensure fresh epoch")
|
||||
def ensure_fresh_epoch(
|
||||
shell: Shell, cluster: Cluster, alive_node: Optional[StorageNode] = None
|
||||
) -> int:
|
||||
@reporter.step("Ensure fresh epoch")
|
||||
def ensure_fresh_epoch(shell: Shell, cluster: Cluster, alive_node: Optional[StorageNode] = None) -> int:
|
||||
# ensure new fresh epoch to avoid epoch switch during test session
|
||||
alive_node = alive_node if alive_node else cluster.services(StorageNode)[0]
|
||||
current_epoch = get_epoch(shell, cluster, alive_node)
|
||||
|
@ -54,7 +51,7 @@ def ensure_fresh_epoch(
|
|||
return epoch
|
||||
|
||||
|
||||
@reporter.step_deco("Wait up to {timeout} seconds for nodes on cluster to align epochs")
|
||||
@reporter.step("Wait up to {timeout} seconds for nodes on cluster to align epochs")
|
||||
def wait_for_epochs_align(shell: Shell, cluster: Cluster, timeout=60):
|
||||
@wait_for_success(timeout, 5, None, True)
|
||||
def check_epochs():
|
||||
|
@ -64,7 +61,7 @@ def wait_for_epochs_align(shell: Shell, cluster: Cluster, timeout=60):
|
|||
check_epochs()
|
||||
|
||||
|
||||
@reporter.step_deco("Get Epoch")
|
||||
@reporter.step("Get Epoch")
|
||||
def get_epoch(shell: Shell, cluster: Cluster, alive_node: Optional[StorageNode] = None):
|
||||
alive_node = alive_node if alive_node else cluster.services(StorageNode)[0]
|
||||
endpoint = alive_node.get_rpc_endpoint()
|
||||
|
@ -77,7 +74,7 @@ def get_epoch(shell: Shell, cluster: Cluster, alive_node: Optional[StorageNode]
|
|||
return int(epoch.stdout)
|
||||
|
||||
|
||||
@reporter.step_deco("Tick Epoch")
|
||||
@reporter.step("Tick Epoch")
|
||||
def tick_epoch(shell: Shell, cluster: Cluster, alive_node: Optional[StorageNode] = None):
|
||||
"""
|
||||
Tick epoch using frostfs-adm or NeoGo if frostfs-adm is not available (DevEnv)
|
||||
|
|
|
@ -10,7 +10,7 @@ from urllib.parse import quote_plus
|
|||
|
||||
import requests
|
||||
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.resources.common import SIMPLE_OBJECT_SIZE
|
||||
from frostfs_testlib.s3.aws_cli_client import command_options
|
||||
from frostfs_testlib.shell import Shell
|
||||
|
@ -21,15 +21,13 @@ from frostfs_testlib.storage.cluster import StorageNode
|
|||
from frostfs_testlib.testing.test_control import retry
|
||||
from frostfs_testlib.utils.file_utils import get_file_hash
|
||||
|
||||
reporter = get_reporter()
|
||||
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
ASSETS_DIR = os.getenv("ASSETS_DIR", "TemporaryDir/")
|
||||
local_shell = LocalShell()
|
||||
|
||||
|
||||
@reporter.step_deco("Get via HTTP Gate")
|
||||
@reporter.step("Get via HTTP Gate")
|
||||
def get_via_http_gate(
|
||||
cid: str,
|
||||
oid: str,
|
||||
|
@ -53,9 +51,7 @@ def get_via_http_gate(
|
|||
else:
|
||||
request = f"{endpoint}{request_path}"
|
||||
|
||||
resp = requests.get(
|
||||
request, headers={"Host": http_hostname}, stream=True, timeout=timeout, verify=False
|
||||
)
|
||||
resp = requests.get(request, headers={"Host": http_hostname}, stream=True, timeout=timeout, verify=False)
|
||||
|
||||
if not resp.ok:
|
||||
raise Exception(
|
||||
|
@ -75,10 +71,8 @@ def get_via_http_gate(
|
|||
return file_path
|
||||
|
||||
|
||||
@reporter.step_deco("Get via Zip HTTP Gate")
|
||||
def get_via_zip_http_gate(
|
||||
cid: str, prefix: str, endpoint: str, http_hostname: str, timeout: Optional[int] = 300
|
||||
):
|
||||
@reporter.step("Get via Zip HTTP Gate")
|
||||
def get_via_zip_http_gate(cid: str, prefix: str, endpoint: str, http_hostname: str, timeout: Optional[int] = 300):
|
||||
"""
|
||||
This function gets given object from HTTP gate
|
||||
cid: container id to get object from
|
||||
|
@ -111,7 +105,7 @@ def get_via_zip_http_gate(
|
|||
return os.path.join(os.getcwd(), ASSETS_DIR, prefix)
|
||||
|
||||
|
||||
@reporter.step_deco("Get via HTTP Gate by attribute")
|
||||
@reporter.step("Get via HTTP Gate by attribute")
|
||||
def get_via_http_gate_by_attribute(
|
||||
cid: str,
|
||||
attribute: dict,
|
||||
|
@ -136,9 +130,7 @@ def get_via_http_gate_by_attribute(
|
|||
else:
|
||||
request = f"{endpoint}{request_path}"
|
||||
|
||||
resp = requests.get(
|
||||
request, stream=True, timeout=timeout, verify=False, headers={"Host": http_hostname}
|
||||
)
|
||||
resp = requests.get(request, stream=True, timeout=timeout, verify=False, headers={"Host": http_hostname})
|
||||
|
||||
if not resp.ok:
|
||||
raise Exception(
|
||||
|
@ -159,7 +151,7 @@ def get_via_http_gate_by_attribute(
|
|||
|
||||
|
||||
# TODO: pass http_hostname as a header
|
||||
@reporter.step_deco("Upload via HTTP Gate")
|
||||
@reporter.step("Upload via HTTP Gate")
|
||||
def upload_via_http_gate(
|
||||
cid: str, path: str, endpoint: str, headers: Optional[dict] = None, timeout: Optional[int] = 300
|
||||
) -> str:
|
||||
|
@ -173,9 +165,7 @@ def upload_via_http_gate(
|
|||
request = f"{endpoint}/upload/{cid}"
|
||||
files = {"upload_file": open(path, "rb")}
|
||||
body = {"filename": path}
|
||||
resp = requests.post(
|
||||
request, files=files, data=body, headers=headers, timeout=timeout, verify=False
|
||||
)
|
||||
resp = requests.post(request, files=files, data=body, headers=headers, timeout=timeout, verify=False)
|
||||
|
||||
if not resp.ok:
|
||||
raise Exception(
|
||||
|
@ -193,7 +183,7 @@ def upload_via_http_gate(
|
|||
return resp.json().get("object_id")
|
||||
|
||||
|
||||
@reporter.step_deco("Check is the passed object large")
|
||||
@reporter.step("Check is the passed object large")
|
||||
def is_object_large(filepath: str) -> bool:
|
||||
"""
|
||||
This function check passed file size and return True if file_size > SIMPLE_OBJECT_SIZE
|
||||
|
@ -208,7 +198,7 @@ def is_object_large(filepath: str) -> bool:
|
|||
|
||||
|
||||
# TODO: pass http_hostname as a header
|
||||
@reporter.step_deco("Upload via HTTP Gate using Curl")
|
||||
@reporter.step("Upload via HTTP Gate using Curl")
|
||||
def upload_via_http_gate_curl(
|
||||
cid: str,
|
||||
filepath: str,
|
||||
|
@ -256,7 +246,7 @@ def upload_via_http_gate_curl(
|
|||
|
||||
|
||||
@retry(max_attempts=3, sleep_interval=1)
|
||||
@reporter.step_deco("Get via HTTP Gate using Curl")
|
||||
@reporter.step("Get via HTTP Gate using Curl")
|
||||
def get_via_http_curl(cid: str, oid: str, endpoint: str, http_hostname: str) -> str:
|
||||
"""
|
||||
This function gets given object from HTTP gate using curl utility.
|
||||
|
@ -280,7 +270,7 @@ def _attach_allure_step(request: str, status_code: int, req_type="GET"):
|
|||
reporter.attach(command_attachment, f"{req_type} Request")
|
||||
|
||||
|
||||
@reporter.step_deco("Try to get object and expect error")
|
||||
@reporter.step("Try to get object and expect error")
|
||||
def try_to_get_object_and_expect_error(
|
||||
cid: str,
|
||||
oid: str,
|
||||
|
@ -296,7 +286,7 @@ def try_to_get_object_and_expect_error(
|
|||
assert match, f"Expected {err} to match {error_pattern}"
|
||||
|
||||
|
||||
@reporter.step_deco("Verify object can be get using HTTP header attribute")
|
||||
@reporter.step("Verify object can be get using HTTP header attribute")
|
||||
def get_object_by_attr_and_verify_hashes(
|
||||
oid: str,
|
||||
file_name: str,
|
||||
|
@ -305,9 +295,7 @@ def get_object_by_attr_and_verify_hashes(
|
|||
endpoint: str,
|
||||
http_hostname: str,
|
||||
) -> None:
|
||||
got_file_path_http = get_via_http_gate(
|
||||
cid=cid, oid=oid, endpoint=endpoint, http_hostname=http_hostname
|
||||
)
|
||||
got_file_path_http = get_via_http_gate(cid=cid, oid=oid, endpoint=endpoint, http_hostname=http_hostname)
|
||||
got_file_path_http_attr = get_via_http_gate_by_attribute(
|
||||
cid=cid, attribute=attrs, endpoint=endpoint, http_hostname=http_hostname
|
||||
)
|
||||
|
@ -348,9 +336,7 @@ def verify_object_hash(
|
|||
shell=shell,
|
||||
endpoint=random_node.get_rpc_endpoint(),
|
||||
)
|
||||
got_file_path_http = object_getter(
|
||||
cid=cid, oid=oid, endpoint=endpoint, http_hostname=http_hostname
|
||||
)
|
||||
got_file_path_http = object_getter(cid=cid, oid=oid, endpoint=endpoint, http_hostname=http_hostname)
|
||||
|
||||
assert_hashes_are_equal(file_name, got_file_path, got_file_path_http)
|
||||
|
||||
|
@ -359,18 +345,14 @@ def assert_hashes_are_equal(orig_file_name: str, got_file_1: str, got_file_2: st
|
|||
msg = "Expected hashes are equal for files {f1} and {f2}"
|
||||
got_file_hash_http = get_file_hash(got_file_1)
|
||||
assert get_file_hash(got_file_2) == got_file_hash_http, msg.format(f1=got_file_2, f2=got_file_1)
|
||||
assert get_file_hash(orig_file_name) == got_file_hash_http, msg.format(
|
||||
f1=orig_file_name, f2=got_file_1
|
||||
)
|
||||
assert get_file_hash(orig_file_name) == got_file_hash_http, msg.format(f1=orig_file_name, f2=got_file_1)
|
||||
|
||||
|
||||
def attr_into_header(attrs: dict) -> dict:
|
||||
return {f"X-Attribute-{_key}": _value for _key, _value in attrs.items()}
|
||||
|
||||
|
||||
@reporter.step_deco(
|
||||
"Convert each attribute (Key=Value) to the following format: -H 'X-Attribute-Key: Value'"
|
||||
)
|
||||
@reporter.step("Convert each attribute (Key=Value) to the following format: -H 'X-Attribute-Key: Value'")
|
||||
def attr_into_str_header_curl(attrs: dict) -> list:
|
||||
headers = []
|
||||
for k, v in attrs.items():
|
||||
|
@ -379,9 +361,7 @@ def attr_into_str_header_curl(attrs: dict) -> list:
|
|||
return headers
|
||||
|
||||
|
||||
@reporter.step_deco(
|
||||
"Try to get object via http (pass http_request and optional attributes) and expect error"
|
||||
)
|
||||
@reporter.step("Try to get object via http (pass http_request and optional attributes) and expect error")
|
||||
def try_to_get_object_via_passed_request_and_expect_error(
|
||||
cid: str,
|
||||
oid: str,
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.storage.cluster import ClusterNode
|
||||
from frostfs_testlib.testing.test_control import retry
|
||||
|
||||
reporter = get_reporter()
|
||||
|
||||
|
||||
class IpTablesHelper:
|
||||
@staticmethod
|
||||
|
@ -21,11 +19,7 @@ class IpTablesHelper:
|
|||
@staticmethod
|
||||
def restore_input_traffic_to_port(node: ClusterNode) -> None:
|
||||
shell = node.host.get_shell()
|
||||
ports = (
|
||||
shell.exec("iptables -L --numeric | grep DROP | awk '{print $7}'")
|
||||
.stdout.strip()
|
||||
.split("\n")
|
||||
)
|
||||
ports = shell.exec("iptables -L --numeric | grep DROP | awk '{print $7}'").stdout.strip().split("\n")
|
||||
if ports[0] == "":
|
||||
return
|
||||
for port in ports:
|
||||
|
@ -34,11 +28,7 @@ class IpTablesHelper:
|
|||
@staticmethod
|
||||
def restore_input_traffic_to_node(node: ClusterNode) -> None:
|
||||
shell = node.host.get_shell()
|
||||
unlock_ip = (
|
||||
shell.exec("iptables -L --numeric | grep DROP | awk '{print $4}'")
|
||||
.stdout.strip()
|
||||
.split("\n")
|
||||
)
|
||||
unlock_ip = shell.exec("iptables -L --numeric | grep DROP | awk '{print $4}'").stdout.strip().split("\n")
|
||||
if unlock_ip[0] == "":
|
||||
return
|
||||
for ip in unlock_ip:
|
||||
|
@ -47,17 +37,17 @@ class IpTablesHelper:
|
|||
|
||||
# TODO Move class to HOST
|
||||
class IfUpDownHelper:
|
||||
@reporter.step_deco("Down {interface} to {node}")
|
||||
@reporter.step("Down {interface} to {node}")
|
||||
def down_interface(self, node: ClusterNode, interface: str) -> None:
|
||||
shell = node.host.get_shell()
|
||||
shell.exec(f"ifdown {interface}")
|
||||
|
||||
@reporter.step_deco("Up {interface} to {node}")
|
||||
@reporter.step("Up {interface} to {node}")
|
||||
def up_interface(self, node: ClusterNode, interface: str) -> None:
|
||||
shell = node.host.get_shell()
|
||||
shell.exec(f"ifup {interface}")
|
||||
|
||||
@reporter.step_deco("Up all interface to {node}")
|
||||
@reporter.step("Up all interface to {node}")
|
||||
def up_all_interface(self, node: ClusterNode) -> None:
|
||||
shell = node.host.get_shell()
|
||||
interfaces = list(node.host.config.interfaces.keys())
|
||||
|
@ -65,7 +55,7 @@ class IfUpDownHelper:
|
|||
for name_interface in interfaces:
|
||||
self.check_state_up(node, name_interface)
|
||||
|
||||
@reporter.step_deco("Down all interface to {node}")
|
||||
@reporter.step("Down all interface to {node}")
|
||||
def down_all_interface(self, node: ClusterNode) -> None:
|
||||
shell = node.host.get_shell()
|
||||
interfaces = list(node.host.config.interfaces.keys())
|
||||
|
@ -73,12 +63,10 @@ class IfUpDownHelper:
|
|||
for name_interface in interfaces:
|
||||
self.check_state_down(node, name_interface)
|
||||
|
||||
@reporter.step_deco("Check {node} to {interface}")
|
||||
@reporter.step("Check {node} to {interface}")
|
||||
def check_state(self, node: ClusterNode, interface: str) -> str:
|
||||
shell = node.host.get_shell()
|
||||
return shell.exec(
|
||||
f"ip link show {interface} | sed -z 's/.*state \(.*\) mode .*/\\1/'"
|
||||
).stdout.strip()
|
||||
return shell.exec(f"ip link show {interface} | sed -z 's/.*state \(.*\) mode .*/\\1/'").stdout.strip()
|
||||
|
||||
@retry(max_attempts=5, sleep_interval=5, expected_result="UP")
|
||||
def check_state_up(self, node: ClusterNode, interface: str) -> str:
|
||||
|
|
|
@ -6,13 +6,9 @@ from dataclasses import dataclass
|
|||
from time import sleep
|
||||
from typing import Optional
|
||||
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.cli import FrostfsAdm, FrostfsCli
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.resources.cli import (
|
||||
FROSTFS_ADM_CONFIG_PATH,
|
||||
FROSTFS_ADM_EXEC,
|
||||
FROSTFS_CLI_EXEC,
|
||||
)
|
||||
from frostfs_testlib.resources.cli import FROSTFS_ADM_CONFIG_PATH, FROSTFS_ADM_EXEC, FROSTFS_CLI_EXEC
|
||||
from frostfs_testlib.resources.common import MORPH_BLOCK_TIME
|
||||
from frostfs_testlib.shell import Shell
|
||||
from frostfs_testlib.steps.epoch import tick_epoch, wait_for_epochs_align
|
||||
|
@ -20,7 +16,6 @@ from frostfs_testlib.storage.cluster import Cluster, StorageNode
|
|||
from frostfs_testlib.storage.dataclasses.frostfs_services import S3Gate
|
||||
from frostfs_testlib.utils import datetime_utils
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
|
||||
|
@ -40,7 +35,7 @@ class HealthStatus:
|
|||
return HealthStatus(network, health)
|
||||
|
||||
|
||||
@reporter.step_deco("Get Locode from random storage node")
|
||||
@reporter.step("Get Locode from random storage node")
|
||||
def get_locode_from_random_node(cluster: Cluster) -> str:
|
||||
node = random.choice(cluster.services(StorageNode))
|
||||
locode = node.get_un_locode()
|
||||
|
@ -48,7 +43,7 @@ def get_locode_from_random_node(cluster: Cluster) -> str:
|
|||
return locode
|
||||
|
||||
|
||||
@reporter.step_deco("Healthcheck for storage node {node}")
|
||||
@reporter.step("Healthcheck for storage node {node}")
|
||||
def storage_node_healthcheck(node: StorageNode) -> HealthStatus:
|
||||
"""
|
||||
The function returns storage node's health status.
|
||||
|
@ -62,7 +57,7 @@ def storage_node_healthcheck(node: StorageNode) -> HealthStatus:
|
|||
return HealthStatus.from_stdout(output)
|
||||
|
||||
|
||||
@reporter.step_deco("Set status for {node}")
|
||||
@reporter.step("Set status for {node}")
|
||||
def storage_node_set_status(node: StorageNode, status: str, retries: int = 0) -> None:
|
||||
"""
|
||||
The function sets particular status for given node.
|
||||
|
@ -75,7 +70,7 @@ def storage_node_set_status(node: StorageNode, status: str, retries: int = 0) ->
|
|||
_run_control_command_with_retries(node, command, retries)
|
||||
|
||||
|
||||
@reporter.step_deco("Get netmap snapshot")
|
||||
@reporter.step("Get netmap snapshot")
|
||||
def get_netmap_snapshot(node: StorageNode, shell: Shell) -> str:
|
||||
"""
|
||||
The function returns string representation of netmap snapshot.
|
||||
|
@ -95,7 +90,7 @@ def get_netmap_snapshot(node: StorageNode, shell: Shell) -> str:
|
|||
).stdout
|
||||
|
||||
|
||||
@reporter.step_deco("Get shard list for {node}")
|
||||
@reporter.step("Get shard list for {node}")
|
||||
def node_shard_list(node: StorageNode) -> list[str]:
|
||||
"""
|
||||
The function returns list of shards for specified storage node.
|
||||
|
@ -109,7 +104,7 @@ def node_shard_list(node: StorageNode) -> list[str]:
|
|||
return re.findall(r"Shard (.*):", output)
|
||||
|
||||
|
||||
@reporter.step_deco("Shard set for {node}")
|
||||
@reporter.step("Shard set for {node}")
|
||||
def node_shard_set_mode(node: StorageNode, shard: str, mode: str) -> str:
|
||||
"""
|
||||
The function sets mode for specified shard.
|
||||
|
@ -120,7 +115,7 @@ def node_shard_set_mode(node: StorageNode, shard: str, mode: str) -> str:
|
|||
return _run_control_command_with_retries(node, command)
|
||||
|
||||
|
||||
@reporter.step_deco("Drop object from {node}")
|
||||
@reporter.step("Drop object from {node}")
|
||||
def drop_object(node: StorageNode, cid: str, oid: str) -> str:
|
||||
"""
|
||||
The function drops object from specified node.
|
||||
|
@ -131,14 +126,14 @@ def drop_object(node: StorageNode, cid: str, oid: str) -> str:
|
|||
return _run_control_command_with_retries(node, command)
|
||||
|
||||
|
||||
@reporter.step_deco("Delete data from host for node {node}")
|
||||
@reporter.step("Delete data from host for node {node}")
|
||||
def delete_node_data(node: StorageNode) -> None:
|
||||
node.stop_service()
|
||||
node.host.delete_storage_node_data(node.name)
|
||||
time.sleep(datetime_utils.parse_time(MORPH_BLOCK_TIME))
|
||||
|
||||
|
||||
@reporter.step_deco("Exclude node {node_to_exclude} from network map")
|
||||
@reporter.step("Exclude node {node_to_exclude} from network map")
|
||||
def exclude_node_from_network_map(
|
||||
node_to_exclude: StorageNode,
|
||||
alive_node: StorageNode,
|
||||
|
@ -154,12 +149,10 @@ def exclude_node_from_network_map(
|
|||
wait_for_epochs_align(shell, cluster)
|
||||
|
||||
snapshot = get_netmap_snapshot(node=alive_node, shell=shell)
|
||||
assert (
|
||||
node_netmap_key not in snapshot
|
||||
), f"Expected node with key {node_netmap_key} to be absent in network map"
|
||||
assert node_netmap_key not in snapshot, f"Expected node with key {node_netmap_key} to be absent in network map"
|
||||
|
||||
|
||||
@reporter.step_deco("Include node {node_to_include} into network map")
|
||||
@reporter.step("Include node {node_to_include} into network map")
|
||||
def include_node_to_network_map(
|
||||
node_to_include: StorageNode,
|
||||
alive_node: StorageNode,
|
||||
|
@ -178,37 +171,29 @@ def include_node_to_network_map(
|
|||
check_node_in_map(node_to_include, shell, alive_node)
|
||||
|
||||
|
||||
@reporter.step_deco("Check node {node} in network map")
|
||||
def check_node_in_map(
|
||||
node: StorageNode, shell: Shell, alive_node: Optional[StorageNode] = None
|
||||
) -> None:
|
||||
@reporter.step("Check node {node} in network map")
|
||||
def check_node_in_map(node: StorageNode, shell: Shell, alive_node: Optional[StorageNode] = None) -> None:
|
||||
alive_node = alive_node or node
|
||||
|
||||
node_netmap_key = node.get_wallet_public_key()
|
||||
logger.info(f"Node ({node.label}) netmap key: {node_netmap_key}")
|
||||
|
||||
snapshot = get_netmap_snapshot(alive_node, shell)
|
||||
assert (
|
||||
node_netmap_key in snapshot
|
||||
), f"Expected node with key {node_netmap_key} to be in network map"
|
||||
assert node_netmap_key in snapshot, f"Expected node with key {node_netmap_key} to be in network map"
|
||||
|
||||
|
||||
@reporter.step_deco("Check node {node} NOT in network map")
|
||||
def check_node_not_in_map(
|
||||
node: StorageNode, shell: Shell, alive_node: Optional[StorageNode] = None
|
||||
) -> None:
|
||||
@reporter.step("Check node {node} NOT in network map")
|
||||
def check_node_not_in_map(node: StorageNode, shell: Shell, alive_node: Optional[StorageNode] = None) -> None:
|
||||
alive_node = alive_node or node
|
||||
|
||||
node_netmap_key = node.get_wallet_public_key()
|
||||
logger.info(f"Node ({node.label}) netmap key: {node_netmap_key}")
|
||||
|
||||
snapshot = get_netmap_snapshot(alive_node, shell)
|
||||
assert (
|
||||
node_netmap_key not in snapshot
|
||||
), f"Expected node with key {node_netmap_key} to be NOT in network map"
|
||||
assert node_netmap_key not in snapshot, f"Expected node with key {node_netmap_key} to be NOT in network map"
|
||||
|
||||
|
||||
@reporter.step_deco("Wait for node {node} is ready")
|
||||
@reporter.step("Wait for node {node} is ready")
|
||||
def wait_for_node_to_be_ready(node: StorageNode) -> None:
|
||||
timeout, attempts = 30, 6
|
||||
for _ in range(attempts):
|
||||
|
@ -219,12 +204,10 @@ def wait_for_node_to_be_ready(node: StorageNode) -> None:
|
|||
except Exception as err:
|
||||
logger.warning(f"Node {node} is not ready:\n{err}")
|
||||
sleep(timeout)
|
||||
raise AssertionError(
|
||||
f"Node {node} hasn't gone to the READY state after {timeout * attempts} seconds"
|
||||
)
|
||||
raise AssertionError(f"Node {node} hasn't gone to the READY state after {timeout * attempts} seconds")
|
||||
|
||||
|
||||
@reporter.step_deco("Remove nodes from network map trough cli-adm morph command")
|
||||
@reporter.step("Remove nodes from network map trough cli-adm morph command")
|
||||
def remove_nodes_from_map_morph(
|
||||
shell: Shell,
|
||||
cluster: Cluster,
|
||||
|
|
|
@ -8,21 +8,21 @@ from typing import Optional
|
|||
from neo3.wallet import utils as neo3_utils
|
||||
from neo3.wallet import wallet as neo3_wallet
|
||||
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.cli import NeoGo
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.resources.cli import NEOGO_EXECUTABLE
|
||||
from frostfs_testlib.resources.common import FROSTFS_CONTRACT, GAS_HASH, MORPH_BLOCK_TIME
|
||||
from frostfs_testlib.shell import Shell
|
||||
from frostfs_testlib.storage.dataclasses.frostfs_services import MorphChain
|
||||
from frostfs_testlib.utils import converting_utils, datetime_utils, wallet_utils
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
EMPTY_PASSWORD = ""
|
||||
TX_PERSIST_TIMEOUT = 15 # seconds
|
||||
ASSET_POWER_SIDECHAIN = 10**12
|
||||
|
||||
|
||||
def get_nns_contract_hash(morph_chain: MorphChain) -> str:
|
||||
return morph_chain.rpc_client.get_contract_state(1)["hash"]
|
||||
|
||||
|
@ -39,6 +39,7 @@ def get_contract_hash(morph_chain: MorphChain, resolve_name: str, shell: Shell)
|
|||
stack_data = json.loads(out.stdout.replace("\n", ""))["stack"][0]["value"]
|
||||
return bytes.decode(base64.b64decode(stack_data[0]["value"]))
|
||||
|
||||
|
||||
def transaction_accepted(morph_chain: MorphChain, tx_id: str):
|
||||
"""
|
||||
This function returns True in case of accepted TX.
|
||||
|
@ -62,7 +63,7 @@ def transaction_accepted(morph_chain: MorphChain, tx_id: str):
|
|||
return False
|
||||
|
||||
|
||||
@reporter.step_deco("Get FrostFS Balance")
|
||||
@reporter.step("Get FrostFS Balance")
|
||||
def get_balance(shell: Shell, morph_chain: MorphChain, wallet_path: str, wallet_password: str = ""):
|
||||
"""
|
||||
This function returns FrostFS balance for given wallet.
|
||||
|
@ -82,7 +83,8 @@ def get_balance(shell: Shell, morph_chain: MorphChain, wallet_path: str, wallet_
|
|||
logger.error(f"failed to get wallet balance: {out}")
|
||||
raise out
|
||||
|
||||
@reporter.step_deco("Transfer Gas")
|
||||
|
||||
@reporter.step("Transfer Gas")
|
||||
def transfer_gas(
|
||||
shell: Shell,
|
||||
amount: int,
|
||||
|
@ -111,16 +113,10 @@ def transfer_gas(
|
|||
"""
|
||||
wallet_from_path = wallet_from_path or morph_chain.get_wallet_path()
|
||||
wallet_from_password = (
|
||||
wallet_from_password
|
||||
if wallet_from_password is not None
|
||||
else morph_chain.get_wallet_password()
|
||||
)
|
||||
address_from = address_from or wallet_utils.get_last_address_from_wallet(
|
||||
wallet_from_path, wallet_from_password
|
||||
)
|
||||
address_to = address_to or wallet_utils.get_last_address_from_wallet(
|
||||
wallet_to_path, wallet_to_password
|
||||
wallet_from_password if wallet_from_password is not None else morph_chain.get_wallet_password()
|
||||
)
|
||||
address_from = address_from or wallet_utils.get_last_address_from_wallet(wallet_from_path, wallet_from_password)
|
||||
address_to = address_to or wallet_utils.get_last_address_from_wallet(wallet_to_path, wallet_to_password)
|
||||
|
||||
neogo = NeoGo(shell, neo_go_exec_path=NEOGO_EXECUTABLE)
|
||||
out = neogo.nep17.transfer(
|
||||
|
@ -141,7 +137,7 @@ def transfer_gas(
|
|||
time.sleep(datetime_utils.parse_time(MORPH_BLOCK_TIME))
|
||||
|
||||
|
||||
@reporter.step_deco("Get Sidechain Balance")
|
||||
@reporter.step("Get Sidechain Balance")
|
||||
def get_sidechain_balance(morph_chain: MorphChain, address: str):
|
||||
resp = morph_chain.rpc_client.get_nep17_balances(address=address)
|
||||
logger.info(f"Got getnep17balances response: {resp}")
|
||||
|
|
|
@ -8,27 +8,23 @@ from typing import Optional
|
|||
|
||||
from dateutil.parser import parse
|
||||
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.cli import FrostfsAuthmate
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.resources.cli import FROSTFS_AUTHMATE_EXEC
|
||||
from frostfs_testlib.resources.common import CREDENTIALS_CREATE_TIMEOUT
|
||||
from frostfs_testlib.s3 import S3ClientWrapper, VersioningStatus
|
||||
from frostfs_testlib.shell import CommandOptions, InteractiveInput, Shell
|
||||
from frostfs_testlib.shell.interfaces import SshCredentials
|
||||
from frostfs_testlib.steps.cli.container import (
|
||||
search_container_by_name,
|
||||
search_nodes_with_container,
|
||||
)
|
||||
from frostfs_testlib.steps.cli.container import search_container_by_name, search_nodes_with_container
|
||||
from frostfs_testlib.storage.cluster import Cluster, ClusterNode
|
||||
from frostfs_testlib.storage.dataclasses.frostfs_services import S3Gate
|
||||
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||
from frostfs_testlib.utils.cli_utils import _run_with_passwd
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
|
||||
@reporter.step_deco("Expected all objects are presented in the bucket")
|
||||
@reporter.step("Expected all objects are presented in the bucket")
|
||||
def check_objects_in_bucket(
|
||||
s3_client: S3ClientWrapper,
|
||||
bucket: str,
|
||||
|
@ -37,13 +33,9 @@ def check_objects_in_bucket(
|
|||
) -> None:
|
||||
unexpected_objects = unexpected_objects or []
|
||||
bucket_objects = s3_client.list_objects(bucket)
|
||||
assert len(bucket_objects) == len(
|
||||
expected_objects
|
||||
), f"Expected {len(expected_objects)} objects in the bucket"
|
||||
assert len(bucket_objects) == len(expected_objects), f"Expected {len(expected_objects)} objects in the bucket"
|
||||
for bucket_object in expected_objects:
|
||||
assert (
|
||||
bucket_object in bucket_objects
|
||||
), f"Expected object {bucket_object} in objects list {bucket_objects}"
|
||||
assert bucket_object in bucket_objects, f"Expected object {bucket_object} in objects list {bucket_objects}"
|
||||
|
||||
for bucket_object in unexpected_objects:
|
||||
assert (
|
||||
|
@ -51,21 +43,17 @@ def check_objects_in_bucket(
|
|||
), f"Expected object {bucket_object} not in objects list {bucket_objects}"
|
||||
|
||||
|
||||
@reporter.step_deco("Try to get object and got error")
|
||||
def try_to_get_objects_and_expect_error(
|
||||
s3_client: S3ClientWrapper, bucket: str, object_keys: list
|
||||
) -> None:
|
||||
@reporter.step("Try to get object and got error")
|
||||
def try_to_get_objects_and_expect_error(s3_client: S3ClientWrapper, bucket: str, object_keys: list) -> None:
|
||||
for obj in object_keys:
|
||||
try:
|
||||
s3_client.get_object(bucket, obj)
|
||||
raise AssertionError(f"Object {obj} found in bucket {bucket}")
|
||||
except Exception as err:
|
||||
assert "The specified key does not exist" in str(
|
||||
err
|
||||
), f"Expected error in exception {err}"
|
||||
assert "The specified key does not exist" in str(err), f"Expected error in exception {err}"
|
||||
|
||||
|
||||
@reporter.step_deco("Set versioning status to '{status}' for bucket '{bucket}'")
|
||||
@reporter.step("Set versioning status to '{status}' for bucket '{bucket}'")
|
||||
def set_bucket_versioning(s3_client: S3ClientWrapper, bucket: str, status: VersioningStatus):
|
||||
if status == VersioningStatus.UNDEFINED:
|
||||
return
|
||||
|
@ -83,12 +71,8 @@ def object_key_from_file_path(full_path: str) -> str:
|
|||
def assert_tags(
|
||||
actual_tags: list, expected_tags: Optional[list] = None, unexpected_tags: Optional[list] = None
|
||||
) -> None:
|
||||
expected_tags = (
|
||||
[{"Key": key, "Value": value} for key, value in expected_tags] if expected_tags else []
|
||||
)
|
||||
unexpected_tags = (
|
||||
[{"Key": key, "Value": value} for key, value in unexpected_tags] if unexpected_tags else []
|
||||
)
|
||||
expected_tags = [{"Key": key, "Value": value} for key, value in expected_tags] if expected_tags else []
|
||||
unexpected_tags = [{"Key": key, "Value": value} for key, value in unexpected_tags] if unexpected_tags else []
|
||||
if expected_tags == []:
|
||||
assert not actual_tags, f"Expected there is no tags, got {actual_tags}"
|
||||
assert len(expected_tags) == len(actual_tags)
|
||||
|
@ -98,7 +82,7 @@ def assert_tags(
|
|||
assert tag not in actual_tags, f"Tag {tag} should not be in {actual_tags}"
|
||||
|
||||
|
||||
@reporter.step_deco("Expected all tags are presented in object")
|
||||
@reporter.step("Expected all tags are presented in object")
|
||||
def check_tags_by_object(
|
||||
s3_client: S3ClientWrapper,
|
||||
bucket: str,
|
||||
|
@ -107,12 +91,10 @@ def check_tags_by_object(
|
|||
unexpected_tags: Optional[list] = None,
|
||||
) -> None:
|
||||
actual_tags = s3_client.get_object_tagging(bucket, key)
|
||||
assert_tags(
|
||||
expected_tags=expected_tags, unexpected_tags=unexpected_tags, actual_tags=actual_tags
|
||||
)
|
||||
assert_tags(expected_tags=expected_tags, unexpected_tags=unexpected_tags, actual_tags=actual_tags)
|
||||
|
||||
|
||||
@reporter.step_deco("Expected all tags are presented in bucket")
|
||||
@reporter.step("Expected all tags are presented in bucket")
|
||||
def check_tags_by_bucket(
|
||||
s3_client: S3ClientWrapper,
|
||||
bucket: str,
|
||||
|
@ -120,9 +102,7 @@ def check_tags_by_bucket(
|
|||
unexpected_tags: Optional[list] = None,
|
||||
) -> None:
|
||||
actual_tags = s3_client.get_bucket_tagging(bucket)
|
||||
assert_tags(
|
||||
expected_tags=expected_tags, unexpected_tags=unexpected_tags, actual_tags=actual_tags
|
||||
)
|
||||
assert_tags(expected_tags=expected_tags, unexpected_tags=unexpected_tags, actual_tags=actual_tags)
|
||||
|
||||
|
||||
def assert_object_lock_mode(
|
||||
|
@ -135,25 +115,19 @@ def assert_object_lock_mode(
|
|||
retain_period: Optional[int] = None,
|
||||
):
|
||||
object_dict = s3_client.get_object(bucket, file_name, full_output=True)
|
||||
assert (
|
||||
object_dict.get("ObjectLockMode") == object_lock_mode
|
||||
), f"Expected Object Lock Mode is {object_lock_mode}"
|
||||
assert object_dict.get("ObjectLockMode") == object_lock_mode, f"Expected Object Lock Mode is {object_lock_mode}"
|
||||
assert (
|
||||
object_dict.get("ObjectLockLegalHoldStatus") == legal_hold_status
|
||||
), f"Expected Object Lock Legal Hold Status is {legal_hold_status}"
|
||||
object_retain_date = object_dict.get("ObjectLockRetainUntilDate")
|
||||
retain_date = (
|
||||
parse(object_retain_date) if isinstance(object_retain_date, str) else object_retain_date
|
||||
)
|
||||
retain_date = parse(object_retain_date) if isinstance(object_retain_date, str) else object_retain_date
|
||||
if retain_until_date:
|
||||
assert retain_date.strftime("%Y-%m-%dT%H:%M:%S") == retain_until_date.strftime(
|
||||
"%Y-%m-%dT%H:%M:%S"
|
||||
), f'Expected Object Lock Retain Until Date is {str(retain_until_date.strftime("%Y-%m-%dT%H:%M:%S"))}'
|
||||
elif retain_period:
|
||||
last_modify_date = object_dict.get("LastModified")
|
||||
last_modify = (
|
||||
parse(last_modify_date) if isinstance(last_modify_date, str) else last_modify_date
|
||||
)
|
||||
last_modify = parse(last_modify_date) if isinstance(last_modify_date, str) else last_modify_date
|
||||
assert (
|
||||
retain_date - last_modify + timedelta(seconds=1)
|
||||
).days == retain_period, f"Expected retention period is {retain_period} days"
|
||||
|
@ -187,7 +161,7 @@ def assert_s3_acl(acl_grants: list, permitted_users: str):
|
|||
logger.error("FULL_CONTROL is given to All Users")
|
||||
|
||||
|
||||
@reporter.step_deco("Init S3 Credentials")
|
||||
@reporter.step("Init S3 Credentials")
|
||||
def init_s3_credentials(
|
||||
wallet: WalletInfo,
|
||||
shell: Shell,
|
||||
|
@ -213,24 +187,18 @@ def init_s3_credentials(
|
|||
container_placement_policy=container_placement_policy,
|
||||
).stdout
|
||||
aws_access_key_id = str(
|
||||
re.search(r"access_key_id.*:\s.(?P<aws_access_key_id>\w*)", issue_secret_output).group(
|
||||
"aws_access_key_id"
|
||||
)
|
||||
re.search(r"access_key_id.*:\s.(?P<aws_access_key_id>\w*)", issue_secret_output).group("aws_access_key_id")
|
||||
)
|
||||
aws_secret_access_key = str(
|
||||
re.search(
|
||||
r"secret_access_key.*:\s.(?P<aws_secret_access_key>\w*)", issue_secret_output
|
||||
).group("aws_secret_access_key")
|
||||
)
|
||||
cid = str(
|
||||
re.search(r"container_id.*:\s.(?P<container_id>\w*)", issue_secret_output).group(
|
||||
"container_id"
|
||||
re.search(r"secret_access_key.*:\s.(?P<aws_secret_access_key>\w*)", issue_secret_output).group(
|
||||
"aws_secret_access_key"
|
||||
)
|
||||
)
|
||||
cid = str(re.search(r"container_id.*:\s.(?P<container_id>\w*)", issue_secret_output).group("container_id"))
|
||||
return cid, aws_access_key_id, aws_secret_access_key
|
||||
|
||||
|
||||
@reporter.step_deco("Delete bucket with all objects")
|
||||
@reporter.step("Delete bucket with all objects")
|
||||
def delete_bucket_with_objects(s3_client: S3ClientWrapper, bucket: str):
|
||||
versioning_status = s3_client.get_bucket_versioning_status(bucket)
|
||||
if versioning_status == VersioningStatus.ENABLED.value:
|
||||
|
@ -255,7 +223,7 @@ def delete_bucket_with_objects(s3_client: S3ClientWrapper, bucket: str):
|
|||
s3_client.delete_bucket(bucket)
|
||||
|
||||
|
||||
@reporter.step_deco("Search nodes bucket")
|
||||
@reporter.step("Search nodes bucket")
|
||||
def search_nodes_with_bucket(
|
||||
cluster: Cluster,
|
||||
bucket_name: str,
|
||||
|
@ -264,7 +232,5 @@ def search_nodes_with_bucket(
|
|||
endpoint: str,
|
||||
) -> list[ClusterNode]:
|
||||
cid = search_container_by_name(wallet=wallet, name=bucket_name, shell=shell, endpoint=endpoint)
|
||||
nodes_list = search_nodes_with_container(
|
||||
wallet=wallet, cid=cid, shell=shell, endpoint=endpoint, cluster=cluster
|
||||
)
|
||||
nodes_list = search_nodes_with_container(wallet=wallet, cid=cid, shell=shell, endpoint=endpoint, cluster=cluster)
|
||||
return nodes_list
|
||||
|
|
|
@ -7,8 +7,8 @@ from dataclasses import dataclass
|
|||
from enum import Enum
|
||||
from typing import Any, Optional
|
||||
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.cli import FrostfsCli
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.resources.cli import FROSTFS_CLI_EXEC
|
||||
from frostfs_testlib.resources.common import ASSETS_DIR, DEFAULT_WALLET_CONFIG
|
||||
from frostfs_testlib.shell import Shell
|
||||
|
@ -17,7 +17,6 @@ from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
|||
from frostfs_testlib.testing.readable import HumanReadableEnum
|
||||
from frostfs_testlib.utils import json_utils, wallet_utils
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
UNRELATED_KEY = "unrelated key in the session"
|
||||
|
@ -50,7 +49,7 @@ class Lifetime:
|
|||
iat: int = 0
|
||||
|
||||
|
||||
@reporter.step_deco("Generate Session Token")
|
||||
@reporter.step("Generate Session Token")
|
||||
def generate_session_token(
|
||||
owner_wallet: WalletInfo,
|
||||
session_wallet: WalletInfo,
|
||||
|
@ -72,9 +71,7 @@ def generate_session_token(
|
|||
|
||||
file_path = os.path.join(tokens_dir, str(uuid.uuid4()))
|
||||
|
||||
pub_key_64 = wallet_utils.get_wallet_public_key(
|
||||
session_wallet.path, session_wallet.password, "base64"
|
||||
)
|
||||
pub_key_64 = wallet_utils.get_wallet_public_key(session_wallet.path, session_wallet.password, "base64")
|
||||
|
||||
lifetime = lifetime or Lifetime()
|
||||
|
||||
|
@ -99,7 +96,7 @@ def generate_session_token(
|
|||
return file_path
|
||||
|
||||
|
||||
@reporter.step_deco("Generate Session Token For Container")
|
||||
@reporter.step("Generate Session Token For Container")
|
||||
def generate_container_session_token(
|
||||
owner_wallet: WalletInfo,
|
||||
session_wallet: WalletInfo,
|
||||
|
@ -126,11 +123,7 @@ def generate_container_session_token(
|
|||
"container": {
|
||||
"verb": verb.value,
|
||||
"wildcard": cid is None,
|
||||
**(
|
||||
{"containerID": {"value": f"{json_utils.encode_for_json(cid)}"}}
|
||||
if cid is not None
|
||||
else {}
|
||||
),
|
||||
**({"containerID": {"value": f"{json_utils.encode_for_json(cid)}"}} if cid is not None else {}),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -143,7 +136,7 @@ def generate_container_session_token(
|
|||
)
|
||||
|
||||
|
||||
@reporter.step_deco("Generate Session Token For Object")
|
||||
@reporter.step("Generate Session Token For Object")
|
||||
def generate_object_session_token(
|
||||
owner_wallet: WalletInfo,
|
||||
session_wallet: WalletInfo,
|
||||
|
@ -185,7 +178,7 @@ def generate_object_session_token(
|
|||
)
|
||||
|
||||
|
||||
@reporter.step_deco("Get signed token for container session")
|
||||
@reporter.step("Get signed token for container session")
|
||||
def get_container_signed_token(
|
||||
owner_wallet: WalletInfo,
|
||||
user_wallet: WalletInfo,
|
||||
|
@ -207,7 +200,7 @@ def get_container_signed_token(
|
|||
return sign_session_token(shell, session_token_file, owner_wallet)
|
||||
|
||||
|
||||
@reporter.step_deco("Get signed token for object session")
|
||||
@reporter.step("Get signed token for object session")
|
||||
def get_object_signed_token(
|
||||
owner_wallet: WalletInfo,
|
||||
user_wallet: WalletInfo,
|
||||
|
@ -234,7 +227,7 @@ def get_object_signed_token(
|
|||
return sign_session_token(shell, session_token_file, owner_wallet)
|
||||
|
||||
|
||||
@reporter.step_deco("Create Session Token")
|
||||
@reporter.step("Create Session Token")
|
||||
def create_session_token(
|
||||
shell: Shell,
|
||||
owner: str,
|
||||
|
@ -265,7 +258,7 @@ def create_session_token(
|
|||
return session_token
|
||||
|
||||
|
||||
@reporter.step_deco("Sign Session Token")
|
||||
@reporter.step("Sign Session Token")
|
||||
def sign_session_token(shell: Shell, session_token_file: str, wlt: WalletInfo) -> str:
|
||||
"""
|
||||
This function signs the session token by the given wallet.
|
||||
|
@ -279,10 +272,6 @@ def sign_session_token(shell: Shell, session_token_file: str, wlt: WalletInfo) -
|
|||
The path to the signed token.
|
||||
"""
|
||||
signed_token_file = os.path.join(os.getcwd(), ASSETS_DIR, str(uuid.uuid4()))
|
||||
frostfscli = FrostfsCli(
|
||||
shell=shell, frostfs_cli_exec_path=FROSTFS_CLI_EXEC, config_file=DEFAULT_WALLET_CONFIG
|
||||
)
|
||||
frostfscli.util.sign_session_token(
|
||||
wallet=wlt.path, from_file=session_token_file, to_file=signed_token_file
|
||||
)
|
||||
frostfscli = FrostfsCli(shell=shell, frostfs_cli_exec_path=FROSTFS_CLI_EXEC, config_file=DEFAULT_WALLET_CONFIG)
|
||||
frostfscli.util.sign_session_token(wallet=wlt.path, from_file=session_token_file, to_file=signed_token_file)
|
||||
return signed_token_file
|
||||
|
|
|
@ -3,7 +3,7 @@ from time import sleep
|
|||
|
||||
import pytest
|
||||
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.resources.error_patterns import OBJECT_ALREADY_REMOVED
|
||||
from frostfs_testlib.shell import Shell
|
||||
from frostfs_testlib.steps.cli.object import delete_object, get_object
|
||||
|
@ -12,16 +12,13 @@ from frostfs_testlib.steps.tombstone import verify_head_tombstone
|
|||
from frostfs_testlib.storage.cluster import Cluster
|
||||
from frostfs_testlib.storage.dataclasses.storage_object_info import StorageObjectInfo
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
CLEANUP_TIMEOUT = 10
|
||||
|
||||
|
||||
@reporter.step_deco("Delete Objects")
|
||||
def delete_objects(
|
||||
storage_objects: list[StorageObjectInfo], shell: Shell, cluster: Cluster
|
||||
) -> None:
|
||||
@reporter.step("Delete Objects")
|
||||
def delete_objects(storage_objects: list[StorageObjectInfo], shell: Shell, cluster: Cluster) -> None:
|
||||
"""
|
||||
Deletes given storage objects.
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"""
|
||||
import logging
|
||||
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.resources.error_patterns import OBJECT_NOT_FOUND
|
||||
from frostfs_testlib.shell import Shell
|
||||
from frostfs_testlib.steps.cli.object import head_object
|
||||
|
@ -14,14 +14,11 @@ from frostfs_testlib.steps.complex_object_actions import get_last_object
|
|||
from frostfs_testlib.storage.cluster import StorageNode
|
||||
from frostfs_testlib.utils import string_utils
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
|
||||
@reporter.step_deco("Get Object Copies")
|
||||
def get_object_copies(
|
||||
complexity: str, wallet: str, cid: str, oid: str, shell: Shell, nodes: list[StorageNode]
|
||||
) -> int:
|
||||
@reporter.step("Get Object Copies")
|
||||
def get_object_copies(complexity: str, wallet: str, cid: str, oid: str, shell: Shell, nodes: list[StorageNode]) -> int:
|
||||
"""
|
||||
The function performs requests to all nodes of the container and
|
||||
finds out if they store a copy of the object. The procedure is
|
||||
|
@ -45,10 +42,8 @@ def get_object_copies(
|
|||
)
|
||||
|
||||
|
||||
@reporter.step_deco("Get Simple Object Copies")
|
||||
def get_simple_object_copies(
|
||||
wallet: str, cid: str, oid: str, shell: Shell, nodes: list[StorageNode]
|
||||
) -> int:
|
||||
@reporter.step("Get Simple Object Copies")
|
||||
def get_simple_object_copies(wallet: str, cid: str, oid: str, shell: Shell, nodes: list[StorageNode]) -> int:
|
||||
"""
|
||||
To figure out the number of a simple object copies, only direct
|
||||
HEAD requests should be made to the every node of the container.
|
||||
|
@ -66,9 +61,7 @@ def get_simple_object_copies(
|
|||
copies = 0
|
||||
for node in nodes:
|
||||
try:
|
||||
response = head_object(
|
||||
wallet, cid, oid, shell=shell, endpoint=node.get_rpc_endpoint(), is_direct=True
|
||||
)
|
||||
response = head_object(wallet, cid, oid, shell=shell, endpoint=node.get_rpc_endpoint(), is_direct=True)
|
||||
if response:
|
||||
logger.info(f"Found object {oid} on node {node}")
|
||||
copies += 1
|
||||
|
@ -78,10 +71,8 @@ def get_simple_object_copies(
|
|||
return copies
|
||||
|
||||
|
||||
@reporter.step_deco("Get Complex Object Copies")
|
||||
def get_complex_object_copies(
|
||||
wallet: str, cid: str, oid: str, shell: Shell, nodes: list[StorageNode]
|
||||
) -> int:
|
||||
@reporter.step("Get Complex Object Copies")
|
||||
def get_complex_object_copies(wallet: str, cid: str, oid: str, shell: Shell, nodes: list[StorageNode]) -> int:
|
||||
"""
|
||||
To figure out the number of a complex object copies, we firstly
|
||||
need to retrieve its Last object. We consider that the number of
|
||||
|
@ -102,10 +93,8 @@ def get_complex_object_copies(
|
|||
return get_simple_object_copies(wallet, cid, last_oid, shell, nodes)
|
||||
|
||||
|
||||
@reporter.step_deco("Get Nodes With Object")
|
||||
def get_nodes_with_object(
|
||||
cid: str, oid: str, shell: Shell, nodes: list[StorageNode]
|
||||
) -> list[StorageNode]:
|
||||
@reporter.step("Get Nodes With Object")
|
||||
def get_nodes_with_object(cid: str, oid: str, shell: Shell, nodes: list[StorageNode]) -> list[StorageNode]:
|
||||
"""
|
||||
The function returns list of nodes which store
|
||||
the given object.
|
||||
|
@ -141,7 +130,7 @@ def get_nodes_with_object(
|
|||
return nodes_list
|
||||
|
||||
|
||||
@reporter.step_deco("Get Nodes Without Object")
|
||||
@reporter.step("Get Nodes Without Object")
|
||||
def get_nodes_without_object(
|
||||
wallet: str, cid: str, oid: str, shell: Shell, nodes: list[StorageNode]
|
||||
) -> list[StorageNode]:
|
||||
|
@ -160,9 +149,7 @@ def get_nodes_without_object(
|
|||
nodes_list = []
|
||||
for node in nodes:
|
||||
try:
|
||||
res = head_object(
|
||||
wallet, cid, oid, shell=shell, endpoint=node.get_rpc_endpoint(), is_direct=True
|
||||
)
|
||||
res = head_object(wallet, cid, oid, shell=shell, endpoint=node.get_rpc_endpoint(), is_direct=True)
|
||||
if res is None:
|
||||
nodes_list.append(node)
|
||||
except Exception as err:
|
||||
|
|
|
@ -3,18 +3,15 @@ import logging
|
|||
|
||||
from neo3.wallet import wallet
|
||||
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.shell import Shell
|
||||
from frostfs_testlib.steps.cli.object import head_object
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
|
||||
|
||||
@reporter.step_deco("Verify Head Tombstone")
|
||||
def verify_head_tombstone(
|
||||
wallet_path: str, cid: str, oid_ts: str, oid: str, shell: Shell, endpoint: str
|
||||
):
|
||||
@reporter.step("Verify Head Tombstone")
|
||||
def verify_head_tombstone(wallet_path: str, cid: str, oid_ts: str, oid: str, shell: Shell, endpoint: str):
|
||||
header = head_object(wallet_path, cid, oid_ts, shell=shell, endpoint=endpoint)["header"]
|
||||
|
||||
s_oid = header["sessionToken"]["body"]["object"]["target"]["objects"]
|
||||
|
@ -30,12 +27,6 @@ def verify_head_tombstone(
|
|||
|
||||
assert header["ownerID"] == addr, "Tombstone Owner ID is wrong"
|
||||
assert header["objectType"] == "TOMBSTONE", "Header Type isn't Tombstone"
|
||||
assert (
|
||||
header["sessionToken"]["body"]["object"]["verb"] == "DELETE"
|
||||
), "Header Session Type isn't DELETE"
|
||||
assert (
|
||||
header["sessionToken"]["body"]["object"]["target"]["container"] == cid
|
||||
), "Header Session ID is wrong"
|
||||
assert (
|
||||
oid in header["sessionToken"]["body"]["object"]["target"]["objects"]
|
||||
), "Header Session OID is wrong"
|
||||
assert header["sessionToken"]["body"]["object"]["verb"] == "DELETE", "Header Session Type isn't DELETE"
|
||||
assert header["sessionToken"]["body"]["object"]["target"]["container"] == cid, "Header Session ID is wrong"
|
||||
assert oid in header["sessionToken"]["body"]["object"]["target"]["objects"], "Header Session OID is wrong"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue