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
7 changes: 5 additions & 2 deletions framework/python/src/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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")

Expand Down
1 change: 1 addition & 0 deletions framework/python/src/common/statuses.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class TestrunStatus:
COMPLIANT = "Compliant"
NON_COMPLIANT = "Non-Compliant"
STOPPING = "Stopping"
VALIDATING = "Validating Network"


class TestResult:
Expand Down
14 changes: 10 additions & 4 deletions framework/python/src/net_orc/network_orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,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()

try:
if 'validate' in self._session.get_runtime_params():
# Start the validator after network is ready
self._session.set_status(TestrunStatus.VALIDATING)
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')

Expand Down
9 changes: 8 additions & 1 deletion framework/python/src/net_orc/network_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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')
Expand Down Expand Up @@ -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: '

Expand Down Expand Up @@ -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()
Expand All @@ -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
Expand Down
8 changes: 8 additions & 0 deletions framework/python/src/net_orc/ovs_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}',
Expand Down
6 changes: 6 additions & 0 deletions modules/ui/src/app/mocks/testrun.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions modules/ui/src/app/model/testrun-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export enum StatusOfTestrun {
Idle = 'Idle',
Monitoring = 'Monitoring',
Error = 'Error',
Validating = 'Validating Network',
}

export enum StatusOfTestResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
</p>
</div>
<div *ngIf="!data.finished" [ngSwitch]="data.status">
<ng-container
*ngSwitchCase="StatusOfTestrun.Validating"
[ngTemplateOutlet]="Validating">
</ng-container>
<ng-container
*ngSwitchCase="StatusOfTestrun.WaitingForDevice"
[ngTemplateOutlet]="WaitingForDevice">
Expand Down Expand Up @@ -105,6 +109,12 @@
</div>
</ng-template>

<ng-template #Validating>
<div>
<p class="progress-card-result-title">Validating virtual network</p>
</div>
</ng-template>

<ng-template #Monitoring>
<div>
<p class="progress-card-result-title">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ export class TestrunStatusCardComponent {
return (
status === StatusOfTestrun.Monitoring ||
status === StatusOfTestrun.InProgress ||
status === StatusOfTestrun.WaitingForDevice
status === StatusOfTestrun.WaitingForDevice ||
status === StatusOfTestrun.Validating
);
}

Expand Down
16 changes: 16 additions & 0 deletions modules/ui/src/app/pages/testrun/testrun.store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;

Expand Down
5 changes: 4 additions & 1 deletion modules/ui/src/app/pages/testrun/testrun.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export class TestrunStore extends ComponentStore<TestrunComponentState> {
// perform some additional actions
tap(res => {
if (
res?.status === StatusOfTestrun.Validating ||
res?.status === StatusOfTestrun.WaitingForDevice ||
res?.status === StatusOfTestrun.Monitoring ||
(res?.status === StatusOfTestrun.InProgress &&
Expand All @@ -119,6 +120,7 @@ export class TestrunStore extends ComponentStore<TestrunComponentState> {
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)
Expand Down Expand Up @@ -208,7 +210,8 @@ export class TestrunStore extends ComponentStore<TestrunComponentState> {
return (
status === StatusOfTestrun.InProgress ||
status === StatusOfTestrun.WaitingForDevice ||
status === StatusOfTestrun.Monitoring
status === StatusOfTestrun.Monitoring ||
status === StatusOfTestrun.Validating
);
}

Expand Down
1 change: 1 addition & 0 deletions modules/ui/src/app/services/test-run.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ describe('TestRunService', () => {
StatusOfTestrun.InProgress,
StatusOfTestrun.WaitingForDevice,
StatusOfTestrun.Monitoring,
StatusOfTestrun.Validating,
];

const resultsNotInProgress = [
Expand Down
3 changes: 2 additions & 1 deletion modules/ui/src/app/services/test-run.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ export class TestRunService {
return (
status === StatusOfTestrun.InProgress ||
status === StatusOfTestrun.WaitingForDevice ||
status === StatusOfTestrun.Monitoring
status === StatusOfTestrun.Monitoring ||
status === StatusOfTestrun.Validating
);
}

Expand Down
Loading