Add host_status method to Host #103

Merged
abereziny merged 1 commit from abereziny/frostfs-testlib:feature-updates-for-failover into master 2023-10-26 11:07:13 +00:00
4 changed files with 33 additions and 4 deletions

View file

@ -11,7 +11,7 @@ import docker
from requests import HTTPError from requests import HTTPError
from frostfs_testlib.hosting.config import ParsedAttributes 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 import LocalShell, Shell, SSHShell
from frostfs_testlib.shell.command_inspectors import SudoInspector from frostfs_testlib.shell.command_inspectors import SudoInspector
@ -87,6 +87,15 @@ class DockerHost(Host):
for service_config in self._config.services: for service_config in self._config.services:
self.start_service(service_config.name) 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: def stop_host(self) -> None:
# We emulate stopping machine by stopping all services # We emulate stopping machine by stopping all services
# As an alternative we can probably try to stop docker service... # 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 # 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 # several times. This way waiting stops as soon as container reaches the expected state
for _ in range(iterations): for _ in range(iterations):
container = self._get_container_by_name(container_name) state = self._get_container_state(container_name)
logger.debug(f"Current container state\n:{json.dumps(container, indent=2)}")
if container and container["State"] == expected_state: if state == expected_state:
return return
time.sleep(iteration_wait_time) time.sleep(iteration_wait_time)
raise RuntimeError(f"Container {container_name} is not in {expected_state} state.") 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)

View file

@ -4,6 +4,13 @@ from typing import Optional
from frostfs_testlib.hosting.config import CLIConfig, HostConfig, ServiceConfig from frostfs_testlib.hosting.config import CLIConfig, HostConfig, ServiceConfig
from frostfs_testlib.shell.interfaces import Shell 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): class DiskInfo(dict):
@ -79,6 +86,10 @@ class Host(ABC):
def start_host(self) -> None: def start_host(self) -> None:
"""Starts the host machine.""" """Starts the host machine."""
@abstractmethod
def get_host_status(self) -> HostStatus:
"""Check host status."""
@abstractmethod @abstractmethod
def stop_host(self, mode: str) -> None: def stop_host(self, mode: str) -> None:
"""Stops the host machine. """Stops the host machine.

View file

@ -10,6 +10,7 @@ class ConfigAttributes:
ENDPOINT_DATA_0 = "endpoint_data0" ENDPOINT_DATA_0 = "endpoint_data0"
ENDPOINT_DATA_1 = "endpoint_data1" ENDPOINT_DATA_1 = "endpoint_data1"
ENDPOINT_INTERNAL = "endpoint_internal0" ENDPOINT_INTERNAL = "endpoint_internal0"
ENDPOINT_PROMETHEUS = "endpoint_prometheus"
CONTROL_ENDPOINT = "control_endpoint" CONTROL_ENDPOINT = "control_endpoint"
UN_LOCODE = "un_locode" UN_LOCODE = "un_locode"
HTTP_HOSTNAME = "http_hostname" HTTP_HOSTNAME = "http_hostname"

View file

@ -64,6 +64,9 @@ class NodeBase(HumanReadableABC):
def service_healthcheck(self) -> bool: def service_healthcheck(self) -> bool:
"""Service healthcheck.""" """Service healthcheck."""
def get_metrics_endpoint(self) -> str:
return self._get_attribute(ConfigAttributes.ENDPOINT_PROMETHEUS)
def stop_service(self): def stop_service(self):
with reporter.step(f"Stop {self.name} service on {self.host.config.address}"): with reporter.step(f"Stop {self.name} service on {self.host.config.address}"):
self.host.stop_service(self.name) self.host.stop_service(self.name)