SERVER-117835 fix symbol check suggested command (#47067)
GitOrigin-RevId: 68c94d6912ada19f0b87499ac8030674b9b75be0
This commit is contained in:
parent
ea24c3ae95
commit
f7c6ecd634
@ -9,6 +9,20 @@ mongo_cc_binary(
|
||||
srcs = ["unit_test.cpp"],
|
||||
)
|
||||
|
||||
# Verifies evergreen symbol-check report uses the exact bazel invocation
|
||||
# emitted by the Evergreen bazel compile script, and suggests *_with_debug targets.
|
||||
py_test(
|
||||
name = "test_generate_symbol_check_report",
|
||||
srcs = ["test_generate_symbol_check_report.py"],
|
||||
data = [
|
||||
"//evergreen:generate_symbol_check_report.py",
|
||||
],
|
||||
deps = [
|
||||
"//buildscripts:simple_report",
|
||||
"//buildscripts/util",
|
||||
],
|
||||
)
|
||||
|
||||
# Test for verifying test_wrapper.sh timeout behavior and coredump generation.
|
||||
# This test intentionally hangs to trigger the timeout mechanism in test_wrapper.sh.
|
||||
# When run via the --run_under=//bazel:test_wrapper param, it should:
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
import runpy
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
|
||||
def _repo_root_from_runfiles() -> pathlib.Path:
|
||||
test_srcdir = os.environ.get("TEST_SRCDIR")
|
||||
test_workspace = os.environ.get("TEST_WORKSPACE")
|
||||
if not test_srcdir or not test_workspace:
|
||||
raise RuntimeError(
|
||||
"Expected TEST_SRCDIR and TEST_WORKSPACE to be set by Bazel test environment"
|
||||
)
|
||||
return pathlib.Path(test_srcdir) / test_workspace
|
||||
|
||||
|
||||
class GenerateSymbolCheckReportTest(unittest.TestCase):
|
||||
def test_uses_bazel_compile_raw_invocation_and_flags(self):
|
||||
repo_root = _repo_root_from_runfiles()
|
||||
script_path = repo_root / "evergreen" / "generate_symbol_check_report.py"
|
||||
self.assertTrue(script_path.exists(), f"Missing runfile: {script_path}")
|
||||
|
||||
# Simulate the Evergreen layout:
|
||||
# - script runs with cwd=.../src
|
||||
# - expansions.yml lives one directory above cwd (../expansions.yml)
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
workdir = pathlib.Path(td)
|
||||
(workdir / "expansions.yml").write_text('run_for_symbol_check: "true"\n')
|
||||
|
||||
src = workdir / "src"
|
||||
src.mkdir(parents=True)
|
||||
|
||||
bazel_build_flags = "--config=evg --config=symbol-checker --keep_going"
|
||||
bazel_build_invocation = "bazel build --config=evg --config=symbol-checker //src/..."
|
||||
(src / ".bazel_build_flags").write_text(bazel_build_flags + "\n")
|
||||
(src / ".bazel_build_invocation").write_text(bazel_build_invocation + "\n")
|
||||
|
||||
checked_dir = src / "bazel-bin" / "buildscripts" / "bazel_testbuilds"
|
||||
checked_dir.mkdir(parents=True)
|
||||
checked_path = checked_dir / "unit_test_checked"
|
||||
checked_payload = {
|
||||
"status": "failed",
|
||||
"target": "//buildscripts/bazel_testbuilds:unit_test",
|
||||
"sym_file": "ignored.sym",
|
||||
"missing": ["some_symbol"],
|
||||
}
|
||||
checked_path.write_text(json.dumps(checked_payload))
|
||||
|
||||
old_cwd = os.getcwd()
|
||||
try:
|
||||
os.chdir(src)
|
||||
with self.assertRaises(SystemExit) as ctx:
|
||||
runpy.run_path(str(script_path), run_name="__main__")
|
||||
finally:
|
||||
os.chdir(old_cwd)
|
||||
|
||||
# With a failing _checked file, the report script should exit non-zero.
|
||||
self.assertEqual(ctx.exception.code, 1)
|
||||
|
||||
# The helper artifact should prefer the exact invocation written by bazel_compile.sh.
|
||||
self.assertEqual(
|
||||
(src / "bazel-invocation.txt").read_text().strip(), bazel_build_invocation
|
||||
)
|
||||
|
||||
# The report content should prefer the exact flags written by bazel_compile.sh.
|
||||
report = json.loads((src / "report.json").read_text())
|
||||
log_raw = report["results"][0]["log_raw"]
|
||||
expected_repro_target = checked_payload["target"] + "_with_debug"
|
||||
self.assertIn(
|
||||
f"bazel build {bazel_build_flags} {expected_repro_target}",
|
||||
log_raw,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@ -25,6 +25,10 @@ py_library(
|
||||
"oauthlib",
|
||||
group = "testing",
|
||||
),
|
||||
dependency(
|
||||
"pyyaml",
|
||||
group = "core",
|
||||
),
|
||||
dependency(
|
||||
"structlog",
|
||||
group = "evergreen",
|
||||
|
||||
@ -5,6 +5,23 @@ import sys
|
||||
from buildscripts.simple_report import make_report, put_report, try_combine_reports
|
||||
from buildscripts.util.read_config import read_config_file
|
||||
|
||||
|
||||
def _read_optional_text_file(path: str) -> str | None:
|
||||
try:
|
||||
with open(path) as f:
|
||||
content = f.read().strip()
|
||||
except OSError:
|
||||
return None
|
||||
return content or None
|
||||
|
||||
|
||||
def _with_debug_target(target: str) -> str:
|
||||
"""Symbol-check aspect emits cc_library-like targets as *_with_debug."""
|
||||
if target.endswith("_with_debug"):
|
||||
return target
|
||||
return f"{target}_with_debug"
|
||||
|
||||
|
||||
# 1. detect if we should run symbol-check reporting
|
||||
expansions = read_config_file("../expansions.yml")
|
||||
symbol_check = expansions.get("run_for_symbol_check", None)
|
||||
@ -14,6 +31,11 @@ if not symbol_check:
|
||||
|
||||
failures = []
|
||||
|
||||
# Prefer the exact Bazel flags/invocation emitted by the Evergreen Bazel compile script.
|
||||
# This script is run from the "src" directory (see evergreen/run_python_script.sh).
|
||||
bazel_build_flags = _read_optional_text_file(".bazel_build_flags")
|
||||
bazel_build_invocation = _read_optional_text_file(".bazel_build_invocation")
|
||||
|
||||
# 2. walk bazel-bin for *_checked files emitted by the aspect
|
||||
for root, _, files in os.walk("bazel-bin"):
|
||||
for name in files:
|
||||
@ -51,7 +73,11 @@ for root, _, files in os.walk("bazel-bin"):
|
||||
repro_target = target or sym_file or checked_path
|
||||
lines.append("")
|
||||
lines.append("To reproduce:")
|
||||
lines.append(f" bazel build --config=symbol-checker {repro_target}")
|
||||
repro_target = _with_debug_target(str(repro_target))
|
||||
if bazel_build_flags:
|
||||
lines.append(f" bazel build {bazel_build_flags} {repro_target}")
|
||||
else:
|
||||
lines.append(f" bazel build --config=symbol-checker {repro_target}")
|
||||
|
||||
content = "\n".join(lines)
|
||||
|
||||
@ -62,9 +88,17 @@ for root, _, files in os.walk("bazel-bin"):
|
||||
failures.append((synthetic_file, content))
|
||||
|
||||
# 3. write a helper invocation file
|
||||
# adjust this to your actual symbol-check build config if you have one
|
||||
with open("bazel-invocation.txt", "w") as f:
|
||||
f.write("bazel build --config=symbol-checker //src/...")
|
||||
if bazel_build_invocation:
|
||||
# Keep the exact command that CI ran (targets included).
|
||||
f.write(bazel_build_invocation)
|
||||
elif bazel_build_flags:
|
||||
# Fall back to the exact flags from CI (best effort on targets).
|
||||
f.write(f"bazel build {bazel_build_flags} //src/...")
|
||||
else:
|
||||
# Last-resort fallback.
|
||||
f.write("bazel build --config=symbol-checker //src/...")
|
||||
|
||||
|
||||
# 4. emit reports
|
||||
if failures:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user