"""Tests der Fähigkeiten-Erkennung — reine Funktionen, keine Infrastruktur. Die Testdaten sind ECHTE Ausgaben, am 25.07.2026 im Worker-Image der Rippy-VM abgenommen (AGENTS Regel D). Erfundene Formate hätten hier keinen Wert: genau daran ist die Erkennung vorher gescheitert. """ import caps # Wörtlich aus `docker exec rippy-worker-1 HandBrakeCLI --help` (HandBrake im # Worker-Image, 25.07.2026). Bemerkenswert: KEIN Hardware-Encoder dabei. HB_HILFE_ECHT = """ -Z, --preset Select preset by name -e, --encoder Select video encoder: svt_av1 svt_av1_10bit x264 x264_10bit x265 x265_10bit x265_12bit mpeg4 mpeg2 VP8 VP9 VP9_10bit theora --encoder-preset Adjust video encoding settings """ # Wie dieselbe Stelle auf einer Maschine MIT Hardware-Encodern aussieht # (HandBrake-Windows-Build; Struktur identisch, nur mehr Namen). HB_HILFE_MIT_HARDWARE = """ -e, --encoder Select video encoder: x264 x265 nvenc_h264 nvenc_h265 qsv_h264 qsv_h265 --encoder-preset """ def test_encoder_liste_wird_aus_echter_hilfe_gelesen(): encoder = caps.parse_encoder_liste(HB_HILFE_ECHT) assert encoder == [ "svt_av1", "svt_av1_10bit", "x264", "x264_10bit", "x265", "x265_10bit", "x265_12bit", "mpeg4", "mpeg2", "VP8", "VP9", "VP9_10bit", "theora", ] # Der Block endet an der nächsten Option — sie darf nicht mitgelesen werden assert not any("encoder-preset" in e for e in encoder) assert not any(e.startswith("-") for e in encoder) def test_encoder_liste_ohne_handbrake_ist_leer(): assert caps.parse_encoder_liste("") == [] assert caps.parse_encoder_liste(None) == [] assert caps.parse_encoder_liste("irgendein Text ohne Encoder-Abschnitt") == [] def test_ohne_handbrake_keine_encoder(): """Der wichtigste Fall: vorher standen cpu-x264/cpu-x265 fest verdrahtet in der Liste. Ein Rip-Worker ohne HandBrake behauptete damit, komprimieren zu können — und jeder Transcode dort endete sofort mit 'nicht installiert'.""" assert caps.leite_backends_ab([]) == [] assert caps.leite_backends_ab(None) == [] def test_backends_aus_echter_liste(): """Das Worker-Image der VM kann laut eigener Auskunft keine Hardware — entsprechend steht hier nur CPU.""" encoder = caps.parse_encoder_liste(HB_HILFE_ECHT) assert caps.leite_backends_ab(encoder) == ["cpu-x264", "cpu-x265", "cpu-av1"] def test_handbrakes_liste_ist_die_auskunft_ohne_geraetepruefung(): """Regel-Wechsel 25.07.2026, weil die alte Fassung einen Bug hatte. Vorher wurde zusätzlich ein Gerät verlangt: /dev/dri für VAAPI/QSV/VCE bzw. nvidia-smi für NVENC. Unter WINDOWS gibt es beides nicht — der PC des Commanders (RX 9070 XT) meldete deshalb nur CPU-Encoder, obwohl HandBrakes Windows-Build vce_*/nvenc_*/qsv_* beherrscht. Der Bug traf genau den Anwendungsfall, für den externe Worker gedacht sind. Die Prüfung war zudem überflüssig: HandBrake probiert Hardware beim Start selbst an und listet nur Nutzbares (auf der VM belegt — 'qsv: not available on this system', und qsv_* fehlt dann in --help). Wer die Liste hat, hat die Antwort; eine zweite Meinung braucht es nicht. """ mit_hw = caps.parse_encoder_liste(HB_HILFE_MIT_HARDWARE) backends = caps.leite_backends_ab(mit_hw) assert "nvenc" in backends assert "qsv" in backends # Ohne Geräteprüfung — es gibt keine Parameter mehr, die das verhindern assert caps.leite_backends_ab(mit_hw) == backends def test_hardware_wird_nach_familie_unterschieden(): """Vorher landete alles in „vaapi" — eine AMD-Karte lief damit unter dem Intel-Namen, und das UI konnte nicht sagen, welches Preset passt.""" amd = caps.leite_backends_ab(["x265", "vce_h264", "vce_h265"]) assert "vce" in amd assert "qsv" not in amd and "nvenc" not in amd intel = caps.leite_backends_ab(["x265", "qsv_h265"]) assert "qsv" in intel and "vce" not in intel def test_hardware_av1_bekommt_eigene_kennung(): """AV1 in Hardware ist derzeit die beste Kombination aus Tempo und Dateigröße — das darf nicht in „nvenc" verschwinden, sonst kann das UI es nicht empfehlen.""" backends = caps.leite_backends_ab(["x265", "nvenc_h265", "nvenc_av1"]) assert "nvenc" in backends assert "nvenc-av1" in backends # Ohne AV1 in der Liste gibt es die Kennung auch nicht assert "nvenc-av1" not in caps.leite_backends_ab(["nvenc_h265"]) def test_simd_stufe_erkennt_die_hoechste(): assert caps.beste_simd("fpu vme de sse4_2 avx avx2") == "avx2" assert caps.beste_simd("sse4_2 avx avx2 avx512f") == "avx512f" assert caps.beste_simd("fpu vme de pse tsc sse4_2") == "sse4_2" assert caps.beste_simd("") == "unbekannt" assert caps.beste_simd(None) == "unbekannt" def test_simd_stufe_der_rippy_vm_ist_sse4_2(): """Echt gemessen auf der Rippy-VM (25.07.2026): generisches QEMU-CPU-Modell, `grep -c avx2 /proc/cpuinfo` = 0. Genau das macht Software-4K dort so lahm.""" flags_vm = ( "fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 " "clflush mmx fxsr sse sse2 syscall nx lm rep_good nopl cpuid " "pni cx16 sse4_1 sse4_2 x2apic popcnt aes hypervisor lahf_lm" ) assert caps.beste_simd(flags_vm) == "sse4_2" # --- Preset-Liste: die Namen, die HandBrake wirklich kennt ------------------- # Wörtlich aus `HandBrakeCLI --preset-list` im Worker-Image (26.07.2026, # HandBrake 1.6.1) — gekürzt auf je zwei Presets pro Kategorie, Struktur und # Einrückung unverändert. Die zwei Logzeilen oben stehen dort wirklich mit # drin (HandBrake schreibt sie in denselben Strom) und müssen wegfallen. HB_PRESETS_ECHT = """[10:26:05] Compile-time hardening features are enabled [10:26:05] qsv: not available on this system Cannot load libnvidia-encode.so.1 General/ Very Fast 2160p60 4K AV1 AV1 video (up to 2160p60) and AAC stereo audio, in an MP4 container. Super HQ 1080p30 Surround High quality H.264 video (up to 1080p30) and high bit rate AAC surround audio, in an MP4 container. Matroska/ H.265 MKV 2160p60 4K H.265 video (up to 2160p60) and surround audio, in an MKV container. H.265 MKV 1080p30 H.265 video (up to 1080p30) and surround audio, in an MKV container. Hardware/ AV1 QSV 2160p 4K AV1 video (up to 2160p) and surround audio, in an MP4 container. H.265 VCN 2160p 4K H.265 video (up to 2160p) and surround audio, in an MP4 container. CLI Defaults/ CLI Default """ def test_preset_liste_kommt_aus_der_einrueckung(): presets = caps.parse_preset_liste(HB_PRESETS_ECHT) assert presets == [ "Very Fast 2160p60 4K AV1", "Super HQ 1080p30 Surround", "H.265 MKV 2160p60 4K", "H.265 MKV 1080p30", "AV1 QSV 2160p 4K", "H.265 VCN 2160p 4K", "CLI Default", ] def test_preset_liste_nimmt_keine_beschreibung_und_kein_log(): """Beschreibungen (8 Leerzeichen), Kategorien (0) und HandBrakes eigene Logzeilen (0) dürfen nicht als Preset-Namen durchgehen.""" presets = caps.parse_preset_liste(HB_PRESETS_ECHT) assert not any(p.endswith("/") for p in presets) assert not any("container" in p for p in presets) assert not any(p.startswith("[") for p in presets) assert "Cannot load libnvidia-encode.so.1" not in presets def test_preset_liste_leer_bleibt_leer(): assert caps.parse_preset_liste("") == [] assert caps.parse_preset_liste(None) == [] def test_hardware_presets_stehen_auch_ohne_hardware_in_der_liste(): """Richtigstellung zum SAVEPOINT v3.16: Dort galt es als unmöglich, die Hardware-Preset-Namen auf der Rippy-VM zu ermitteln, weil dort kein Hardware-Encoder läuft. Die Messung sagt das Gegenteil — `--preset-list` nennt sie, `--help` nennt nur die nutzbaren Encoder. Zwei Fragen, zwei Quellen.""" presets = caps.parse_preset_liste(HB_PRESETS_ECHT) assert "H.265 VCN 2160p 4K" in presets # AMD, aus der VM-Liste assert "AV1 QSV 2160p 4K" in presets # Intel, aus der VM-Liste # ... und dieselbe Maschine meldet trotzdem KEINEN Hardware-Encoder: assert caps.leite_backends_ab(caps.parse_encoder_liste(HB_HILFE_ECHT)) == [ "cpu-x264", "cpu-x265", "cpu-av1", ]