import importlib.util import json import os import tempfile import unittest from pathlib import Path from types import SimpleNamespace from unittest import mock class CoreTests(unittest.TestCase): @classmethod def setUpClass(cls): cls.temp = tempfile.TemporaryDirectory() root = Path(cls.temp.name) for name in ("source", "view", "cache", "state"): (root / name).mkdir() (root / "cache" / ".pretranscode-cache").touch() os.environ.update({ "SOURCE_ROOT": str(root / "source"), "VIEW_ROOT": str(root / "view"), "CACHE_ROOT": str(root / "cache"), "STATE_ROOT": str(root / "state"), "JELLYFIN_LIBRARY_ROOT": "/library", "JELLYFIN_ORIGINAL_ROOT": "/original", "JELLYFIN_CACHE_ROOT": "/cached", }) spec = importlib.util.spec_from_file_location("pretranscode", Path(__file__).parents[1] / "pretranscode.py") cls.module = importlib.util.module_from_spec(spec) spec.loader.exec_module(cls.module) cls.root = root @classmethod def tearDownClass(cls): cls.temp.cleanup() def test_paths_are_configurable(self): m = self.module self.assertEqual(m.relative_source("/library/tv/Show/episode.mkv"), "tv/Show/episode.mkv") self.assertEqual(m.source_target("tv/Show/episode.mkv"), "/original/tv/Show/episode.mkv") self.assertTrue(m.cache_target("tv/Show/episode.mkv").startswith("/cached/files/")) def test_series_lock_key(self): m = self.module self.assertEqual(m.item_key("tv/Show/Season 1/Episode.mkv"), "series:Show") self.assertEqual(m.item_key("movies/Movie/file.mkv"), "item:movies/Movie/file.mkv") def test_fixed_codec_blacklist(self): manager = self.module.Manager() self.assertTrue(manager.incompatible({"codec": "hevc", "bit_depth": 10})) self.assertTrue(manager.incompatible({"codec": "h264", "bit_depth": 10})) self.assertFalse(manager.incompatible({"codec": "h264", "bit_depth": 8})) self.assertFalse(manager.incompatible({"codec": "av1", "bit_depth": 10})) def test_quality_filters_are_global(self): manager = self.module.Manager() sdr = manager.ffmpeg_command(Path("show.mkv"), Path("out.mkv.partial"), {}) hdr = manager.ffmpeg_command( Path("show.HDR10.mkv"), Path("out.mkv.partial"), {"color_transfer": "smpte2084"} ) self.assertTrue(any("zscale=dither=error_diffusion,format=yuv420p" in value for value in sdr)) self.assertIn("-filter_complex", sdr) self.assertIn("[video]", sdr) self.assertNotIn("-vf", sdr) self.assertIn("18", sdr) self.assertTrue(any("tonemap=tonemap=hable" in value for value in hdr)) self.assertIn("bt709", hdr) def test_probe_detects_dolby_vision_stream_metadata(self): manager = self.module.Manager() result = SimpleNamespace( returncode=0, stderr="", stdout=json.dumps({ "streams": [{ "codec_name": "h264", "profile": "High", "pix_fmt": "yuv420p", "bits_per_raw_sample": "8", "color_transfer": "bt709", "side_data_list": [{"side_data_type": "DOVI configuration record"}], }], "format": {"duration": "10.0"}, }), ) with mock.patch.object(self.module.subprocess, "run", return_value=result): details = manager.probe(Path("cached.mkv")) self.assertTrue(details["dolby_vision"]) def test_validation_rejects_inherited_dolby_vision_metadata(self): manager = self.module.Manager() output = self.root / "cache" / "invalid.mkv" output.write_bytes(b"x" * 1_000_001) details = {"codec": "h264", "bit_depth": 8, "dolby_vision": True, "duration": 10.0} with mock.patch.object(manager, "probe", return_value=details): with self.assertRaisesRegex(RuntimeError, "Dolby Vision"): manager.validate_output(Path("source.mkv"), output, 10.0) def test_cache_requires_matching_source_fingerprint(self): m = self.module manager = m.Manager() relative = "movies/Test/Test.mkv" source = self.root / "source" / relative source.parent.mkdir(parents=True, exist_ok=True) source.write_bytes(b"original") output, manifest = manager.cache_paths(relative) output.write_bytes(b"cached") manifest.write_text(json.dumps({ "relative": relative, "source_fingerprint": m.fingerprint(source), "encode_profile": m.ENCODE_PROFILE, })) self.assertTrue(manager.cache_valid(relative)) source.write_bytes(b"changed") self.assertFalse(manager.cache_valid(relative)) def test_lru_touches_only_manifest(self): m = self.module manager = m.Manager() relative = "movies/LRU/LRU.mkv" source = self.root / "source" / relative source.parent.mkdir(parents=True, exist_ok=True) source.write_bytes(b"original") output, manifest = manager.cache_paths(relative) output.write_bytes(b"cached") manifest.write_text(json.dumps({ "relative": relative, "source_fingerprint": m.fingerprint(source), "encode_profile": m.ENCODE_PROFILE, })) os.utime(output, (100, 100)) os.utime(manifest, (100, 100)) manager.touch_cache(relative) self.assertEqual(output.stat().st_mtime, 100) self.assertGreater(manifest.stat().st_mtime, 100) def test_smaller_cache_limit_evicts_oldest_content(self): m = self.module manager = m.Manager() relative = "movies/Resize/Resize.mkv" source = self.root / "source" / relative source.parent.mkdir(parents=True, exist_ok=True) source.write_bytes(b"original") output, manifest = manager.cache_paths(relative) output.write_bytes(b"cached rendition") manifest.write_text(json.dumps({ "relative": relative, "source_fingerprint": m.fingerprint(source), "encode_profile": m.ENCODE_PROFILE, })) manager.ensure_link(relative, m.cache_target(relative)) old_limit = m.CACHE_MAX_BYTES try: m.CACHE_MAX_BYTES = 1 manager.enforce_cache_limit() finally: m.CACHE_MAX_BYTES = old_limit self.assertFalse(output.exists()) self.assertEqual(os.readlink(self.root / "view" / relative), m.source_target(relative)) if __name__ == "__main__": unittest.main()