"""Przebieg end-to-end bez modelu językowego. To jest smoke test całego pipeline'u: kontekst APM, adaptery, sandbox, workflow agno, weryfikacja i artefakty audytowe. Uruchamialny na runnerze bez GPU i bez internetu. """ import json import pytest from agentic_codemod.schemas import ChangeRequest, TaskType from agentic_codemod.workflow.runner import run_pipeline @pytest.fixture() def request_upgrade(acme_app): return ChangeRequest( task_type=TaskType.SDK_UPGRADE, repo_path=str(acme_app), package="acme-sdk", module_name="acme", from_version="1.4.2", to_version="2.1.0", ) def test_fixture_jest_czerwony_przed_migracja(acme_app): import subprocess proc = subprocess.run(["python3", "-m", "pytest", "-q"], cwd=acme_app, capture_output=True, text=True) assert proc.returncode != 0, "fixture musi być czerwony, inaczej test e2e niczego nie dowodzi" def test_przebieg_offline_konczy_sie_zielona_weryfikacja(request_upgrade, settings, acme_app): manifest = run_pipeline(request_upgrade, settings=settings, mode="offline", in_place=True) assert manifest.status == "success" assert manifest.verifications and manifest.verifications[-1].passed assert set(manifest.changed_files) == {"pyproject.toml", "src/acme_app/notifier.py"} assert manifest.review and manifest.review.verdict == "approve" assert "acme-sdk==2.1.0" in (acme_app / "pyproject.toml").read_text(encoding="utf-8") def test_przebieg_zapisuje_komplet_artefaktow_audytowych(request_upgrade, settings): run_pipeline(request_upgrade, settings=settings, mode="offline", in_place=True) run_dir = settings.run_dir for name in ( "run.json", "plan.json", "profile.json", "review.json", "merge_request.md", "changes.patch", "trace.jsonl", ): assert (run_dir / name).exists(), f"brak artefaktu {name}" manifest = json.loads((run_dir / "run.json").read_text(encoding="utf-8")) assert manifest["apm_context"]["skills"], "manifest musi odnotować, z jakiego kontekstu korzystał przebieg" assert manifest["run_id"] and manifest["mode"] == "offline" def test_tryb_plan_only_nie_zmienia_kodu(request_upgrade, settings, acme_app): before = (acme_app / "src/acme_app/notifier.py").read_text(encoding="utf-8") manifest = run_pipeline(request_upgrade, settings=settings, mode="offline", in_place=True, plan_only=True) assert manifest.status == "success" assert manifest.plan is not None and manifest.plan.edits assert manifest.changed_files == [] assert (acme_app / "src/acme_app/notifier.py").read_text(encoding="utf-8") == before def test_praca_na_kopii_nie_rusza_katalogu_zrodlowego(request_upgrade, settings, acme_app): before = (acme_app / "src/acme_app/notifier.py").read_text(encoding="utf-8") manifest = run_pipeline(request_upgrade, settings=settings, mode="offline", in_place=False) assert manifest.status == "success" assert (acme_app / "src/acme_app/notifier.py").read_text(encoding="utf-8") == before def test_recenzja_blokuje_gdy_weryfikacja_czerwona(request_upgrade, settings, acme_app): """Sabotujemy testy fixture'u: pipeline nie może zaraportować sukcesu.""" (acme_app / "tests" / "test_notifier.py").write_text( "def test_zawsze_czerwony():\n assert False\n", encoding="utf-8" ) settings.max_iterations = 1 manifest = run_pipeline(request_upgrade, settings=settings, mode="offline", in_place=True) assert manifest.status == "failed" assert not manifest.verifications[-1].passed