#!/usr/bin/env python3 """Testy: samodzielne czytanie build.conf + publikowanie luźnego klienta pag.""" import importlib.machinery, importlib.util, json, os, io, tarfile, tempfile, hashlib, shutil HERE = os.path.dirname(os.path.abspath(__file__)) # Lokalnie obok testu; na serwerze fallback do zainstalowanej kopii. _PAGSYNC = os.path.join(HERE, "pagsync") if not os.path.isfile(_PAGSYNC): _PAGSYNC = "/opt/pagan-web-v2/pagsync" loader = importlib.machinery.SourceFileLoader("pagsync_mod", _PAGSYNC) spec = importlib.util.spec_from_loader("pagsync_mod", loader) mod = importlib.util.module_from_spec(spec) loader.exec_module(mod) def test_build_conf(): for k in ("PAGAN_DO_SIGN", "PAGAN_GPG_KEY", "PAGAN_TEST_XX"): os.environ.pop(k, None) conf = tempfile.NamedTemporaryFile("w", delete=False, suffix=".conf") conf.write("# komentarz\nPAGAN_DO_SIGN=1\nexport PAGAN_GPG_KEY='AABBCC'\nPAGAN_TEST_XX=abc\n") conf.close() mod._load_build_conf(conf.name) os.unlink(conf.name) assert os.environ.get("PAGAN_DO_SIGN") == "1", os.environ.get("PAGAN_DO_SIGN") assert os.environ.get("PAGAN_GPG_KEY") == "AABBCC", os.environ.get("PAGAN_GPG_KEY") assert os.environ.get("PAGAN_TEST_XX") == "abc" # nie nadpisuje już ustawionych os.environ["PAGAN_TEST_XX"] = "keep" conf2 = tempfile.NamedTemporaryFile("w", delete=False, suffix=".conf") conf2.write("PAGAN_TEST_XX=override\n") conf2.close() mod._load_build_conf(conf2.name) os.unlink(conf2.name) assert os.environ["PAGAN_TEST_XX"] == "keep" for k in ("PAGAN_DO_SIGN", "PAGAN_GPG_KEY", "PAGAN_TEST_XX"): os.environ.pop(k, None) print("✅ build.conf: wczytuje, honoruje 'export', nie nadpisuje istniejących") def _make_pag(path, pag_content): inner = io.BytesIO() with tarfile.open(fileobj=inner, mode="w:xz") as tf: data = pag_content ti = tarfile.TarInfo("./usr/bin/pag") ti.size = len(data) tf.addfile(ti, io.BytesIO(data)) inner_bytes = inner.getvalue() with tarfile.open(path, "w:xz") as tf: meta = json.dumps({"name": "pag", "version": "3.3.99", "release": 1}).encode() ti = tarfile.TarInfo("metadata.json") ti.size = len(meta) tf.addfile(ti, io.BytesIO(meta)) ti2 = tarfile.TarInfo("data.tar.xz") ti2.size = len(inner_bytes) tf.addfile(ti2, io.BytesIO(inner_bytes)) def test_publish_pag_client(): tmp = tempfile.mkdtemp(prefix="pagsync-pagclient-") cat = os.path.join(tmp, "stable") os.makedirs(cat) content = b'#!/usr/bin/env python3\nPAG_VERSION = "3.3.99"\n' _make_pag(os.path.join(cat, "pag-3.3.99-1.pag"), content) # starsza paczka – ma zostać wybrana nowsza _make_pag(os.path.join(cat, "pag-3.3.10-1.pag"), b'#!/usr/bin/env python3\nPAG_VERSION = "3.3.10"\n') mod.DO_SIGN = False r = mod._publish_pag_client(cat, verbose=True) assert r, "publish zwróciło False" assert open(os.path.join(cat, "pag"), "rb").read() == content, "zła treść luźnego pag" sha = open(os.path.join(cat, "pag.sha256")).read().strip().split()[0] assert sha == hashlib.sha256(content).hexdigest(), "zły SHA256" # idempotentne: ten sam content → True bez zmian assert mod._publish_pag_client(cat, verbose=False) is True shutil.rmtree(tmp, ignore_errors=True) print("✅ publish: luźny pag z najnowszej paczki + SHA256, idempotentne") def test_real_build_conf(): """Na serwerze: moduł musi wziąć PAGAN_* z /etc/pagan/build.conf.""" conf = "/etc/pagan/build.conf" if not os.path.isfile(conf): print("⏭ brak /etc/pagan/build.conf – pomijam test z prawdziwym plikiem") return for k in ("PAGAN_DO_SIGN", "PAGAN_GPG_KEY"): os.environ.pop(k, None) mod._load_build_conf(conf) assert os.environ.get("PAGAN_DO_SIGN") == "1", os.environ.get("PAGAN_DO_SIGN") assert os.environ.get("PAGAN_GPG_KEY"), "brak klucza GPG z build.conf" print(f"✅ real build.conf: DO_SIGN={os.environ['PAGAN_DO_SIGN']} GPG={os.environ['PAGAN_GPG_KEY']}") for k in ("PAGAN_DO_SIGN", "PAGAN_GPG_KEY"): os.environ.pop(k, None) if __name__ == "__main__": test_build_conf() test_real_build_conf() test_publish_pag_client() print("🎉 Wszystkie testy przeszły.")