From 8935e44d131b225d7f6ba76099dd4af5c1b938ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Grabuszy=C5=84ski?= Date: Tue, 28 Jan 2025 17:31:52 +0100 Subject: [PATCH] Val: video test stubs and media-proxy related fixtures (#304) * Add: stub for fixtures relating to media_proxy process lifecycle (spawning, killing) * Add: removal of sent file at the end of test to avoid disk full errors * Add: tests of mock for cluster and st2110 video transfers * Fix: wrong connection.st2110.transport value * Add: todos for further code extension * in tests/validation: Extending copyright with 2024-2025 * in tests/validation: Removing 'Intel(R)' from Media Communications Mesh --- tests/validation/Engine/client_json.py | 4 +- tests/validation/Engine/connection.py | 6 +-- tests/validation/Engine/connection_json.py | 4 +- .../Engine/connection_json_usage_example.py | 4 +- .../Engine/connection_usage_example.py | 4 +- tests/validation/Engine/const.py | 4 +- tests/validation/Engine/csv_report.py | 4 +- tests/validation/Engine/engine_mcm.py | 27 +++++++++--- tests/validation/Engine/execute.py | 4 +- tests/validation/Engine/fixtures.py | 4 +- tests/validation/Engine/fixtures_mcm.py | 42 +++++++++++++++---- tests/validation/Engine/logging.py | 4 +- tests/validation/Engine/media_files.py | 4 +- tests/validation/Engine/payload.py | 4 +- .../Engine/payload_usage_example.py | 4 +- tests/validation/Engine/stash.py | 4 +- tests/validation/conftest.py | 4 +- .../functional/cluster/video/test_video.py | 35 ++++++++++++++++ .../functional/local/video/test_video.py | 17 +++++--- .../functional/st2110/st20/test_video.py | 35 ++++++++++++++++ 20 files changed, 168 insertions(+), 50 deletions(-) create mode 100644 tests/validation/functional/cluster/video/test_video.py create mode 100644 tests/validation/functional/st2110/st20/test_video.py diff --git a/tests/validation/Engine/client_json.py b/tests/validation/Engine/client_json.py index 3bc3c8bd..6173242a 100644 --- a/tests/validation/Engine/client_json.py +++ b/tests/validation/Engine/client_json.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh import json diff --git a/tests/validation/Engine/connection.py b/tests/validation/Engine/connection.py index 7e4ddc18..df2b3582 100644 --- a/tests/validation/Engine/connection.py +++ b/tests/validation/Engine/connection.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh from enum import Enum @@ -72,7 +72,7 @@ def to_dict(self) -> dict: return { "connection": { "st2110": { - "transport": self.transport.value[0], + "transport": self.transport.value, "remoteIpAddr": self.remoteIpAddr, "remotePort": self.remotePort, "pacing": self.pacing, diff --git a/tests/validation/Engine/connection_json.py b/tests/validation/Engine/connection_json.py index 4e474b63..0430de47 100644 --- a/tests/validation/Engine/connection_json.py +++ b/tests/validation/Engine/connection_json.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh import json diff --git a/tests/validation/Engine/connection_json_usage_example.py b/tests/validation/Engine/connection_json_usage_example.py index 76f49f02..aa054718 100644 --- a/tests/validation/Engine/connection_json_usage_example.py +++ b/tests/validation/Engine/connection_json_usage_example.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh from connection import ConnectionMode, Rdma, St2110, TransportType from connection_json import ConnectionJson diff --git a/tests/validation/Engine/connection_usage_example.py b/tests/validation/Engine/connection_usage_example.py index 995d6766..34073b17 100644 --- a/tests/validation/Engine/connection_usage_example.py +++ b/tests/validation/Engine/connection_usage_example.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh from connection import ConnectionMode, Rdma, St2110, TransportType diff --git a/tests/validation/Engine/const.py b/tests/validation/Engine/const.py index 61fdaf54..8cf14420 100644 --- a/tests/validation/Engine/const.py +++ b/tests/validation/Engine/const.py @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh LOG_FOLDER = "logs" diff --git a/tests/validation/Engine/csv_report.py b/tests/validation/Engine/csv_report.py index 898e80c8..977b49e1 100644 --- a/tests/validation/Engine/csv_report.py +++ b/tests/validation/Engine/csv_report.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh import csv diff --git a/tests/validation/Engine/engine_mcm.py b/tests/validation/Engine/engine_mcm.py index 8de42346..0128e399 100644 --- a/tests/validation/Engine/engine_mcm.py +++ b/tests/validation/Engine/engine_mcm.py @@ -1,12 +1,13 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh import logging -import os import signal import subprocess +from pathlib import Path + import Engine.client_json import Engine.connection import Engine.connection_json @@ -18,7 +19,7 @@ def create_client_json(build: str, client: Engine.client_json.ClientJson): logging.debug("Client JSON:") for line in client.to_json().splitlines(): logging.debug(line) - output_path = os.path.join(build, "tests", "tools", "TestApp", "build", "client.json") + output_path = Path(build, "tests", "tools", "TestApp", "build", "client.json") logging.debug(f"Client JSON path: {output_path}") client.prepare_and_save_json(output_path=output_path) @@ -27,7 +28,7 @@ def create_connection_json(build: str, connection: Engine.connection_json.Connec logging.debug("Connection JSON:") for line in connection.to_json().splitlines(): logging.debug(line) - output_path = os.path.join(build, "tests", "tools", "TestApp", "build", "connection.json") + output_path = Path(build, "tests", "tools", "TestApp", "build", "connection.json") logging.debug(f"Connection JSON path: {output_path}") connection.prepare_and_save_json(output_path=output_path) @@ -50,8 +51,20 @@ def stop_rx_app(rx: Engine.execute.AsyncProcess): rx.process.wait() +def remove_sent_file(file_path: str, app_path: str) -> None: + # filepath "/x/y/z.yuv", app_path "/a/b/" + # removes /a/b/z.yuv + removal_path = Path(app_path, Path(file_path).name) + try: + removal_path.unlink() + logging.debug(f"Removed: {removal_path}") + # except makes the test pass if there's no file to remove + except (FileNotFoundError, NotADirectoryError): + logging.debug(f"Cannot remove. File does not exist: {removal_path}") + + def run_rx_tx_with_file(file_path: str, build: str): - app_path = os.path.join(build, "tests", "tools", "TestApp", "build") + app_path = Path(build, "tests", "tools", "TestApp", "build") try: rx = run_rx_app(cwd=app_path) @@ -59,3 +72,5 @@ def run_rx_tx_with_file(file_path: str, build: str): handle_tx_failure(tx) finally: stop_rx_app(rx) + # TODO: Add checks for transmission errors + remove_sent_file(file_path, app_path) diff --git a/tests/validation/Engine/execute.py b/tests/validation/Engine/execute.py index 3c3baebb..3745474c 100644 --- a/tests/validation/Engine/execute.py +++ b/tests/validation/Engine/execute.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh import logging import os diff --git a/tests/validation/Engine/fixtures.py b/tests/validation/Engine/fixtures.py index ec13d18d..32dceef0 100644 --- a/tests/validation/Engine/fixtures.py +++ b/tests/validation/Engine/fixtures.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh import os from typing import Dict diff --git a/tests/validation/Engine/fixtures_mcm.py b/tests/validation/Engine/fixtures_mcm.py index f8cb7fb3..280a40e2 100644 --- a/tests/validation/Engine/fixtures_mcm.py +++ b/tests/validation/Engine/fixtures_mcm.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh import os import subprocess @@ -10,16 +10,42 @@ @pytest.fixture(scope="session") def build_TestApp(build): path = os.path.join(build, "tests", "tools", "TestApp", "build") - subprocess.run(f"rm -rf {path}", shell=True, timeout=10) - subprocess.run(f"mkdir -p {path}", shell=True, timeout=10) + subprocess.run(f'rm -rf "{path}"', shell=True, timeout=10) + subprocess.run(f'mkdir -p "{path}"', shell=True, timeout=10) subprocess.run("cmake ..", cwd=path, shell=True, timeout=10) subprocess.run("make", cwd=path, shell=True, timeout=10) -@pytest.fixture(scope="package") -def media_proxy_single(): - # Run single media proxy - pass +def kill_all_existing_media_proxies(): + # TODO: This assumes the way previous media_proxy worked will not change in the new version, which is unlikely + "Kills all existing media_proxy processes using their PIDs found with px -aux" + existing_mps = subprocess.run("ps -aux | awk '/media_proxy/{print($2)}'", shell=True, capture_output=True) + mp_pids = existing_mps.stdout.decode("utf-8").split() # returns an array of PIDs + (subprocess.run(f"kill -9 {mp_pid}", shell=True) for mp_pid in mp_pids) + + +@pytest.fixture(scope="package", autouse=False) +def media_proxy_single(sender_mp_port: int, receiver_mp_port: int, kill_existing: bool = True): + # TODO: This assumes the way previous media_proxy worked will not change in the new version, which is unlikely + """Opens new media_proxies for sender and receiver. + May optionally kill the already-running media_proxies first. + + Arguments: + sender_mp_port(int): specifies the port number for sender + receiver_mp_port(int): specifies the port number for receiver + + Keyword arguments: + kill_existing(bool, optional): if use kill_all_existing_media_proxies() function to kill -9 all existing + media_proxies before running new instances + """ + if kill_existing: + kill_all_existing_media_proxies() + # create new media_proxy processes for sender and receiver + sender_mp_proc = subprocess.Popen(f"media_proxy -t {sender_mp_port}") # sender's media_proxy + receiver_mp_proc = subprocess.Popen(f"media_proxy -t {receiver_mp_port}") # receiver media_proxy + yield + sender_mp_proc.terminate() + receiver_mp_proc.terminate() @pytest.fixture(scope="package") diff --git a/tests/validation/Engine/logging.py b/tests/validation/Engine/logging.py index 155f48af..f6e2649a 100644 --- a/tests/validation/Engine/logging.py +++ b/tests/validation/Engine/logging.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh import datetime import logging diff --git a/tests/validation/Engine/media_files.py b/tests/validation/Engine/media_files.py index 08ec1e8b..1c2cc9d0 100644 --- a/tests/validation/Engine/media_files.py +++ b/tests/validation/Engine/media_files.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh # This file is a copy retreived from an MTL project diff --git a/tests/validation/Engine/payload.py b/tests/validation/Engine/payload.py index 3f296aa1..12fd5e83 100644 --- a/tests/validation/Engine/payload.py +++ b/tests/validation/Engine/payload.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh from enum import Enum diff --git a/tests/validation/Engine/payload_usage_example.py b/tests/validation/Engine/payload_usage_example.py index 5f59565b..acb4b2eb 100644 --- a/tests/validation/Engine/payload_usage_example.py +++ b/tests/validation/Engine/payload_usage_example.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh from payload import Audio, Video diff --git a/tests/validation/Engine/stash.py b/tests/validation/Engine/stash.py index 6321e31f..58171bf5 100644 --- a/tests/validation/Engine/stash.py +++ b/tests/validation/Engine/stash.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh import os from typing import List diff --git a/tests/validation/conftest.py b/tests/validation/conftest.py index d6b0fa4b..b202f4ec 100644 --- a/tests/validation/conftest.py +++ b/tests/validation/conftest.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh pytest_plugins = ["Engine.fixtures", "Engine.logging", "Engine.fixtures_mcm"] diff --git a/tests/validation/functional/cluster/video/test_video.py b/tests/validation/functional/cluster/video/test_video.py new file mode 100644 index 00000000..00ad0049 --- /dev/null +++ b/tests/validation/functional/cluster/video/test_video.py @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh +import os +import pytest + +import Engine.client_json +import Engine.connection +import Engine.connection_json +import Engine.engine_mcm as utils +import Engine.execute +import Engine.payload +from Engine.media_files import yuv_files + + +@pytest.mark.parametrize("video_type", [k for k in yuv_files.keys()]) +def test_video(build_TestApp, build: str, media: str, video_type): + client = Engine.client_json.ClientJson() + conn_mpg = Engine.connection.Rdma() + payload = Engine.payload.Video( + width=yuv_files[video_type]["width"], + height=yuv_files[video_type]["height"], + fps=yuv_files[video_type]["fps"], + pixelFormat=yuv_files[video_type]["format"], + ) + connection = Engine.connection_json.ConnectionJson(connection=conn_mpg, payload=payload) + + utils.create_client_json(build, client) + utils.create_connection_json(build, connection) + + # Use a specified file from media_files.py + media_file = yuv_files[video_type]["filename"] + media_file_path = os.path.join(media, media_file) + + utils.run_rx_tx_with_file(file_path=media_file_path, build=build) diff --git a/tests/validation/functional/local/video/test_video.py b/tests/validation/functional/local/video/test_video.py index 4864862d..995b4a0e 100644 --- a/tests/validation/functional/local/video/test_video.py +++ b/tests/validation/functional/local/video/test_video.py @@ -1,7 +1,8 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2024 Intel Corporation -# Intel® Media Communications Mesh +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh import os +import pytest import Engine.client_json import Engine.connection @@ -12,17 +13,23 @@ from Engine.media_files import yuv_files -def test_video(build_TestApp, build: str, media: str): +@pytest.mark.parametrize("video_type", [k for k in yuv_files.keys()]) +def test_video(build_TestApp, build: str, media: str, video_type): client = Engine.client_json.ClientJson() conn_mpg = Engine.connection.MultipointGroup() - payload = Engine.payload.Video(width=3840, height=2160) + payload = Engine.payload.Video( + width=yuv_files[video_type]["width"], + height=yuv_files[video_type]["height"], + fps=yuv_files[video_type]["fps"], + pixelFormat=yuv_files[video_type]["format"], + ) connection = Engine.connection_json.ConnectionJson(connection=conn_mpg, payload=payload) utils.create_client_json(build, client) utils.create_connection_json(build, connection) # Use a specified file from media_files.py - media_file = yuv_files["i2160p25"]["filename"] + media_file = yuv_files[video_type]["filename"] media_file_path = os.path.join(media, media_file) utils.run_rx_tx_with_file(file_path=media_file_path, build=build) diff --git a/tests/validation/functional/st2110/st20/test_video.py b/tests/validation/functional/st2110/st20/test_video.py new file mode 100644 index 00000000..679ae545 --- /dev/null +++ b/tests/validation/functional/st2110/st20/test_video.py @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024-2025 Intel Corporation +# Media Communications Mesh +import os +import pytest + +import Engine.client_json +import Engine.connection +import Engine.connection_json +import Engine.engine_mcm as utils +import Engine.execute +import Engine.payload +from Engine.media_files import yuv_files + + +@pytest.mark.parametrize("video_type", [k for k in yuv_files.keys()]) +def test_video(build_TestApp, build: str, media: str, video_type): + client = Engine.client_json.ClientJson() + conn_mpg = Engine.connection.St2110() + payload = Engine.payload.Video( + width=yuv_files[video_type]["width"], + height=yuv_files[video_type]["height"], + fps=yuv_files[video_type]["fps"], + pixelFormat=yuv_files[video_type]["format"], + ) + connection = Engine.connection_json.ConnectionJson(connection=conn_mpg, payload=payload) + + utils.create_client_json(build, client) + utils.create_connection_json(build, connection) + + # Use a specified file from media_files.py + media_file = yuv_files[video_type]["filename"] + media_file_path = os.path.join(media, media_file) + + utils.run_rx_tx_with_file(file_path=media_file_path, build=build)