From 5d0ae313ef9e06554ce5d2926a847eb209f83ea9 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Fri, 7 Jun 2024 12:32:53 -0600 Subject: [PATCH 1/8] Fix validator Misc logging cleanup --- framework/python/src/common/util.py | 2 -- framework/python/src/net_orc/network_orchestrator.py | 1 + framework/python/src/net_orc/network_validator.py | 9 ++++++++- framework/python/src/net_orc/ovs_control.py | 8 ++++++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/framework/python/src/common/util.py b/framework/python/src/common/util.py index 94866cee6..096aaf4df 100644 --- a/framework/python/src/common/util.py +++ b/framework/python/src/common/util.py @@ -45,8 +45,6 @@ def run_command(cmd, output=True): success = True if output: out = stdout.strip().decode('utf-8') - if out is not None and len(out) != 0: - LOGGER.debug('Command output: ' + out) return out, stderr else: return success diff --git a/framework/python/src/net_orc/network_orchestrator.py b/framework/python/src/net_orc/network_orchestrator.py index b716f2ab4..35357119c 100644 --- a/framework/python/src/net_orc/network_orchestrator.py +++ b/framework/python/src/net_orc/network_orchestrator.py @@ -132,6 +132,7 @@ def start_network(self): if 'validate' in self._session.get_runtime_params(): # Start the validator after network is ready self.validator.start() + self.validator.stop() # Get network ready (via Network orchestrator) LOGGER.debug('Network is ready') diff --git a/framework/python/src/net_orc/network_validator.py b/framework/python/src/net_orc/network_validator.py index df9b96b1d..b8db6075e 100644 --- a/framework/python/src/net_orc/network_validator.py +++ b/framework/python/src/net_orc/network_validator.py @@ -22,6 +22,7 @@ import getpass from common import logger from common import util +from net_orc.ovs_control import OVSControl LOGGER = logger.get_logger('validator') OUTPUT_DIR = 'runtime/validation' @@ -46,6 +47,8 @@ def __init__(self): shutil.rmtree(os.path.join(self._path, OUTPUT_DIR), ignore_errors=True) + self._ovs = OVSControl(session=None) + def start(self): """Start the network validator.""" LOGGER.debug('Starting validator') @@ -87,6 +90,8 @@ def _build_device(self, net_device): def _load_devices(self): LOGGER.info(f'Loading validators from {self._device_dir}') + # Reset device list before loading + self._net_devices = [] loaded_devices = 'Loaded the following validators: ' @@ -286,7 +291,6 @@ def _stop_network_device(self, net_device, kill=False): LOGGER.error(e) def _get_device_container(self, net_device): - LOGGER.debug('Resolving device container: ' + net_device.container_name) container = None try: client = docker.from_env() @@ -305,6 +309,9 @@ def _stop_network_devices(self, kill=False): if not net_device.enable_container: continue self._stop_network_device(net_device, kill) + # Remove the device port form the ovs bridge once validation is done + bridge_intf = DEVICE_BRIDGE + 'i-' + net_device.dir_name + self._ovs.delete_port(DEVICE_BRIDGE,bridge_intf) class FauxDevice: # pylint: disable=too-few-public-methods,too-many-instance-attributes diff --git a/framework/python/src/net_orc/ovs_control.py b/framework/python/src/net_orc/ovs_control.py index 08faa52c1..2c1e17776 100644 --- a/framework/python/src/net_orc/ovs_control.py +++ b/framework/python/src/net_orc/ovs_control.py @@ -59,6 +59,14 @@ def delete_flow(self, bridge_name, flow): success = util.run_command(f'ovs-ofctl del-flows {bridge_name} \'{flow}\'') return success + def delete_port(self, bridge_name, port): + # Delete a port from the bridge using ovs-ofctl commands + success=True + if self.port_exists(bridge_name, port): + LOGGER.debug(f'Deleting port {port} from bridge: {bridge_name}') + success = util.run_command(f'ovs-vsctl del-port {bridge_name} \'{port}\'') + return success + def get_bridge_ports(self, bridge_name): # Get a list of all the ports on a bridge response = util.run_command(f'ovs-vsctl list-ports {bridge_name}', From 7ccd28cc214b6c68c70f6775bc783d0e93ddef3e Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Fri, 7 Jun 2024 12:44:49 -0600 Subject: [PATCH 2/8] Enable validate by default Remove validate arg and replace with no-validate --- framework/python/src/core/test_runner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/python/src/core/test_runner.py b/framework/python/src/core/test_runner.py index 870e97752..749d72e0a 100644 --- a/framework/python/src/core/test_runner.py +++ b/framework/python/src/core/test_runner.py @@ -76,10 +76,10 @@ def parse_args(): help="Define the configuration file for Testrun and Network Orchestrator" ) parser.add_argument( - "--validate", + "--no-validate", default=False, action="store_true", - help="Turn on the validation of the network after network boot") + help="Turn off the validation of the network after network boot") parser.add_argument("-net", "--net-only", action="store_true", @@ -98,7 +98,7 @@ def parse_args(): if __name__ == "__main__": args = parse_args() runner = TestRunner(config_file=args.config_file, - validate=args.validate, + validate=not args.no_validate, net_only=args.net_only, single_intf=args.single_intf, no_ui=args.no_ui) From d4e801244608dcde92b4356961096ad3c95ad992 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Fri, 7 Jun 2024 14:47:18 -0600 Subject: [PATCH 3/8] Add error handling and validating status --- framework/python/src/api/api.py | 1 + .../python/src/net_orc/network_orchestrator.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/framework/python/src/api/api.py b/framework/python/src/api/api.py index 6b9e20d7a..dbb2a2334 100644 --- a/framework/python/src/api/api.py +++ b/framework/python/src/api/api.py @@ -211,6 +211,7 @@ async def start_test_run(self, request: Request, response: Response): # Check Testrun is not already running if self._test_run.get_session().get_status() in [ + "Validating Network", "In Progress", "Waiting for Device", "Monitoring" diff --git a/framework/python/src/net_orc/network_orchestrator.py b/framework/python/src/net_orc/network_orchestrator.py index 35357119c..96c110a7f 100644 --- a/framework/python/src/net_orc/network_orchestrator.py +++ b/framework/python/src/net_orc/network_orchestrator.py @@ -129,11 +129,16 @@ def start_network(self): self.create_net() self.start_network_services() - if 'validate' in self._session.get_runtime_params(): - # Start the validator after network is ready - self.validator.start() - self.validator.stop() - + try: + if 'validate' in self._session.get_runtime_params(): + # Start the validator after network is ready + self._session.set_status('Validating Network') + self.validator.start() + self.validator.stop() + except Exception as e: + LOGGER.error(f'Validation failed {e}') + + self._session.set_status('Waiting for Device') # Get network ready (via Network orchestrator) LOGGER.debug('Network is ready') From dee600868f4a4d24fda9a2a0a96c238a50ffc843 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Fri, 2 Aug 2024 13:41:13 -0600 Subject: [PATCH 4/8] Switch validator to be default off --- framework/python/src/core/test_runner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/python/src/core/test_runner.py b/framework/python/src/core/test_runner.py index 749d72e0a..fbf88d0c3 100644 --- a/framework/python/src/core/test_runner.py +++ b/framework/python/src/core/test_runner.py @@ -76,10 +76,10 @@ def parse_args(): help="Define the configuration file for Testrun and Network Orchestrator" ) parser.add_argument( - "--no-validate", + "--validate", default=False, action="store_true", - help="Turn off the validation of the network after network boot") + help="Turn on the validation of the network after network boot") parser.add_argument("-net", "--net-only", action="store_true", @@ -98,7 +98,7 @@ def parse_args(): if __name__ == "__main__": args = parse_args() runner = TestRunner(config_file=args.config_file, - validate=not args.no_validate, + validate=args. validate, net_only=args.net_only, single_intf=args.single_intf, no_ui=args.no_ui) From 7363baf066b9cebb004d232fa190a1b5a93cd1e9 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Tue, 22 Oct 2024 12:33:03 -0600 Subject: [PATCH 5/8] Fix validating status in UI --- framework/python/src/api/api.py | 7 +++++-- framework/python/src/common/statuses.py | 1 + framework/python/src/core/test_runner.py | 2 +- .../python/src/net_orc/network_orchestrator.py | 2 +- modules/ui/src/app/mocks/testrun.mock.ts | 6 ++++++ modules/ui/src/app/model/testrun-status.ts | 1 + .../testrun-status-card.component.html | 12 ++++++++++++ .../testrun-status-card.component.ts | 3 ++- .../src/app/pages/testrun/testrun.store.spec.ts | 16 ++++++++++++++++ .../ui/src/app/pages/testrun/testrun.store.ts | 5 ++++- .../ui/src/app/services/test-run.service.spec.ts | 1 + modules/ui/src/app/services/test-run.service.ts | 3 ++- 12 files changed, 52 insertions(+), 7 deletions(-) diff --git a/framework/python/src/api/api.py b/framework/python/src/api/api.py index 0d633987c..138dd818d 100644 --- a/framework/python/src/api/api.py +++ b/framework/python/src/api/api.py @@ -277,7 +277,9 @@ async def start_testrun(self, request: Request, response: Response): if self._testrun.get_session().get_status() in [ TestrunStatus.IN_PROGRESS, TestrunStatus.WAITING_FOR_DEVICE, - TestrunStatus.MONITORING + TestrunStatus.MONITORING, + TestrunStatus.VALIDATING + ]: LOGGER.debug("Testrun is already running. Cannot start another instance") response.status_code = status.HTTP_409_CONFLICT @@ -338,7 +340,8 @@ async def stop_testrun(self, response: Response): if (self._testrun.get_session().get_status() not in [TestrunStatus.IN_PROGRESS, TestrunStatus.WAITING_FOR_DEVICE, - TestrunStatus.MONITORING]): + TestrunStatus.MONITORING, + TestrunStatus.VALIDATING]): response.status_code = 404 return self._generate_msg(False, "Testrun is not currently running") diff --git a/framework/python/src/common/statuses.py b/framework/python/src/common/statuses.py index 4817d7cf8..c7487868a 100644 --- a/framework/python/src/common/statuses.py +++ b/framework/python/src/common/statuses.py @@ -23,6 +23,7 @@ class TestrunStatus: COMPLIANT = "Compliant" NON_COMPLIANT = "Non-Compliant" STOPPING = "Stopping" + VALIDATING = "Validating Network" class TestResult: diff --git a/framework/python/src/core/test_runner.py b/framework/python/src/core/test_runner.py index 3954f9dfa..a295f47e1 100644 --- a/framework/python/src/core/test_runner.py +++ b/framework/python/src/core/test_runner.py @@ -98,7 +98,7 @@ def parse_args(): if __name__ == "__main__": args = parse_args() runner = TestRunner(config_file=args.config_file, - validate=args. validate, + validate=args.validate, net_only=args.net_only, single_intf=args.single_intf, no_ui=args.no_ui) diff --git a/framework/python/src/net_orc/network_orchestrator.py b/framework/python/src/net_orc/network_orchestrator.py index dd15ce935..a11947c58 100644 --- a/framework/python/src/net_orc/network_orchestrator.py +++ b/framework/python/src/net_orc/network_orchestrator.py @@ -139,7 +139,7 @@ def start_network(self): try: if 'validate' in self._session.get_runtime_params(): # Start the validator after network is ready - self._session.set_status('Validating Network') + self._session.set_status(TestrunStatus.VALIDATING) self.validator.start() self.validator.stop() except Exception as e: diff --git a/modules/ui/src/app/mocks/testrun.mock.ts b/modules/ui/src/app/mocks/testrun.mock.ts index c90927cd3..3decf9973 100644 --- a/modules/ui/src/app/mocks/testrun.mock.ts +++ b/modules/ui/src/app/mocks/testrun.mock.ts @@ -159,6 +159,12 @@ export const MOCK_PROGRESS_DATA_WAITING_FOR_DEVICE: TestrunStatus = { started: null, }; +export const MOCK_PROGRESS_DATA_VALIDATING: TestrunStatus = { + ...MOCK_PROGRESS_DATA_IN_PROGRESS, + status: StatusOfTestrun.Validating, + started: null, +}; + export const MOCK_PROGRESS_DATA_WITH_ERROR: TestrunStatus = PROGRESS_DATA_RESPONSE(StatusOfTestrun.InProgress, null, { ...TEST_DATA, diff --git a/modules/ui/src/app/model/testrun-status.ts b/modules/ui/src/app/model/testrun-status.ts index faa707f92..a7626dee2 100644 --- a/modules/ui/src/app/model/testrun-status.ts +++ b/modules/ui/src/app/model/testrun-status.ts @@ -66,6 +66,7 @@ export enum StatusOfTestrun { Idle = 'Idle', Monitoring = 'Monitoring', Error = 'Error', + Validating = "Validating Network" } export enum StatusOfTestResult { diff --git a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html index be4d3b259..dac9d0d0a 100644 --- a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html +++ b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html @@ -27,6 +27,10 @@

