Skip to content

Commit afa4640

Browse files
authored
Merge pull request #35 from bastoica/main
Adding Acto (SOSP'23) and Anvil (OSDI'24)
2 parents c534716 + b024b34 commit afa4640

File tree

1,237 files changed

+1084343
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,237 files changed

+1084343
-1
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
{"artifact_id": "sosp24_wasabi", "artifact_dir": "sosp24_wasabi", "artifact_readme": "sosp24_wasabi/wasabi/README.md", "artifact_url": "https://github.com/bastoica/wasabi/tree/sosp24-ae", "evaluator": "sosp24_wasabi/wasabi/_agent_eval/main.py", "expected_score": 4, "docer_env": "bastoica/ae-agent-ubuntu24.04:latest"}
1+
{"artifact_id": "sosp24_wasabi", "artifact_dir": "sosp24_wasabi", "artifact_readme": "sosp24_wasabi/wasabi/README.md", "artifact_url": "https://github.com/bastoica/wasabi/tree/sosp24-ae", "evaluator": "sosp24_wasabi/wasabi/_agent_eval/main.py", "expected_score": 4, "docer_env": "bastoica/ae-agent-ubuntu24.04:latest"}
2+
{"artifact_id": "osdi24_anvil", "artifact_dir": "osdi24_anvil", "artifact_readme": "sosp23_acto/acto/README.md", "artifact_url": "https://github.com/anvil-verifier/anvil", "evaluator": "osdi24_anvil/anvil/_agent_eval/main.py", "expected_score": 4, "docer_env": "bastoica/ae-agent-ubuntu24.04:latest"}
3+
{"artifact_id": "sosp23_acto", "artifact_dir": "sosp23_acto", "artifact_readme": "sosp23_acto/acto/README.md", "artifact_url": "https://github.com/xlab-uiuc/acto", "evaluator": "sosp23_acto/acto/_agent_eval/main.py", "expected_score": 4, "docer_env": "bastoica/ae-agent-ubuntu24.04:latest"}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env python3
2+
import sys
3+
from typing import Dict
4+
5+
from oracle_artifact_build import OracleArtifactBuild
6+
from oracle_env_setup import OracleEnvSetup
7+
from oracle_benchmark_prep import OracleBenchmarkPrep
8+
from oracle_experiment_runs import OracleExperimentRuns
9+
10+
from utils import logger
11+
12+
def main():
13+
results: Dict[str, int] = {}
14+
15+
score = 0
16+
for cls in (OracleEnvSetup, OracleArtifactBuild, OracleBenchmarkPrep, OracleExperimentRuns):
17+
checker = cls()
18+
ok = checker.run()
19+
name = cls.__name__
20+
logger.info(f"{name}: {'PASS' if ok else 'FAIL'}")
21+
if ok:
22+
results[name] = 1
23+
score += 1
24+
else:
25+
results[name] = 0
26+
27+
logger.info(f"Agent scores: {results}")
28+
return score
29+
30+
31+
if __name__ == "__main__":
32+
main()
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import os
2+
import subprocess
3+
from dataclasses import dataclass
4+
from typing import Iterable, Optional, Tuple
5+
from pathlib import Path
6+
7+
from utils import REPO_DIRS
8+
from utils import logger
9+
10+
11+
@dataclass(frozen=True)
12+
class BuildTarget:
13+
name: str
14+
repo_key: str
15+
cmd: list[str]
16+
17+
18+
BUILD_TARGETS: list[BuildTarget] = [
19+
BuildTarget(
20+
name="acto",
21+
repo_key="acto",
22+
cmd=["make", "lib"],
23+
),
24+
]
25+
26+
27+
class OracleArtifactBuild:
28+
29+
def __init__(self) -> None:
30+
self.repo_dirs = REPO_DIRS
31+
32+
def run_shell_command(
33+
self,
34+
cmd: Iterable[str],
35+
cwd: Optional[Path] = None,
36+
) -> Tuple[int, str, str]:
37+
"""
38+
Run a command and return (rc, stdout, stderr) tuple.
39+
"""
40+
try:
41+
cp = subprocess.run(
42+
cmd,
43+
stdout=subprocess.PIPE,
44+
stderr=subprocess.PIPE,
45+
text=True,
46+
cwd=str(cwd) if cwd is not None else None,
47+
)
48+
return cp.returncode, cp.stdout or "", cp.stderr or ""
49+
except FileNotFoundError:
50+
return 127, "", ""
51+
52+
def build_target(self, target: BuildTarget) -> Optional[str]:
53+
"""
54+
Build a single target using its configured repository and command.
55+
"""
56+
repo_dir = self.repo_dirs.get(target.repo_key, "")
57+
if not repo_dir:
58+
return f"{target.name} repo directory undefined"
59+
60+
repo_path = Path(os.path.expanduser(repo_dir))
61+
if not repo_path.exists():
62+
return f"{target.name} repo directory missing"
63+
64+
rc, out, err = self.run_shell_command(target.cmd, cwd=repo_path)
65+
if rc != 0:
66+
return f"{target.name} build failed (rc={rc})"
67+
68+
return None
69+
70+
def build_check(self):
71+
"""
72+
Run builds for all configured targets and collect failures.
73+
"""
74+
problems: list[str] = []
75+
for target in BUILD_TARGETS:
76+
msg = self.build_target(target)
77+
if msg:
78+
problems.append(msg)
79+
if problems:
80+
return False, "; ".join(problems)
81+
return True, ""
82+
83+
def run(self):
84+
ok, why = self.build_check()
85+
logger.info(f"Build: {'PASS' if ok else 'FAIL' + (' - ' + why if why else '')}")
86+
return ok
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env python3
2+
import sys
3+
import subprocess
4+
from pathlib import Path
5+
6+
from utils import REPO_DIRS, logger
7+
8+
9+
class OracleBenchmarkPrep:
10+
11+
def __init__(self):
12+
self.repo_root = Path(REPO_DIRS["acto"])
13+
self.expected_remote = "https://github.com/xlab-uiuc/acto.git"
14+
self.expected_branch = "anvil-dev"
15+
16+
def run_shell_command(self, cmd):
17+
"""
18+
Run a command and return (rc, stdout, stderr) tuple.
19+
"""
20+
try:
21+
cp = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
22+
return cp.returncode, (cp.stdout or "").strip(), (cp.stderr or "").strip()
23+
except FileNotFoundError as e:
24+
return 127, "", str(e)
25+
26+
def check_repo_exists(self):
27+
"""
28+
Check that repository root exists and is a git working tree.
29+
"""
30+
if not self.repo_root.is_dir():
31+
return False, f"acto: FAIL (repo) - directory not found: {self.repo_root}"
32+
33+
rc, out, err = self.run_shell_command(
34+
["git", "-C", str(self.repo_root), "rev-parse", "--is-inside-work-tree"]
35+
)
36+
if rc != 0 or out != "true":
37+
return False, f"acto: FAIL (repo) - not a git working tree: {err or out}"
38+
39+
return True, "acto: PASS (repo) - git working tree present"
40+
41+
def check_remote_origin(self):
42+
"""
43+
Check that <origin> remote matches the expected repository URL.
44+
"""
45+
rc, out, err = self.run_shell_command(
46+
["git", "-C", str(self.repo_root), "remote", "get-url", "origin"]
47+
)
48+
if rc != 0:
49+
return False, f"acto: FAIL (remote) - cannot read origin remote: {err or out}"
50+
51+
origin_url = (out or "").strip()
52+
def normalize(url: str) -> str:
53+
return url[:-4] if url.endswith(".git") else url
54+
55+
if normalize(origin_url) != normalize(self.expected_remote):
56+
return False, (
57+
"acto: FAIL (remote) - origin URL "
58+
f"{origin_url!r} does not match expected {self.expected_remote!r}"
59+
)
60+
61+
return True, f"acto: PASS (remote) - origin URL matches {self.expected_remote}"
62+
63+
def check_branch_and_head(self):
64+
"""
65+
Check that the current branch is the expected one and that the current
66+
commit resolves to a valid hash.
67+
"""
68+
rc, out, err = self.run_shell_command(
69+
["git", "-C", str(self.repo_root), "rev-parse", "--abbrev-ref", "HEAD"]
70+
)
71+
if rc != 0:
72+
return False, f"acto: FAIL (branch) - cannot read current branch: {err or out}"
73+
74+
branch = (out or "").strip()
75+
if branch != self.expected_branch:
76+
return False, f"acto: FAIL (branch) - {branch!r} != expected {self.expected_branch!r}"
77+
78+
rc, out, err = self.run_shell_command(
79+
["git", "-C", str(self.repo_root), "rev-parse", "HEAD"]
80+
)
81+
if rc != 0:
82+
return False, f"acto: FAIL (commit) - cannot read HEAD: {err or out}"
83+
84+
head = (out or "").strip()
85+
if not head:
86+
return False, "acto: FAIL (commit) - empty HEAD hash"
87+
88+
return True, f"acto: PASS (branch/commit) - {branch}@{head[:12]}"
89+
90+
def check_submodules_recursive(self):
91+
"""
92+
Check that submodules (if any) are initialized, approximating a --recursive clone.
93+
"""
94+
gitmodules = self.repo_root / ".gitmodules"
95+
if not gitmodules.exists():
96+
# No submodules configured; nothing to check
97+
return True, "acto: PASS (submodules) - no submodules configured"
98+
99+
rc, out, err = self.run_shell_command(
100+
["git", "-C", str(self.repo_root), "submodule", "status", "--recursive"]
101+
)
102+
if rc != 0:
103+
return False, f"acto: FAIL (submodules) - git submodule status failed: {err or out}"
104+
105+
# Heuristic: lines starting with '-' indicate uninitialized submodules
106+
uninitialized = [line for line in out.splitlines() if line.startswith("-")]
107+
if uninitialized:
108+
return False, (
109+
"acto: FAIL (submodules) - uninitialized submodules present "
110+
"(clone may have been done without --recursive)"
111+
)
112+
113+
return True, "acto: PASS (submodules) - all submodules initialized"
114+
115+
def run(self):
116+
"""
117+
Run all repository checks and return True on overall success.
118+
"""
119+
results: list[bool] = []
120+
121+
ok, msg = self.check_repo_exists()
122+
logger.info(msg)
123+
results.append(ok)
124+
125+
ok, msg = self.check_remote_origin()
126+
logger.info(msg)
127+
results.append(ok)
128+
129+
ok, msg = self.check_branch_and_head()
130+
logger.info(msg)
131+
results.append(ok)
132+
133+
ok, msg = self.check_submodules_recursive()
134+
logger.info(msg)
135+
results.append(ok)
136+
137+
if all(results):
138+
return True
139+
140+
return False

0 commit comments

Comments
 (0)