mirror of
https://github.com/openai/codex.git
synced 2026-04-25 23:24:55 +00:00
feat: introduce find_resource! macro that works with Cargo or Bazel (#8879)
To support Bazelification in https://github.com/openai/codex/pull/8875, this PR introduces a new `find_resource!` macro that we use in place of our existing logic in tests that looks for resources relative to the compile-time `CARGO_MANIFEST_DIR` env var. To make this work, we plan to add the following to all `rust_library()` and `rust_test()` Bazel rules in the project: ``` rustc_env = { "BAZEL_PACKAGE": native.package_name(), }, ``` Our new `find_resource!` macro reads this value via `option_env!("BAZEL_PACKAGE")` so that the Bazel package _of the code using `find_resource!`_ is injected into the code expanded from the macro. (If `find_resource()` were a function, then `option_env!("BAZEL_PACKAGE")` would always be `codex-rs/utils/cargo-bin`, which is not what we want.) Note we only consider the `BAZEL_PACKAGE` value when the `RUNFILES_DIR` environment variable is set at runtime, indicating that the test is being run by Bazel. In this case, we have to concatenate the runtime `RUNFILES_DIR` with the compile-time `BAZEL_PACKAGE` value to build the path to the resource. In testing this change, I discovered one funky edge case in `codex-rs/exec-server/tests/common/lib.rs` where we have to _normalize_ (but not canonicalize!) the result from `find_resource!` because the path contains a `common/..` component that does not exist on disk when the test is run under Bazel, so it must be semantically normalized using the [`path-absolutize`](https://crates.io/crates/path-absolutize) crate before it is passed to `dotslash fetch`. Because this new behavior may be non-obvious, this PR also updates `AGENTS.md` to make humans/Codex aware that this API is preferred.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use assert_cmd::Command as AssertCommand;
|
||||
use codex_core::RolloutRecorder;
|
||||
use codex_core::protocol::GitInfo;
|
||||
use codex_utils_cargo_bin::find_resource;
|
||||
use core_test_support::fs_wait;
|
||||
use core_test_support::skip_if_no_network;
|
||||
use std::time::Duration;
|
||||
@@ -12,6 +13,16 @@ use wiremock::ResponseTemplate;
|
||||
use wiremock::matchers::method;
|
||||
use wiremock::matchers::path;
|
||||
|
||||
fn repo_root() -> std::path::PathBuf {
|
||||
#[expect(clippy::expect_used)]
|
||||
find_resource!(".").expect("failed to resolve repo root")
|
||||
}
|
||||
|
||||
fn cli_responses_fixture() -> std::path::PathBuf {
|
||||
#[expect(clippy::expect_used)]
|
||||
find_resource!("tests/cli_responses_fixture.sse").expect("failed to resolve fixture path")
|
||||
}
|
||||
|
||||
/// Tests streaming chat completions through the CLI using a mock server.
|
||||
/// This test:
|
||||
/// 1. Sets up a mock server that simulates OpenAI's chat completions API
|
||||
@@ -23,6 +34,7 @@ async fn chat_mode_stream_cli() {
|
||||
skip_if_no_network!();
|
||||
|
||||
let server = MockServer::start().await;
|
||||
let repo_root = repo_root();
|
||||
let sse = concat!(
|
||||
"data: {\"choices\":[{\"delta\":{\"content\":\"hi\"}}]}\n\n",
|
||||
"data: {\"choices\":[{\"delta\":{}}]}\n\n",
|
||||
@@ -53,7 +65,7 @@ async fn chat_mode_stream_cli() {
|
||||
.arg("-c")
|
||||
.arg("model_provider=\"mock\"")
|
||||
.arg("-C")
|
||||
.arg(env!("CARGO_MANIFEST_DIR"))
|
||||
.arg(&repo_root)
|
||||
.arg("hello?");
|
||||
cmd.env("CODEX_HOME", home.path())
|
||||
.env("OPENAI_API_KEY", "dummy")
|
||||
@@ -127,6 +139,7 @@ async fn exec_cli_applies_experimental_instructions_file() {
|
||||
);
|
||||
|
||||
let home = TempDir::new().unwrap();
|
||||
let repo_root = repo_root();
|
||||
let bin = codex_utils_cargo_bin::cargo_bin("codex").unwrap();
|
||||
let mut cmd = AssertCommand::new(bin);
|
||||
cmd.arg("exec")
|
||||
@@ -140,7 +153,7 @@ async fn exec_cli_applies_experimental_instructions_file() {
|
||||
"experimental_instructions_file=\"{custom_path_str}\""
|
||||
))
|
||||
.arg("-C")
|
||||
.arg(env!("CARGO_MANIFEST_DIR"))
|
||||
.arg(&repo_root)
|
||||
.arg("hello?\n");
|
||||
cmd.env("CODEX_HOME", home.path())
|
||||
.env("OPENAI_API_KEY", "dummy")
|
||||
@@ -177,8 +190,8 @@ async fn exec_cli_applies_experimental_instructions_file() {
|
||||
async fn responses_api_stream_cli() {
|
||||
skip_if_no_network!();
|
||||
|
||||
let fixture =
|
||||
std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/cli_responses_fixture.sse");
|
||||
let fixture = cli_responses_fixture();
|
||||
let repo_root = repo_root();
|
||||
|
||||
let home = TempDir::new().unwrap();
|
||||
let bin = codex_utils_cargo_bin::cargo_bin("codex").unwrap();
|
||||
@@ -186,7 +199,7 @@ async fn responses_api_stream_cli() {
|
||||
cmd.arg("exec")
|
||||
.arg("--skip-git-repo-check")
|
||||
.arg("-C")
|
||||
.arg(env!("CARGO_MANIFEST_DIR"))
|
||||
.arg(&repo_root)
|
||||
.arg("hello?");
|
||||
cmd.env("CODEX_HOME", home.path())
|
||||
.env("OPENAI_API_KEY", "dummy")
|
||||
@@ -213,8 +226,8 @@ async fn integration_creates_and_checks_session_file() -> anyhow::Result<()> {
|
||||
let prompt = format!("echo {marker}");
|
||||
|
||||
// 3. Use the same offline SSE fixture as responses_api_stream_cli so the test is hermetic.
|
||||
let fixture =
|
||||
std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/cli_responses_fixture.sse");
|
||||
let fixture = cli_responses_fixture();
|
||||
let repo_root = repo_root();
|
||||
|
||||
// 4. Run the codex CLI and invoke `exec`, which is what records a session.
|
||||
let bin = codex_utils_cargo_bin::cargo_bin("codex").unwrap();
|
||||
@@ -222,7 +235,7 @@ async fn integration_creates_and_checks_session_file() -> anyhow::Result<()> {
|
||||
cmd.arg("exec")
|
||||
.arg("--skip-git-repo-check")
|
||||
.arg("-C")
|
||||
.arg(env!("CARGO_MANIFEST_DIR"))
|
||||
.arg(&repo_root)
|
||||
.arg(&prompt);
|
||||
cmd.env("CODEX_HOME", home.path())
|
||||
.env("OPENAI_API_KEY", "dummy")
|
||||
@@ -343,7 +356,7 @@ async fn integration_creates_and_checks_session_file() -> anyhow::Result<()> {
|
||||
cmd2.arg("exec")
|
||||
.arg("--skip-git-repo-check")
|
||||
.arg("-C")
|
||||
.arg(env!("CARGO_MANIFEST_DIR"))
|
||||
.arg(&repo_root)
|
||||
.arg(&prompt2)
|
||||
.arg("resume")
|
||||
.arg("--last");
|
||||
|
||||
Reference in New Issue
Block a user