+ + @@ -105,6 +109,14 @@
+ +
+

+ Validating virtual network +

+
+
+

diff --git a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.ts b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.ts index d84b692e1..101591c98 100644 --- a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.ts +++ b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.ts @@ -92,7 +92,8 @@ export class TestrunStatusCardComponent { return ( status === StatusOfTestrun.Monitoring || status === StatusOfTestrun.InProgress || - status === StatusOfTestrun.WaitingForDevice + status === StatusOfTestrun.WaitingForDevice || + status === StatusOfTestrun.Validating ); } diff --git a/modules/ui/src/app/pages/testrun/testrun.store.spec.ts b/modules/ui/src/app/pages/testrun/testrun.store.spec.ts index 449ffb408..24ffc6ba2 100644 --- a/modules/ui/src/app/pages/testrun/testrun.store.spec.ts +++ b/modules/ui/src/app/pages/testrun/testrun.store.spec.ts @@ -43,6 +43,7 @@ import { MOCK_PROGRESS_DATA_IN_PROGRESS_EMPTY, MOCK_PROGRESS_DATA_MONITORING, MOCK_PROGRESS_DATA_WAITING_FOR_DEVICE, + MOCK_PROGRESS_DATA_VALIDATING, TEST_DATA_RESULT_WITH_RECOMMENDATIONS, TEST_DATA_TABLE_RESULT, } from '../../mocks/testrun.mock'; @@ -171,6 +172,21 @@ describe('TestrunStore', () => { }); }); + it('should set value with empty values for status "Validating Network"', done => { + const expectedResult = EMPTY_RESULT; + + store.overrideSelector( + selectSystemStatus, + MOCK_PROGRESS_DATA_VALIDATING + ); + store.refreshState(); + + testrunStore.viewModel$.pipe(take(1)).subscribe(store => { + expect(store.dataSource).toEqual(expectedResult); + done(); + }); + }); + it('should set value with empty values for status "Cancelled" and empty result', done => { const expectedResult = EMPTY_RESULT; diff --git a/modules/ui/src/app/pages/testrun/testrun.store.ts b/modules/ui/src/app/pages/testrun/testrun.store.ts index 2dc0c19f1..351ec10d1 100644 --- a/modules/ui/src/app/pages/testrun/testrun.store.ts +++ b/modules/ui/src/app/pages/testrun/testrun.store.ts @@ -99,6 +99,7 @@ export class TestrunStore extends ComponentStore { // perform some additional actions tap(res => { if ( + res?.status === StatusOfTestrun.Validating || res?.status === StatusOfTestrun.WaitingForDevice || res?.status === StatusOfTestrun.Monitoring || (res?.status === StatusOfTestrun.InProgress && @@ -119,6 +120,7 @@ export class TestrunStore extends ComponentStore { tap(res => { const results = (res?.tests as TestsData)?.results || []; if ( + res?.status === StatusOfTestrun.Validating || res?.status === StatusOfTestrun.Monitoring || res?.status === StatusOfTestrun.WaitingForDevice || (res?.status === StatusOfTestrun.Cancelled && !results.length) @@ -208,7 +210,8 @@ export class TestrunStore extends ComponentStore { return ( status === StatusOfTestrun.InProgress || status === StatusOfTestrun.WaitingForDevice || - status === StatusOfTestrun.Monitoring + status === StatusOfTestrun.Monitoring || + status === StatusOfTestrun.Validating ); } diff --git a/modules/ui/src/app/services/test-run.service.spec.ts b/modules/ui/src/app/services/test-run.service.spec.ts index bcd3ec592..242155875 100644 --- a/modules/ui/src/app/services/test-run.service.spec.ts +++ b/modules/ui/src/app/services/test-run.service.spec.ts @@ -354,6 +354,7 @@ describe('TestRunService', () => { StatusOfTestrun.InProgress, StatusOfTestrun.WaitingForDevice, StatusOfTestrun.Monitoring, + StatusOfTestrun.Validating, ]; const resultsNotInProgress = [ diff --git a/modules/ui/src/app/services/test-run.service.ts b/modules/ui/src/app/services/test-run.service.ts index 2e66234c7..34c0af123 100644 --- a/modules/ui/src/app/services/test-run.service.ts +++ b/modules/ui/src/app/services/test-run.service.ts @@ -169,7 +169,8 @@ export class TestRunService { return ( status === StatusOfTestrun.InProgress || status === StatusOfTestrun.WaitingForDevice || - status === StatusOfTestrun.Monitoring + status === StatusOfTestrun.Monitoring || + status === StatusOfTestrun.Validating ); } From abf6bb77c68a8e687e363c6a0eaa4aa92b197685 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Tue, 22 Oct 2024 12:41:22 -0600 Subject: [PATCH 6/8] eslint fixes --- modules/ui/src/app/model/testrun-status.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/src/app/model/testrun-status.ts b/modules/ui/src/app/model/testrun-status.ts index a7626dee2..1295e2c9a 100644 --- a/modules/ui/src/app/model/testrun-status.ts +++ b/modules/ui/src/app/model/testrun-status.ts @@ -66,7 +66,7 @@ export enum StatusOfTestrun { Idle = 'Idle', Monitoring = 'Monitoring', Error = 'Error', - Validating = "Validating Network" + Validating = 'Validating Network' } export enum StatusOfTestResult { From 5da6cc9134749e1a08e12470d56a312d510e775e Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Tue, 22 Oct 2024 13:38:19 -0600 Subject: [PATCH 7/8] lint updates --- modules/ui/src/app/model/testrun-status.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/src/app/model/testrun-status.ts b/modules/ui/src/app/model/testrun-status.ts index 1295e2c9a..f14dce652 100644 --- a/modules/ui/src/app/model/testrun-status.ts +++ b/modules/ui/src/app/model/testrun-status.ts @@ -66,7 +66,7 @@ export enum StatusOfTestrun { Idle = 'Idle', Monitoring = 'Monitoring', Error = 'Error', - Validating = 'Validating Network' + Validating = 'Validating Network', } export enum StatusOfTestResult { From b3615e44b670e8139188915bfa4d150549f30c89 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Mon, 2 Dec 2024 10:10:52 -0700 Subject: [PATCH 8/8] linting --- .../testrun-status-card/testrun-status-card.component.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html index dac9d0d0a..9ca1d80b2 100644 --- a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html +++ b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html @@ -111,9 +111,7 @@

-

- Validating virtual network -

+

Validating virtual network