Coverage for mlos_bench/mlos_bench/tests/services/remote/ssh/__init__.py: 100%
27 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-21 01:50 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-21 01:50 +0000
1#
2# Copyright (c) Microsoft Corporation.
3# Licensed under the MIT License.
4#
5"""Common data classes for the SSH service tests."""
7from dataclasses import dataclass
8from subprocess import run
10from pytest_docker.plugin import Services as DockerServices
12from mlos_bench.tests import check_socket
14# The SSH test server port and name.
15# See Also: docker-compose.yml
16SSH_TEST_SERVER_PORT = 2254
17SSH_TEST_SERVER_NAME = "ssh-server"
18ALT_TEST_SERVER_NAME = "alt-server"
19REBOOT_TEST_SERVER_NAME = "reboot-server"
22@dataclass
23class SshTestServerInfo:
24 """A data class for SshTestServerInfo."""
26 compose_project_name: str
27 service_name: str
28 hostname: str
29 username: str
30 id_rsa_path: str
31 _port: int | None = None
33 def get_port(self, uncached: bool = False) -> int:
34 """
35 Gets the port that the SSH test server is listening on.
37 Note: this value can change when the service restarts so we can't rely on
38 the DockerServices.
39 """
40 if self._port is None or uncached:
41 port_cmd = run(
42 (
43 f"docker compose -p {self.compose_project_name} "
44 f"port {self.service_name} {SSH_TEST_SERVER_PORT}"
45 ),
46 shell=True,
47 check=True,
48 capture_output=True,
49 )
50 self._port = int(port_cmd.stdout.decode().strip().split(":")[1])
51 return self._port
53 def to_ssh_service_config(self, uncached: bool = False) -> dict:
54 """Convert to a config dict for SshService."""
55 return {
56 "ssh_hostname": self.hostname,
57 "ssh_port": self.get_port(uncached),
58 "ssh_username": self.username,
59 "ssh_priv_key_path": self.id_rsa_path,
60 }
62 def to_connect_params(self, uncached: bool = False) -> dict:
63 """
64 Convert to a connect_params dict for SshClient.
66 See Also: mlos_bench.services.remote.ssh.ssh_service.SshService._get_connect_params()
67 """
68 return {
69 "host": self.hostname,
70 "port": self.get_port(uncached),
71 "username": self.username,
72 }
75def wait_docker_service_socket(docker_services: DockerServices, hostname: str, port: int) -> None:
76 """Wait until a docker service is ready."""
77 docker_services.wait_until_responsive(
78 check=lambda: check_socket(hostname, port),
79 timeout=30.0,
80 pause=0.5,
81 )