Skip to content

Commit b7a507e

Browse files
authored
Merge pull request #423 from Limmen/elk
managers start/stop tests
2 parents c92fc31 + 852c804 commit b7a507e

5 files changed

+842
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
from typing import List, Any, Generator
2+
import pytest
3+
import docker
4+
import logging
5+
import grpc
6+
from unittest.mock import MagicMock
7+
from docker.types import IPAMConfig, IPAMPool
8+
import time
9+
from csle_common.dao.emulation_config.emulation_env_config import EmulationEnvConfig
10+
from csle_common.util.emulation_util import EmulationUtil
11+
import csle_common.constants.constants as constants
12+
from csle_common.controllers.elk_controller import ELKController
13+
import csle_collector.elk_manager.elk_manager_pb2_grpc
14+
import csle_collector.elk_manager.elk_manager_pb2
15+
import csle_collector.elk_manager.query_elk_manager
16+
from csle_common.metastore.metastore_facade import MetastoreFacade
17+
from IPython.lib.editorhooks import emacs
18+
19+
20+
@pytest.fixture(scope="module")
21+
def docker_client() -> None:
22+
"""
23+
Initialize and Provide a Docker client instance for the test
24+
25+
:return: None
26+
"""
27+
return docker.from_env()
28+
29+
30+
@pytest.fixture(scope="module")
31+
def network(docker_client) -> None:
32+
"""
33+
Create a custom network with a specific subnet
34+
35+
:param docker_client: docker_client
36+
:yield: network
37+
38+
:return: None
39+
"""
40+
subnet = "15.15.15.0/24"
41+
ipam_pool = IPAMPool(subnet=subnet)
42+
ipam_config = IPAMConfig(pool_configs=[ipam_pool])
43+
logging.info(f"Creating virtual network with subnet: {subnet}")
44+
network = docker_client.networks.create("test_network", driver="bridge", ipam=ipam_config)
45+
yield network
46+
network.remove()
47+
48+
49+
def get_derived_containers(docker_client, excluded_tag=constants.CONTAINER_IMAGES.BLANK) -> List[Any]:
50+
"""
51+
Get all the containers except the blank ones
52+
53+
:param docker_client: docker_client
54+
55+
:return: None
56+
"""
57+
# Get all images except those with the excluded tag
58+
config = MetastoreFacade.get_config(id=1)
59+
match_tag = config.version
60+
all_images = docker_client.images.list()
61+
derived_images = [
62+
image
63+
for image in all_images
64+
if any(match_tag in tag for tag in image.tags)
65+
and all(constants.CONTAINER_IMAGES.BASE not in tag for tag in image.tags)
66+
and all(excluded_tag not in tag for tag in image.tags)
67+
]
68+
return derived_images
69+
70+
71+
@pytest.fixture(scope="module", params=get_derived_containers(docker.from_env()))
72+
def container_setup(request, docker_client, network) -> Generator:
73+
"""
74+
Starts a Docker container before running tests and ensures its stopped and removed after tests complete.
75+
76+
:param request: request
77+
:param docker_client: docker_client
78+
:yield: container
79+
80+
:return: None
81+
"""
82+
# Create and start each derived container
83+
image = request.param
84+
container = docker_client.containers.create(
85+
image.tags[0],
86+
command="sh -c 'while true; do sleep 3600; done'",
87+
detach=True,
88+
)
89+
network.connect(container)
90+
container.start()
91+
yield container
92+
logging.info(f"Stopping and removing container: {container.id} with image: {container.image.tags}")
93+
container.stop()
94+
container.remove()
95+
96+
97+
def test_start_elk_manager(container_setup) -> None:
98+
"""
99+
Start elk_manager in a container
100+
101+
:param container_setup: container_setup
102+
103+
:return: None
104+
"""
105+
failed_containers = []
106+
containers_info = []
107+
container_setup.reload()
108+
assert container_setup.status == "running"
109+
# Mock emulation_env_config
110+
emulation_env_config = MagicMock(spec=EmulationEnvConfig)
111+
emulation_env_config.get_connection.return_value = MagicMock()
112+
emulation_env_config.elk_config = MagicMock()
113+
emulation_env_config.elk_config.container.docker_gw_bridge_ip = container_setup.attrs[
114+
constants.DOCKER.NETWORK_SETTINGS
115+
][constants.DOCKER.IP_ADDRESS_INFO]
116+
emulation_env_config.elk_config.get_connection.return_value = MagicMock()
117+
emulation_env_config.elk_config.elk_manager_port = 50051
118+
emulation_env_config.elk_config.elk_manager_log_dir = "/var/log/elk"
119+
emulation_env_config.elk_config.elk_manager_log_file = "elk.log"
120+
emulation_env_config.elk_config.elk_manager_max_workers = 4
121+
122+
ip = emulation_env_config.elk_config.container.docker_gw_bridge_ip
123+
port = emulation_env_config.elk_config.elk_manager_port
124+
try:
125+
# Start elk_manager command
126+
cmd = (
127+
f"/root/miniconda3/bin/python3 /elk_manager.py "
128+
f"--port {emulation_env_config.elk_config.elk_manager_port} "
129+
f"--logdir {emulation_env_config.elk_config.elk_manager_log_dir} "
130+
f"--logfile {emulation_env_config.elk_config.elk_manager_log_file} "
131+
f"--maxworkers {emulation_env_config.elk_config.elk_manager_max_workers}"
132+
)
133+
# Run cmd in the container
134+
logging.info(
135+
f"Starting elk manager in container: {container_setup.id} " f"with image: {container_setup.image.tags}"
136+
)
137+
container_setup.exec_run(cmd, detach=True)
138+
# Check if elk_manager starts
139+
cmd = (
140+
f"sh -c '{constants.COMMANDS.PS_AUX} | {constants.COMMANDS.GREP} "
141+
f"{constants.COMMANDS.SPACE_DELIM}{constants.TRAFFIC_COMMANDS.ELK_MANAGER_FILE_NAME}'"
142+
)
143+
logging.info(
144+
f"Verifying that elk manager is running in container: {container_setup.id} "
145+
f"with image: {container_setup.image.tags}"
146+
)
147+
result = container_setup.exec_run(cmd)
148+
output = result.output.decode("utf-8")
149+
assert constants.COMMANDS.SEARCH_ELK_MANAGER in output, "Elk manager is not running in the container"
150+
time.sleep(5)
151+
# Call grpc
152+
with grpc.insecure_channel(f"{ip}:{port}", options=constants.GRPC_SERVERS.GRPC_OPTIONS) as channel:
153+
stub = csle_collector.elk_manager.elk_manager_pb2_grpc.ElkManagerStub(channel)
154+
elk_dto = csle_collector.elk_manager.query_elk_manager.get_elk_status(stub)
155+
assert elk_dto
156+
except Exception as e:
157+
print(f"Error occurred in container {container_setup.name}: {e}")
158+
failed_containers.append(container_setup.name)
159+
containers_info.append(
160+
{
161+
"container_status": container_setup.status,
162+
"container_image": container_setup.image.tags,
163+
"name": container_setup.name,
164+
"error": str(e),
165+
}
166+
)
167+
if failed_containers:
168+
logging.info("Containers that failed to start the elk manager:")
169+
logging.info(containers_info)
170+
assert not failed_containers, f"T{failed_containers} failed"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
from typing import List, Any, Generator
2+
import pytest
3+
import docker
4+
import logging
5+
import grpc
6+
from unittest.mock import MagicMock
7+
from docker.types import IPAMConfig, IPAMPool
8+
import time
9+
from csle_common.dao.emulation_config.emulation_env_config import EmulationEnvConfig
10+
from csle_common.util.emulation_util import EmulationUtil
11+
import csle_common.constants.constants as constants
12+
import csle_collector.kafka_manager.kafka_manager_pb2_grpc
13+
import csle_collector.kafka_manager.kafka_manager_pb2
14+
import csle_collector.kafka_manager.query_kafka_server
15+
from csle_common.metastore.metastore_facade import MetastoreFacade
16+
from IPython.lib.editorhooks import emacs
17+
18+
19+
@pytest.fixture(scope="module")
20+
def docker_client() -> None:
21+
"""
22+
Initialize and Provide a Docker client instance for the test
23+
24+
:return: None
25+
"""
26+
return docker.from_env()
27+
28+
29+
@pytest.fixture(scope="module")
30+
def network(docker_client) -> None:
31+
"""
32+
Create a custom network with a specific subnet
33+
34+
:param docker_client: docker_client
35+
:yield: network
36+
37+
:return: None
38+
"""
39+
subnet = "15.15.15.0/24"
40+
ipam_pool = IPAMPool(subnet=subnet)
41+
ipam_config = IPAMConfig(pool_configs=[ipam_pool])
42+
logging.info(f"Creating virtual network with subnet: {subnet}")
43+
network = docker_client.networks.create("test_network", driver="bridge", ipam=ipam_config)
44+
yield network
45+
network.remove()
46+
47+
48+
def get_derived_containers(docker_client, excluded_tag=constants.CONTAINER_IMAGES.BLANK) -> List[Any]:
49+
"""
50+
Get all the containers except the blank ones
51+
52+
:param docker_client: docker_client
53+
54+
:return: None
55+
"""
56+
# Get all images except those with the excluded tag
57+
config = MetastoreFacade.get_config(id=1)
58+
match_tag = config.version
59+
all_images = docker_client.images.list()
60+
derived_images = [
61+
image
62+
for image in all_images
63+
if any(match_tag in tag for tag in image.tags)
64+
and all(constants.CONTAINER_IMAGES.BASE not in tag for tag in image.tags)
65+
and all(excluded_tag not in tag for tag in image.tags)
66+
]
67+
return derived_images
68+
69+
70+
@pytest.fixture(scope="module", params=get_derived_containers(docker.from_env()))
71+
def container_setup(request, docker_client, network) -> Generator:
72+
"""
73+
Starts a Docker container before running tests and ensures its stopped and removed after tests complete.
74+
75+
:param request: request
76+
:param docker_client: docker_client
77+
:yield: container
78+
79+
:return: None
80+
"""
81+
# Create and start each derived container
82+
image = request.param
83+
container = docker_client.containers.create(
84+
image.tags[0],
85+
command="sh -c 'while true; do sleep 3600; done'",
86+
detach=True,
87+
)
88+
network.connect(container)
89+
container.start()
90+
yield container
91+
logging.info(f"Stopping and removing container: {container.id} with image: {container.image.tags}")
92+
container.stop()
93+
container.remove()
94+
95+
96+
def test_start_kafka_manager(container_setup) -> None:
97+
"""
98+
Start kafka_manager in a container
99+
100+
:param container_setup: container_setup
101+
102+
:return: None
103+
"""
104+
failed_containers = []
105+
containers_info = []
106+
container_setup.reload()
107+
assert container_setup.status == "running"
108+
# Mock emulation_env_config
109+
emulation_env_config = MagicMock(spec=EmulationEnvConfig)
110+
emulation_env_config.get_connection.return_value = MagicMock()
111+
emulation_env_config.kafka_config = MagicMock()
112+
emulation_env_config.kafka_config.container.docker_gw_bridge_ip = container_setup.attrs[
113+
constants.DOCKER.NETWORK_SETTINGS
114+
][constants.DOCKER.IP_ADDRESS_INFO]
115+
emulation_env_config.kafka_config.get_connection.return_value = MagicMock()
116+
emulation_env_config.kafka_config.kafka_manager_port = 50051
117+
emulation_env_config.kafka_config.kafka_manager_log_dir = "/var/log/kafka"
118+
emulation_env_config.kafka_config.kafka_manager_log_file = "kafka.log"
119+
emulation_env_config.kafka_config.kafka_manager_max_workers = 4
120+
121+
ip = emulation_env_config.kafka_config.container.docker_gw_bridge_ip
122+
port = emulation_env_config.kafka_config.kafka_manager_port
123+
try:
124+
# Start kafka_manager command
125+
cmd = (
126+
f"/root/miniconda3/bin/python3 /kafka_manager.py "
127+
f"--port {emulation_env_config.kafka_config.kafka_manager_port} "
128+
f"--logdir {emulation_env_config.kafka_config.kafka_manager_log_dir} "
129+
f"--logfile {emulation_env_config.kafka_config.kafka_manager_log_file} "
130+
f"--maxworkers {emulation_env_config.kafka_config.kafka_manager_max_workers}"
131+
)
132+
# Run cmd in the container
133+
logging.info(
134+
f"Starting kafka manager in container: {container_setup.id} " f"with image: {container_setup.image.tags}"
135+
)
136+
container_setup.exec_run(cmd, detach=True)
137+
# Check if kafka_manager starts
138+
cmd = (
139+
f"sh -c '{constants.COMMANDS.PS_AUX} | {constants.COMMANDS.GREP} "
140+
f"{constants.COMMANDS.SPACE_DELIM}{constants.TRAFFIC_COMMANDS.KAFKA_MANAGER_FILE_NAME}'"
141+
)
142+
logging.info(
143+
f"Verifying that kafka manager is running in container: {container_setup.id} "
144+
f"with image: {container_setup.image.tags}"
145+
)
146+
result = container_setup.exec_run(cmd)
147+
output = result.output.decode("utf-8")
148+
assert constants.COMMANDS.SEARCH_KAFKA_MANAGER in output, "Kafka manager is not running in the container"
149+
time.sleep(5)
150+
# Call grpc
151+
with grpc.insecure_channel(f"{ip}:{port}", options=constants.GRPC_SERVERS.GRPC_OPTIONS) as channel:
152+
stub = csle_collector.kafka_manager.kafka_manager_pb2_grpc.KafkaManagerStub(channel)
153+
kafka_dto = csle_collector.kafka_manager.query_kafka_server.get_kafka_status(stub)
154+
assert kafka_dto
155+
except Exception as e:
156+
print(f"Error occurred in container {container_setup.name}: {e}")
157+
failed_containers.append(container_setup.name)
158+
containers_info.append(
159+
{
160+
"container_status": container_setup.status,
161+
"container_image": container_setup.image.tags,
162+
"name": container_setup.name,
163+
"error": str(e),
164+
}
165+
)
166+
if failed_containers:
167+
logging.info("Containers that failed to start the kafka manager:")
168+
logging.info(containers_info)
169+
assert not failed_containers, f"T{failed_containers} failed"

0 commit comments

Comments
 (0)