Skip to content

Commit 9b9e49e

Browse files
qarlosalbertocodebot
authored andcommitted
ci: pass fail criteria in viavi tests
1 parent 7c611e5 commit 9b9e49e

File tree

2 files changed

+91
-15
lines changed

2 files changed

+91
-15
lines changed

tests/e2e/tests/steps/stub.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import logging
1313
from concurrent.futures import as_completed, ThreadPoolExecutor
1414
from contextlib import contextmanager, suppress
15+
from dataclasses import dataclass
1516
from time import sleep
1617
from typing import Dict, Generator, List, Optional, Sequence, Tuple
1718

@@ -23,7 +24,7 @@
2324
from retina.client.exception import ErrorReportedByAgent
2425
from retina.launcher.artifacts import RetinaTestData
2526
from retina.protocol import RanStub
26-
from retina.protocol.base_pb2 import PingRequest, PingResponse, PLMN, StartInfo, StopResponse, UEDefinition
27+
from retina.protocol.base_pb2 import Metrics, PingRequest, PingResponse, PLMN, StartInfo, StopResponse, UEDefinition
2728
from retina.protocol.fivegc_pb2 import FiveGCStartInfo, IPerfResponse
2829
from retina.protocol.fivegc_pb2_grpc import FiveGCStub
2930
from retina.protocol.gnb_pb2 import GNBStartInfo
@@ -48,6 +49,17 @@
4849
ATTACH_TIMEOUT: int = 90
4950

5051

