Test: make GStreamer a first-class Application adapter#1614
Conversation
debe4bb to
cd630fd
Compare
DawidWesierski4
left a comment
There was a problem hiding this comment.
please put the tests into the old testing harness don't add test_gst
this is pointless this way :<
| ``execute_test`` delegates to :func:`GstreamerApp.execute_test`. | ||
|
|
||
| Because execution is delegated, this adapter intentionally BYPASSES the | ||
| base-class run machinery (netsniff hook, PTP extension, SIGINT->SIGKILL stop |
There was a problem hiding this comment.
netsniff hook, PTP extension can be tested in gstreamer
-> g_param_spec_boolean("enable-ptp", "Enable onboard PTP",
-> netsniff hook -> the gstreamer should have compliance testing ?
There was a problem hiding this comment.
the only question is about if we should
|
|
||
|
|
||
| @pytest.mark.nightly | ||
| @pytest.mark.parametrize("application", ["gstreamer"]) |
There was a problem hiding this comment.
This shudn't work like this
test_gst_video_format should be included into the st20 tests
right now this is just renaming not refactoring the tests :<
Refactor the GStreamer pytest suite to the unified Application pattern
used by RxTxApp and FFmpeg. GStreamer is now selectable via
app_factory("gstreamer") and @pytest.mark.parametrize("application",
["gstreamer"]), replacing the procedural GstreamerApp.setup_* +
GstreamerApp.execute_test calls in every test.
- Add mtl_engine/gstreamer.py: GStreamer(Application), a thin wrapper
over the procedural GstreamerApp (kept as the single source of truth).
create_command() materializes TX/RX token lists by dispatching on
session_type (st20p/st30/st40p); execute_test() delegates to
GstreamerApp.execute_test. The crossed ST2022-7 redundant mapping is
derived from a 4-port nic list + ip_pools.
- Register the "gstreamer" branch in conftest.app_factory.
- Add tests/validation/test_gstreamer_adapter.py: characterization unit
tests asserting the adapter emits byte-for-byte identical gst-launch
commands vs the procedural builders (st20p/st30/st40p basic+redundant).
- Refactor video_format, video_resolution, audio_format and anc_format
onto the adapter. All parametrize matrices, ids, markers, skip guards,
frame-info assertions and logging helpers are preserved; the redundant
per-test _append_redundant_params boilerplate is removed in favour of
redundant=True.
Behavior is unchanged: verified on real E810 VFs (st20p, st30,
st40i_basic, st40p redundant all pass).
…e size The preflight hugepage check assumed 2 MiB pages (HugePages_Free * 2), misreporting hosts booted with default_hugepagesz=1G: 32 free 1G pages read as 64 MiB instead of 32768 MiB and tripped the <1024 MiB guard. Derive the factor from Hugepagesize in /proc/meminfo instead. Backward compatible: on 2 MiB-default hosts Hugepagesize is 2048 kB so the multiplier is still 2.
Relocate the GStreamer pytest suites out of their own single/gstreamer and dual/gstreamer trees into the protocol-organized siblings, matching how ffmpeg/rxtxapp are arranged. GStreamer is already an app_factory application, so this is a pure move with no test-body changes. - single: test_video_format -> single/st20p/test_gst_video_format.py, test_video_resolution -> single/st20p/test_gst_video_resolution.py, test_audio_format -> single/st30p/test_gst_audio_format.py, test_anc_format -> single/st40p/test_gst_anc_format.py. - dual: moved under per-protocol gstreamer/ subfolders (dual/st20p/gstreamer, dual/st30p/gstreamer, dual/st40/gstreamer), mirroring the existing dual/ffmpeg layout. - Delete the now-empty single/gstreamer and dual/gstreamer trees. All moves are git renames (R100, byte-identical). Tree-wide collection unchanged (1193 tests); the moved suites collect 233. Relocated st20p gst video_format suite re-run on real E810 VFs: 2 passed, 2 skipped.
dual/st40 lacked the package marker its siblings dual/st20p and dual/st30p have. Add an empty __init__.py for consistent package discovery. Empty file, matching the existing convention.
Revert the consolidation of GStreamer tests under the tests/dual tree back to their original gstreamer/ directory structure. The full combination (single + dual) is saved on local backup branch 'backup-gstreamer-with-dual' for later use. This branch now only consolidates single-host gstreamer tests.
Fold GStreamer st20p resolution and st30p audio-format tests into the shared parametrized suites (application = rxtxapp | ffmpeg | gstreamer), translating UNIVERSAL_PARAMS to GStreamer caps in the adapter. Keep GStreamer-only cases (audiotestsrc st30, onboard-PTP st20p) where an integrity comparison is not technically possible, properly refactored. Add enable-ptp plumbing through the st20p TX/RX builders and the adapter, plus a GStreamer PTP st20p test. Rename st40p anc test; keep and extend the offline adapter characterization test.
9b4e765 to
c1d746d
Compare
Delete the 5 identity tests that built a golden token list by calling the same GstreamerApp builders the adapter calls, then asserted equality (tautological, flagged as pointless in review). Keep the 3 translation tests that pin the new UNIVERSAL_PARAMS -> GStreamer caps mapping and the enable_ptp token, and retarget the module docstring to that scope.
| # SPDX-License-Identifier: BSD-3-Clause | ||
| # Copyright(c) 2026 Intel Corporation | ||
| """GStreamer ST20P onboard-PTP validation. | ||
|
|
||
| Exercises the GStreamer plugin ``enable-ptp`` property (onboard PTP client) on | ||
| a single-host TX+RX ST20P pipeline. GStreamer drives synthetic planar media, so | ||
| this validates that the stream transports and md5-matches end to end with PTP | ||
| enabled; it is GStreamer-only because the ``enable-ptp`` knob lives in the | ||
| plugin (the RxTxApp PTP coverage lives under the integrity-based ptp tests). | ||
| """ | ||
|
|
||
| import os | ||
|
|
||
| import mtl_engine.media_creator as media_create | ||
| import pytest | ||
| from common.nicctl import InterfaceSetup | ||
| from mtl_engine import ip_pools | ||
| from mtl_engine.media_files import yuv_files_422rfc10 | ||
|
|
||
|
|
||
| @pytest.mark.nightly | ||
| @pytest.mark.ptp |
There was a problem hiding this comment.
i don't think we should have tests like this in the PTP folder
this very well could be a general test, why is it only done for gstreamer ?
apart from name the test is completly general ?
| # GStreamer reads raw planar media (I422_10LE / v210), not the RFC4175-packed | ||
| # files RxTxApp/FFmpeg consume, so it self-provides a synthetic clip of the same | ||
| # resolution. Generating raw 4K/8K clips is impractical, so GStreamer only runs | ||
| # the <=1080p resolutions; RxTxApp/FFmpeg still sweep the full range. | ||
| _GST_MAX_HEIGHT = 1080 | ||
|
|
||
|
|
||
| def _prepare_gstreamer_media(host, info, media_file_path, request): | ||
| """Generate a synthetic planar clip for GStreamer; return (input, output, gst_format). | ||
|
|
||
| The st20 plugin only emits v210 when the width is a multiple of six (pixel | ||
| groups are six pixels wide); otherwise it falls back to I422_10LE. The clip | ||
| is written next to the fixture-provided media file so it lands in the | ||
| managed media/ramdisk directory rather than a hardcoded path. | ||
| """ | ||
| width, height, fps = info["width"], info["height"], info["fps"] | ||
| gst_format = "v210" if width % 6 == 0 else "I422_10LE" | ||
| if gst_format == "v210": | ||
| SDBQ1971_conversion_v210_720p_error( | ||
| video_format=gst_format, resolution_height=height, request=request | ||
| ) | ||
|
|
||
| media_dir = str(host.connection.path(media_file_path).parent) | ||
| input_file = media_create.create_video_file( | ||
| width=width, | ||
| height=height, | ||
| framerate=fps, | ||
| format=gst_format, | ||
| media_path=media_dir, | ||
| duration=3, | ||
| host=host, | ||
| ) | ||
| output_file = os.path.join(media_dir, "output_video.yuv") | ||
| return input_file, output_file, gst_format |
There was a problem hiding this comment.
this is not the place for it ?
we could have functions in our gstreamer class that does it ?
also this is impractical solution ... it was done as a workaround in gstreamer ?
using it this way is in my opinion wrong
let's just use the input files like in other tests and have the normal file src pipeline,
TLDR -> we used generic file production cuz it was easier it fails cuz we did it this way
i don't think it's resonable to skip the test to keep that syntetic input and only run the format check below Full HD resolution
| if height > _GST_MAX_HEIGHT: | ||
| pytest.skip( |
There was a problem hiding this comment.
as said above this is easly fixed and can be removed via not propagating this wird workaround we did back in the day
| for path in gst_cleanup: | ||
| media_create.remove_file(path, host=host) |
There was a problem hiding this comment.
should not be there ;<
|
|
||
| """GStreamer ST40P ancillary transport validation. | ||
|
|
||
| Exercises ANC payload handling over GStreamer across frame rates, payload |
There was a problem hiding this comment.
if we wan't the gstreamer to be general this description would need to be changed
| def _frame_info_path(base_dir=None): | ||
| target_dir = base_dir or "/tmp" | ||
| base = GstreamerApp.sanitize_filename(GstreamerApp.get_case_id()) | ||
| token = uuid.uuid4().hex | ||
| return os.path.join(target_dir, f"{base}_{token}_frameinfo.log") |
There was a problem hiding this comment.
if we want this test to be general then logic like that should go to the gstreamer class instead of the general tests
| """ | ||
| Validate ST40P ancillary (ANC) transport over GStreamer across frame-rate and | ||
| payload-size matrices to exercise scheduling, pacing, and metadata delivery. | ||
| Small and medium text payloads are generated on the fly, transmitted over | ||
| paired VFs on a single physical port, and captured for byte-for-byte | ||
| comparison by the harness. |
There was a problem hiding this comment.
this would need to be updated to reflect the general nature of the test
| @contextmanager | ||
| def _test_summary(name: str, expectation: str): | ||
| """Structured test logging so pytest.log captures start/fail/pass summaries.""" | ||
| log_info(f"[{name}] START: {expectation}") |
There was a problem hiding this comment.
logging logic check would need to be moved into the Application class
This if i remember correctly is already there
This function in itself is fine but at the end of the day is used by a lot of tests with gstreamer specific logging
Refactor the GStreamer pytest suite onto the unified Application pattern
already used by RxTxApp and FFmpeg. GStreamer is now selectable via
app_factory("gstreamer") and the "application" parametrize, replacing the
procedural GstreamerApp.setup_* / execute_test calls in every test.
the procedural GstreamerApp (kept as single source of truth). Dispatches
st20p/st30/st40p by session_type; derives the crossed ST2022-7 redundant
mapping from a 4-port nic list + ip_pools.
identical gst-launch commands vs the procedural builders.
the adapter; all matrices, ids, markers, skip guards and assertions kept.
Removes the per-test redundant-param boilerplate in favour of redundant=True.
Also fixes the preflight hugepage check to compute free MiB from the actual
Hugepagesize instead of assuming 2 MiB pages.
Behavior unchanged: verified on real E810 VFs (st20p, st30, st40i_basic,
st40p redundant all pass).