#!/usr/bin/env python3 import json import os import subprocess import sys import unittest from pathlib import Path from tempfile import TemporaryDirectory import run_bazel_with_buildbuddy class RunBazelWithBuildBuddyTest(unittest.TestCase): def github_env( self, temp_dir: str, *, repository: str = "openai/codex", fork: bool = False, event_name: str = "pull_request", ) -> dict[str, str]: event_path = Path(temp_dir) / "event.json" event_path.write_text( json.dumps({"pull_request": {"head": {"repo": {"fork": fork}}}}), encoding="utf-8", ) return { "BUILDBUDDY_API_KEY": "token", "GITHUB_ACTIONS": "true", "GITHUB_EVENT_NAME": event_name, "GITHUB_EVENT_PATH": str(event_path), "GITHUB_REPOSITORY": repository, } def test_keyless_invocation_drops_remote_ci_configuration(self) -> None: self.assertIsNone( run_bazel_with_buildbuddy.remote_config( ["build", "--config=ci-linux", "//codex-rs/cli:codex"], {}, ) ) self.assertEqual( run_bazel_with_buildbuddy.bazel_args_with_remote_config( ["build", "--config=ci-linux", "--", "//codex-rs/cli:codex"], {}, ), ["build", "--", "//codex-rs/cli:codex"], ) def test_program_arguments_after_separator_do_not_select_or_lose_rbe(self) -> None: args = ["run", "//codex-rs/cli:codex", "--", "--config=remote"] self.assertEqual( run_bazel_with_buildbuddy.bazel_args_with_remote_config(args, {}), args, ) self.assertEqual( run_bazel_with_buildbuddy.remote_config( args, {"BUILDBUDDY_API_KEY": "fork-token"} ), "buildbuddy-generic", ) def test_upstream_push_selects_openai_rbe_before_target_separator(self) -> None: with TemporaryDirectory() as temp_dir: env = self.github_env(temp_dir, event_name="push") self.assertEqual( run_bazel_with_buildbuddy.bazel_args_with_remote_config( ["build", "--config=ci-linux", "--", "//codex-rs/cli:codex"], env, ), [ "build", "--config=buildbuddy-openai-rbe", "--remote_header=x-buildbuddy-api-key=token", "--config=ci-linux", "--", "//codex-rs/cli:codex", ], ) def test_windows_cross_ci_configuration_follows_remote_configuration(self) -> None: env = {"BUILDBUDDY_API_KEY": "fork-token"} self.assertEqual( run_bazel_with_buildbuddy.bazel_args_with_remote_config( ["build", "--config=ci-windows-cross", "//codex-rs/cli:codex"], env, ), [ "build", "--config=buildbuddy-generic-rbe", "--remote_header=x-buildbuddy-api-key=fork-token", "--config=ci-windows-cross", "//codex-rs/cli:codex", ], ) def test_query_remote_configuration_is_inserted_before_expression(self) -> None: expression = 'kind("rust_library rule", //codex-rs/...)' env = {"BUILDBUDDY_API_KEY": "fork-token"} for command in ("query", "cquery", "aquery"): with self.subTest(command=command): self.assertEqual( run_bazel_with_buildbuddy.bazel_args_with_remote_config( [ command, "--config=ci-windows-cross", "--output=label", expression, ], env, ), [ command, "--config=buildbuddy-generic-rbe", "--remote_header=x-buildbuddy-api-key=fork-token", "--config=ci-windows-cross", "--output=label", expression, ], ) def test_same_repository_pull_request_selects_openai_host(self) -> None: with TemporaryDirectory() as temp_dir: self.assertEqual( run_bazel_with_buildbuddy.remote_config( ["build", "--config=ci-v8"], self.github_env(temp_dir) ), "buildbuddy-openai-rbe", ) def test_fork_pull_request_cannot_select_openai_host(self) -> None: with TemporaryDirectory() as temp_dir: env = self.github_env(temp_dir, fork=True) self.assertEqual( run_bazel_with_buildbuddy.remote_config( ["build", "--config=ci-v8"], env ), "buildbuddy-generic-rbe", ) def test_run_in_fork_repository_cannot_select_openai_host(self) -> None: with TemporaryDirectory() as temp_dir: env = self.github_env(temp_dir, repository="contributor/codex") self.assertEqual( run_bazel_with_buildbuddy.remote_config( ["build", "--config=ci-v8"], env ), "buildbuddy-generic-rbe", ) def test_pull_request_without_readable_event_payload_fails_closed(self) -> None: for event_path in (None, "missing-event.json"): env = { "BUILDBUDDY_API_KEY": "token", "GITHUB_ACTIONS": "true", "GITHUB_EVENT_NAME": "pull_request", "GITHUB_REPOSITORY": "openai/codex", } if event_path is not None: env["GITHUB_EVENT_PATH"] = event_path with self.subTest(event_path=event_path): self.assertEqual( run_bazel_with_buildbuddy.remote_config(["build"], env), "buildbuddy-generic", ) def test_bazel_command_uses_configured_binary_locally(self) -> None: self.assertEqual( run_bazel_with_buildbuddy.bazel_command( "info", "execution_root", env={"CODEX_BAZEL_BIN": "fake-bazel"}, ), ["fake-bazel", "info", "execution_root"], ) def test_bazel_command_normalizes_github_actions_startup_options(self) -> None: env = { "BAZEL_OUTPUT_USER_ROOT": "/tmp/bazel-output", "GITHUB_ACTIONS": "true", } self.assertEqual( run_bazel_with_buildbuddy.bazel_command("build", "//codex-rs/...", env=env), [ "bazel", "--output_user_root=/tmp/bazel-output", "--noexperimental_remote_repo_contents_cache", "build", "//codex-rs/...", ], ) self.assertEqual( run_bazel_with_buildbuddy.bazel_command( "--experimental_remote_repo_contents_cache", "build", "//codex-rs/...", env=env, ), [ "bazel", "--output_user_root=/tmp/bazel-output", "--experimental_remote_repo_contents_cache", "build", "//codex-rs/...", ], ) def test_main_preserves_spaced_argument_and_child_exit_status(self) -> None: spaced_arg = ( r"--test_env=PATH=C:\Program Files\PowerShell\7;C:\Program Files\Git\bin" ) child_code = ( f"import sys; sys.exit(37 if sys.argv[1] == {spaced_arg!r} else 91)" ) env = os.environ.copy() env["CODEX_BAZEL_BIN"] = sys.executable env.pop("BAZEL_OUTPUT_USER_ROOT", None) env.pop("BUILDBUDDY_API_KEY", None) env.pop("GITHUB_ACTIONS", None) result = subprocess.run( [ sys.executable, str(Path(run_bazel_with_buildbuddy.__file__)), "-c", child_code, spaced_arg, ], env=env, check=False, capture_output=True, text=True, ) self.assertEqual(result.returncode, 37, result.stderr) if __name__ == "__main__": unittest.main()