52+
@dataclass
53+
class GnbMetrics:
54+
"""
55+
Metrics from a GNB
56+
"""
57+
58+
ul_brate_agregate: float
59+
dl_brate_agregate: float
60+
nof_kos_aggregate: float
61+
62+
5163
# pylint: disable=too-many-arguments,too-many-locals
5264
def start_and_attach(
5365
ue_array: Sequence[UEStub],
@@ -681,3 +693,25 @@ def _get_metrics_msg(stub: RanStub, name: str, fail_if_kos: bool = False) -> str
681693
return f"{name} has KOs and/or retrxs"
682694

683695
return ""
696+
697+
698+
def get_metrics(stub: RanStub) -> GnbMetrics:
699+
"""
700+
Get metrics from a stub
701+
"""
702+
with suppress(grpc.RpcError):
703+
metrics: Metrics = stub.GetMetrics(Empty())
704+
705+
ul_brate_aggregate = 0
706+
dl_brate_aggregate = 0
707+
nof_kos_aggregate = 0
708+
709+
for ue_info in metrics.ue_array:
710+
if ue_info.ul_bitrate:
711+
ul_brate_aggregate += ue_info.ul_bitrate
712+
if ue_info.dl_bitrate:
713+
dl_brate_aggregate += ue_info.dl_bitrate
714+
if ue_info.nof_kos or ue_info.nof_retx:
715+
nof_kos_aggregate += ue_info.nof_kos
716+
717+
return GnbMetrics(ul_brate_aggregate, dl_brate_aggregate, nof_kos_aggregate)

tests/e2e/tests/viavi.py

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
"""
1010
Launch tests in Viavi
1111
"""
12-
1312
import logging
13+
import operator
1414
from dataclasses import dataclass
1515
from enum import Enum
1616
from pathlib import Path
17-
from typing import Optional
17+
from typing import Callable, Optional
1818

1919
import pytest
2020
from pytest import mark, param
@@ -29,7 +29,7 @@
2929
from retina.viavi.client import CampaignStatusEnum, Viavi
3030

3131
from .steps.configuration import configure_metric_server_for_gnb
32-
from .steps.stub import GNB_STARTUP_TIMEOUT, handle_start_error, stop
32+
from .steps.stub import get_metrics, GNB_STARTUP_TIMEOUT, GnbMetrics, handle_start_error, stop
3333

3434
CAMPAIGN_FILENAME = "C:\\ci\\CI 4x4 ORAN-FH.xml"
3535
_OMIT_VIAVI_FAILURE_LIST = ["authentication"]
@@ -50,10 +50,12 @@ class _ViaviConfiguration:
5050
Viavi configuration
5151
"""
5252

53-
max_pdschs_per_slot: int
54-
max_puschs_per_slot: int
55-
enable_qos_viavi: bool
56-
warning_as_errors: bool
53+
max_pdschs_per_slot: int = 1
54+
max_puschs_per_slot: int = 1
55+
enable_qos_viavi: bool = False
56+
warning_as_errors: bool = True
57+
expected_ul_bitrate: float = 0
58+
expected_dl_bitrate: float = 0
5759

5860

5961
@pytest.fixture
@@ -244,7 +246,6 @@ def test_viavi_debug(
244246
log_search=log_search,
245247
post_commands=post_commands,
246248
warning_as_errors=False,
247-
fail_if_kos=False,
248249
)
249250

250251

@@ -349,7 +350,7 @@ def _test_viavi(
349350
gnb_stop_timeout=gnb_stop_timeout,
350351
log_search=log_search,
351352
warning_as_errors=test_configuration.warning_as_errors,
352-
fail_if_kos=fail_if_kos,
353+
fail_if_kos=False,
353354
)
354355

355356
# This except and the finally should be inside the request, but the campaign_name makes it complicated
@@ -365,15 +366,52 @@ def _test_viavi(
365366
logging.info("Folder with Viavi report: %s", report_folder)
366367
logging.info("Downloading Viavi report")
367368
viavi.download_directory(report_folder, Path(test_log_folder).joinpath("viavi"))
368-
viavi_failure_manager = viavi.get_test_failures()
369-
if viavi_failure_manager.get_number_of_failures(_OMIT_VIAVI_FAILURE_LIST) > 0:
370-
nof_failures = viavi_failure_manager.get_number_of_failures(_OMIT_VIAVI_FAILURE_LIST)
371-
viavi_failure_manager.print_failures(_OMIT_VIAVI_FAILURE_LIST)
372-
pytest.fail(f"Viavi Test Failed with {nof_failures} failures")
369+
run_check_fail_criteria(test_configuration, gnb, viavi, fail_if_kos)
373370
except HTTPError:
374371
logging.error("Viavi Reports could not be downloaded")
375372

376373

374+
def run_check_fail_criteria(test_configuration: _ViaviConfiguration, gnb: GNBStub, viavi: Viavi, fail_if_kos: bool):
375+
"""
376+
Check pass/fail criteria
377+
"""
378+
379+
is_ok = True
380+
381+
# Check metrics
382+
gnb_metrics: GnbMetrics = get_metrics(gnb)
383+
384+
is_ok &= check_and_print_criteria(
385+
"DL bitrate", gnb_metrics.dl_brate_agregate, test_configuration.expected_dl_bitrate, operator.gt
386+
)
387+
is_ok &= check_and_print_criteria(
388+
"UL bitrate", gnb_metrics.ul_brate_agregate, test_configuration.expected_ul_bitrate, operator.gt
389+
)
390+
is_ok &= (
391+
check_and_print_criteria("Number of KOs and/or retrxs", gnb_metrics.nof_kos_aggregate, 0, operator.eq)
392+
and not fail_if_kos
393+
)
394+
395+
# Check procedure table
396+
viavi_failure_manager = viavi.get_test_failures()
397+
viavi_failure_manager.print_failures(_OMIT_VIAVI_FAILURE_LIST)
398+
is_ok &= viavi_failure_manager.get_number_of_failures(_OMIT_VIAVI_FAILURE_LIST) > 0
399+
400+
if not is_ok:
401+
pytest.fail("Test didn't pass all the criteria")
402+
403+
404+
def check_and_print_criteria(
405+
name: str, current: float, expected: float, operator_method: Callable[[float, float], bool]
406+
) -> bool:
407+
"""
408+
Check and print criteria
409+
"""
410+
is_ok = operator_method(current, expected)
411+
(logging.info if is_ok else logging.error)(f"{name} expected: {expected}, actual: {current}")
412+
return is_ok
413+
414+
377415
def get_viavi_configuration(test_name: str, warning_as_errors: bool) -> _ViaviConfiguration:
378416
"""
379417
Get Viavi configuration
@@ -384,12 +422,16 @@ def get_viavi_configuration(test_name: str, warning_as_errors: bool) -> _ViaviCo
384422
max_puschs_per_slot=8,
385423
enable_qos_viavi=False,
386424
warning_as_errors=warning_as_errors,
425+
expected_dl_bitrate=80e6,
426+
expected_ul_bitrate=80e6,
387427
)
388428
if test_name == _TestName.UE32_STATIC_DL_UL_UDP.value:
389429
return _ViaviConfiguration(
390430
max_pdschs_per_slot=1,
391431
max_puschs_per_slot=1,
392432
enable_qos_viavi=False,
393433
warning_as_errors=warning_as_errors,
434+
expected_dl_bitrate=80e6,
435+
expected_ul_bitrate=80e6,
394436
)
395437
raise ValueError(f"Test name {test_name} not supported")

0 commit comments

Comments
 (0)