Files
codex/.github/scripts/test_bazel_target_lists.py
2026-06-09 17:42:53 +00:00

152 lines
5.1 KiB
Python

#!/usr/bin/env python3
import json
import os
import subprocess
import unittest
from pathlib import Path
from tempfile import TemporaryDirectory
REPO_ROOT = Path(__file__).resolve().parents[2]
RELEASE_SCRIPT = REPO_ROOT / "scripts" / "list-bazel-release-targets.sh"
CLIPPY_SCRIPT = REPO_ROOT / "scripts" / "list-bazel-clippy-targets.sh"
class BazelTargetListsTest(unittest.TestCase):
def run_selector(
self,
script: Path,
*args: str,
production_targets: tuple[str, ...] = (
"//codex-rs/cli:codex",
"//codex-rs/core:core",
),
test_targets: tuple[str, ...] = (
"//codex-rs/core:core-unit-tests-bin",
"//codex-rs/core:core-all-test-bin",
"//codex-rs/core:core-all-test-windows-cross-bin",
),
fail_query_containing: str = "",
) -> tuple[subprocess.CompletedProcess[str], list[list[str]]]:
with TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
query_log = temp_path / "queries.jsonl"
fake_query = temp_path / "fake-bazel-query.py"
fake_query.write_text(
"""#!/usr/bin/env python3
import json
import os
import sys
from pathlib import Path
with Path(os.environ["QUERY_LOG"]).open("a", encoding="utf-8") as query_log:
query_log.write(json.dumps(sys.argv[1:]) + "\\n")
query = sys.argv[-1]
if os.environ["FAIL_QUERY_CONTAINING"] and os.environ["FAIL_QUERY_CONTAINING"] in query:
raise SystemExit("injected query failure")
if "rust_(binary|library|proc_macro) rule" in query:
print(os.environ["PRODUCTION_TARGETS"])
elif "rust_test rule" in query:
print(os.environ["TEST_TARGETS"])
else:
raise SystemExit(f"unexpected query: {query}")
""",
encoding="utf-8",
)
fake_query.chmod(0o755)
env = os.environ.copy()
env.update(
{
"CODEX_BAZEL_QUERY_SCRIPT": str(fake_query),
"FAIL_QUERY_CONTAINING": fail_query_containing,
"PRODUCTION_TARGETS": "\n".join(production_targets),
"QUERY_LOG": str(query_log),
"TEST_TARGETS": "\n".join(test_targets),
}
)
result = subprocess.run(
["bash", str(script), *args],
cwd=REPO_ROOT,
env=env,
check=False,
capture_output=True,
text=True,
)
queries = [
json.loads(line)
for line in query_log.read_text(encoding="utf-8").splitlines()
]
return result, queries
def test_release_targets_are_sorted_explicit_production_rules(self) -> None:
result, queries = self.run_selector(
RELEASE_SCRIPT,
production_targets=(
"//codex-rs/core:core",
"//codex-rs/cli:codex",
),
)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(
result.stdout.splitlines(),
["//codex-rs/cli:codex", "//codex-rs/core:core"],
)
self.assertEqual(len(queries), 1)
self.assertIn("rust_(binary|library|proc_macro) rule", queries[0][-1])
self.assertIn("//visibility:public", queries[0][-1])
self.assertNotIn("rust_test rule", queries[0][-1])
def test_release_targets_fail_when_discovery_is_empty(self) -> None:
result, _ = self.run_selector(RELEASE_SCRIPT, production_targets=())
self.assertNotEqual(result.returncode, 0)
self.assertIn("No Bazel release-build targets found.", result.stderr)
def test_native_clippy_adds_manual_native_test_binaries(self) -> None:
result, queries = self.run_selector(CLIPPY_SCRIPT)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(
result.stdout.splitlines(),
[
"//codex-rs/cli:codex",
"//codex-rs/core:core",
"//codex-rs/core:core-all-test-bin",
"//codex-rs/core:core-unit-tests-bin",
],
)
self.assertEqual(len(queries), 2)
self.assertIn("rust_test rule", queries[1][-1])
def test_cross_clippy_never_queries_or_returns_test_rules(self) -> None:
result, queries = self.run_selector(
CLIPPY_SCRIPT,
"--windows-cross-compile",
)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(
result.stdout.splitlines(),
["//codex-rs/cli:codex", "//codex-rs/core:core"],
)
self.assertEqual(len(queries), 1)
self.assertNotIn("rust_test rule", queries[0][-1])
def test_native_clippy_prints_nothing_when_test_discovery_fails(self) -> None:
result, queries = self.run_selector(
CLIPPY_SCRIPT,
fail_query_containing="rust_test rule",
)
self.assertNotEqual(result.returncode, 0)
self.assertEqual(result.stdout, "")
self.assertEqual(len(queries), 2)
if __name__ == "__main__":
unittest.main()