Skip to content

Commit 7bbdf97

Browse files
committed
Add results.csv preparation. Add new logger levels
1 parent 3a46b35 commit 7bbdf97

File tree

5 files changed

+119
-6
lines changed

5 files changed

+119
-6
lines changed

tests/validation/Engine/const.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
DEFAULT_INPUT_PATH = "/opt/intel/input_path/"
88
DEFAULT_OUTPUT_PATH = "/opt/intel/output_path/"
99

10+
TESTCMD_LVL = 24 # Custom logging level for test commands
11+
1012
# time for establishing connection for example between TX and RX in st2110
1113
MTL_ESTABLISH_TIMEOUT = 2
1214
MCM_ESTABLISH_TIMEOUT = 5

tests/validation/Engine/rx_tx_app_engine_mcm.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import Engine.rx_tx_app_client_json
1313
import Engine.rx_tx_app_connection_json
14-
from Engine.const import LOG_FOLDER, RX_TX_APP_ERROR_KEYWORDS, DEFAULT_OUTPUT_PATH
14+
from Engine.const import LOG_FOLDER, RX_TX_APP_ERROR_KEYWORDS, DEFAULT_OUTPUT_PATH, TESTCMD_LVL
1515
from Engine.mcm_apps import (
1616
get_media_proxy_port,
1717
output_validator,
@@ -279,6 +279,7 @@ def start(self):
279279
f"Starting Tx app with payload: {self.payload.payload_type} on {self.host}"
280280
)
281281
cmd = self._get_app_cmd("Tx")
282+
logger.log(TESTCMD_LVL, f"Tx command: {cmd}")
282283
self.process = self.host.connection.start_process(
283284
cmd, shell=True, stderr_to_stdout=True, cwd=self.app_path
284285
)
@@ -334,6 +335,7 @@ def start(self):
334335
f"Starting Rx app with payload: {self.payload.payload_type} on {self.host}"
335336
)
336337
cmd = self._get_app_cmd("Rx")
338+
logger.log(TESTCMD_LVL, f"Rx command: {cmd}")
337339
self.process = self.host.connection.start_process(
338340
cmd, shell=True, stderr_to_stdout=True, cwd=self.app_path
339341
)

tests/validation/common/ffmpeg_handler/ffmpeg.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
SSHRemoteProcessEndException,
1010
RemoteProcessInvalidState,
1111
)
12-
from Engine.const import LOG_FOLDER
12+
from Engine.const import LOG_FOLDER, TESTCMD_LVL
1313
from Engine.mcm_apps import save_process_log
1414

1515
from .ffmpeg_io import FFmpegIO
@@ -77,6 +77,7 @@ def __init__(self, host, ffmpeg_instance: FFmpeg, log_path=None):
7777
def start(self):
7878
"""Starts the FFmpeg process on the host, waits for the process to start."""
7979
cmd = self.ff.get_command()
80+
logger.log(TESTCMD_LVL, f"ffmpeg command: {cmd}")
8081
ffmpeg_process = self.host.connection.start_process(
8182
cmd, stderr_to_stdout=True, shell=True
8283
)

tests/validation/conftest.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import shutil
88
from ipaddress import IPv4Interface
99
from pathlib import Path
10+
from typing import Dict
1011

