"""Otomasyon modülü: kademe/rastgele seçim, dış test ekleme, uçtan uca kural tabanlı çalıştırma ve raporlar.""" import io import json import zipfile from collections import Counter import pytest from otomasyon import calistir, isler, katalog, modeller from otomasyon.metin import M def test_tiers(): assert modeller.tier("claude|claude-opus-5") == 1 assert modeller.tier("claude|claude-fable-5-1") == 1 assert modeller.tier("claude|claude-sonnet-5-5") == 2 assert modeller.tier("claude|claude-haiku-4-5-20251001") == 3 assert modeller.tier("claude|claude-3-opus-20240229") == 3 assert modeller.tier("openai|gpt-6-astra") == 1 assert modeller.tier("openai|gpt-5-mini") == 2 assert modeller.tier("openai|gpt-4.1-nano") == 3 assert modeller.tier("ollama|qwen2.5-coder:32b") == 1 assert modeller.tier("ollama|qwen2.5-coder:14b") == 2 assert modeller.tier("ollama|qwen2.5-coder:7b") == 3 assert modeller.tier("ollama|x:latest", {"note": "32.8B · Q4_K_M"}) == 1 assert modeller.tier("kural") == 3 def test_picker_prefers_top_tier(): pool = [{"secim": "a", "kademe": 1}, {"secim": "b", "kademe": 2}, {"secim": "c", "kademe": 3}] pk = modeller.Picker(pool, seed=1, bias=6) c = Counter(pk.pick()["secim"] for _ in range(3000)) assert c["a"] > c["b"] > c["c"] assert c["a"] / 3000 > 0.5 pk.drop("a") assert all(pk.pick()["secim"] != "a" for _ in range(50)) assert pk.pick(exclude={"b", "c"}) is None def test_metin_has_both_languages(): for k, v in M.items(): assert v.get("tr") and v.get("en"), k def test_validate_questions(): ok = [{"soru": "x?", "tip": "sayi", "cevap": 5, "belge": "a.pdf"}, {"soru": "y?", "tip": "cevapsiz"}] assert katalog.validate_questions(ok, {"a.pdf"}, False) == [] bad = [{"soru": "x?", "tip": "sayi", "cevap": "beş"}, {"soru": "", "tip": "metin"}, {"soru": "z?", "tip": "liste", "cevap": "a"}, {"soru": "w?", "tip": "metin", "cevap": "k", "belge": "yok.pdf"}] errs = katalog.validate_questions(bad, {"a.pdf"}, False) assert len(errs) == 4 @pytest.fixture() def tmp_dirs(tmp_path, monkeypatch): monkeypatch.setattr(katalog, "EXT_DIR", tmp_path / "testler") monkeypatch.setattr(isler, "JOBS_DIR", tmp_path / "isler") return tmp_path def _sample_zip() -> bytes: csv = "İl;2023;2024\nAnkara;1.234,5;1.300,0\nİzmir;980,0;1.010,5\nToplam;2.214,5;2.310,5\n" qs = {"sorular": [ {"soru": "Ankara'nın 2024 değeri nedir?", "tip": "sayi", "cevap": 1300.0, "belge": "iller.csv"}, {"soru": "2024'te en yüksek değere sahip il hangisidir?", "tip": "metin", "cevap": "Ankara", "belge": "iller.csv"}, {"soru": "Bursa'nın 2024 değeri nedir?", "tip": "cevapsiz", "belge": "iller.csv"}]} buf = io.BytesIO() with zipfile.ZipFile(buf, "w") as z: z.writestr("paket/iller.csv", csv.encode("utf-8")) z.writestr("paket/sorular.json", json.dumps(qs, ensure_ascii=False)) z.writestr("paket/test.json", json.dumps({"ad": "İl değerleri", "aciklama": "küçük CSV testi"})) return buf.getvalue() def test_add_external_and_run_end_to_end(tmp_dirs): test, errs = katalog.add_external_test("", "", False, zip_bytes=_sample_zip()) assert errs == [] and test is not None assert test.name() == "İl değerleri" and test.n_docs() == 1 and len(test.questions()) == 3 assert any(x.key == test.key for x in katalog.all_tests()) spec = {"ad": "birim testi", "testler": [test.key, "pilot"], "kip": "single", "model": "kural", "modeller": [], "havuz": {}, "ust_agirlik": 6, "sinir": 4, "tohum": 1, "kendini_duzeltme": True, "max_deneme": 3, "yedek": True, "diller": ["tr", "en"], "bicimler": ["html", "pdf"]} d = isler.create_job(spec) calistir.main(d) st = isler.read_status(d) assert st["faz"] == "bitti", st.get("hata") assert [u["durum"] for u in st["birimler"]] == ["bitti", "bitti"] u = st["birimler"][0] assert u["yapilan"] == 3 for k in ("tr_html", "tr_pdf", "en_html", "en_pdf"): p = d / u["klasor"] / u["raporlar"][k] assert p.exists() and p.stat().st_size > 1000 assert (d / "genel_rapor_tr.pdf").read_bytes()[:4] == b"%PDF" assert "İl değerleri" in (d / "genel_rapor_tr.html").read_text(encoding="utf-8") z = zipfile.ZipFile(d / "tum_raporlar.zip") assert sum(n.endswith(".pdf") for n in z.namelist()) == 6 # tek başına genel rapor: bağlantı yok; paketteki genel rapor: test raporlarına göreli bağlantı var alone = (d / "genel_rapor_tr.html").read_text(encoding="utf-8") assert "