diff --git a/tests/integration_tests/game_layer/actions/test_application_request_permission.py b/tests/integration_tests/game_layer/actions/test_application_request_permission.py new file mode 100644 index 00000000..36a7ae57 --- /dev/null +++ b/tests/integration_tests/game_layer/actions/test_application_request_permission.py @@ -0,0 +1,54 @@ +# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK +from typing import Tuple + +import pytest + +from primaite.game.agent.interface import ProxyAgent +from primaite.game.game import PrimaiteGame +from primaite.simulator.network.hardware.nodes.host.computer import Computer +from primaite.simulator.network.hardware.nodes.host.server import Server +from primaite.simulator.system.applications.application import ApplicationOperatingState +from primaite.simulator.system.applications.web_browser import WebBrowser +from primaite.simulator.system.services.service import ServiceOperatingState + + +@pytest.fixture +def game_and_agent_fixture(game_and_agent): + """Create a game with a simple agent that can be controlled by the tests.""" + game, agent = game_and_agent + + client_1: Computer = game.simulation.network.get_node_by_hostname("client_1") + client_1.start_up_duration = 3 + + return (game, agent) + + +def test_application_cannot_perform_actions_unless_running(game_and_agent_fixture: Tuple[PrimaiteGame, ProxyAgent]): + """Test the the request permissions prevent any actions unless application is running.""" + game, agent = game_and_agent_fixture + + client_1 = game.simulation.network.get_node_by_hostname("client_1") + browser: WebBrowser = client_1.software_manager.software.get("WebBrowser") + + browser.close() + assert browser.operating_state == ApplicationOperatingState.CLOSED + + action = ("NODE_APPLICATION_SCAN", {"node_id": 0, "application_id": 0}) + agent.store_action(action) + game.step() + assert browser.operating_state == ApplicationOperatingState.CLOSED + + action = ("NODE_APPLICATION_CLOSE", {"node_id": 0, "application_id": 0}) + agent.store_action(action) + game.step() + assert browser.operating_state == ApplicationOperatingState.CLOSED + + action = ("NODE_APPLICATION_FIX", {"node_id": 0, "application_id": 0}) + agent.store_action(action) + game.step() + assert browser.operating_state == ApplicationOperatingState.CLOSED + + action = ("NODE_APPLICATION_EXECUTE", {"node_id": 0, "application_id": 0}) + agent.store_action(action) + game.step() + assert browser.operating_state == ApplicationOperatingState.CLOSED diff --git a/tests/integration_tests/game_layer/actions/test_nic_request_permission.py b/tests/integration_tests/game_layer/actions/test_nic_request_permission.py new file mode 100644 index 00000000..4c1619e7 --- /dev/null +++ b/tests/integration_tests/game_layer/actions/test_nic_request_permission.py @@ -0,0 +1,97 @@ +# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK +from typing import Tuple + +import pytest + +from primaite.game.agent.interface import ProxyAgent +from primaite.game.game import PrimaiteGame +from primaite.simulator.network.hardware.nodes.host.computer import Computer +from primaite.simulator.network.hardware.nodes.host.server import Server +from primaite.simulator.system.services.service import ServiceOperatingState + + +@pytest.fixture +def game_and_agent_fixture(game_and_agent): + """Create a game with a simple agent that can be controlled by the tests.""" + game, agent = game_and_agent + + client_1: Computer = game.simulation.network.get_node_by_hostname("client_1") + client_1.start_up_duration = 3 + + return (game, agent) + + +def test_nic_cannot_be_turned_off_if_not_on(game_and_agent_fixture: Tuple[PrimaiteGame, ProxyAgent]): + """Test that a NIC cannot be disabled if it is not enabled.""" + game, agent = game_and_agent_fixture + + client_1 = game.simulation.network.get_node_by_hostname("client_1") + nic = client_1.network_interface[1] + nic.disable() + assert nic.enabled is False + + action = ( + "HOST_NIC_DISABLE", + { + "node_id": 0, # client_1 + "nic_id": 0, # the only nic (eth-1) + }, + ) + agent.store_action(action) + game.step() + + assert nic.enabled is False + + +def test_nic_cannot_be_turned_on_if_already_on(game_and_agent_fixture: Tuple[PrimaiteGame, ProxyAgent]): + """Test that a NIC cannot be enabled if it is already enabled.""" + game, agent = game_and_agent_fixture + + client_1 = game.simulation.network.get_node_by_hostname("client_1") + nic = client_1.network_interface[1] + assert nic.enabled + + action = ( + "HOST_NIC_ENABLE", + { + "node_id": 0, # client_1 + "nic_id": 0, # the only nic (eth-1) + }, + ) + agent.store_action(action) + game.step() + + assert nic.enabled + + +def test_that_a_nic_can_be_enabled_and_disabled(game_and_agent_fixture: Tuple[PrimaiteGame, ProxyAgent]): + """Tests that a NIC can be enabled and disabled.""" + game, agent = game_and_agent_fixture + + client_1 = game.simulation.network.get_node_by_hostname("client_1") + nic = client_1.network_interface[1] + assert nic.enabled + + action = ( + "HOST_NIC_DISABLE", + { + "node_id": 0, # client_1 + "nic_id": 0, # the only nic (eth-1) + }, + ) + agent.store_action(action) + game.step() + + assert nic.enabled is False + + action = ( + "HOST_NIC_ENABLE", + { + "node_id": 0, # client_1 + "nic_id": 0, # the only nic (eth-1) + }, + ) + agent.store_action(action) + game.step() + + assert nic.enabled diff --git a/tests/integration_tests/game_layer/actions/test_node_request_permission.py b/tests/integration_tests/game_layer/actions/test_node_request_permission.py index be6c00e7..fdf04ad5 100644 --- a/tests/integration_tests/game_layer/actions/test_node_request_permission.py +++ b/tests/integration_tests/game_layer/actions/test_node_request_permission.py @@ -1 +1,94 @@ # © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK +from typing import Tuple + +import pytest + +from primaite.game.agent.interface import ProxyAgent +from primaite.game.game import PrimaiteGame +from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState +from primaite.simulator.network.hardware.nodes.host.computer import Computer + + +@pytest.fixture +def game_and_agent_fixture(game_and_agent): + """Create a game with a simple agent that can be controlled by the tests.""" + game, agent = game_and_agent + + client_1: Computer = game.simulation.network.get_node_by_hostname("client_1") + client_1.start_up_duration = 3 + + return (game, agent) + + +def test_node_startup_shutdown(game_and_agent_fixture: Tuple[PrimaiteGame, ProxyAgent]): + """Test that the node can be shut down and started up.""" + game, agent = game_and_agent_fixture + + client_1 = game.simulation.network.get_node_by_hostname("client_1") + + assert client_1.operating_state == NodeOperatingState.ON + + # turn it off + action = ("NODE_SHUTDOWN", {"node_id": 0}) + agent.store_action(action) + game.step() + + assert client_1.operating_state == NodeOperatingState.SHUTTING_DOWN + + for i in range(client_1.shut_down_duration + 1): + action = ("DONOTHING", {"node_id": 0}) + agent.store_action(action) + game.step() + + assert client_1.operating_state == NodeOperatingState.OFF + + # turn it on + action = ("NODE_STARTUP", {"node_id": 0}) + agent.store_action(action) + game.step() + + assert client_1.operating_state == NodeOperatingState.BOOTING + + for i in range(client_1.start_up_duration + 1): + action = ("DONOTHING", {"node_id": 0}) + agent.store_action(action) + game.step() + + assert client_1.operating_state == NodeOperatingState.ON + + +def test_node_cannot_be_started_up_if_node_is_already_on(game_and_agent_fixture: Tuple[PrimaiteGame, ProxyAgent]): + """Test that a node cannot be started up if it is already on.""" + game, agent = game_and_agent_fixture + + client_1 = game.simulation.network.get_node_by_hostname("client_1") + assert client_1.operating_state == NodeOperatingState.ON + + # turn it on + action = ("NODE_STARTUP", {"node_id": 0}) + agent.store_action(action) + game.step() + + assert client_1.operating_state == NodeOperatingState.ON + + +def test_node_cannot_be_shut_down_if_node_is_already_off(game_and_agent_fixture: Tuple[PrimaiteGame, ProxyAgent]): + """Test that a node cannot be shut down if it is already off.""" + game, agent = game_and_agent_fixture + + client_1 = game.simulation.network.get_node_by_hostname("client_1") + client_1.power_off() + + for i in range(client_1.shut_down_duration + 1): + action = ("DONOTHING", {"node_id": 0}) + agent.store_action(action) + game.step() + + assert client_1.operating_state == NodeOperatingState.OFF + + # turn it ff + action = ("NODE_SHUTDOWN", {"node_id": 0}) + agent.store_action(action) + game.step() + + assert client_1.operating_state == NodeOperatingState.OFF diff --git a/tests/integration_tests/game_layer/actions/test_service_request_permission.py b/tests/integration_tests/game_layer/actions/test_service_request_permission.py new file mode 100644 index 00000000..3054c73b --- /dev/null +++ b/tests/integration_tests/game_layer/actions/test_service_request_permission.py @@ -0,0 +1,106 @@ +# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK +from typing import Tuple + +import pytest + +from primaite.game.agent.interface import ProxyAgent +from primaite.game.game import PrimaiteGame +from primaite.simulator.network.hardware.nodes.host.computer import Computer +from primaite.simulator.network.hardware.nodes.host.server import Server +from primaite.simulator.system.services.service import ServiceOperatingState + + +@pytest.fixture +def game_and_agent_fixture(game_and_agent): + """Create a game with a simple agent that can be controlled by the tests.""" + game, agent = game_and_agent + + client_1: Computer = game.simulation.network.get_node_by_hostname("client_1") + client_1.start_up_duration = 3 + + return (game, agent) + + +def test_service_start(game_and_agent_fixture: Tuple[PrimaiteGame, ProxyAgent]): + """Test that the validator makes sure that the service is stopped before starting the service.""" + game, agent = game_and_agent_fixture + + server_1: Server = game.simulation.network.get_node_by_hostname("server_1") + dns_server = server_1.software_manager.software.get("DNSServer") + + dns_server.pause() + assert dns_server.operating_state == ServiceOperatingState.PAUSED + + action = ("NODE_SERVICE_START", {"node_id": 1, "service_id": 0}) + agent.store_action(action) + game.step() + assert dns_server.operating_state == ServiceOperatingState.PAUSED + + dns_server.stop() + + assert dns_server.operating_state == ServiceOperatingState.STOPPED + + action = ("NODE_SERVICE_START", {"node_id": 1, "service_id": 0}) + agent.store_action(action) + game.step() + + assert dns_server.operating_state == ServiceOperatingState.RUNNING + + +def test_service_resume(game_and_agent_fixture: Tuple[PrimaiteGame, ProxyAgent]): + """Test that the validator checks if the service is paused before resuming.""" + game, agent = game_and_agent_fixture + + server_1: Server = game.simulation.network.get_node_by_hostname("server_1") + dns_server = server_1.software_manager.software.get("DNSServer") + + action = ("NODE_SERVICE_RESUME", {"node_id": 1, "service_id": 0}) + agent.store_action(action) + game.step() + assert dns_server.operating_state == ServiceOperatingState.RUNNING + + dns_server.pause() + + assert dns_server.operating_state == ServiceOperatingState.PAUSED + + action = ("NODE_SERVICE_RESUME", {"node_id": 1, "service_id": 0}) + agent.store_action(action) + game.step() + + assert dns_server.operating_state == ServiceOperatingState.RUNNING + + +def test_service_cannot_perform_actions_unless_running(game_and_agent_fixture: Tuple[PrimaiteGame, ProxyAgent]): + """Test to make sure that the service cannot perform certain actions while not running.""" + game, agent = game_and_agent_fixture + + server_1: Server = game.simulation.network.get_node_by_hostname("server_1") + dns_server = server_1.software_manager.software.get("DNSServer") + + dns_server.stop() + assert dns_server.operating_state == ServiceOperatingState.STOPPED + + action = ("NODE_SERVICE_SCAN", {"node_id": 1, "service_id": 0}) + agent.store_action(action) + game.step() + assert dns_server.operating_state == ServiceOperatingState.STOPPED + + action = ("NODE_SERVICE_PAUSE", {"node_id": 1, "service_id": 0}) + agent.store_action(action) + game.step() + assert dns_server.operating_state == ServiceOperatingState.STOPPED + + action = ("NODE_SERVICE_RESUME", {"node_id": 1, "service_id": 0}) + agent.store_action(action) + game.step() + assert dns_server.operating_state == ServiceOperatingState.STOPPED + + action = ("NODE_SERVICE_RESTART", {"node_id": 1, "service_id": 0}) + agent.store_action(action) + game.step() + assert dns_server.operating_state == ServiceOperatingState.STOPPED + + action = ("NODE_SERVICE_FIX", {"node_id": 1, "service_id": 0}) + agent.store_action(action) + game.step() + assert dns_server.operating_state == ServiceOperatingState.STOPPED