Skip to content

Commit 8df4783

Browse files
sofyakurilovaOlgaMardvilkojboddeyjhughesoti
authored
V1.3 (#393)
* Adds version analytics event (#306) * Techdebt: adds state for testrun page (#392) * Fix tests (#397) * Fix tests * Update node version * 331379891: (feat) disable connection settings when testrun is in progress (#371) * 331379891: (feat) disable connection settings when testrun is in progress * 331379891: (fix) include more testrun results as progress * 331379891: (fix) fix spelling * 333349715: (fix) GAR 1.3 The disabled system settings panel contains a focusable element (#388) Co-authored-by: Volha Mardvilka <[email protected]> --------- Co-authored-by: Volha Mardvilka <[email protected]> * Disable device item if device in progress (#370) * Adds ga to track testrun initiation (#415) Adds ga ti track testrun initiation * Fix function return value (#421) * Fix redirect + adds google analytics (#420) * Adds certificates drawer component with list of certificates (#414) Adds certificates drawer component with list of certificates. Upload and delete is out of scope * List modules (#425) * Adds delete certificate (#424) Adds delete certificate * Adds class for links to track report type on download; adds event when download report is clicked on progress page (#434) * Adds upload certificate (#431) * Adds upload certificate * move delete functionality to certificates store * Catch error on report/certificate deletion (#438) * Fix button size; fix text-overflow (#440) * Adds focus on next or close button when certificate is deleted (#439) * Adds focus on next or close button when certificate is deleted * Enable test modules for initiate test run dialog (#400) Enable test modules for initiate test run dialog * Add steps to resolve to PDF report (#411) * Add progress for steps to resolve * Formatting * Remove print statements * Allow for no steps to resolve * Add multipage * Fix multipage * Fix config * update report unit tests --------- Signed-off-by: J Boddey <[email protected]> Co-authored-by: jhughesbiot <[email protected]> * Add new mac addr field for report deleting (#432) * Bump version to v1.2.2 (#433) * 337012359: (feat) add snackBar with wait or stop testrun (#444) * 337012359: (feat) add snackBar with wait or stop testrun * 337012359: (fix) update to fix failed tests * 337012359: (fix) add fix for deletCertificate test --------- Co-authored-by: Volha Mardvilka <[email protected]> * Feature/port stats (#430) * Add port speed and duplex tests Add unit tests for port stats testing Add place holder for ip port link test * Add ethtool to system dependencies Restructure conn stats methods and tests Resolve port stat information for link test * Fix runtime issue * Implement link test Fix unit tests Misc port stats updates * fix pylint issues * update readme * pylint fixes --------- Signed-off-by: J Boddey <[email protected]> Co-authored-by: J Boddey <[email protected]> * 339315842: (feat) add risk assessment tab (#450) * 339315842: (feat) add risk assessment tab * 339315842: (feat) add risk assessment tab --------- Co-authored-by: Volha Mardvilka <[email protected]> * Add steps to resolve to PDF report (#411) * Add progress for steps to resolve * Formatting * Remove print statements * Allow for no steps to resolve * Add multipage * Fix multipage * Fix config * update report unit tests --------- Signed-off-by: J Boddey <[email protected]> Co-authored-by: jhughesbiot <[email protected]> * Add new mac addr field for report deleting (#432) * Remove rebase error --------- Signed-off-by: J Boddey <[email protected]> Co-authored-by: Olga Mardvilko <[email protected]> Co-authored-by: Volha Mardvilka <[email protected]> Co-authored-by: J Boddey <[email protected]> Co-authored-by: jhughesbiot <[email protected]> Co-authored-by: jhughesbiot <[email protected]>
1 parent e8fd570 commit 8df4783

File tree

110 files changed

+4363
-784
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+4363
-784
lines changed

.github/workflows/testing.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ jobs:
7676
- name: Install Node
7777
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
7878
with:
79-
node-version: 18.13.0
79+
node-version: 18.18.0
8080
- name: Install Chromium Browser
8181
run: sudo apt install chromium-browser
8282
- name: Install dependencies
@@ -99,7 +99,7 @@ jobs:
9999
- name: Install Node
100100
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
101101
with:
102-
node-version: 18.13.0
102+
node-version: 18.18.0
103103
- name: Install dependencies
104104
run: npm install && npm ci
105105
working-directory: ./modules/ui

cmd/prepare

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@
2020
echo Installing system dependencies
2121

2222
# Install system dependencies
23-
sudo apt-get update && sudo apt-get install openvswitch-common openvswitch-switch python3 libpangocairo-1.0-0
23+
sudo apt-get update && sudo apt-get install openvswitch-common openvswitch-switch python3 libpangocairo-1.0-0 ethtool
2424

2525
echo Finished installing system dependencies

framework/python/src/api/api.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ def __init__(self, test_run):
9595
self._router.add_api_route("/device/edit",
9696
self.edit_device,
9797
methods=["POST"])
98+
99+
self._router.add_api_route("/system/modules",
100+
self.get_test_modules)
98101

99102
# Allow all origins to access the API
100103
origins = ["*"]
@@ -551,6 +554,20 @@ async def get_results(self, response: Response,
551554
response.status_code = 404
552555
return self._generate_msg(False, "Test results could not be found")
553556

557+
async def get_test_modules(self):
558+
559+
LOGGER.debug("Received request to list test modules")
560+
561+
test_modules = []
562+
563+
for test_module in self._get_test_run().get_test_orc().get_test_modules():
564+
565+
# Only add module if it is an actual, enabled test module
566+
if (test_module.enabled and test_module.enable_container):
567+
test_modules.append(test_module.display_name)
568+
569+
return test_modules
570+
554571
def _validate_device_json(self, json_obj):
555572

556573
# Check all required properties are present
@@ -575,3 +592,6 @@ def _validate_device_json(self, json_obj):
575592
return False
576593

577594
return True
595+
596+
def _get_test_run(self):
597+
return self._test_run

framework/python/src/common/testreport.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ def __init__(self,
5858
self._report_url = ''
5959
self._cur_page = 0
6060
# Placeholder until available in json report
61-
self._version = 'v1.2.2'
61+
self._version = 'v1.3-alpha'
62+
63+
def get_mac_addr(self):
64+
return self._mac_addr
6265

6366
def get_mac_addr(self):
6467
return self._mac_addr
@@ -94,6 +97,12 @@ def get_report_url(self):
9497
def set_mac_addr(self, mac_addr):
9598
self._mac_addr = mac_addr
9699

100+
def set_mac_addr(self, mac_addr):
101+
self._mac_addr = mac_addr
102+
103+
def set_mac_addr(self, mac_addr):
104+
self._mac_addr = mac_addr
105+
97106
def to_json(self):
98107
report_json = {}
99108

framework/python/src/core/testrun.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,18 @@ def __init__(self,
100100
if validate:
101101
self._session.add_runtime_param('validate')
102102

103-
self.load_all_devices()
104-
105103
self._net_orc = net_orc.NetworkOrchestrator(
106104
session=self._session)
107105
self._test_orc = test_orc.TestOrchestrator(
108106
self._session,
109107
self._net_orc)
110108

109+
# Load device repository
110+
self.load_all_devices()
111+
112+
# Load test modules
113+
self._test_orc.start()
114+
111115
if self._no_ui:
112116

113117
# Check Testrun is able to start
@@ -324,8 +328,6 @@ def start(self):
324328
if self._net_only:
325329
LOGGER.info('Network only option configured, no tests will be run')
326330
else:
327-
self._test_orc.start()
328-
329331
self.get_net_orc().get_listener().register_callback(
330332
self._device_stable,
331333
[NetworkEvent.DEVICE_STABLE]
@@ -382,6 +384,9 @@ def get_config_file(self):
382384
def get_net_orc(self):
383385
return self._net_orc
384386

387+
def get_test_orc(self):
388+
return self._test_orc
389+
385390
def _start_network(self):
386391
# Start the network orchestrator
387392
if not self.get_net_orc().start():

framework/python/src/net_orc/ip_control.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def add_namespace(self, namespace):
4242
return success
4343

4444
def check_interface_status(self, interface_name):
45-
output = util.run_command(cmd=f'ip link show {interface_name}',output=True)
45+
output = util.run_command(cmd=f'ip link show {interface_name}', output=True)
4646
if 'state DOWN ' in output[0]:
4747
return False
4848
else:
@@ -81,6 +81,22 @@ def get_links(self):
8181
netns_links.append(interface_name.strip())
8282
return netns_links
8383

84+
def get_iface_connection_stats(self, iface):
85+
"""Extract information about the physical connection"""
86+
response = util.run_command(f'ethtool {iface}')
87+
if len(response[1]) == 0:
88+
return response[0]
89+
else:
90+
return None
91+
92+
def get_iface_port_stats(self, iface):
93+
"""Extract information about packets connection"""
94+
response = util.run_command(f'ethtool -S {iface}')
95+
if len(response[1]) == 0:
96+
return response[0]
97+
else:
98+
return None
99+
84100
def get_namespaces(self):
85101
result = util.run_command('ip netns list')
86102
#Strip ID's from the namespace results

framework/python/src/net_orc/network_orchestrator.py

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ def _device_discovered(self, mac_addr):
173173
# Ignore discovered device
174174
return
175175

176+
self._get_port_stats(pre_monitor=True)
176177
self._monitor_in_progress = True
177178

178179
LOGGER.debug(
@@ -203,6 +204,8 @@ def _device_discovered(self, mac_addr):
203204
with open(runtime_device_conf, 'w', encoding='utf-8') as f:
204205
json.dump(self._session.get_target_device().to_config_json(), f, indent=2)
205206

207+
self._get_conn_stats()
208+
206209
if device.ip_addr is None:
207210
LOGGER.info(
208211
f'Timed out whilst waiting for {mac_addr} to obtain an IP address')
@@ -216,6 +219,31 @@ def _device_discovered(self, mac_addr):
216219

217220
self._start_device_monitor(device)
218221

222+
def _get_conn_stats(self):
223+
""" Extract information about the physical connection
224+
and store it to a file for the conn test module to access"""
225+
dev_int = self._session.get_device_interface()
226+
conn_stats = self._ip_ctrl.get_iface_connection_stats(dev_int)
227+
if conn_stats is not None:
228+
eth_out_file = os.path.join(NET_DIR, 'ethtool_conn_stats.txt')
229+
with open(eth_out_file, 'w', encoding='utf-8') as f:
230+
f.write(conn_stats)
231+
else:
232+
LOGGER.error('Failed to generate connection stats')
233+
234+
def _get_port_stats(self, pre_monitor=True):
235+
""" Extract information about the port statistics
236+
and store it to a file for the conn test module to access"""
237+
dev_int = self._session.get_device_interface()
238+
port_stats = self._ip_ctrl.get_iface_port_stats(dev_int)
239+
if port_stats is not None:
240+
suffix = 'pre_monitor' if pre_monitor else 'post_monitor'
241+
eth_out_file = os.path.join(NET_DIR, f'ethtool_port_stats_{suffix}.txt')
242+
with open(eth_out_file, 'w', encoding='utf-8') as f:
243+
f.write(port_stats)
244+
else:
245+
LOGGER.error('Failed to generate port stats')
246+
219247
def monitor_in_progress(self):
220248
return self._monitor_in_progress
221249

@@ -261,6 +289,7 @@ def _start_device_monitor(self, device):
261289
wrpcap(os.path.join(device_runtime_dir, 'monitor.pcap'),
262290
self._monitor_packets)
263291
self._monitor_in_progress = False
292+
self._get_port_stats(pre_monitor=False)
264293
self.get_listener().call_callback(NetworkEvent.DEVICE_STABLE,
265294
device.mac_addr)
266295

@@ -498,23 +527,22 @@ def _start_network_service(self, net_module):
498527
try:
499528
client = docker.from_env()
500529
net_module.container = client.containers.run(
501-
net_module.image_name,
502-
auto_remove=True,
503-
cap_add=['NET_ADMIN'],
504-
name=net_module.container_name,
505-
hostname=net_module.container_name,
506-
# Undetermined version of docker seems to have broken
507-
# DNS configuration (/etc/resolv.conf) Re-add when/if
508-
# this network is utilized and DNS issue is resolved
509-
#network=PRIVATE_DOCKER_NET,
510-
privileged=True,
511-
detach=True,
512-
mounts=net_module.mounts,
513-
environment={
514-
'TZ': self.get_session().get_timezone(),
515-
'HOST_USER': util.get_host_user()
516-
}
517-
)
530+
net_module.image_name,
531+
auto_remove=True,
532+
cap_add=['NET_ADMIN'],
533+
name=net_module.container_name,
534+
hostname=net_module.container_name,
535+
# Undetermined version of docker seems to have broken
536+
# DNS configuration (/etc/resolv.conf) Re-add when/if
537+
# this network is utilized and DNS issue is resolved
538+
#network=PRIVATE_DOCKER_NET,
539+
privileged=True,
540+
detach=True,
541+
mounts=net_module.mounts,
542+
environment={
543+
'TZ': self.get_session().get_timezone(),
544+
'HOST_USER': util.get_host_user()
545+
})
518546
except docker.errors.ContainerError as error:
519547
LOGGER.error('Container run error')
520548
LOGGER.error(error)

modules/test/conn/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ Within the ```python/src``` directory, the below tests are executed. A few dhcp
1414

1515
| ID | Description | Expected Behavior | Required Result |
1616
|------------------------------|----------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------|
17+
| connection.port_link | The network switch port connected to the device has an active link without errors | When the etherent cable is connected to the port, the device triggers the port to its enabled \"Link UP\" (LEDs illuminate on device and switch ports if present) state, and the switch shows no errors with the LEDs and when interrogated with a \"show interface\" command on most network switches. | Required |
18+
| connection.port_speed | The network switch port connected to the device has auto-negotiated a speed that is 10 Mbps or higher | When the ethernet cable is connected to the port, the device autonegotiates a speed that can be checked with the \"show interface\" command on most network switches. The output of this command must also show that the \"configured speed\" is set to \"auto\". | Required |
19+
| connection.port_duplex | The network switch port connected to the device has auto-negotiated full-duplex. | When the ethernet cable is connected to the port, the device autonegotiates a full-duplex connection. | Required |
1720
| connection.dhcp_address | The device under test has received an IP address from the DHCP server and responds to an ICMP echo (ping) request | The device is not set up with a static IP address. The device accepts an IP address from a DHCP server (RFC 2131) and responds successfully to an ICMP echo (ping) request. | Required |
1821
| connection.mac_address | Check and note device physical address. | N/A | Required |
1922
| connection.mac_oui | The device under test has a MAC address prefix that is registered against a known manufacturer. | The MAC address prefix is registered in the IEEE Organizationally Unique Identifier database. | Required |

modules/test/conn/conf/module_config.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@
1313
"timeout": 1800
1414
},
1515
"tests": [
16+
{
17+
"name": "connection.port_link",
18+
"test_description": "The network switch port connected to the device has an active link without errors",
19+
"expected_behavior": "When the etherent cable is connected to the port, the device triggers the port to its enabled \"Link UP\" (LEDs illuminate on device and switch ports if present) state, and the switch shows no errors with the LEDs and when interrogated with a \"show interface\" command on most network switches.",
20+
"required_result": "Required"
21+
},
22+
{
23+
"name": "connection.port_speed",
24+
"test_description": "The network switch port connected to the device has auto-negotiated a speed that is 10 Mbps or higher",
25+
"expected_behavior": "When the ethernet cable is connected to the port, the device autonegotiates a speed that can be checked with the \"show interface\" command on most network switches. The output of this command must also show that the \"configured speed\" is set to \"auto\".",
26+
"required_result": "Required"
27+
},
28+
{
29+
"name": "connection.port_duplex",
30+
"test_description": "The network switch port connected to the device has auto-negotiated full-duplex",
31+
"expected_behavior": "When the ethernet cable is connected to the port, the device autonegotiates a full-duplex connection.",
32+
"required_result": "Required"
33+
},
1634
{
1735
"name": "connection.switch.arp_inspection",
1836
"test_description": "The device implements ARP correctly as per RFC826",

modules/test/conn/python/src/connection_module.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@
2020
from dhcp1.client import Client as DHCPClient1
2121
from dhcp2.client import Client as DHCPClient2
2222
from dhcp_util import DHCPUtil
23+
from port_stats_util import PortStatsUtil
2324

2425
LOG_NAME = 'test_connection'
25-
LOGGER = None
2626
OUI_FILE = '/usr/local/etc/oui.txt'
2727
STARTUP_CAPTURE_FILE = '/runtime/device/startup.pcap'
2828
MONITOR_CAPTURE_FILE = '/runtime/device/monitor.pcap'
2929
DHCP_CAPTURE_FILE = '/runtime/network/dhcp-1.pcap'
3030
SLAAC_PREFIX = 'fd10:77be:4186'
3131
TR_CONTAINER_MAC_PREFIX = '9a:02:57:1e:8f:'
32+
LOGGER = None
3233

3334
# Should be at least twice as much as the max lease time
3435
# set in the DHCP server
@@ -38,10 +39,15 @@
3839
class ConnectionModule(TestModule):
3940
"""Connection Test module"""
4041

41-
def __init__(self, module):
42-
super().__init__(module_name=module, log_name=LOG_NAME)
42+
def __init__(self, module, log_dir=None, conf_file=None, results_dir=None):
43+
super().__init__(module_name=module,
44+
log_name=LOG_NAME,
45+
log_dir=log_dir,
46+
conf_file=conf_file,
47+
results_dir=results_dir)
4348
global LOGGER
4449
LOGGER = self._get_logger()
50+
self._port_stats = PortStatsUtil(logger=LOGGER)
4551
self.dhcp1_client = DHCPClient1()
4652
self.dhcp2_client = DHCPClient2()
4753
self._dhcp_util = DHCPUtil(self.dhcp1_client, self.dhcp2_client, LOGGER)
@@ -74,6 +80,18 @@ def __init__(self, module):
7480
# response = self.dhcp1_client.set_dhcp_range('10.10.10.20','10.10.10.30')
7581
# print("Set Range: " + str(response))
7682

83+
def _connection_port_link(self):
84+
LOGGER.info('Running connection.port_link')
85+
return self._port_stats.connection_port_link_test()
86+
87+
def _connection_port_speed(self):
88+
LOGGER.info('Running connection.port_speed')
89+
return self._port_stats.connection_port_speed_test()
90+
91+
def _connection_port_duplex(self):
92+
LOGGER.info('Running connection.port_duplex')
93+
return self._port_stats.connection_port_duplex_test()
94+
7795
def _connection_switch_arp_inspection(self):
7896
LOGGER.info('Running connection.switch.arp_inspection')
7997

0 commit comments

Comments
 (0)