Skip to content

Test: make GStreamer a first-class Application adapter#1614

Open
awilczyns wants to merge 7 commits into
mainfrom
gstreamer-pytest-refactor
Open

Test: make GStreamer a first-class Application adapter#1614
awilczyns wants to merge 7 commits into
mainfrom
gstreamer-pytest-refactor

Conversation

@awilczyns

Copy link
Copy Markdown
Collaborator

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.

  • Add mtl_engine/gstreamer.py: GStreamer(Application), a thin wrapper over
    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.
  • Register the "gstreamer" branch in conftest.app_factory.
  • Add characterization unit tests asserting the adapter emits byte-for-byte
    identical gst-launch commands vs the procedural builders.
  • Refactor video_format, video_resolution, audio_format and anc_format onto
    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).

@awilczyns
awilczyns requested a review from staszczuk as a code owner June 15, 2026 12:17
@awilczyns
awilczyns force-pushed the gstreamer-pytest-refactor branch from debe4bb to cd630fd Compare June 15, 2026 12:19

@DawidWesierski4 DawidWesierski4 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the only question is about if we should



@pytest.mark.nightly
@pytest.mark.parametrize("application", ["gstreamer"])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@awilczyns
awilczyns force-pushed the gstreamer-pytest-refactor branch from 9b4e765 to c1d746d Compare July 1, 2026 10:43
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.
Comment on lines +1 to +22
# 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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ?

Comment on lines +15 to +48
# 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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment on lines +105 to +106
if height > _GST_MAX_HEIGHT:
pytest.skip(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as said above this is easly fixed and can be removed via not propagating this wird workaround we did back in the day

Comment on lines +151 to +152
for path in gst_cleanup:
media_create.remove_file(path, host=host)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should not be there ;<


"""GStreamer ST40P ancillary transport validation.

Exercises ANC payload handling over GStreamer across frame rates, payload

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we wan't the gstreamer to be general this description would need to be changed

Comment on lines 24 to 28
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")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we want this test to be general then logic like that should go to the gstreamer class instead of the general tests

Comment on lines 187 to 192
"""
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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would need to be updated to reflect the general nature of the test

Comment on lines 141 to 144
@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}")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants