import hashlib from id_configurator.config import Configuration from id_configurator.context import Context from id_configurator.modules.apk import ApkModule KEY_BYTES = b"fake-apk-key-bytes" KEY_FILENAME = f"{hashlib.sha256(KEY_BYTES).hexdigest()[:16]}.rsa.pub" CONFIG_DATA = { "uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode", "configurations": { "apk": { "repositories": [ { "name": "main", "url": "https://example.invalid/v3.19/main", "key": KEY_BYTES, }, {"name": "community", "url": "https://example.invalid/v3.19/community"}, ] } }, } def make_config() -> Configuration: return Configuration.model_validate(CONFIG_DATA) def test_is_relevant_false_without_src(tmp_path) -> None: context = Context(config=make_config(), dst=tmp_path / "dst", src=None) assert ApkModule().is_relevant(context) is False def test_is_relevant_false_without_apk_dir(tmp_path) -> None: src = tmp_path / "src" src.mkdir() context = Context(config=make_config(), dst=tmp_path / "dst", src=src) assert ApkModule().is_relevant(context) is False def test_is_relevant_true_with_apk_dir(tmp_path) -> None: src = tmp_path / "src" (src / "etc/apk").mkdir(parents=True) context = Context(config=make_config(), dst=tmp_path / "dst", src=src) assert ApkModule().is_relevant(context) is True def test_apply_copies_existing_repositories_unchanged_without_url_to_replace( tmp_path, ) -> None: src = tmp_path / "src" apk_dir = src / "etc/apk" apk_dir.mkdir(parents=True) (apk_dir / "repositories").write_text( "# comment\nhttps://old-mirror.invalid/v3.18/main\nhttps://old-mirror.invalid/v3.18/community\n", encoding="utf-8", ) dst = tmp_path / "dst" context = Context(config=make_config(), dst=dst, src=src) ApkModule().apply(context) # No configured repository declares a url_to_replace, so the existing # lines are copied through unchanged, still active. content = (dst / "etc/apk/repositories").read_text(encoding="utf-8") assert content == ( "# comment\n" "https://old-mirror.invalid/v3.18/main\n" "https://old-mirror.invalid/v3.18/community\n" "https://example.invalid/v3.19/main\n" "https://example.invalid/v3.19/community\n" ) key_content = (dst / "etc/apk/keys" / KEY_FILENAME).read_bytes() assert key_content == KEY_BYTES def test_apply_disables_only_existing_lines_matching_url_to_replace(tmp_path) -> None: src = tmp_path / "src" apk_dir = src / "etc/apk" apk_dir.mkdir(parents=True) (apk_dir / "repositories").write_text( "https://old-mirror.invalid/v3.18/main\nhttps://old-mirror.invalid/v3.18/community\n", encoding="utf-8", ) data = { "uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode", "configurations": { "apk": { "repositories": [ { "name": "main", "url": "https://example.invalid/v3.19/main", "url_to_replace": "https://old-mirror.invalid/v3.18/main", } ] } }, } dst = tmp_path / "dst" context = Context(config=Configuration.model_validate(data), dst=dst, src=src) ApkModule().apply(context) content = (dst / "etc/apk/repositories").read_text(encoding="utf-8") assert content == ( "# https://old-mirror.invalid/v3.18/main\n" "https://old-mirror.invalid/v3.18/community\n" "https://example.invalid/v3.19/main\n" ) def test_apply_without_existing_repositories_file(tmp_path) -> None: src = tmp_path / "src" (src / "etc/apk").mkdir(parents=True) dst = tmp_path / "dst" context = Context(config=make_config(), dst=dst, src=src) ApkModule().apply(context) content = (dst / "etc/apk/repositories").read_text(encoding="utf-8") assert ( content == "https://example.invalid/v3.19/main\nhttps://example.invalid/v3.19/community\n" ) def test_apply_skips_repository_when_url_to_replace_matches_nothing(tmp_path) -> None: src = tmp_path / "src" apk_dir = src / "etc/apk" apk_dir.mkdir(parents=True) (apk_dir / "repositories").write_text( "https://old-mirror.invalid/v3.18/main\n", encoding="utf-8" ) data = { "uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode", "configurations": { "apk": { "repositories": [ { "name": "main", "url": "https://example.invalid/v3.19/main", "url_to_replace": "https://other.invalid/*", } ] } }, } dst = tmp_path / "dst" context = Context(config=Configuration.model_validate(data), dst=dst, src=src) ApkModule().apply(context) content = (dst / "etc/apk/repositories").read_text(encoding="utf-8") assert "example.invalid" not in content def test_apply_writes_repository_when_url_to_replace_matches_existing(tmp_path) -> None: src = tmp_path / "src" apk_dir = src / "etc/apk" apk_dir.mkdir(parents=True) (apk_dir / "repositories").write_text( "https://old-mirror.invalid/v3.18/main\n", encoding="utf-8" ) data = { "uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode", "configurations": { "apk": { "repositories": [ { "name": "main", "url": "https://example.invalid/v3.19/main", "url_to_replace": "https://old-mirror.invalid/*", } ] } }, } dst = tmp_path / "dst" context = Context(config=Configuration.model_validate(data), dst=dst, src=src) ApkModule().apply(context) content = (dst / "etc/apk/repositories").read_text(encoding="utf-8") assert "https://example.invalid/v3.19/main" in content def test_apply_reuses_cached_existing_urls_and_handles_missing_file(tmp_path) -> None: src = tmp_path / "src" (src / "etc/apk").mkdir(parents=True) data = { "uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode", "configurations": { "apk": { "repositories": [ { "name": "main", "url": "https://example.invalid/v3.19/main", "url_to_replace": "https://old.invalid/*", }, { "name": "community", "url": "https://example.invalid/v3.19/community", "url_to_replace": "https://old.invalid/*", }, ] } }, } dst = tmp_path / "dst" context = Context(config=Configuration.model_validate(data), dst=dst, src=src) ApkModule().apply(context) assert not (dst / "etc/apk/repositories").exists() def test_apply_writes_nothing_when_no_repositories_at_all(tmp_path) -> None: empty_config = Configuration.model_validate( {"uuid": "12345678-1234-5678-1234-567812345678", "organisation": "InterDiode"} ) src = tmp_path / "src" (src / "etc/apk").mkdir(parents=True) dst = tmp_path / "dst" context = Context(config=empty_config, dst=dst, src=src) ApkModule().apply(context) assert not (dst / "etc/apk/repositories").exists()