diff --git a/src/primaite/simulator/network/hardware/base.py b/src/primaite/simulator/network/hardware/base.py index 1858345b..945eb345 100644 --- a/src/primaite/simulator/network/hardware/base.py +++ b/src/primaite/simulator/network/hardware/base.py @@ -926,6 +926,9 @@ class Node(SimComponent): shut_down_countdown: int = 0 "Time steps needed until node is shut down." + is_resetting: bool = False + "If true, the node will try turning itself off then back on again." + def __init__(self, **kwargs): """ Initialize the Node with various components and managers. @@ -982,7 +985,7 @@ class Node(SimComponent): rm.add_request("shutdown", RequestType(func=lambda request, context: self.power_off())) rm.add_request("startup", RequestType(func=lambda request, context: self.power_on())) - rm.add_request("reset", RequestType(func=lambda request, context: ...)) # TODO implement node reset + rm.add_request("reset", RequestType(func=lambda request, context: self.reset())) # TODO implement node reset rm.add_request("logon", RequestType(func=lambda request, context: ...)) # TODO implement logon request rm.add_request("logoff", RequestType(func=lambda request, context: ...)) # TODO implement logoff request @@ -1090,6 +1093,11 @@ class Node(SimComponent): self.operating_state = NodeOperatingState.OFF self.sys_log.info("Turned off") + # if resetting turn back on + if self.is_resetting: + self.is_resetting = False + self.power_on() + # apply time step to node components if self.operating_state == NodeOperatingState.ON: for process_id in self.processes: @@ -1184,6 +1192,20 @@ class Node(SimComponent): self.operating_state = NodeOperatingState.OFF self.sys_log.info("Turned off") + def reset(self): + """ + Resets the node. + + Powers off the node and sets is_resetting to True. + Applying more timesteps will eventually turn the node back on. + """ + if not self.operating_state.ON: + self.sys_log.error(f"Cannot reset {self.hostname} - node is not turned on.") + else: + self.is_resetting = True + self.sys_log.info(f"Resetting {self.hostname}...") + self.power_off() + def connect_nic(self, nic: NIC): """ Connect a NIC (Network Interface Card) to the node. diff --git a/tests/unit_tests/_primaite/_simulator/_network/_hardware/test_node_actions.py b/tests/unit_tests/_primaite/_simulator/_network/_hardware/test_node_actions.py index f886b8fe..6161bbf6 100644 --- a/tests/unit_tests/_primaite/_simulator/_network/_hardware/test_node_actions.py +++ b/tests/unit_tests/_primaite/_simulator/_network/_hardware/test_node_actions.py @@ -123,3 +123,28 @@ def test_node_red_scan(node, service, application): assert application.revealed_to_red is True assert folder.revealed_to_red is True assert file.revealed_to_red is True + + +def test_reset_node(node): + """Test that a node can be reset.""" + node.operating_state = NodeOperatingState.ON + + node.apply_request(["reset"]) + assert node.operating_state == NodeOperatingState.SHUTTING_DOWN + + """ + 3 steps to shut down + 2 steps to set up the turning of it back on + 3 steps to turn back on + + 3 + 2 + 3 = 8 + kwik mafs + """ + + for i in range(8): + node.apply_timestep(timestep=i) + + if i == 3: + assert node.operating_state == NodeOperatingState.BOOTING + + assert node.operating_state == NodeOperatingState.ON