1112
from mfd_host import Host
1213
from mfd_connect.exceptions import (
@@ -16,6 +17,7 @@
1617
import pytest
1718

1819
from common.nicctl import Nicctl
20+
1921
from Engine.const import (
2022
ALLOWED_FFMPEG_VERSIONS,
2123
DEFAULT_FFMPEG_PATH,
@@ -32,11 +34,35 @@
3234
MCM_BUILD_PATH,
3335
MTL_BUILD_PATH,
3436
OPENH264_VERSION_TAG,
37+
TESTCMD_LVL
38+
)
39+
from Engine.csv_report import (
40+
csv_add_test,
41+
csv_write_report,
42+
update_compliance_result,
43+
3544
)
3645
from Engine.mcm_apps import MediaProxy, MeshAgent, get_mcm_path, get_mtl_path
3746
from datetime import datetime
47+
from mfd_common_libs.custom_logger import add_logging_level
48+
from mfd_common_libs.log_levels import TEST_FAIL, TEST_INFO, TEST_PASS
49+
from pytest_mfd_logging.amber_log_formatter import AmberLogFormatter
50+
3851

3952
logger = logging.getLogger(__name__)
53+
phase_report_key = pytest.StashKey[Dict[str, pytest.CollectReport]]()
54+
55+
56+
@pytest.hookimpl(wrapper=True, tryfirst=True)
57+
def pytest_runtest_makereport(item, call):
58+
# execute all other hooks to obtain the report object
59+
rep = yield
60+
61+
# store test results for each phase of a call, which can
62+
# be "setup", "call", "teardown"
63+
item.stash.setdefault(phase_report_key, {})[rep.when] = rep
64+
65+
return rep
4066

4167

4268
@pytest.fixture(scope="function")
@@ -770,3 +796,89 @@ def log_interface_driver_info(hosts: dict[str, Host]) -> None:
770796
logger.info(
771797
f"Interface {interface.name} on host {host.name} uses driver: {driver_info.driver_name} ({driver_info.driver_version})"
772798
)
799+
800+
801+
@pytest.fixture(scope="session", autouse=True)
802+
def log_session():
803+
add_logging_level("TESTCMD", TESTCMD_LVL)
804+
805+
today = datetime.today()
806+
folder = today.strftime("%Y-%m-%dT%H:%M:%S")
807+
path = os.path.join(LOG_FOLDER, folder)
808+
path_symlink = os.path.join(LOG_FOLDER, "latest")
809+
try:
810+
os.remove(path_symlink)
811+
except FileNotFoundError:
812+
pass
813+
os.makedirs(path, exist_ok=True)
814+
os.symlink(folder, path_symlink)
815+
yield
816+
shutil.copy("pytest.log", f"{LOG_FOLDER}/latest/pytest.log")
817+
csv_write_report(f"{LOG_FOLDER}/latest/report.csv")
818+
819+
@pytest.fixture(scope="function", autouse=True)
820+
def log_case(request, caplog: pytest.LogCaptureFixture):
821+
case_id = request.node.nodeid
822+
case_folder = os.path.dirname(case_id)
823+
os.makedirs(os.path.join(LOG_FOLDER, "latest", case_folder), exist_ok=True)
824+
logfile = os.path.join(LOG_FOLDER, "latest", f"{case_id}.log")
825+
fh = logging.FileHandler(logfile)
826+
formatter = request.session.config.pluginmanager.get_plugin(
827+
"logging-plugin"
828+
).formatter
829+
format = AmberLogFormatter(formatter)
830+
fh.setFormatter(format)
831+
fh.setLevel(logging.DEBUG)
832+
logger = logging.getLogger()
833+
logger.addHandler(fh)
834+
yield
835+
report = request.node.stash[phase_report_key]
836+
if report["setup"].failed:
837+
logging.log(level=TEST_FAIL, msg=f"Setup failed for {case_id}")
838+
os.chmod(logfile, 0o4755)
839+
result = "Fail"
840+
elif ("call" not in report) or report["call"].failed:
841+
logging.log(level=TEST_FAIL, msg=f"Test failed for {case_id}")
842+
os.chmod(logfile, 0o4755)
843+
result = "Fail"
844+
elif report["call"].passed:
845+
logging.log(level=TEST_PASS, msg=f"Test passed for {case_id}")
846+
os.chmod(logfile, 0o755)
847+
result = "Pass"
848+
else:
849+
logging.log(level=TEST_INFO, msg=f"Test skipped for {case_id}")
850+
result = "Skip"
851+
852+
logger.removeHandler(fh)
853+
854+
commands = []
855+
for record in caplog.get_records("call"):
856+
if record.levelno == TESTCMD_LVL:
857+
commands.append(record.message)
858+
859+
csv_add_test(
860+
test_case=case_id,
861+
commands="\n".join(commands),
862+
result=result,
863+
issue="n/a",
864+
result_note="n/a",
865+
)
866+
867+
868+
@pytest.fixture(scope="session")
869+
def compliance_report(request, log_session, test_config):
870+
"""
871+
This function is used for compliance check and report.
872+
"""
873+
# TODO: Implement compliance check logic. When tcpdump pcap is enabled, at the end of the test session all pcaps
874+
# shall be send into EBU list.
875+
# Pcaps shall be stored in the ramdisk, and then moved to the compliance
876+
# folder or send into EBU list after each test finished and remove it from the ramdisk.
877+
# Compliance report generation logic goes here after yield. Or in another class / function but triggered here.
878+
# AFAIK names of pcaps contains test name so it can be matched with result of each test like in code below.
879+
yield
880+
if test_config.get("compliance", False):
881+
logging.info("Compliance mode enabled, updating compliance results")
882+
for item in request.session.items:
883+
test_case = item.nodeid
884+
update_compliance_result(test_case, "Fail")

tests/validation/pytest.ini

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
[pytest]
22
pythonpath = .
3-
log_cli = true
43
log_cli_level = info
54
log_file = pytest.log
6-
log_file_level = debug
7-
log_file_format = %(asctime)s,%(msecs)03d %(levelname)-8s %(filename)s:%(lineno)d %(message)s
8-
log_file_date_format = %Y-%m-%d %H:%M:%S

0 commit comments

Comments
 (0)