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
|
@ -4,9 +4,9 @@ import re
|
|||
import yaml
|
||||
from yarl import URL
|
||||
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.hosting import Host, Hosting
|
||||
from frostfs_testlib.hosting.config import ServiceConfig
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.storage import get_service_registry
|
||||
from frostfs_testlib.storage.configuration.interfaces import ServiceConfigurationYml
|
||||
from frostfs_testlib.storage.configuration.service_configuration import ServiceConfiguration
|
||||
|
@ -16,8 +16,6 @@ from frostfs_testlib.storage.dataclasses.node_base import NodeBase, ServiceClass
|
|||
from frostfs_testlib.storage.dataclasses.storage_object_info import Interfaces
|
||||
from frostfs_testlib.storage.service_registry import ServiceRegistry
|
||||
|
||||
reporter = get_reporter()
|
||||
|
||||
|
||||
class ClusterNode:
|
||||
"""
|
||||
|
|
|
@ -4,13 +4,11 @@ from typing import Any
|
|||
|
||||
import yaml
|
||||
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.shell.interfaces import CommandOptions
|
||||
from frostfs_testlib.storage.configuration.interfaces import ServiceConfigurationYml
|
||||
from frostfs_testlib.storage.dataclasses.node_base import ServiceClass
|
||||
|
||||
reporter = get_reporter()
|
||||
|
||||
|
||||
class ServiceConfiguration(ServiceConfigurationYml):
|
||||
def __init__(self, service: "ServiceClass") -> None:
|
||||
|
|
|
@ -2,18 +2,16 @@ import copy
|
|||
from typing import Optional
|
||||
|
||||
import frostfs_testlib.resources.optionals as optionals
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.load.interfaces.scenario_runner import ScenarioRunner
|
||||
from frostfs_testlib.load.load_config import EndpointSelectionStrategy, LoadParams, LoadScenario, LoadType
|
||||
from frostfs_testlib.load.load_report import LoadReport
|
||||
from frostfs_testlib.load.load_verifiers import LoadVerifier
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.storage.cluster import ClusterNode
|
||||
from frostfs_testlib.storage.dataclasses.frostfs_services import S3Gate, StorageNode
|
||||
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||
from frostfs_testlib.testing.test_control import run_optionally
|
||||
|
||||
reporter = get_reporter()
|
||||
|
||||
|
||||
class BackgroundLoadController:
|
||||
k6_dir: str
|
||||
|
@ -86,7 +84,7 @@ class BackgroundLoadController:
|
|||
return all_endpoints[load_type][endpoint_selection_strategy]
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_BACKGROUND_LOAD_ENABLED)
|
||||
@reporter.step_deco("Prepare load instances")
|
||||
@reporter.step("Prepare load instances")
|
||||
def prepare(self):
|
||||
self.endpoints = self._get_endpoints(self.load_params.load_type, self.load_params.endpoint_selection_strategy)
|
||||
self.runner.prepare(self.load_params, self.cluster_nodes, self.nodes_under_load, self.k6_dir)
|
||||
|
@ -99,7 +97,7 @@ class BackgroundLoadController:
|
|||
self.started = True
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_BACKGROUND_LOAD_ENABLED)
|
||||
@reporter.step_deco("Stop load")
|
||||
@reporter.step("Stop load")
|
||||
def stop(self):
|
||||
self.runner.stop()
|
||||
|
||||
|
@ -108,7 +106,7 @@ class BackgroundLoadController:
|
|||
return self.runner.is_running
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_BACKGROUND_LOAD_ENABLED)
|
||||
@reporter.step_deco("Reset load")
|
||||
@reporter.step("Reset load")
|
||||
def _reset_for_consequent_load(self):
|
||||
"""This method is required if we want to run multiple loads during test run.
|
||||
Raise load counter by 1 and append it to load_id
|
||||
|
@ -118,7 +116,7 @@ class BackgroundLoadController:
|
|||
self.load_params.set_id(f"{self.load_params.load_id}_{self.load_counter}")
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_BACKGROUND_LOAD_ENABLED)
|
||||
@reporter.step_deco("Startup load")
|
||||
@reporter.step("Startup load")
|
||||
def startup(self):
|
||||
self.prepare()
|
||||
self.preset()
|
||||
|
@ -129,7 +127,7 @@ class BackgroundLoadController:
|
|||
self.runner.preset()
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_BACKGROUND_LOAD_ENABLED)
|
||||
@reporter.step_deco("Stop and get results of load")
|
||||
@reporter.step("Stop and get results of load")
|
||||
def teardown(self, load_report: Optional[LoadReport] = None):
|
||||
if not self.started:
|
||||
return
|
||||
|
@ -141,7 +139,7 @@ class BackgroundLoadController:
|
|||
load_report.add_summaries(self.load_summaries)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_BACKGROUND_LOAD_ENABLED)
|
||||
@reporter.step_deco("Run post-load verification")
|
||||
@reporter.step("Run post-load verification")
|
||||
def verify(self):
|
||||
try:
|
||||
load_issues = self._collect_load_issues()
|
||||
|
@ -153,7 +151,7 @@ class BackgroundLoadController:
|
|||
self._reset_for_consequent_load()
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_BACKGROUND_LOAD_ENABLED)
|
||||
@reporter.step_deco("Collect load issues")
|
||||
@reporter.step("Collect load issues")
|
||||
def _collect_load_issues(self):
|
||||
verifier = LoadVerifier(self.load_params)
|
||||
return verifier.collect_load_issues(self.load_summaries)
|
||||
|
@ -163,7 +161,7 @@ class BackgroundLoadController:
|
|||
self.runner.wait_until_finish(soft_timeout)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_BACKGROUND_LOAD_ENABLED)
|
||||
@reporter.step_deco("Verify loaded objects")
|
||||
@reporter.step("Verify loaded objects")
|
||||
def _run_verify_scenario(self) -> list[str]:
|
||||
self.verification_params = LoadParams(
|
||||
verify_clients=self.load_params.verify_clients,
|
||||
|
|
|
@ -4,12 +4,12 @@ import time
|
|||
from typing import TypeVar
|
||||
|
||||
import frostfs_testlib.resources.optionals as optionals
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.cli import FrostfsAdm, FrostfsCli
|
||||
from frostfs_testlib.cli.netmap_parser import NetmapParser
|
||||
from frostfs_testlib.healthcheck.interfaces import Healthcheck
|
||||
from frostfs_testlib.hosting.interfaces import HostStatus
|
||||
from frostfs_testlib.plugins import load_all
|
||||
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.common import DEFAULT_WALLET_CONFIG, MORPH_BLOCK_TIME
|
||||
from frostfs_testlib.shell import CommandOptions, Shell, SshConnectionProvider
|
||||
|
@ -21,7 +21,6 @@ from frostfs_testlib.testing import parallel
|
|||
from frostfs_testlib.testing.test_control import retry, run_optionally, wait_for_success
|
||||
from frostfs_testlib.utils.datetime_utils import parse_time
|
||||
|
||||
reporter = get_reporter()
|
||||
logger = logging.getLogger("NeoLogger")
|
||||
if_up_down_helper = IfUpDownHelper()
|
||||
|
||||
|
@ -76,7 +75,7 @@ class ClusterStateController:
|
|||
return online_svc
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Stop host of node {node}")
|
||||
@reporter.step("Stop host of node {node}")
|
||||
def stop_node_host(self, node: ClusterNode, mode: str):
|
||||
# Drop ssh connection for this node before shutdown
|
||||
provider = SshConnectionProvider()
|
||||
|
@ -88,7 +87,7 @@ class ClusterStateController:
|
|||
self._wait_for_host_offline(node)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Shutdown whole cluster")
|
||||
@reporter.step("Shutdown whole cluster")
|
||||
def shutdown_cluster(self, mode: str, reversed_order: bool = False):
|
||||
nodes = reversed(self.cluster.cluster_nodes) if reversed_order else self.cluster.cluster_nodes
|
||||
|
||||
|
@ -105,7 +104,7 @@ class ClusterStateController:
|
|||
self._wait_for_host_offline(node)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start host of node {node}")
|
||||
@reporter.step("Start host of node {node}")
|
||||
def start_node_host(self, node: ClusterNode, startup_healthcheck: bool = True):
|
||||
with reporter.step(f"Start host {node.host.config.address}"):
|
||||
node.host.start_host()
|
||||
|
@ -115,7 +114,7 @@ class ClusterStateController:
|
|||
self.wait_startup_healthcheck()
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start stopped hosts")
|
||||
@reporter.step("Start stopped hosts")
|
||||
def start_stopped_hosts(self, reversed_order: bool = False):
|
||||
if not self.stopped_nodes:
|
||||
return
|
||||
|
@ -133,35 +132,35 @@ class ClusterStateController:
|
|||
self.wait_after_storage_startup()
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Detach disk {device} at {mountpoint} on node {node}")
|
||||
@reporter.step("Detach disk {device} at {mountpoint} on node {node}")
|
||||
def detach_disk(self, node: StorageNode, device: str, mountpoint: str):
|
||||
disk_controller = self._get_disk_controller(node, device, mountpoint)
|
||||
self.detached_disks[disk_controller.id] = disk_controller
|
||||
disk_controller.detach()
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Attach disk {device} at {mountpoint} on node {node}")
|
||||
@reporter.step("Attach disk {device} at {mountpoint} on node {node}")
|
||||
def attach_disk(self, node: StorageNode, device: str, mountpoint: str):
|
||||
disk_controller = self._get_disk_controller(node, device, mountpoint)
|
||||
disk_controller.attach()
|
||||
self.detached_disks.pop(disk_controller.id, None)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Restore detached disks")
|
||||
@reporter.step("Restore detached disks")
|
||||
def restore_disks(self):
|
||||
for disk_controller in self.detached_disks.values():
|
||||
disk_controller.attach()
|
||||
self.detached_disks = {}
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Stop all {service_type} services")
|
||||
@reporter.step("Stop all {service_type} services")
|
||||
def stop_services_of_type(self, service_type: type[ServiceClass], mask: bool = True):
|
||||
services = self.cluster.services(service_type)
|
||||
self.stopped_services.update(services)
|
||||
parallel([service.stop_service for service in services], mask=mask)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start all {service_type} services")
|
||||
@reporter.step("Start all {service_type} services")
|
||||
def start_services_of_type(self, service_type: type[ServiceClass]):
|
||||
services = self.cluster.services(service_type)
|
||||
parallel([service.start_service for service in services])
|
||||
|
@ -176,24 +175,24 @@ class ClusterStateController:
|
|||
result = s3gate.get_metric("frostfs_s3_gw_pool_current_nodes")
|
||||
assert 'address="127.0.0.1' in result.stdout, "S3Gate should connect to local storage node"
|
||||
|
||||
@reporter.step_deco("Wait for S3Gates reconnection to local storage")
|
||||
@reporter.step("Wait for S3Gates reconnection to local storage")
|
||||
def wait_s3gates(self):
|
||||
online_s3gates = self._get_online(S3Gate)
|
||||
if online_s3gates:
|
||||
parallel(self.wait_s3gate, online_s3gates)
|
||||
|
||||
@reporter.step_deco("Wait for cluster startup healtcheck")
|
||||
@reporter.step("Wait for cluster startup healtcheck")
|
||||
def wait_startup_healthcheck(self):
|
||||
nodes = self.cluster.nodes(self._get_online(StorageNode))
|
||||
parallel(self.healthcheck.startup_healthcheck, nodes)
|
||||
|
||||
@reporter.step_deco("Wait for storage reconnection to the system")
|
||||
@reporter.step("Wait for storage reconnection to the system")
|
||||
def wait_after_storage_startup(self):
|
||||
self.wait_startup_healthcheck()
|
||||
self.wait_s3gates()
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start all stopped services")
|
||||
@reporter.step("Start all stopped services")
|
||||
def start_all_stopped_services(self):
|
||||
stopped_storages = self._get_stopped_by_type(StorageNode)
|
||||
parallel([service.start_service for service in self.stopped_services])
|
||||
|
@ -203,21 +202,21 @@ class ClusterStateController:
|
|||
self.wait_after_storage_startup()
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Stop {service_type} service on {node}")
|
||||
@reporter.step("Stop {service_type} service on {node}")
|
||||
def stop_service_of_type(self, node: ClusterNode, service_type: type[ServiceClass], mask: bool = True):
|
||||
service = node.service(service_type)
|
||||
service.stop_service(mask)
|
||||
self.stopped_services.add(service)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start {service_type} service on {node}")
|
||||
@reporter.step("Start {service_type} service on {node}")
|
||||
def start_service_of_type(self, node: ClusterNode, service_type: type[ServiceClass]):
|
||||
service = node.service(service_type)
|
||||
service.start_service()
|
||||
self.stopped_services.discard(service)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start all stopped {service_type} services")
|
||||
@reporter.step("Start all stopped {service_type} services")
|
||||
def start_stopped_services_of_type(self, service_type: type[ServiceClass]):
|
||||
stopped_svc = self._get_stopped_by_type(service_type)
|
||||
if not stopped_svc:
|
||||
|
@ -231,7 +230,7 @@ class ClusterStateController:
|
|||
|
||||
# TODO: Deprecated
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Stop all storage services on cluster")
|
||||
@reporter.step("Stop all storage services on cluster")
|
||||
def stop_all_storage_services(self, reversed_order: bool = False):
|
||||
nodes = reversed(self.cluster.cluster_nodes) if reversed_order else self.cluster.cluster_nodes
|
||||
|
||||
|
@ -240,7 +239,7 @@ class ClusterStateController:
|
|||
|
||||
# TODO: Deprecated
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Stop all S3 gates on cluster")
|
||||
@reporter.step("Stop all S3 gates on cluster")
|
||||
def stop_all_s3_gates(self, reversed_order: bool = False):
|
||||
nodes = reversed(self.cluster.cluster_nodes) if reversed_order else self.cluster.cluster_nodes
|
||||
|
||||
|
@ -249,42 +248,42 @@ class ClusterStateController:
|
|||
|
||||
# TODO: Deprecated
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Stop storage service on {node}")
|
||||
@reporter.step("Stop storage service on {node}")
|
||||
def stop_storage_service(self, node: ClusterNode, mask: bool = True):
|
||||
self.stop_service_of_type(node, StorageNode, mask)
|
||||
|
||||
# TODO: Deprecated
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start storage service on {node}")
|
||||
@reporter.step("Start storage service on {node}")
|
||||
def start_storage_service(self, node: ClusterNode):
|
||||
self.start_service_of_type(node, StorageNode)
|
||||
|
||||
# TODO: Deprecated
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start stopped storage services")
|
||||
@reporter.step("Start stopped storage services")
|
||||
def start_stopped_storage_services(self):
|
||||
self.start_stopped_services_of_type(StorageNode)
|
||||
|
||||
# TODO: Deprecated
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Stop s3 gate on {node}")
|
||||
@reporter.step("Stop s3 gate on {node}")
|
||||
def stop_s3_gate(self, node: ClusterNode, mask: bool = True):
|
||||
self.stop_service_of_type(node, S3Gate, mask)
|
||||
|
||||
# TODO: Deprecated
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start s3 gate on {node}")
|
||||
@reporter.step("Start s3 gate on {node}")
|
||||
def start_s3_gate(self, node: ClusterNode):
|
||||
self.start_service_of_type(node, S3Gate)
|
||||
|
||||
# TODO: Deprecated
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start stopped S3 gates")
|
||||
@reporter.step("Start stopped S3 gates")
|
||||
def start_stopped_s3_gates(self):
|
||||
self.start_stopped_services_of_type(S3Gate)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Suspend {process_name} service in {node}")
|
||||
@reporter.step("Suspend {process_name} service in {node}")
|
||||
def suspend_service(self, process_name: str, node: ClusterNode):
|
||||
node.host.wait_success_suspend_process(process_name)
|
||||
if self.suspended_services.get(process_name):
|
||||
|
@ -293,20 +292,20 @@ class ClusterStateController:
|
|||
self.suspended_services[process_name] = [node]
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Resume {process_name} service in {node}")
|
||||
@reporter.step("Resume {process_name} service in {node}")
|
||||
def resume_service(self, process_name: str, node: ClusterNode):
|
||||
node.host.wait_success_resume_process(process_name)
|
||||
if self.suspended_services.get(process_name) and node in self.suspended_services[process_name]:
|
||||
self.suspended_services[process_name].remove(node)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Start suspend processes services")
|
||||
@reporter.step("Start suspend processes services")
|
||||
def resume_suspended_services(self):
|
||||
for process_name, list_nodes in self.suspended_services.items():
|
||||
[node.host.wait_success_resume_process(process_name) for node in list_nodes]
|
||||
self.suspended_services = {}
|
||||
|
||||
@reporter.step_deco("Drop traffic to {node}, with ports - {ports}, nodes - {block_nodes}")
|
||||
@reporter.step("Drop traffic to {node}, with ports - {ports}, nodes - {block_nodes}")
|
||||
def drop_traffic(
|
||||
self,
|
||||
mode: str,
|
||||
|
@ -327,7 +326,7 @@ class ClusterStateController:
|
|||
time.sleep(wakeup_timeout)
|
||||
self.dropped_traffic.append(node)
|
||||
|
||||
@reporter.step_deco("Ping traffic")
|
||||
@reporter.step("Ping traffic")
|
||||
def ping_traffic(
|
||||
self,
|
||||
node: ClusterNode,
|
||||
|
@ -343,7 +342,7 @@ class ClusterStateController:
|
|||
return False
|
||||
return True
|
||||
|
||||
@reporter.step_deco("Start traffic to {node}")
|
||||
@reporter.step("Start traffic to {node}")
|
||||
def restore_traffic(
|
||||
self,
|
||||
mode: str,
|
||||
|
@ -358,12 +357,12 @@ class ClusterStateController:
|
|||
case "nodes":
|
||||
IpTablesHelper.restore_input_traffic_to_node(node=node)
|
||||
|
||||
@reporter.step_deco("Restore blocked nodes")
|
||||
@reporter.step("Restore blocked nodes")
|
||||
def restore_all_traffic(self):
|
||||
parallel(self._restore_traffic_to_node, self.dropped_traffic)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Hard reboot host {node} via magic SysRq option")
|
||||
@reporter.step("Hard reboot host {node} via magic SysRq option")
|
||||
def panic_reboot_host(self, node: ClusterNode, wait_for_return: bool = True, startup_healthcheck: bool = True):
|
||||
shell = node.host.get_shell()
|
||||
shell.exec('sudo sh -c "echo 1 > /proc/sys/kernel/sysrq"')
|
||||
|
@ -383,14 +382,14 @@ class ClusterStateController:
|
|||
if startup_healthcheck:
|
||||
self.wait_startup_healthcheck()
|
||||
|
||||
@reporter.step_deco("Down {interface} to {nodes}")
|
||||
@reporter.step("Down {interface} to {nodes}")
|
||||
def down_interface(self, nodes: list[ClusterNode], interface: str):
|
||||
for node in nodes:
|
||||
if_up_down_helper.down_interface(node=node, interface=interface)
|
||||
assert if_up_down_helper.check_state(node=node, interface=interface) == "DOWN"
|
||||
self.nodes_with_modified_interface.append(node)
|
||||
|
||||
@reporter.step_deco("Up {interface} to {nodes}")
|
||||
@reporter.step("Up {interface} to {nodes}")
|
||||
def up_interface(self, nodes: list[ClusterNode], interface: str):
|
||||
for node in nodes:
|
||||
if_up_down_helper.up_interface(node=node, interface=interface)
|
||||
|
@ -398,17 +397,17 @@ class ClusterStateController:
|
|||
if node in self.nodes_with_modified_interface:
|
||||
self.nodes_with_modified_interface.remove(node)
|
||||
|
||||
@reporter.step_deco("Restore interface")
|
||||
@reporter.step("Restore interface")
|
||||
def restore_interfaces(self):
|
||||
for node in self.nodes_with_modified_interface:
|
||||
if_up_down_helper.up_all_interface(node)
|
||||
|
||||
@reporter.step_deco("Get node time")
|
||||
@reporter.step("Get node time")
|
||||
def get_node_date(self, node: ClusterNode) -> datetime:
|
||||
shell = node.host.get_shell()
|
||||
return datetime.datetime.strptime(shell.exec("hwclock -r").stdout.strip(), "%Y-%m-%d %H:%M:%S.%f%z")
|
||||
|
||||
@reporter.step_deco("Set node time to {in_date}")
|
||||
@reporter.step("Set node time to {in_date}")
|
||||
def change_node_date(self, node: ClusterNode, in_date: datetime) -> None:
|
||||
shell = node.host.get_shell()
|
||||
shell.exec(f"date -s @{time.mktime(in_date.timetuple())}")
|
||||
|
@ -417,7 +416,7 @@ class ClusterStateController:
|
|||
with reporter.step(f"Verify difference between {node_time} and {in_date} is less than a minute"):
|
||||
assert (self.get_node_date(node) - in_date) < datetime.timedelta(minutes=1)
|
||||
|
||||
@reporter.step_deco(f"Restore time")
|
||||
@reporter.step(f"Restore time")
|
||||
def restore_node_date(self, node: ClusterNode) -> None:
|
||||
shell = node.host.get_shell()
|
||||
now_time = datetime.datetime.now(datetime.timezone.utc)
|
||||
|
@ -425,14 +424,14 @@ class ClusterStateController:
|
|||
shell.exec(f"date -s @{time.mktime(now_time.timetuple())}")
|
||||
shell.exec("hwclock --systohc")
|
||||
|
||||
@reporter.step_deco("Change the synchronizer status to {status}")
|
||||
@reporter.step("Change the synchronizer status to {status}")
|
||||
def set_sync_date_all_nodes(self, status: str):
|
||||
if status == "active":
|
||||
parallel(self._enable_date_synchronizer, self.cluster.cluster_nodes)
|
||||
return
|
||||
parallel(self._disable_date_synchronizer, self.cluster.cluster_nodes)
|
||||
|
||||
@reporter.step_deco("Set MaintenanceModeAllowed - {status}")
|
||||
@reporter.step("Set MaintenanceModeAllowed - {status}")
|
||||
def set_maintenance_mode_allowed(self, status: str, cluster_node: ClusterNode) -> None:
|
||||
frostfs_adm = FrostfsAdm(
|
||||
shell=cluster_node.host.get_shell(),
|
||||
|
@ -441,7 +440,7 @@ class ClusterStateController:
|
|||
)
|
||||
frostfs_adm.morph.set_config(set_key_value=f"MaintenanceModeAllowed={status}")
|
||||
|
||||
@reporter.step_deco("Set mode node to {status}")
|
||||
@reporter.step("Set mode node to {status}")
|
||||
def set_mode_node(self, cluster_node: ClusterNode, wallet: str, status: str, await_tick: bool = True) -> None:
|
||||
rpc_endpoint = cluster_node.storage_node.get_rpc_endpoint()
|
||||
control_endpoint = cluster_node.service(StorageNode).get_control_endpoint()
|
||||
|
@ -465,8 +464,7 @@ class ClusterStateController:
|
|||
|
||||
self.check_node_status(status=status, wallet=wallet, cluster_node=cluster_node)
|
||||
|
||||
@wait_for_success(80, 8)
|
||||
@reporter.step_deco("Check status node, status - {status}")
|
||||
@wait_for_success(80, 8, title="Wait for storage status become {status}")
|
||||
def check_node_status(self, status: str, wallet: str, cluster_node: ClusterNode):
|
||||
frostfs_cli = FrostfsCli(
|
||||
shell=self.shell, frostfs_cli_exec_path=FROSTFS_CLI_EXEC, config_file=DEFAULT_WALLET_CONFIG
|
||||
|
@ -537,13 +535,13 @@ class ClusterStateController:
|
|||
interfaces.append(ip)
|
||||
return interfaces
|
||||
|
||||
@reporter.step_deco("Ping node")
|
||||
@reporter.step("Ping node")
|
||||
def _ping_host(self, node: ClusterNode):
|
||||
options = CommandOptions(check=False)
|
||||
return self.shell.exec(f"ping {node.host.config.address} -c 1", options).return_code
|
||||
|
||||
@retry(max_attempts=60, sleep_interval=5, expected_result=HostStatus.ONLINE)
|
||||
@reporter.step_deco("Waiting for {node} to go online")
|
||||
@reporter.step("Waiting for {node} to go online")
|
||||
def _wait_for_host_online(self, node: ClusterNode):
|
||||
try:
|
||||
ping_result = self._ping_host(node)
|
||||
|
@ -555,7 +553,7 @@ class ClusterStateController:
|
|||
return HostStatus.OFFLINE
|
||||
|
||||
@retry(max_attempts=60, sleep_interval=5, expected_result=HostStatus.OFFLINE)
|
||||
@reporter.step_deco("Waiting for {node} to go offline")
|
||||
@reporter.step("Waiting for {node} to go offline")
|
||||
def _wait_for_host_offline(self, node: ClusterNode):
|
||||
try:
|
||||
ping_result = self._ping_host(node)
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
from typing import Any
|
||||
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.storage.cluster import ClusterNode
|
||||
from frostfs_testlib.storage.controllers.cluster_state_controller import ClusterStateController, StateManager
|
||||
from frostfs_testlib.storage.dataclasses.node_base import ServiceClass
|
||||
from frostfs_testlib.testing import parallel
|
||||
|
||||
reporter = get_reporter()
|
||||
|
||||
|
||||
class ConfigStateManager(StateManager):
|
||||
def __init__(self, cluster_state_controller: ClusterStateController) -> None:
|
||||
|
@ -15,7 +13,7 @@ class ConfigStateManager(StateManager):
|
|||
self.services_with_changed_config: set[tuple[ClusterNode, ServiceClass]] = set()
|
||||
self.cluster = self.csc.cluster
|
||||
|
||||
@reporter.step_deco("Change configuration for {service_type} on all nodes")
|
||||
@reporter.step("Change configuration for {service_type} on all nodes")
|
||||
def set_on_all_nodes(self, service_type: type[ServiceClass], values: dict[str, Any]):
|
||||
services = self.cluster.services(service_type)
|
||||
nodes = self.cluster.nodes(services)
|
||||
|
@ -25,7 +23,7 @@ class ConfigStateManager(StateManager):
|
|||
parallel([node.config(service_type).set for node in nodes], values=values)
|
||||
self.csc.start_services_of_type(service_type)
|
||||
|
||||
@reporter.step_deco("Change configuration for {service_type} on {node}")
|
||||
@reporter.step("Change configuration for {service_type} on {node}")
|
||||
def set_on_node(self, node: ClusterNode, service_type: type[ServiceClass], values: dict[str, Any]):
|
||||
self.services_with_changed_config.add((node, service_type))
|
||||
|
||||
|
@ -33,7 +31,7 @@ class ConfigStateManager(StateManager):
|
|||
node.config(service_type).set(values)
|
||||
self.csc.start_service_of_type(node, service_type)
|
||||
|
||||
@reporter.step_deco("Revert all configuration changes")
|
||||
@reporter.step("Revert all configuration changes")
|
||||
def revert_all(self):
|
||||
if not self.services_with_changed_config:
|
||||
return
|
||||
|
@ -44,7 +42,7 @@ class ConfigStateManager(StateManager):
|
|||
self.csc.start_all_stopped_services()
|
||||
|
||||
# TODO: parallel can't have multiple parallel_items :(
|
||||
@reporter.step_deco("Revert all configuration {node_and_service}")
|
||||
@reporter.step("Revert all configuration {node_and_service}")
|
||||
def _revert_svc(self, node_and_service: tuple[ClusterNode, ServiceClass]):
|
||||
node, service_type = node_and_service
|
||||
self.csc.stop_service_of_type(node, service_type)
|
||||
|
|
|
@ -4,16 +4,14 @@ from typing import Optional, TypedDict, TypeVar
|
|||
|
||||
import yaml
|
||||
|
||||
from frostfs_testlib import reporter
|
||||
from frostfs_testlib.hosting.config import ServiceConfig
|
||||
from frostfs_testlib.hosting.interfaces import Host
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.shell.interfaces import CommandResult
|
||||
from frostfs_testlib.storage.constants import ConfigAttributes
|
||||
from frostfs_testlib.testing.readable import HumanReadableABC
|
||||
from frostfs_testlib.utils import wallet_utils
|
||||
|
||||
reporter = get_reporter()
|
||||
|
||||
|
||||
@dataclass
|
||||
class NodeBase(HumanReadableABC):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue