Skip to content

Commit a3df28c

Browse files
committed
fix: builder default field and silly things
Signed-off-by: Andrew Chin <achin34@gatech.edu>
1 parent 88eec0e commit a3df28c

8 files changed

Lines changed: 126 additions & 33 deletions

File tree

oss-crs-infra/builder-sidecar/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def health():
8888
async def submit_build(
8989
patch: UploadFile = File(...),
9090
crs_name: str = Form(...),
91-
builder_name: str = Form(...),
91+
builder_name: str = Form(""),
9292
rebuild_id: int = Form(None),
9393
cpuset: str = Form(""),
9494
mem_limit: str = Form(""),

oss_crs/src/env_policy.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ def build_run_service_env(
176176
"OSS_CRS_SUBMIT_DIR": "/OSS_CRS_SUBMIT_DIR",
177177
"OSS_CRS_SHARED_DIR": "/OSS_CRS_SHARED_DIR",
178178
"OSS_CRS_LOG_DIR": "/OSS_CRS_LOG_DIR",
179+
"BUILDER_MODULE": "builder-sidecar",
179180
}
180181
if harness:
181182
system_env["OSS_CRS_TARGET_HARNESS"] = harness

oss_crs/tests/integration/fixtures/builder-sidecar-full/oss-crs/crs.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ target_build_phase:
1919
crs_run_phase:
2020
patcher:
2121
dockerfile: oss-crs/patcher.Dockerfile
22-
additional_env:
23-
BUILDER_MODULE: builder-sidecar
2422

2523
supported_target:
2624
mode:

oss_crs/tests/integration/fixtures/builder-sidecar-full/test-e2e.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ def main() -> int:
3737
fail("OSS_CRS_FETCH_DIR not set")
3838

3939
log(f"OSS_CRS_NAME={os.environ.get('OSS_CRS_NAME', '(unset)')}")
40-
log(f"BUILDER_MODULE={os.environ.get('BUILDER_MODULE', '(unset)')}")
40+
log(
41+
f"BUILDER_MODULE={os.environ.get('BUILDER_MODULE', '(unset)')} (should be framework-injected)"
42+
)
4143

4244
# --- Fetch diff from FETCH_DIR ---
4345
log("Fetching diff from FETCH_DIR...")
@@ -77,8 +79,16 @@ def main() -> int:
7779
)
7880
log(f"PASS: {harness_name} contains __llvm_profile symbols")
7981

80-
# --- Apply patch + build (default builder) ---
81-
log("Applying patch and building via Python API...")
82+
# --- Apply patch + build (no builder_name, exercises default/auto-detect) ---
83+
log("Applying patch and building via Python API (no builder_name)...")
84+
default_build_response = RESPONSE_DIR / "build-default"
85+
default_build_rc = crs.apply_patch_build(PATCH, default_build_response)
86+
if default_build_rc != 0:
87+
fail(f"Build (default builder_name) failed with exit code {default_build_rc}")
88+
log(f"Build (default) exit code: {default_build_rc}")
89+
90+
# --- Apply patch + build (explicit builder_name) ---
91+
log("Applying patch and building via Python API (builder_name=default-build)...")
8292
build_response = RESPONSE_DIR / "build"
8393
build_rc = crs.apply_patch_build(
8494
PATCH, build_response, builder_name="default-build"

oss_crs/tests/integration/fixtures/builder-sidecar-full/test-e2e.sh

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,19 @@ grep -c "__llvm_profile" "$COVERAGE_DIR/build/$HARNESS_NAME" > /dev/null 2>&1 \
4040
|| fail "$HARNESS_NAME missing __llvm_profile symbols — not coverage instrumented"
4141
log "PASS: $HARNESS_NAME contains __llvm_profile symbols"
4242

43-
# --- Apply patch + build (default builder) ---
44-
log "Applying patch and building via libCRS..."
43+
# --- Apply patch + build (no --builder-name, exercises default/auto-detect) ---
44+
log "Applying patch and building via libCRS (no --builder-name)..."
4545
log "libCRS location: $(which libCRS 2>&1)"
4646
log "OSS_CRS_NAME=$OSS_CRS_NAME"
47+
rm -rf "$RESPONSE_DIR/build-default"
48+
mkdir -p "$RESPONSE_DIR/build-default"
49+
libCRS apply-patch-build "$PATCH" "$RESPONSE_DIR/build-default" 2>&1
50+
DEFAULT_BUILD_RC=$?
51+
[ "$DEFAULT_BUILD_RC" -eq 0 ] || fail "Build (default builder_name) failed with exit code $DEFAULT_BUILD_RC"
52+
log "Build (default) exit code: $DEFAULT_BUILD_RC"
53+
54+
# --- Apply patch + build (explicit --builder-name) ---
55+
log "Applying patch and building via libCRS (--builder-name default-build)..."
4756
rm -rf "$RESPONSE_DIR/build"
4857
mkdir -p "$RESPONSE_DIR/build"
4958
libCRS apply-patch-build "$PATCH" "$RESPONSE_DIR/build" --builder-name default-build 2>&1

oss_crs/tests/integration/fixtures/builder-sidecar-lite/oss-crs/crs.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ target_build_phase:
1414
crs_run_phase:
1515
patcher:
1616
dockerfile: oss-crs/patcher.Dockerfile
17-
additional_env:
18-
BUILDER_MODULE: builder-sidecar
1917

2018
supported_target:
2119
mode:

oss_crs/tests/unit/test_env_policy.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,54 @@ def test_run_env_preserves_existing_precedence_and_system_wins() -> None:
8282
assert plan.effective_env["OSS_CRS_FETCH_DIR"] == "/OSS_CRS_FETCH_DIR"
8383
assert plan.effective_env["OSS_CRS_LLM_API_URL"] == "http://llm"
8484
assert plan.effective_env["OSS_CRS_LLM_API_KEY"] == "sk-test"
85+
assert plan.effective_env["BUILDER_MODULE"] == "builder-sidecar"
8586
assert any("ENV001" in warning for warning in plan.warnings)
87+
88+
89+
def test_run_env_injects_builder_module() -> None:
90+
"""Framework must inject BUILDER_MODULE so CRS developers don't need to set it."""
91+
plan = build_run_service_env(
92+
target_env={
93+
"engine": "libfuzzer",
94+
"architecture": "x86_64",
95+
"name": "proj",
96+
"language": "c",
97+
"repo_path": "/repo",
98+
},
99+
sanitizer="address",
100+
run_env_type="local",
101+
crs_name="crs-a",
102+
module_name="patcher",
103+
run_id="r1",
104+
cpuset="0-1",
105+
memory_limit="2G",
106+
module_additional_env=None,
107+
crs_additional_env=None,
108+
scope="test:run",
109+
)
110+
assert plan.effective_env["BUILDER_MODULE"] == "builder-sidecar"
111+
112+
113+
def test_run_env_builder_module_not_overridable_by_crs() -> None:
114+
"""BUILDER_MODULE is a system env — CRS additional_env must not override it."""
115+
plan = build_run_service_env(
116+
target_env={
117+
"engine": "libfuzzer",
118+
"architecture": "x86_64",
119+
"name": "proj",
120+
"language": "c",
121+
"repo_path": "/repo",
122+
},
123+
sanitizer="address",
124+
run_env_type="local",
125+
crs_name="crs-a",
126+
module_name="patcher",
127+
run_id="r1",
128+
cpuset="0-1",
129+
memory_limit="2G",
130+
module_additional_env=None,
131+
crs_additional_env={"BUILDER_MODULE": "custom-builder"},
132+
scope="test:run",
133+
)
134+
# System env wins — framework always controls BUILDER_MODULE
135+
assert plan.effective_env["BUILDER_MODULE"] == "builder-sidecar"

scripts/verify-patch-all.py

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
_compose_tmpdir = tempfile.mkdtemp(prefix="verify-patch-")
4040
COMPOSE = Path(_compose_tmpdir) / "compose.yaml"
4141
COMPOSE.write_text(COMPOSE_CONTENT)
42-
atexit.register(lambda: __import__("shutil").rmtree(_compose_tmpdir, ignore_errors=True))
42+
atexit.register(
43+
lambda: __import__("shutil").rmtree(_compose_tmpdir, ignore_errors=True)
44+
)
4345

4446
# Set to None to run all, or list specific benchmark names to filter.
4547
# SELECTED_BENCHMARKS = None
@@ -84,13 +86,25 @@ def get_artifacts(proj: Path, harness: str, build_id: str) -> dict | None:
8486
"""Fetch full artifacts dict via oss-crs artifacts."""
8587
try:
8688
result = subprocess.run(
87-
["uv", "run", "oss-crs", "artifacts",
88-
"--compose-file", str(COMPOSE),
89-
"--fuzz-proj-path", str(proj),
90-
"--target-harness", harness,
91-
"--build-id", build_id,
92-
"--run-id", build_id],
93-
capture_output=True, text=True, timeout=30,
89+
[
90+
"uv",
91+
"run",
92+
"oss-crs",
93+
"artifacts",
94+
"--compose-file",
95+
str(COMPOSE),
96+
"--fuzz-proj-path",
97+
str(proj),
98+
"--target-harness",
99+
harness,
100+
"--build-id",
101+
build_id,
102+
"--run-id",
103+
build_id,
104+
],
105+
capture_output=True,
106+
text=True,
107+
timeout=30,
94108
cwd=str(PROJECT_ROOT),
95109
)
96110
if result.returncode != 0:
@@ -113,9 +127,16 @@ def get_timing_from_artifacts(artifacts: dict) -> dict | None:
113127

114128

115129
def main():
116-
parser = argparse.ArgumentParser(description="Run verify-patch against CRSBench benchmarks")
117-
parser.add_argument("-n", "--limit", type=int, default=0,
118-
help="Max benchmarks to run (0 = all, default: all)")
130+
parser = argparse.ArgumentParser(
131+
description="Run verify-patch against CRSBench benchmarks"
132+
)
133+
parser.add_argument(
134+
"-n",
135+
"--limit",
136+
type=int,
137+
default=0,
138+
help="Max benchmarks to run (0 = all, default: all)",
139+
)
119140
args = parser.parse_args()
120141

121142
if not BENCHMARKS_DIR.is_dir():
@@ -124,9 +145,11 @@ def main():
124145

125146
targets = list(discover_targets(BENCHMARKS_DIR))
126147
if SELECTED_BENCHMARKS is not None:
127-
targets = [(p, h, d, pv) for p, h, d, pv in targets if p.name in SELECTED_BENCHMARKS]
148+
targets = [
149+
(p, h, d, pv) for p, h, d, pv in targets if p.name in SELECTED_BENCHMARKS
150+
]
128151
if args.limit > 0:
129-
targets = targets[:args.limit]
152+
targets = targets[: args.limit]
130153
print(f"Running {len(targets)} benchmarks\n")
131154

132155
results = []
@@ -135,9 +158,9 @@ def main():
135158
for proj, harness, diff, pov_dir in targets:
136159
name = proj.name
137160
build_id = f"vp-{name}"
138-
print(f"{'='*60}")
161+
print(f"{'=' * 60}")
139162
print(f" {name} | {harness}")
140-
print(f"{'='*60}")
163+
print(f"{'=' * 60}")
141164

142165
rc = subprocess.run(
143166
[str(SCRIPT), str(proj), harness, str(diff), str(pov_dir), str(COMPOSE)],
@@ -156,7 +179,9 @@ def main():
156179
test_s = timing.get("test", 0)
157180
print(f"\n Timing: rebuild={rebuild_s:.1f}s test={test_s:.1f}s")
158181

159-
crs_data = list(artifacts["crs"].values())[0] if artifacts.get("crs") else {}
182+
crs_data = (
183+
list(artifacts["crs"].values())[0] if artifacts.get("crs") else {}
184+
)
160185
log_paths = {}
161186
if crs_data.get("log_dir"):
162187
log_paths["crs_log_dir"] = crs_data["log_dir"]
@@ -175,28 +200,30 @@ def main():
175200
results.append((name, harness, status))
176201
print(f" -> {status}\n")
177202

178-
print(f"\n{'='*60}")
203+
print(f"\n{'=' * 60}")
179204
print(" SUMMARY")
180-
print(f"{'='*60}")
205+
print(f"{'=' * 60}")
181206
passed = sum(1 for _, _, s in results if s == "PASS")
182207
for name, harness, status in results:
183208
t = all_timings.get(name)
184209
timing_str = ""
185210
if t:
186-
timing_str = f" rebuild={t.get('rebuild',0):.1f}s test={t.get('test',0):.1f}s"
211+
timing_str = (
212+
f" rebuild={t.get('rebuild', 0):.1f}s test={t.get('test', 0):.1f}s"
213+
)
187214
print(f" {status} {name} ({harness}){timing_str}")
188215
print(f"\n {passed}/{len(results)} passed")
189216

190217
if all_timings:
191-
print(f"\n{'='*60}")
218+
print(f"\n{'=' * 60}")
192219
print(" ALL TIMINGS (JSON)")
193-
print(f"{'='*60}")
220+
print(f"{'=' * 60}")
194221
print(json.dumps(all_timings, indent=2))
195222

196223
if all_logs:
197-
print(f"\n{'='*60}")
224+
print(f"\n{'=' * 60}")
198225
print(" LOG PATHS")
199-
print(f"{'='*60}")
226+
print(f"{'=' * 60}")
200227
for name, paths in all_logs.items():
201228
print(f"\n {name}:")
202229
for key, path in paths.items():

0 commit comments

Comments
 (0)