@@ -307,6 +307,62 @@ def test_negative_fps_excluded(self):
307307 assert CustomCollector ._average_source_fps (metadata ) == 25.0
308308
309309
310+ class TestSanitizeSourceReference :
311+ def test_strips_credentials_from_rtsp_url (self ):
312+ assert (
313+ CustomCollector ._sanitize_source_reference ("rtsp://admin:secret@192.168.1.1:554/stream1" )
314+ == "rtsp://192.168.1.1:554/stream1"
315+ )
316+
317+ def test_strips_credentials_from_http_url (self ):
318+ assert (
319+ CustomCollector ._sanitize_source_reference ("http://user:pass@example.com:8080/feed" )
320+ == "http://example.com:8080/feed"
321+ )
322+
323+ def test_strips_username_only (self ):
324+ assert (
325+ CustomCollector ._sanitize_source_reference ("rtsp://admin@10.0.0.1/live" )
326+ == "rtsp://10.0.0.1/live"
327+ )
328+
329+ def test_preserves_url_without_credentials (self ):
330+ assert (
331+ CustomCollector ._sanitize_source_reference ("rtsp://192.168.1.1:554/stream" )
332+ == "rtsp://192.168.1.1:554/stream"
333+ )
334+
335+ def test_preserves_device_index (self ):
336+ assert CustomCollector ._sanitize_source_reference ("0" ) == "0"
337+
338+ def test_preserves_file_path (self ):
339+ assert CustomCollector ._sanitize_source_reference ("/dev/video0" ) == "/dev/video0"
340+
341+ def test_preserves_regular_file_path (self ):
342+ assert (
343+ CustomCollector ._sanitize_source_reference ("/home/user/video.mp4" )
344+ == "/home/user/video.mp4"
345+ )
346+
347+ def test_strips_credentials_and_query_params (self ):
348+ assert (
349+ CustomCollector ._sanitize_source_reference ("rtsp://user:p%40ss@cam.local:554/ch1?transport=tcp" )
350+ == "rtsp://cam.local:554/ch1"
351+ )
352+
353+ def test_strips_query_params_without_credentials (self ):
354+ assert (
355+ CustomCollector ._sanitize_source_reference ("rtsp://cam.local:554/stream?token=secret123&channel=1" )
356+ == "rtsp://cam.local:554/stream"
357+ )
358+
359+ def test_strips_fragment (self ):
360+ assert (
361+ CustomCollector ._sanitize_source_reference ("http://example.com/feed#section" )
362+ == "http://example.com/feed"
363+ )
364+
365+
310366class TestExtractSourceLabel :
311367 def test_single_source (self ):
312368 metadata = [
@@ -338,6 +394,31 @@ def test_none_source_reference_excluded(self):
338394 ]
339395 assert CustomCollector ._extract_source_label (metadata ) == "rtsp://cam1.local/stream"
340396
397+ def test_strips_credentials_from_source_references (self ):
398+ metadata = [
399+ {"source_reference" : "rtsp://admin:secret@192.168.1.1:554/stream" , "source_id" : 0 },
400+ {"source_reference" : "rtsp://user:pass@10.0.0.1:554/live" , "source_id" : 1 },
401+ ]
402+ assert (
403+ CustomCollector ._extract_source_label (metadata )
404+ == "rtsp://192.168.1.1:554/stream,rtsp://10.0.0.1:554/live"
405+ )
406+
407+ def test_strips_query_params_from_source_references (self ):
408+ metadata = [
409+ {"source_reference" : "rtsp://cam.local/stream?token=secret&channel=1" , "source_id" : 0 },
410+ ]
411+ assert CustomCollector ._extract_source_label (metadata ) == "rtsp://cam.local/stream"
412+
413+ def test_returns_empty_when_source_labels_disabled (self ):
414+ metadata = [
415+ {"source_reference" : "rtsp://cam1.local/stream" , "source_id" : 0 },
416+ ]
417+ with patch (
418+ "inference.core.managers.prometheus.METRICS_INCLUDE_SOURCE_LABELS" , False
419+ ):
420+ assert CustomCollector ._extract_source_label (metadata ) == ""
421+
341422
342423def _find_samples (metric_families , name ):
343424 """Return all samples for a given metric family name."""
0 commit comments