huggingface/ai-deadlines
781
1"""Status enum and git mapping: pushed + sha vs no_changes vs error."""2 3import subprocess4from datetime import date5from pathlib import Path6 7from agents.pipeline_utils import (8 conference_result_payload,9 get_agent_wall_clock_seconds,10 get_modal_conference_timeout,11 git_commit_conference,12 pipeline_result,13 push_conference_yaml,14 remote_call_error_payload,15 resolve_conference_status,16 write_conference_yaml,17)18 19CURRENT_YAML = """\20- title: Demo21 year: 202522 id: demo2523 date: January 1 - 2, 202524 start: '2025-01-01'25 end: '2025-01-02'26- title: Demo27 year: 202728 id: demo2729 date: January 1 - 2, 202730 start: '2027-01-01'31 end: '2027-01-02'32 timezone: AoE33"""34 35UPDATED_YAML = """\36- title: Demo37 year: 202538 id: demo2539 date: January 1 - 2, 202540 start: '2025-01-01'41 end: '2025-01-02'42- title: Demo43 year: 202744 id: demo2745 date: January 1 - 2, 202746 start: '2027-01-01'47 end: '2027-01-02'48 timezone: AoE49 city: Paris50"""51 52 53def _init_repo(tmp_path: Path) -> Path:54 subprocess.run(["git", "init"], cwd=tmp_path, check=True, capture_output=True)55 subprocess.run(56 ["git", "config", "user.email", "agent@test.local"],57 cwd=tmp_path,58 check=True,59 capture_output=True,60 )61 subprocess.run(62 ["git", "config", "user.name", "Test Agent"],63 cwd=tmp_path,64 check=True,65 capture_output=True,66 )67 subprocess.run(68 ["git", "config", "commit.gpgsign", "false"],69 cwd=tmp_path,70 check=True,71 capture_output=True,72 )73 return tmp_path74 75 76def test_resolve_status_does_not_collapse_error_and_timeout_to_no_changes():77 assert resolve_conference_status(pushed=True) == "pushed"78 assert resolve_conference_status(pushed=False) == "no_changes"79 assert resolve_conference_status(error="boom") == "error"80 assert resolve_conference_status(timed_out=True) == "timeout"81 assert resolve_conference_status(status="pushed") == "pushed"82 assert resolve_conference_status(status="timeout", pushed=False) == "timeout"83 84 85def test_payload_passes_commit_sha_on_pushed():86 payload = conference_result_payload(87 "neurips",88 pipeline_result(status="pushed", commit_sha="abc123", reasoning="updated"),89 )90 assert payload["status"] == "pushed"91 assert payload["commit_sha"] == "abc123"92 assert payload["conference"] == "neurips"93 94 95def test_payload_error_is_not_no_changes():96 payload = conference_result_payload(97 "aaai",98 pipeline_result(status="error", error="validation failed"),99 )100 assert payload["status"] == "error"101 assert payload["error"] == "validation failed"102 assert "commit_sha" not in payload103 104 105def test_remote_timeout_exception_maps_to_timeout():106 class FunctionTimeoutError(Exception):107 pass108 109 payload = remote_call_error_payload("ecir", FunctionTimeoutError("timeout after 3600s"))110 assert payload["status"] == "timeout"111 assert payload["conference"] == "ecir"112 113 114def test_git_commit_returns_sha(tmp_path: Path):115 repo = _init_repo(tmp_path)116 relpath = "src/data/conferences/demo.yml"117 path = repo / relpath118 write_conference_yaml(path, CURRENT_YAML)119 subprocess.run(["git", "add", relpath], cwd=repo, check=True, capture_output=True)120 subprocess.run(121 ["git", "commit", "-m", "initial"],122 cwd=repo,123 check=True,124 capture_output=True,125 )126 127 write_conference_yaml(path, UPDATED_YAML)128 sha = git_commit_conference(repo, relpath, "Update demo deadlines")129 assert sha130 assert len(sha) >= 7131 head = subprocess.run(132 ["git", "rev-parse", "HEAD"],133 cwd=repo,134 check=True,135 capture_output=True,136 text=True,137 )138 assert head.stdout.strip() == sha139 140 141def test_git_commit_nothing_to_commit_returns_none(tmp_path: Path):142 repo = _init_repo(tmp_path)143 relpath = "src/data/conferences/demo.yml"144 path = repo / relpath145 write_conference_yaml(path, CURRENT_YAML)146 subprocess.run(["git", "add", relpath], cwd=repo, check=True, capture_output=True)147 subprocess.run(148 ["git", "commit", "-m", "initial"],149 cwd=repo,150 check=True,151 capture_output=True,152 )153 154 sha = git_commit_conference(repo, relpath, "Update demo deadlines")155 assert sha is None156 157 158def test_push_conference_yaml_skip_remote_returns_pushed_and_sha(tmp_path: Path):159 repo = _init_repo(tmp_path)160 relpath = "src/data/conferences/demo.yml"161 path = repo / relpath162 write_conference_yaml(path, CURRENT_YAML)163 subprocess.run(["git", "add", relpath], cwd=repo, check=True, capture_output=True)164 subprocess.run(165 ["git", "commit", "-m", "initial"],166 cwd=repo,167 check=True,168 capture_output=True,169 )170 171 result = push_conference_yaml(172 conference_name="demo",173 updated_yaml=UPDATED_YAML,174 current_yaml=CURRENT_YAML,175 project_root=repo,176 today=date(2026, 8, 28),177 skip_remote_push=True,178 )179 assert result["status"] == "pushed"180 assert result["pushed"] is True181 assert result["commit_sha"]182 assert path.read_text(encoding="utf-8").startswith("- title: Demo")183 184 185def test_push_rejects_invalid_yaml_without_commit(tmp_path: Path):186 repo = _init_repo(tmp_path)187 result = push_conference_yaml(188 conference_name="demo",189 updated_yaml="this: [unterminated",190 current_yaml=CURRENT_YAML,191 project_root=repo,192 today=date(2026, 8, 28),193 skip_remote_push=True,194 )195 assert result["status"] == "error"196 assert result["pushed"] is False197 assert result["commit_sha"] is None198 assert not (repo / "src/data/conferences/demo.yml").exists()199 200 201def test_modal_timeout_env(monkeypatch):202 monkeypatch.delenv("MODAL_CONFERENCE_TIMEOUT", raising=False)203 assert get_modal_conference_timeout() == 3600204 monkeypatch.setenv("MODAL_CONFERENCE_TIMEOUT", "1800")205 assert get_modal_conference_timeout() == 1800206 207 208def test_agent_wall_clock_env(monkeypatch):209 monkeypatch.delenv("AGENT_WALL_CLOCK_SECONDS", raising=False)210 monkeypatch.delenv("RETRIEVAL_WALL_CLOCK_SECONDS", raising=False)211 assert get_agent_wall_clock_seconds("retrieval") == 300.0212 monkeypatch.setenv("RETRIEVAL_WALL_CLOCK_SECONDS", "240")213 assert get_agent_wall_clock_seconds("retrieval") == 240.0214 monkeypatch.setenv("RETRIEVAL_WALL_CLOCK_SECONDS", "0")215 assert get_agent_wall_clock_seconds("retrieval") is None216 