#2064: added a method that checks if the class can perform actions and added it where necessary + tests everywhere
This commit is contained in:
@@ -263,7 +263,7 @@ class FolderObservation(AbstractObservation):
|
||||
self.files.append(FileObservation())
|
||||
while len(self.files) > num_files_per_folder:
|
||||
truncated_file = self.files.pop()
|
||||
msg = f"Too many files in folde observation. Truncating file {truncated_file}"
|
||||
msg = f"Too many files in folder observation. Truncating file {truncated_file}"
|
||||
_LOGGER.warn(msg)
|
||||
|
||||
self.default_observation = {
|
||||
|
||||
@@ -2,9 +2,11 @@ from abc import abstractmethod
|
||||
from enum import Enum
|
||||
from typing import Any, Dict, Set
|
||||
|
||||
from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState
|
||||
from primaite import getLogger
|
||||
from primaite.simulator.system.software import IOSoftware, SoftwareHealthState
|
||||
|
||||
_LOGGER = getLogger(__name__)
|
||||
|
||||
|
||||
class ApplicationOperatingState(Enum):
|
||||
"""Enumeration of Application Operating States."""
|
||||
@@ -52,7 +54,7 @@ class Application(IOSoftware):
|
||||
state = super().describe_state()
|
||||
state.update(
|
||||
{
|
||||
"opearting_state": self.operating_state.value,
|
||||
"operating_state": self.operating_state.value,
|
||||
"execution_control_status": self.execution_control_status,
|
||||
"num_executions": self.num_executions,
|
||||
"groups": list(self.groups),
|
||||
@@ -60,10 +62,28 @@ class Application(IOSoftware):
|
||||
)
|
||||
return state
|
||||
|
||||
def _can_perform_action(self) -> bool:
|
||||
"""
|
||||
Checks if the application can perform actions.
|
||||
|
||||
This is done by checking if the application is operating properly or the node it is installed
|
||||
in is operational.
|
||||
|
||||
Returns true if the software can perform actions.
|
||||
"""
|
||||
if not super()._can_perform_action():
|
||||
return False
|
||||
|
||||
if self.operating_state is not self.operating_state.RUNNING:
|
||||
# service is not running
|
||||
_LOGGER.error(f"Cannot perform action: {self.name} is {self.operating_state.name}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def run(self) -> None:
|
||||
"""Open the Application."""
|
||||
if self.software_manager and self.software_manager.node.operating_state is not NodeOperatingState.ON:
|
||||
self.sys_log.error(f"Unable to run application. {self.software_manager.node.hostname} is not turned on.")
|
||||
if not super()._can_perform_action():
|
||||
return
|
||||
|
||||
if self.operating_state == ApplicationOperatingState.CLOSED:
|
||||
@@ -78,6 +98,9 @@ class Application(IOSoftware):
|
||||
|
||||
def install(self) -> None:
|
||||
"""Install Application."""
|
||||
if self._can_perform_action():
|
||||
return
|
||||
|
||||
super().install()
|
||||
if self.operating_state == ApplicationOperatingState.CLOSED:
|
||||
self.sys_log.info(f"Installing Application {self.name}")
|
||||
@@ -102,4 +125,4 @@ class Application(IOSoftware):
|
||||
:param payload: The payload to receive.
|
||||
:return: True if successful, False otherwise.
|
||||
"""
|
||||
pass
|
||||
return super().receive(payload=payload, session_id=session_id, **kwargs)
|
||||
|
||||
@@ -54,7 +54,10 @@ class DatabaseClient(Application):
|
||||
|
||||
def connect(self) -> bool:
|
||||
"""Connect to a Database Service."""
|
||||
if not self.connected and self.operating_state.RUNNING:
|
||||
if not self._can_perform_action():
|
||||
return False
|
||||
|
||||
if not self.connected:
|
||||
return self._connect(self.server_ip_address, self.server_password)
|
||||
return False
|
||||
|
||||
@@ -135,19 +138,31 @@ class DatabaseClient(Application):
|
||||
self.operating_state = ApplicationOperatingState.RUNNING
|
||||
self.connect()
|
||||
|
||||
def query(self, sql: str) -> bool:
|
||||
def query(self, sql: str, is_reattempt: bool = False) -> bool:
|
||||
"""
|
||||
Send a query to the Database Service.
|
||||
|
||||
:param sql: The SQL query.
|
||||
:param: sql: The SQL query.
|
||||
:param: is_reattempt: If true, the action has been reattempted.
|
||||
:return: True if the query was successful, otherwise False.
|
||||
"""
|
||||
if self.connected and self.operating_state.RUNNING:
|
||||
if not self._can_perform_action():
|
||||
return False
|
||||
|
||||
if self.connected:
|
||||
query_id = str(uuid4())
|
||||
|
||||
# Initialise the tracker of this ID to False
|
||||
self._query_success_tracker[query_id] = False
|
||||
return self._query(sql=sql, query_id=query_id)
|
||||
else:
|
||||
if is_reattempt:
|
||||
return False
|
||||
|
||||
if not self.connect():
|
||||
return False
|
||||
|
||||
self.query(sql=sql, is_reattempt=True)
|
||||
|
||||
def receive(self, payload: Any, session_id: str, **kwargs) -> bool:
|
||||
"""
|
||||
|
||||
@@ -65,6 +65,9 @@ class WebBrowser(Application):
|
||||
:param: url: The address of the web page the browser requests
|
||||
:type: url: str
|
||||
"""
|
||||
if not self._can_perform_action():
|
||||
return False
|
||||
|
||||
# reset latest response
|
||||
self.latest_response = HttpResponsePacket(status_code=HttpStatusCode.NOT_FOUND)
|
||||
|
||||
|
||||
@@ -48,6 +48,10 @@ class DatabaseService(Service):
|
||||
|
||||
def backup_database(self) -> bool:
|
||||
"""Create a backup of the database to the configured backup server."""
|
||||
# check if this action can be performed
|
||||
if not self._can_perform_action():
|
||||
return False
|
||||
|
||||
# check if the backup server was configured
|
||||
if self.backup_server is None:
|
||||
self.sys_log.error(f"{self.name} - {self.sys_log.hostname}: not configured.")
|
||||
@@ -73,6 +77,10 @@ class DatabaseService(Service):
|
||||
|
||||
def restore_backup(self) -> bool:
|
||||
"""Restore a backup from backup server."""
|
||||
# check if this action can be performed
|
||||
if not self._can_perform_action():
|
||||
return False
|
||||
|
||||
software_manager: SoftwareManager = self.software_manager
|
||||
ftp_client_service: FTPClient = software_manager.software["FTPClient"]
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from ipaddress import IPv4Address
|
||||
from typing import Dict, Optional
|
||||
from typing import Dict, Optional, Union
|
||||
|
||||
from primaite import getLogger
|
||||
from primaite.simulator.network.protocols.dns import DNSPacket, DNSRequest
|
||||
@@ -51,13 +51,16 @@ class DNSClient(Service):
|
||||
"""
|
||||
pass
|
||||
|
||||
def add_domain_to_cache(self, domain_name: str, ip_address: IPv4Address):
|
||||
def add_domain_to_cache(self, domain_name: str, ip_address: IPv4Address) -> Union[bool, None]:
|
||||
"""
|
||||
Adds a domain name to the DNS Client cache.
|
||||
|
||||
:param: domain_name: The domain name to save to cache
|
||||
:param: ip_address: The IP Address to attach the domain name to
|
||||
"""
|
||||
if not self._can_perform_action():
|
||||
return False
|
||||
|
||||
self.dns_cache[domain_name] = ip_address
|
||||
|
||||
def check_domain_exists(
|
||||
@@ -72,6 +75,9 @@ class DNSClient(Service):
|
||||
:param: session_id: The Session ID the payload is to originate from. Optional.
|
||||
:param: is_reattempt: Checks if the request has been reattempted. Default is False.
|
||||
"""
|
||||
if not self._can_perform_action():
|
||||
return False
|
||||
|
||||
# check if DNS server is configured
|
||||
if self.dns_server is None:
|
||||
self.sys_log.error(f"{self.name}: DNS Server is not configured")
|
||||
|
||||
@@ -48,6 +48,9 @@ class DNSServer(Service):
|
||||
:param target_domain: The single domain name requested by a DNS client.
|
||||
:return ip_address: The IP address of that domain name or None.
|
||||
"""
|
||||
if not self._can_perform_action():
|
||||
return
|
||||
|
||||
return self.dns_table.get(target_domain)
|
||||
|
||||
def dns_register(self, domain_name: str, domain_ip_address: IPv4Address):
|
||||
@@ -60,6 +63,9 @@ class DNSServer(Service):
|
||||
:param: domain_ip_address: The IP address that the domain should route to
|
||||
:type: domain_ip_address: IPv4Address
|
||||
"""
|
||||
if not self._can_perform_action():
|
||||
return
|
||||
|
||||
self.dns_table[domain_name] = domain_ip_address
|
||||
|
||||
def reset_component_for_episode(self, episode: int):
|
||||
|
||||
@@ -3,7 +3,6 @@ from typing import Any, Dict, Optional
|
||||
|
||||
from primaite import getLogger
|
||||
from primaite.simulator.core import RequestManager, RequestType
|
||||
from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState
|
||||
from primaite.simulator.system.software import IOSoftware, SoftwareHealthState
|
||||
|
||||
_LOGGER = getLogger(__name__)
|
||||
@@ -41,6 +40,25 @@ class Service(IOSoftware):
|
||||
restart_countdown: Optional[int] = None
|
||||
"If currently restarting, how many timesteps remain until the restart is finished."
|
||||
|
||||
def _can_perform_action(self) -> bool:
|
||||
"""
|
||||
Checks if the service can perform actions.
|
||||
|
||||
This is done by checking if the service is operating properly or the node it is installed
|
||||
in is operational.
|
||||
|
||||
Returns true if the software can perform actions.
|
||||
"""
|
||||
if not super()._can_perform_action():
|
||||
return False
|
||||
|
||||
if self.operating_state is not self.operating_state.RUNNING:
|
||||
# service is not running
|
||||
_LOGGER.error(f"Cannot perform action: {self.name} is {self.operating_state.name}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def receive(self, payload: Any, session_id: str, **kwargs) -> bool:
|
||||
"""
|
||||
Receives a payload from the SessionManager.
|
||||
@@ -108,8 +126,7 @@ class Service(IOSoftware):
|
||||
def start(self, **kwargs) -> None:
|
||||
"""Start the service."""
|
||||
# cant start the service if the node it is on is off
|
||||
if self.software_manager and self.software_manager.node.operating_state is not NodeOperatingState.ON:
|
||||
self.sys_log.error(f"Unable to start service. {self.software_manager.node.hostname} is not turned on.")
|
||||
if not super()._can_perform_action():
|
||||
return
|
||||
|
||||
if self.operating_state == ServiceOperatingState.STOPPED:
|
||||
|
||||
@@ -226,6 +226,21 @@ class IOSoftware(Software):
|
||||
)
|
||||
return state
|
||||
|
||||
@abstractmethod
|
||||
def _can_perform_action(self) -> bool:
|
||||
"""
|
||||
Checks if the software can perform actions.
|
||||
|
||||
This is done by checking if the software is operating properly or the node it is installed
|
||||
in is operational.
|
||||
|
||||
Returns true if the software can perform actions.
|
||||
"""
|
||||
if self.software_manager and self.software_manager.node.operating_state is NodeOperatingState.OFF:
|
||||
_LOGGER.debug(f"{self.name} Error: {self.software_manager.node.hostname} is not online.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def send(
|
||||
self,
|
||||
payload: Any,
|
||||
@@ -244,6 +259,9 @@ class IOSoftware(Software):
|
||||
|
||||
:return: True if successful, False otherwise.
|
||||
"""
|
||||
if not self._can_perform_action():
|
||||
return False
|
||||
|
||||
return self.software_manager.send_payload_to_session_manager(
|
||||
payload=payload, dest_ip_address=dest_ip_address, dest_port=dest_port, session_id=session_id
|
||||
)
|
||||
@@ -262,8 +280,5 @@ class IOSoftware(Software):
|
||||
:param kwargs: Additional keyword arguments specific to the implementation.
|
||||
:return: True if the payload was successfully received and processed, False otherwise.
|
||||
"""
|
||||
# return false if node that software is on is off
|
||||
if self.software_manager and self.software_manager.node.operating_state is NodeOperatingState.OFF:
|
||||
_LOGGER.debug(f"{self.name} Error: {self.software_manager.node.hostname} is not online.")
|
||||
return False
|
||||
return True
|
||||
# return false if not allowed to perform actions
|
||||
return self._can_perform_action()
|
||||
|
||||
110
tests/integration_tests/system/test_application_on_node.py
Normal file
110
tests/integration_tests/system/test_application_on_node.py
Normal file
@@ -0,0 +1,110 @@
|
||||
from typing import Tuple
|
||||
|
||||
import pytest
|
||||
|
||||
from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState
|
||||
from primaite.simulator.network.hardware.nodes.computer import Computer
|
||||
from primaite.simulator.system.applications.application import Application, ApplicationOperatingState
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def populated_node(application_class) -> Tuple[Application, Computer]:
|
||||
computer: Computer = Computer(
|
||||
hostname="test_computer",
|
||||
ip_address="192.168.1.2",
|
||||
subnet_mask="255.255.255.0",
|
||||
default_gateway="192.168.1.1",
|
||||
operating_state=NodeOperatingState.ON,
|
||||
)
|
||||
computer.software_manager.install(application_class)
|
||||
|
||||
app = computer.software_manager.software["TestApplication"]
|
||||
app.run()
|
||||
|
||||
return app, computer
|
||||
|
||||
|
||||
def test_service_on_offline_node(application_class):
|
||||
"""Test to check that the service cannot be interacted with when node it is on is off."""
|
||||
computer: Computer = Computer(
|
||||
hostname="test_computer",
|
||||
ip_address="192.168.1.2",
|
||||
subnet_mask="255.255.255.0",
|
||||
default_gateway="192.168.1.1",
|
||||
operating_state=NodeOperatingState.ON,
|
||||
)
|
||||
computer.software_manager.install(application_class)
|
||||
|
||||
app: Application = computer.software_manager.software["TestApplication"]
|
||||
|
||||
computer.power_off()
|
||||
|
||||
for i in range(computer.shut_down_duration + 1):
|
||||
computer.apply_timestep(timestep=i)
|
||||
|
||||
assert computer.operating_state is NodeOperatingState.OFF
|
||||
assert app.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
app.run()
|
||||
assert app.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
|
||||
def test_server_turns_off_service(populated_node):
|
||||
"""Check that the service is turned off when the server is turned off"""
|
||||
app, computer = populated_node
|
||||
|
||||
assert computer.operating_state is NodeOperatingState.ON
|
||||
assert app.operating_state is ApplicationOperatingState.RUNNING
|
||||
|
||||
computer.power_off()
|
||||
|
||||
for i in range(computer.shut_down_duration + 1):
|
||||
computer.apply_timestep(timestep=i)
|
||||
|
||||
assert computer.operating_state is NodeOperatingState.OFF
|
||||
assert app.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
|
||||
def test_service_cannot_be_turned_on_when_server_is_off(populated_node):
|
||||
"""Check that the service cannot be started when the server is off."""
|
||||
app, computer = populated_node
|
||||
|
||||
assert computer.operating_state is NodeOperatingState.ON
|
||||
assert app.operating_state is ApplicationOperatingState.RUNNING
|
||||
|
||||
computer.power_off()
|
||||
|
||||
for i in range(computer.shut_down_duration + 1):
|
||||
computer.apply_timestep(timestep=i)
|
||||
|
||||
assert computer.operating_state is NodeOperatingState.OFF
|
||||
assert app.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
app.run()
|
||||
|
||||
assert computer.operating_state is NodeOperatingState.OFF
|
||||
assert app.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
|
||||
def test_server_turns_on_service(populated_node):
|
||||
"""Check that turning on the server turns on service."""
|
||||
app, computer = populated_node
|
||||
|
||||
assert computer.operating_state is NodeOperatingState.ON
|
||||
assert app.operating_state is ApplicationOperatingState.RUNNING
|
||||
|
||||
computer.power_off()
|
||||
|
||||
for i in range(computer.shut_down_duration + 1):
|
||||
computer.apply_timestep(timestep=i)
|
||||
|
||||
assert computer.operating_state is NodeOperatingState.OFF
|
||||
assert app.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
computer.power_on()
|
||||
|
||||
for i in range(computer.start_up_duration + 1):
|
||||
computer.apply_timestep(timestep=i)
|
||||
|
||||
assert computer.operating_state is NodeOperatingState.ON
|
||||
assert app.operating_state is ApplicationOperatingState.RUNNING
|
||||
@@ -3,34 +3,66 @@ from typing import Tuple
|
||||
import pytest
|
||||
|
||||
from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState
|
||||
from primaite.simulator.network.hardware.nodes.computer import Computer
|
||||
from primaite.simulator.network.hardware.nodes.server import Server
|
||||
from primaite.simulator.system.applications.application import Application, ApplicationOperatingState
|
||||
from primaite.simulator.system.services.service import Service, ServiceOperatingState
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def populated_node(service_class, application_class) -> Tuple[Application, Server, Service]:
|
||||
def populated_node(
|
||||
service_class,
|
||||
) -> Tuple[Server, Service]:
|
||||
server = Server(
|
||||
hostname="server", ip_address="192.168.0.1", subnet_mask="255.255.255.0", operating_state=NodeOperatingState.ON
|
||||
)
|
||||
server.software_manager.install(service_class)
|
||||
server.software_manager.install(application_class)
|
||||
|
||||
app = server.software_manager.software["TestApplication"]
|
||||
app.run()
|
||||
service = server.software_manager.software["TestService"]
|
||||
service.start()
|
||||
|
||||
return app, server, service
|
||||
return server, service
|
||||
|
||||
|
||||
def test_service_on_offline_node(service_class):
|
||||
"""Test to check that the service cannot be interacted with when node it is on is off."""
|
||||
computer: Computer = Computer(
|
||||
hostname="test_computer",
|
||||
ip_address="192.168.1.2",
|
||||
subnet_mask="255.255.255.0",
|
||||
default_gateway="192.168.1.1",
|
||||
operating_state=NodeOperatingState.ON,
|
||||
)
|
||||
computer.software_manager.install(service_class)
|
||||
|
||||
service: Service = computer.software_manager.software["TestService"]
|
||||
|
||||
computer.power_off()
|
||||
|
||||
for i in range(computer.shut_down_duration + 1):
|
||||
computer.apply_timestep(timestep=i)
|
||||
|
||||
assert computer.operating_state is NodeOperatingState.OFF
|
||||
assert service.operating_state is ServiceOperatingState.STOPPED
|
||||
|
||||
service.start()
|
||||
assert service.operating_state is ServiceOperatingState.STOPPED
|
||||
|
||||
service.resume()
|
||||
assert service.operating_state is ServiceOperatingState.STOPPED
|
||||
|
||||
service.restart()
|
||||
assert service.operating_state is ServiceOperatingState.STOPPED
|
||||
|
||||
service.pause()
|
||||
assert service.operating_state is ServiceOperatingState.STOPPED
|
||||
|
||||
|
||||
def test_server_turns_off_service(populated_node):
|
||||
"""Check that the service is turned off when the server is turned off"""
|
||||
app, server, service = populated_node
|
||||
server, service = populated_node
|
||||
|
||||
assert server.operating_state is NodeOperatingState.ON
|
||||
assert service.operating_state is ServiceOperatingState.RUNNING
|
||||
assert app.operating_state is ApplicationOperatingState.RUNNING
|
||||
|
||||
server.power_off()
|
||||
|
||||
@@ -39,16 +71,14 @@ def test_server_turns_off_service(populated_node):
|
||||
|
||||
assert server.operating_state is NodeOperatingState.OFF
|
||||
assert service.operating_state is ServiceOperatingState.STOPPED
|
||||
assert app.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
|
||||
def test_service_cannot_be_turned_on_when_server_is_off(populated_node):
|
||||
"""Check that the service cannot be started when the server is off."""
|
||||
app, server, service = populated_node
|
||||
server, service = populated_node
|
||||
|
||||
assert server.operating_state is NodeOperatingState.ON
|
||||
assert service.operating_state is ServiceOperatingState.RUNNING
|
||||
assert app.operating_state is ApplicationOperatingState.RUNNING
|
||||
|
||||
server.power_off()
|
||||
|
||||
@@ -57,23 +87,19 @@ def test_service_cannot_be_turned_on_when_server_is_off(populated_node):
|
||||
|
||||
assert server.operating_state is NodeOperatingState.OFF
|
||||
assert service.operating_state is ServiceOperatingState.STOPPED
|
||||
assert app.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
service.start()
|
||||
app.run()
|
||||
|
||||
assert server.operating_state is NodeOperatingState.OFF
|
||||
assert service.operating_state is ServiceOperatingState.STOPPED
|
||||
assert app.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
|
||||
def test_server_turns_on_service(populated_node):
|
||||
"""Check that turning on the server turns on service."""
|
||||
app, server, service = populated_node
|
||||
server, service = populated_node
|
||||
|
||||
assert server.operating_state is NodeOperatingState.ON
|
||||
assert service.operating_state is ServiceOperatingState.RUNNING
|
||||
assert app.operating_state is ApplicationOperatingState.RUNNING
|
||||
|
||||
server.power_off()
|
||||
|
||||
@@ -82,7 +108,6 @@ def test_server_turns_on_service(populated_node):
|
||||
|
||||
assert server.operating_state is NodeOperatingState.OFF
|
||||
assert service.operating_state is ServiceOperatingState.STOPPED
|
||||
assert app.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
server.power_on()
|
||||
|
||||
@@ -91,4 +116,3 @@ def test_server_turns_on_service(populated_node):
|
||||
|
||||
assert server.operating_state is NodeOperatingState.ON
|
||||
assert service.operating_state is ServiceOperatingState.RUNNING
|
||||
assert app.operating_state is ApplicationOperatingState.RUNNING
|
||||
@@ -78,3 +78,25 @@ def test_web_page_request_from_shut_down_server(uc2_network):
|
||||
|
||||
assert web_client.get_webpage("http://arcd.com/users/") is False
|
||||
assert web_client.latest_response.status_code == HttpStatusCode.NOT_FOUND
|
||||
|
||||
|
||||
def test_web_page_request_from_closed_web_browser(uc2_network):
|
||||
client_1: Computer = uc2_network.get_node_by_hostname("client_1")
|
||||
web_client: WebBrowser = client_1.software_manager.software["WebBrowser"]
|
||||
web_client.run()
|
||||
|
||||
web_server: Server = uc2_network.get_node_by_hostname("web_server")
|
||||
|
||||
assert web_client.operating_state == ApplicationOperatingState.RUNNING
|
||||
|
||||
assert web_client.get_webpage("http://arcd.com/users/") is True
|
||||
|
||||
# latest response should have status code 200
|
||||
assert web_client.latest_response.status_code == HttpStatusCode.OK
|
||||
|
||||
web_client.close()
|
||||
|
||||
# node should be off
|
||||
assert web_client.operating_state is ApplicationOperatingState.CLOSED
|
||||
|
||||
assert web_client.get_webpage("http://arcd.com/users/") is False
|
||||
|
||||
@@ -11,6 +11,7 @@ from primaite.simulator.network.transmission.network_layer import IPProtocol
|
||||
from primaite.simulator.network.transmission.transport_layer import Port
|
||||
from primaite.simulator.system.services.dns.dns_client import DNSClient
|
||||
from primaite.simulator.system.services.dns.dns_server import DNSServer
|
||||
from primaite.simulator.system.services.service import ServiceOperatingState
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
@@ -54,6 +55,44 @@ def test_create_dns_client(dns_client):
|
||||
assert dns_client_service.protocol is IPProtocol.TCP
|
||||
|
||||
|
||||
def test_dns_client_add_domain_to_cache_when_not_running(dns_client):
|
||||
dns_client_service: DNSClient = dns_client.software_manager.software["DNSClient"]
|
||||
assert dns_client.operating_state is NodeOperatingState.OFF
|
||||
assert dns_client_service.operating_state is ServiceOperatingState.STOPPED
|
||||
|
||||
assert (
|
||||
dns_client_service.add_domain_to_cache(domain_name="test.com", ip_address=IPv4Address("192.168.1.100")) is False
|
||||
)
|
||||
|
||||
assert dns_client_service.dns_cache.get("test.com") is None
|
||||
|
||||
|
||||
def test_dns_client_check_domain_exists_when_not_running(dns_client):
|
||||
dns_client.operating_state = NodeOperatingState.ON
|
||||
dns_client_service: DNSClient = dns_client.software_manager.software["DNSClient"]
|
||||
dns_client_service.start()
|
||||
|
||||
assert dns_client.operating_state is NodeOperatingState.ON
|
||||
assert dns_client_service.operating_state is ServiceOperatingState.RUNNING
|
||||
|
||||
assert (
|
||||
dns_client_service.add_domain_to_cache(domain_name="test.com", ip_address=IPv4Address("192.168.1.100"))
|
||||
is not False
|
||||
)
|
||||
|
||||
assert dns_client_service.check_domain_exists("test.com") is True
|
||||
|
||||
dns_client.power_off()
|
||||
|
||||
for i in range(dns_client.shut_down_duration + 1):
|
||||
dns_client.apply_timestep(timestep=i)
|
||||
|
||||
assert dns_client.operating_state is NodeOperatingState.OFF
|
||||
assert dns_client_service.operating_state is ServiceOperatingState.STOPPED
|
||||
|
||||
assert dns_client_service.check_domain_exists("test.com") is False
|
||||
|
||||
|
||||
def test_dns_server_domain_name_registration(dns_server):
|
||||
"""Test to check if the domain name registration works."""
|
||||
dns_server_service: DNSServer = dns_server.software_manager.software["DNSServer"]
|
||||
@@ -68,7 +107,9 @@ def test_dns_server_domain_name_registration(dns_server):
|
||||
|
||||
def test_dns_client_check_domain_in_cache(dns_client):
|
||||
"""Test to make sure that the check_domain_in_cache returns the correct values."""
|
||||
dns_client.operating_state = NodeOperatingState.ON
|
||||
dns_client_service: DNSClient = dns_client.software_manager.software["DNSClient"]
|
||||
dns_client_service.start()
|
||||
|
||||
# add a domain to the dns client cache
|
||||
dns_client_service.add_domain_to_cache("real-domain.com", IPv4Address("192.168.1.12"))
|
||||
|
||||
Reference in New Issue
Block a user