From f4111a1374e8c28f3908de2f59a7bcb3ae1c5bc6 Mon Sep 17 00:00:00 2001 From: Andrey Berezin Date: Thu, 26 Oct 2023 13:34:42 +0300 Subject: [PATCH] [#103] Add host_status method to Host Signed-off-by: Andrey Berezin --- src/frostfs_testlib/hosting/docker_host.py | 22 +++++++++++++++---- src/frostfs_testlib/hosting/interfaces.py | 11 ++++++++++ src/frostfs_testlib/storage/constants.py | 1 + .../storage/dataclasses/node_base.py | 3 +++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/frostfs_testlib/hosting/docker_host.py b/src/frostfs_testlib/hosting/docker_host.py index 289c94d..d582418 100644 --- a/src/frostfs_testlib/hosting/docker_host.py +++ b/src/frostfs_testlib/hosting/docker_host.py @@ -11,7 +11,7 @@ import docker from requests import HTTPError from frostfs_testlib.hosting.config import ParsedAttributes -from frostfs_testlib.hosting.interfaces import DiskInfo, Host +from frostfs_testlib.hosting.interfaces import DiskInfo, Host, HostStatus from frostfs_testlib.shell import LocalShell, Shell, SSHShell from frostfs_testlib.shell.command_inspectors import SudoInspector @@ -87,6 +87,15 @@ class DockerHost(Host): for service_config in self._config.services: self.start_service(service_config.name) + def get_host_status(self) -> HostStatus: + # We emulate host status by checking all services. + for service_config in self._config.services: + state = self._get_container_state(service_config.name) + if state != "running": + return HostStatus.OFFLINE + + return HostStatus.ONLINE + def stop_host(self) -> None: # We emulate stopping machine by stopping all services # As an alternative we can probably try to stop docker service... @@ -293,11 +302,16 @@ class DockerHost(Host): # To speed things up, we break timeout in smaller iterations and check container state # several times. This way waiting stops as soon as container reaches the expected state for _ in range(iterations): - container = self._get_container_by_name(container_name) - logger.debug(f"Current container state\n:{json.dumps(container, indent=2)}") + state = self._get_container_state(container_name) - if container and container["State"] == expected_state: + if state == expected_state: return time.sleep(iteration_wait_time) raise RuntimeError(f"Container {container_name} is not in {expected_state} state.") + + def _get_container_state(self, container_name: str) -> str: + container = self._get_container_by_name(container_name) + logger.debug(f"Current container state\n:{json.dumps(container, indent=2)}") + + return container.get("State", None) diff --git a/src/frostfs_testlib/hosting/interfaces.py b/src/frostfs_testlib/hosting/interfaces.py index 4c94ca0..4388791 100644 --- a/src/frostfs_testlib/hosting/interfaces.py +++ b/src/frostfs_testlib/hosting/interfaces.py @@ -4,6 +4,13 @@ from typing import Optional from frostfs_testlib.hosting.config import CLIConfig, HostConfig, ServiceConfig from frostfs_testlib.shell.interfaces import Shell +from frostfs_testlib.testing.readable import HumanReadableEnum + + +class HostStatus(HumanReadableEnum): + ONLINE = "Online" + OFFLINE = "Offline" + UNKNOWN = "Unknown" class DiskInfo(dict): @@ -79,6 +86,10 @@ class Host(ABC): def start_host(self) -> None: """Starts the host machine.""" + @abstractmethod + def get_host_status(self) -> HostStatus: + """Check host status.""" + @abstractmethod def stop_host(self, mode: str) -> None: """Stops the host machine. diff --git a/src/frostfs_testlib/storage/constants.py b/src/frostfs_testlib/storage/constants.py index dbaac5a..2284ce3 100644 --- a/src/frostfs_testlib/storage/constants.py +++ b/src/frostfs_testlib/storage/constants.py @@ -10,6 +10,7 @@ class ConfigAttributes: ENDPOINT_DATA_0 = "endpoint_data0" ENDPOINT_DATA_1 = "endpoint_data1" ENDPOINT_INTERNAL = "endpoint_internal0" + ENDPOINT_PROMETHEUS = "endpoint_prometheus" CONTROL_ENDPOINT = "control_endpoint" UN_LOCODE = "un_locode" HTTP_HOSTNAME = "http_hostname" diff --git a/src/frostfs_testlib/storage/dataclasses/node_base.py b/src/frostfs_testlib/storage/dataclasses/node_base.py index 5352080..ecfe61c 100644 --- a/src/frostfs_testlib/storage/dataclasses/node_base.py +++ b/src/frostfs_testlib/storage/dataclasses/node_base.py @@ -64,6 +64,9 @@ class NodeBase(HumanReadableABC): def service_healthcheck(self) -> bool: """Service healthcheck.""" + def get_metrics_endpoint(self) -> str: + return self._get_attribute(ConfigAttributes.ENDPOINT_PROMETHEUS) + def stop_service(self): with reporter.step(f"Stop {self.name} service on {self.host.config.address}"): self.host.stop_service(self.name)