#2064: add handling of offline service to dns, ftp and database
This commit is contained in:
@@ -173,6 +173,9 @@ class DatabaseService(Service):
|
||||
:param session_id: The session identifier.
|
||||
:return: True if the Status Code is 200, otherwise False.
|
||||
"""
|
||||
if not super().receive(payload=payload, session_id=session_id, **kwargs):
|
||||
return False
|
||||
|
||||
result = {"status_code": 500, "data": []}
|
||||
if isinstance(payload, dict) and payload.get("type"):
|
||||
if payload["type"] == "connect_request":
|
||||
|
||||
@@ -88,10 +88,14 @@ class DNSServer(Service):
|
||||
|
||||
:return: True if DNS request returns a valid IP, otherwise, False
|
||||
"""
|
||||
if not super().receive(payload=payload, session_id=session_id, **kwargs):
|
||||
return False
|
||||
|
||||
# The payload should be a DNS packet
|
||||
if not isinstance(payload, DNSPacket):
|
||||
_LOGGER.debug(f"{payload} is not a DNSPacket")
|
||||
return False
|
||||
|
||||
# cast payload into a DNS packet
|
||||
payload: DNSPacket = payload
|
||||
if payload.dns_request is not None:
|
||||
|
||||
@@ -86,10 +86,10 @@ class FTPServer(FTPServiceABC):
|
||||
prevents an FTP request loop - FTP client and servers can exist on
|
||||
the same node.
|
||||
"""
|
||||
if payload.status_code is not None:
|
||||
if not super().receive(payload=payload, session_id=session_id, **kwargs):
|
||||
return False
|
||||
|
||||
if not super().receive(payload=payload, session_id=session_id, **kwargs):
|
||||
if payload.status_code is not None:
|
||||
return False
|
||||
|
||||
self.send(self._process_ftp_command(payload=payload, session_id=session_id), session_id)
|
||||
|
||||
@@ -155,12 +155,12 @@ class WebServer(Service):
|
||||
:param: payload: The payload to send.
|
||||
:param: session_id: The id of the session. Optional.
|
||||
"""
|
||||
if not super().receive(payload=payload, session_id=session_id, **kwargs):
|
||||
return False
|
||||
|
||||
# check if the payload is an HTTPPacket
|
||||
if not isinstance(payload, HttpRequestPacket):
|
||||
self.sys_log.error("Payload is not an HTTPPacket")
|
||||
return False
|
||||
|
||||
if not super().receive(payload=payload, session_id=session_id, **kwargs):
|
||||
return False
|
||||
|
||||
return self._process_http_request(payload=payload, session_id=session_id)
|
||||
|
||||
@@ -3,7 +3,7 @@ from enum import Enum
|
||||
from ipaddress import IPv4Address
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from primaite.simulator.core import RequestManager, RequestType, SimComponent
|
||||
from primaite.simulator.core import _LOGGER, RequestManager, RequestType, SimComponent
|
||||
from primaite.simulator.file_system.file_system import FileSystem, Folder
|
||||
from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState
|
||||
from primaite.simulator.network.transmission.transport_layer import Port
|
||||
@@ -264,5 +264,6 @@ class IOSoftware(Software):
|
||||
"""
|
||||
# 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
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
from ipaddress import IPv4Address
|
||||
|
||||
from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState
|
||||
from primaite.simulator.network.hardware.nodes.server import Server
|
||||
from primaite.simulator.system.applications.database_client import DatabaseClient
|
||||
from primaite.simulator.system.services.database.database_service import DatabaseService
|
||||
from primaite.simulator.system.services.ftp.ftp_server import FTPServer
|
||||
from primaite.simulator.system.services.service import ServiceOperatingState
|
||||
|
||||
|
||||
def test_database_client_server_connection(uc2_network):
|
||||
@@ -55,7 +57,8 @@ def test_database_client_query(uc2_network):
|
||||
"""Tests DB query across the network returns HTTP status 200 and date."""
|
||||
web_server: Server = uc2_network.get_node_by_hostname("web_server")
|
||||
db_client: DatabaseClient = web_server.software_manager.software["DatabaseClient"]
|
||||
db_client.connect()
|
||||
|
||||
assert db_client.connected
|
||||
|
||||
assert db_client.query("SELECT")
|
||||
|
||||
@@ -92,3 +95,28 @@ def test_restore_backup(uc2_network):
|
||||
assert db_service.restore_backup() is True
|
||||
|
||||
assert db_service.file_system.get_file(folder_name="database", file_name="database.db") is not None
|
||||
|
||||
|
||||
def test_database_client_cannot_query_offline_database_server(uc2_network):
|
||||
"""Tests DB query across the network returns HTTP status 404 when db server is offline."""
|
||||
db_server: Server = uc2_network.get_node_by_hostname("database_server")
|
||||
db_service: DatabaseService = db_server.software_manager.software["DatabaseService"]
|
||||
|
||||
assert db_server.operating_state is NodeOperatingState.ON
|
||||
assert db_service.operating_state is ServiceOperatingState.RUNNING
|
||||
|
||||
web_server: Server = uc2_network.get_node_by_hostname("web_server")
|
||||
db_client: DatabaseClient = web_server.software_manager.software["DatabaseClient"]
|
||||
assert db_client.connected
|
||||
|
||||
assert db_client.query("SELECT") is True
|
||||
|
||||
db_server.power_off()
|
||||
|
||||
for i in range(db_server.shut_down_duration + 1):
|
||||
uc2_network.apply_timestep(timestep=i)
|
||||
|
||||
assert db_server.operating_state is NodeOperatingState.OFF
|
||||
assert db_service.operating_state is ServiceOperatingState.STOPPED
|
||||
|
||||
assert db_client.query("SELECT") is False
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
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.services.dns.dns_client import DNSClient
|
||||
@@ -24,3 +25,39 @@ def test_dns_client_server(uc2_network):
|
||||
# arcd.com is registered in dns server and should be saved to cache
|
||||
assert dns_client.check_domain_exists(target_domain="arcd.com")
|
||||
assert dns_client.dns_cache.get("arcd.com", None) is not None
|
||||
|
||||
assert len(dns_client.dns_cache) == 1
|
||||
|
||||
|
||||
def test_dns_client_requests_offline_dns_server(uc2_network):
|
||||
client_1: Computer = uc2_network.get_node_by_hostname("client_1")
|
||||
domain_controller: Server = uc2_network.get_node_by_hostname("domain_controller")
|
||||
|
||||
dns_client: DNSClient = client_1.software_manager.software["DNSClient"]
|
||||
dns_server: DNSServer = domain_controller.software_manager.software["DNSServer"]
|
||||
|
||||
assert dns_client.operating_state == ServiceOperatingState.RUNNING
|
||||
assert dns_server.operating_state == ServiceOperatingState.RUNNING
|
||||
|
||||
dns_server.show()
|
||||
|
||||
# arcd.com is registered in dns server
|
||||
assert dns_client.check_domain_exists(target_domain="arcd.com")
|
||||
assert dns_client.dns_cache.get("arcd.com", None) is not None
|
||||
|
||||
assert len(dns_client.dns_cache) == 1
|
||||
dns_client.dns_cache = {}
|
||||
|
||||
domain_controller.power_off()
|
||||
|
||||
for i in range(domain_controller.shut_down_duration + 1):
|
||||
uc2_network.apply_timestep(timestep=i)
|
||||
|
||||
assert domain_controller.operating_state == NodeOperatingState.OFF
|
||||
assert dns_server.operating_state == ServiceOperatingState.STOPPED
|
||||
|
||||
# this time it should not cache because dns server is not online
|
||||
assert dns_client.check_domain_exists(target_domain="arcd.com") is False
|
||||
assert dns_client.dns_cache.get("arcd.com", None) is None
|
||||
|
||||
assert len(dns_client.dns_cache) == 0
|
||||
|
||||
@@ -3,6 +3,7 @@ from ipaddress import IPv4Address
|
||||
import pytest
|
||||
|
||||
from primaite.simulator.network.hardware.base import Node
|
||||
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.network.protocols.dns import DNSPacket, DNSReply, DNSRequest
|
||||
@@ -15,10 +16,13 @@ from primaite.simulator.system.services.dns.dns_server import DNSServer
|
||||
@pytest.fixture(scope="function")
|
||||
def dns_server() -> Node:
|
||||
node = Server(
|
||||
hostname="dns_server", ip_address="192.168.1.10", subnet_mask="255.255.255.0", default_gateway="192.168.1.1"
|
||||
hostname="dns_server",
|
||||
ip_address="192.168.1.10",
|
||||
subnet_mask="255.255.255.0",
|
||||
default_gateway="192.168.1.1",
|
||||
operating_state=NodeOperatingState.ON,
|
||||
)
|
||||
node.software_manager.install(software_class=DNSServer)
|
||||
node.software_manager.software["DNSServer"].start()
|
||||
return node
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user