Skip to content

Commit 1322f77

Browse files
authored
Merge pull request #414 from Limmen/host_manager
test host_manager is running in the container
2 parents 3518898 + babfac4 commit 1322f77

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import pytest
2+
import docker
3+
import logging
4+
import grpc
5+
from unittest.mock import MagicMock
6+
from docker.types import IPAMConfig, IPAMPool
7+
import time
8+
from csle_common.dao.emulation_config.emulation_env_config import EmulationEnvConfig
9+
from csle_common.util.emulation_util import EmulationUtil
10+
import csle_common.constants.constants as constants
11+
from csle_common.controllers.host_controller import HostController
12+
import csle_collector.host_manager.host_manager_pb2_grpc
13+
import csle_collector.host_manager.host_manager_pb2
14+
from IPython.lib.editorhooks import emacs
15+
16+
17+
@pytest.fixture(scope="module")
18+
def docker_client() -> None:
19+
"""
20+
Initialize and Provide a Docker client instance for the test
21+
22+
:return: None
23+
"""
24+
return docker.from_env()
25+
26+
27+
@pytest.fixture(scope="module")
28+
def network(docker_client) -> None:
29+
"""
30+
Create a custom network with a specific subnet
31+
32+
:param docker_client: docker_client
33+
:yield: network
34+
35+
:return: None
36+
"""
37+
ipam_pool = IPAMPool(subnet="15.15.15.0/24")
38+
ipam_config = IPAMConfig(pool_configs=[ipam_pool])
39+
network = docker_client.networks.create("test_network", driver="bridge", ipam=ipam_config)
40+
yield network
41+
network.remove()
42+
43+
44+
def get_derived_containers(docker_client, excluded_tag="blank") -> None:
45+
"""
46+
Get all the containers except the blank ones
47+
48+
:param docker_client: docker_client
49+
50+
:return: None
51+
"""
52+
# Get all images except those with the excluded tag
53+
match_tag = "0.6.0"
54+
all_images = docker_client.images.list()
55+
derived_images = [
56+
image
57+
for image in all_images
58+
if any(match_tag in tag for tag in image.tags)
59+
and all("base" not in tag for tag in image.tags)
60+
and all(excluded_tag not in tag for tag in image.tags)
61+
]
62+
return derived_images
63+
64+
65+
@pytest.fixture(scope="module", params=get_derived_containers(docker.from_env()))
66+
def container_setup(request, docker_client, network) -> None:
67+
"""
68+
Starts a Docker container before running tests and ensures its stopped and removed after tests complete.
69+
70+
:param request: request
71+
:param docker_client: docker_client
72+
:yield: container
73+
74+
:return: None
75+
"""
76+
# Create and start each derived container
77+
image = request.param
78+
container = docker_client.containers.create(
79+
image.tags[0], # Use the first tag for the image
80+
command="sh -c 'while true; do sleep 3600; done'",
81+
detach=True,
82+
)
83+
network.connect(container)
84+
container.start()
85+
yield container
86+
container.stop()
87+
container.remove()
88+
89+
90+
def test_start_host_manager(container_setup) -> None:
91+
"""
92+
Start host_manager in a container
93+
94+
:param container_setup: container_setup
95+
96+
:return: None
97+
"""
98+
failed_containers = []
99+
containers_info = []
100+
container_setup.reload()
101+
assert container_setup.status == "running"
102+
# Mock emulation_env_config
103+
emulation_env_config = MagicMock(spec=EmulationEnvConfig)
104+
emulation_env_config.get_connection.return_value = MagicMock()
105+
emulation_env_config.host_manager_config = MagicMock()
106+
emulation_env_config.host_manager_config.host_manager_port = 8080
107+
emulation_env_config.host_manager_config.host_manager_log_dir = "/var/log/host_manager"
108+
emulation_env_config.host_manager_config.host_manager_log_file = "host_manager.log"
109+
emulation_env_config.host_manager_config.host_manager_max_workers = 4
110+
111+
ip = container_setup.attrs["NetworkSettings"]["IPAddress"]
112+
port = emulation_env_config.host_manager_config.host_manager_port
113+
try:
114+
# Start host_manager command
115+
cmd = (
116+
f"/root/miniconda3/bin/python3 /host_manager.py "
117+
f"--port {emulation_env_config.host_manager_config.host_manager_port} "
118+
f"--logdir {emulation_env_config.host_manager_config.host_manager_log_dir} "
119+
f"--logfile {emulation_env_config.host_manager_config.host_manager_log_file} "
120+
f"--maxworkers {emulation_env_config.host_manager_config.host_manager_max_workers}"
121+
)
122+
# Run cmd in the container
123+
result = container_setup.exec_run(cmd, detach=True)
124+
# Check if host_manager starts
125+
cmd = (
126+
f"sh -c '{constants.COMMANDS.PS_AUX} | {constants.COMMANDS.GREP} "
127+
f"{constants.COMMANDS.SPACE_DELIM}{constants.TRAFFIC_COMMANDS.HOST_MANAGER_FILE_NAME}'"
128+
)
129+
result = container_setup.exec_run(cmd)
130+
output = result.output.decode("utf-8")
131+
assert constants.COMMANDS.SEARCH_HOST_MANAGER in output, "Host manager is not running in the container"
132+
time.sleep(5)
133+
# Call grpc
134+
with grpc.insecure_channel(f"{ip}:{port}", options=constants.GRPC_SERVERS.GRPC_OPTIONS) as channel:
135+
stub = csle_collector.host_manager.host_manager_pb2_grpc.HostManagerStub(channel)
136+
status = csle_collector.host_manager.query_host_manager.get_host_status(stub=stub)
137+
assert status
138+
except Exception as e:
139+
print(f"Error occurred in container {container_setup.name}: {e}")
140+
failed_containers.append(container_setup.name)
141+
containers_info.append(
142+
{
143+
"container_status": container_setup.status,
144+
"container_image": container_setup.image.tags,
145+
"name": container_setup.name,
146+
"error": str(e),
147+
}
148+
)
149+
if failed_containers:
150+
print("Containers that failed to start the host manager:")
151+
print(containers_info)
152+
assert not failed_containers, f"T{failed_containers} failed"

0 commit comments

Comments
 (0)