Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion conf/system.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
"device_intf": "enx123456789123",
"internet_intf": "enx123456789124"
},
"log_level": "INFO"
"log_level": "INFO",
"startup_timeout": 60,
"monitor_period": 300,
"runtime": 1200
}
8 changes: 4 additions & 4 deletions framework/device.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""Track device object information."""
from dataclasses import dataclass
from network_device import NetworkDevice


@dataclass
class Device:
class Device(NetworkDevice):
"""Represents a physical device and it's configuration."""

make: str
model: str
mac_addr: str
make: str = None
model: str = None
test_modules: str = None
22 changes: 16 additions & 6 deletions framework/testrun.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import signal
import time
import logger
from device import Device

# Locate parent directory
current_dir = os.path.dirname(os.path.realpath(__file__))
Expand All @@ -30,6 +29,8 @@
import test_orchestrator as test_orc # pylint: disable=wrong-import-position,import-outside-toplevel
import network_orchestrator as net_orc # pylint: disable=wrong-import-position,import-outside-toplevel

from device import Device # pylint: disable=wrong-import-position,import-outside-toplevel

LOGGER = logger.get_logger('test_run')
CONFIG_FILE = 'conf/system.json'
EXAMPLE_CONFIG_FILE = 'conf/system.json.example'
Expand Down Expand Up @@ -80,9 +81,11 @@ def start(self):
else:
self._start_network()
self._test_orc.start()

self._net_orc.listener.register_callback(
self._device_discovered,
[NetworkEvent.DEVICE_DISCOVERED])
self._device_stable,
[NetworkEvent.DEVICE_STABLE]
)

LOGGER.info("Waiting for devices on the network...")

Expand Down Expand Up @@ -117,6 +120,10 @@ def _get_config_abs(self, config_file=None):
return os.path.abspath(config_file)

def _start_network(self):
# Load in local device configs to the network orchestrator
self._net_orc._devices = self._devices

# Start the network orchestrator
self._net_orc.start()

def _run_tests(self, device):
Expand Down Expand Up @@ -169,9 +176,12 @@ def _device_discovered(self, mac_addr):
LOGGER.info(
f'Discovered {device.make} {device.model} on the network')
else:
device = Device(make=None, model=None, mac_addr=mac_addr)
device = Device(mac_addr=mac_addr)
self._devices.append(device)
LOGGER.info(
f'A new device has been discovered with mac address {mac_addr}')

# TODO: Pass device information to test orchestrator/runner
self._run_tests(device)
def _device_stable(self, mac_addr):
device = self.get_device(mac_addr)
LOGGER.info(f'Device with mac address {mac_addr} is ready for testing.')
self._test_orc.run_test_modules(device)
31 changes: 17 additions & 14 deletions net_orc/python/src/listener.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Intercepts network traffic between network services and the device
under test."""
import threading
from scapy.all import AsyncSniffer, DHCP, get_if_hwaddr
import logger
from network_event import NetworkEvent
Expand All @@ -12,7 +13,6 @@
DHCP_ACK = 5
CONTAINER_MAC_PREFIX = '9a:02:57:1e:8f'


class Listener:
"""Methods to start and stop the network listener."""

Expand Down Expand Up @@ -47,22 +47,25 @@ def register_callback(self, callback, events=[]): # pylint: disable=dangerous-d
}
)

def call_callback(self, net_event, *args):
for callback in self._callbacks:
if net_event in callback['events']:
callback_thread = threading.Thread(target=callback['callback'], name="Callback thread", args=args)
callback_thread.start()

def _packet_callback(self, packet):

# Ignore packets originating from our containers
if packet.src.startswith(CONTAINER_MAC_PREFIX) or packet.src == self._device_intf_mac:
return
# DHCP ACK callback
if DHCP in packet and self._get_dhcp_type(packet) == DHCP_ACK:
self.call_callback(NetworkEvent.DHCP_LEASE_ACK, packet)

# New device discovered callback
if not packet.src is None and packet.src not in self._discovered_devices:
self._device_discovered(packet.src)
# Ignore packets originating from our containers
if packet.src.startswith(CONTAINER_MAC_PREFIX) or packet.src == self._device_intf_mac:
return
self._discovered_devices.append(packet.src)
self.call_callback(NetworkEvent.DEVICE_DISCOVERED, packet.src)

def _get_dhcp_type(self, packet):
return packet[DHCP].options[0][1]

def _device_discovered(self, mac_addr):
LOGGER.debug(f'Discovered device with address {mac_addr}')
self._discovered_devices.append(mac_addr)

for callback in self._callbacks:
if NetworkEvent.DEVICE_DISCOVERED in callback['events']:
callback['callback'](mac_addr)
return packet[DHCP].options[0][1]
9 changes: 9 additions & 0 deletions net_orc/python/src/network_device.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Track device object information."""
from dataclasses import dataclass

@dataclass
class NetworkDevice:
"""Represents a physical device and it's configuration."""

mac_addr: str
ip_addr: str = None
6 changes: 2 additions & 4 deletions net_orc/python/src/network_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

class NetworkEvent(Enum):
"""All possible network events."""

ALL = 0
DEVICE_DISCOVERED = 1
DHCP_LEASE_NEW = 2
DHCP_LEASE_RENEWED = 3
DEVICE_STABLE = 2
DHCP_LEASE_ACK = 3
Loading