#1706 - Got the core Node class build and working with ARP and the ability to ping another node. Added some basic tests in. Next job is to create the Node subclasses. Then move ARP and ICMP into a service that is used by all nodes.

This commit is contained in:
Chris McCarthy
2023-08-02 21:54:21 +01:00
parent 3660e27c15
commit 897dbdf10c
23 changed files with 879 additions and 309 deletions

View File

@@ -0,0 +1,25 @@
from primaite.simulator.network.hardware.base import Link, NIC, Node
def test_node_to_node_ping():
node_a = Node(hostname="node_a")
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0", gateway="192.168.0.1")
node_a.connect_nic(nic_a)
node_a.turn_on()
node_b = Node(hostname="node_b")
nic_b = NIC(ip_address="192.168.0.11", subnet_mask="255.255.255.0", gateway="192.168.0.1")
node_b.connect_nic(nic_b)
node_b.turn_on()
Link(endpoint_a=nic_a, endpoint_b=nic_b)
assert node_a.ping("192.168.0.11")
node_a.turn_off()
assert not node_a.ping("192.168.0.11")
node_a.turn_on()
assert node_a.ping("192.168.0.11")

View File

@@ -0,0 +1,21 @@
from primaite.simulator.network.hardware.base import Link, NIC, Node
def test_link_up():
"""Tests Nodes, NICs, and Links can all be connected and be in an enabled/up state."""
node_a = Node(hostname="node_a")
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0", gateway="192.168.0.1")
node_a.connect_nic(nic_a)
node_a.turn_on()
assert nic_a.enabled
node_b = Node(hostname="node_b")
nic_b = NIC(ip_address="192.168.0.11", subnet_mask="255.255.255.0", gateway="192.168.0.1")
node_b.connect_nic(nic_b)
node_b.turn_on()
assert nic_b.enabled
link = Link(endpoint_a=nic_a, endpoint_b=nic_b)
assert link.up

View File

@@ -1,6 +1,6 @@
import pytest
from primaite.simulator.network.transmission.physical_layer import Link, NIC
from primaite.simulator.network.hardware.base import Link, NIC
def test_link_fails_with_same_nic():

View File

@@ -3,7 +3,7 @@ from ipaddress import IPv4Address
import pytest
from primaite.simulator.network.transmission.physical_layer import generate_mac_address, NIC
from primaite.simulator.network.hardware.base import generate_mac_address, NIC
def test_mac_address_generation():

View File

@@ -0,0 +1,10 @@
import re
from ipaddress import IPv4Address
import pytest
from primaite.simulator.network.hardware.base import Node
def test_node_creation():
node = Node(hostname="host_1")

View File

@@ -1,7 +1,7 @@
import pytest
from primaite.simulator.network.transmission.data_link_layer import EthernetHeader, Frame
from primaite.simulator.network.transmission.network_layer import ICMPHeader, IPPacket, IPProtocol, Precedence
from primaite.simulator.network.transmission.network_layer import ICMPPacket, IPPacket, IPProtocol, Precedence
from primaite.simulator.network.transmission.primaite_layer import AgentSource, DataStatus
from primaite.simulator.network.transmission.transport_layer import Port, TCPFlags, TCPHeader, UDPHeader
@@ -76,7 +76,7 @@ def test_icmp_frame_creation():
frame = Frame(
ethernet=EthernetHeader(src_mac_addr="aa:bb:cc:dd:ee:ff", dst_mac_addr="11:22:33:44:55:66"),
ip=IPPacket(src_ip="192.168.0.10", dst_ip="192.168.0.20", protocol=IPProtocol.ICMP),
icmp=ICMPHeader(),
icmp=ICMPPacket(),
)
assert frame

View File

@@ -1,24 +1,24 @@
import pytest
from primaite.simulator.network.transmission.network_layer import ICMPHeader, ICMPType
from primaite.simulator.network.transmission.network_layer import ICMPPacket, ICMPType
def test_icmp_minimal_header_creation():
"""Checks the minimal ICMPHeader (ping 1 request) creation using default values."""
ping = ICMPHeader()
"""Checks the minimal ICMPPacket (ping 1 request) creation using default values."""
ping = ICMPPacket()
assert ping.icmp_type == ICMPType.ECHO_REQUEST
assert ping.icmp_code == 0
assert ping.identifier
assert ping.sequence == 1
assert ping.sequence == 0
def test_valid_icmp_type_code_pairing():
"""Tests ICMPHeader creation with valid type and code pairing."""
assert ICMPHeader(icmp_type=ICMPType.DESTINATION_UNREACHABLE, icmp_code=6)
"""Tests ICMPPacket creation with valid type and code pairing."""
assert ICMPPacket(icmp_type=ICMPType.DESTINATION_UNREACHABLE, icmp_code=6)
def test_invalid_icmp_type_code_pairing():
"""Tests ICMPHeader creation fails with invalid type and code pairing."""
"""Tests ICMPPacket creation fails with invalid type and code pairing."""
with pytest.raises(ValueError):
assert ICMPHeader(icmp_type=ICMPType.DESTINATION_UNREACHABLE, icmp_code=16)
assert ICMPPacket(icmp_type=ICMPType.DESTINATION_UNREACHABLE, icmp_code=16)

View File

@@ -1,4 +1,5 @@
from typing import Callable, Dict, List, Literal, Tuple
from uuid import uuid4
import pytest
from pydantic import ValidationError
@@ -35,15 +36,17 @@ class TestIsolatedSimComponent:
"""Validate that our added functionality does not interfere with pydantic."""
class TestComponent(SimComponent):
uuid: str
name: str
size: Tuple[float, float]
def describe_state(self) -> Dict:
return {}
comp = TestComponent(name="computer", size=(5, 10))
uuid = str(uuid4())
comp = TestComponent(uuid=uuid, name="computer", size=(5, 10))
dump = comp.model_dump()
assert dump == {"name": "computer", "size": (5, 10)}
assert dump == {"uuid": uuid, "name": "computer", "size": (5, 10)}
def test_apply_action(self):
"""Validate that we can override apply_action behaviour and it updates the state of the component."""