Skip to content

Commit c591b06

Browse files
ENT-1677: Document RTSPS TLS env vars and extend producer tests
Add module docstring for ROBOFLOW_RTSP_TLS_VALIDATION_FLAGS and CA bundle env vars (self-hosted escape hatch). Assert env var is restored after open, on capture failure, and untouched for int device indices.
1 parent 5d9ab74 commit c591b06

2 files changed

Lines changed: 61 additions & 1 deletion

File tree

inference/core/interfaces/camera/rtsp_opencv_tls.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
1-
"""OpenCV/FFmpeg RTSPS TLS option builder (ENT-1544 B3)."""
1+
"""OpenCV/FFmpeg RTSPS TLS option builder (ENT-1544 B3).
2+
3+
Environment variables (also set by rfdm on Roboflow Edge devices):
4+
5+
* ``ROBOFLOW_RTSP_TLS_VALIDATION_FLAGS`` — ``127`` strict (default when unset),
6+
``126`` or ``0`` to disable certificate verification (self-signed / custom CA).
7+
* ``GST_SSL_CA_CERTIFICATE`` or ``SSL_CERT_FILE`` — PEM bundle for ``cafile``.
8+
9+
Self-hosted / OSS deployments without rfdm must set these explicitly on the
10+
inference container. Unmanaged ``rtsps://`` sources with self-signed certs need
11+
``ROBOFLOW_RTSP_TLS_VALIDATION_FLAGS=126`` or the open will fail after this wiring.
12+
"""
213

314
from __future__ import annotations
415

tests/inference/unit_tests/core/interfaces/camera/test_video_source.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,3 +1908,52 @@ def fake_video_capture(video, *args, **kwargs):
19081908
# while VideoCapture runs for RTSPS, and left alone for plain RTSP
19091909
assert "tls_verify;1" in seen["rtsps://camera.example/stream"]
19101910
assert seen["rtsp://camera.example/stream"] is None
1911+
assert OPENCV_FFMPEG_CAPTURE_OPTIONS_ENV_VAR not in os.environ
1912+
1913+
1914+
def test_cv2_producer_restores_ffmpeg_tls_env_after_open(
1915+
monkeypatch: pytest.MonkeyPatch,
1916+
) -> None:
1917+
monkeypatch.delenv(OPENCV_FFMPEG_CAPTURE_OPTIONS_ENV_VAR, raising=False)
1918+
monkeypatch.delenv(RTSP_TLS_VALIDATION_FLAGS_ENV_VAR, raising=False)
1919+
1920+
with patch.object(video_source.cv2, "VideoCapture", MagicMock()):
1921+
CV2VideoFrameProducer("rtsps://camera.example/stream")
1922+
1923+
assert OPENCV_FFMPEG_CAPTURE_OPTIONS_ENV_VAR not in os.environ
1924+
1925+
1926+
def test_cv2_producer_restores_ffmpeg_tls_env_when_capture_raises(
1927+
monkeypatch: pytest.MonkeyPatch,
1928+
) -> None:
1929+
monkeypatch.delenv(OPENCV_FFMPEG_CAPTURE_OPTIONS_ENV_VAR, raising=False)
1930+
monkeypatch.delenv(RTSP_TLS_VALIDATION_FLAGS_ENV_VAR, raising=False)
1931+
1932+
def failing_video_capture(*args, **kwargs):
1933+
raise RuntimeError("simulated open failure")
1934+
1935+
with patch.object(
1936+
video_source.cv2, "VideoCapture", failing_video_capture
1937+
), pytest.raises(RuntimeError):
1938+
CV2VideoFrameProducer("rtsps://camera.example/stream")
1939+
1940+
assert OPENCV_FFMPEG_CAPTURE_OPTIONS_ENV_VAR not in os.environ
1941+
1942+
1943+
def test_cv2_producer_leaves_ffmpeg_tls_env_unset_for_device_index(
1944+
monkeypatch: pytest.MonkeyPatch,
1945+
) -> None:
1946+
monkeypatch.delenv(OPENCV_FFMPEG_CAPTURE_OPTIONS_ENV_VAR, raising=False)
1947+
seen = {}
1948+
1949+
def fake_video_capture(video, *args, **kwargs):
1950+
seen["video"] = video
1951+
seen["env"] = os.environ.get(OPENCV_FFMPEG_CAPTURE_OPTIONS_ENV_VAR)
1952+
return MagicMock()
1953+
1954+
with patch.object(video_source.cv2, "VideoCapture", fake_video_capture):
1955+
CV2VideoFrameProducer(0)
1956+
1957+
assert seen["video"] == 0
1958+
assert seen["env"] is None
1959+
assert OPENCV_FFMPEG_CAPTURE_OPTIONS_ENV_VAR not in os.environ

0 commit comments

Comments
 (0)