mirror of
https://github.com/openai/codex.git
synced 2026-09-14 11:57:03 +00:00
## Why PR #13783 moved the `codex.rs` unit tests into `codex_tests.rs`. This applies the same extraction pattern across the rest of `codex-rs/core` so the production modules stay focused on runtime code instead of large inline test blocks. Keeping the tests in sibling files also makes follow-up edits easier to review because product changes no longer have to share a file with hundreds or thousands of lines of test scaffolding. ## What changed - replaced each inline `mod tests { ... }` in `codex-rs/core/src/**` with a path-based module declaration - moved each extracted unit test module into a sibling `*_tests.rs` file, using `mod_tests.rs` for `mod.rs` modules - preserved the existing `cfg(...)` guards and module-local structure so the refactor remains structural rather than behavioral ## Testing - `cargo test -p codex-core --lib` (`1653 passed; 0 failed; 5 ignored`) - `just fix -p codex-core` - `cargo fmt --check` - `cargo shear`
107 lines
3.1 KiB
Rust
107 lines
3.1 KiB
Rust
use std::path::Path;
|
|
use std::path::PathBuf;
|
|
use std::time::Duration;
|
|
|
|
use codex_protocol::ThreadId;
|
|
use rand::Rng;
|
|
use tracing::debug;
|
|
use tracing::error;
|
|
|
|
use crate::parse_command::shlex_join;
|
|
|
|
const INITIAL_DELAY_MS: u64 = 200;
|
|
const BACKOFF_FACTOR: f64 = 2.0;
|
|
|
|
/// Emit structured feedback metadata as key/value pairs.
|
|
///
|
|
/// This logs a tracing event with `target: "feedback_tags"`. If
|
|
/// `codex_feedback::CodexFeedback::metadata_layer()` is installed, these fields are captured and
|
|
/// later attached as tags when feedback is uploaded.
|
|
///
|
|
/// Values are wrapped with [`tracing::field::DebugValue`], so the expression only needs to
|
|
/// implement [`std::fmt::Debug`].
|
|
///
|
|
/// Example:
|
|
///
|
|
/// ```rust
|
|
/// codex_core::feedback_tags!(model = "gpt-5", cached = true);
|
|
/// codex_core::feedback_tags!(provider = provider_id, request_id = request_id);
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! feedback_tags {
|
|
($( $key:ident = $value:expr ),+ $(,)?) => {
|
|
::tracing::info!(
|
|
target: "feedback_tags",
|
|
$( $key = ::tracing::field::debug(&$value) ),+
|
|
);
|
|
};
|
|
}
|
|
|
|
pub fn backoff(attempt: u64) -> Duration {
|
|
let exp = BACKOFF_FACTOR.powi(attempt.saturating_sub(1) as i32);
|
|
let base = (INITIAL_DELAY_MS as f64 * exp) as u64;
|
|
let jitter = rand::rng().random_range(0.9..1.1);
|
|
Duration::from_millis((base as f64 * jitter) as u64)
|
|
}
|
|
|
|
pub(crate) fn error_or_panic(message: impl std::string::ToString) {
|
|
if cfg!(debug_assertions) {
|
|
panic!("{}", message.to_string());
|
|
} else {
|
|
error!("{}", message.to_string());
|
|
}
|
|
}
|
|
|
|
pub(crate) fn try_parse_error_message(text: &str) -> String {
|
|
debug!("Parsing server error response: {}", text);
|
|
let json = serde_json::from_str::<serde_json::Value>(text).unwrap_or_default();
|
|
if let Some(error) = json.get("error")
|
|
&& let Some(message) = error.get("message")
|
|
&& let Some(message_str) = message.as_str()
|
|
{
|
|
return message_str.to_string();
|
|
}
|
|
if text.is_empty() {
|
|
return "Unknown error".to_string();
|
|
}
|
|
text.to_string()
|
|
}
|
|
|
|
pub fn resolve_path(base: &Path, path: &PathBuf) -> PathBuf {
|
|
if path.is_absolute() {
|
|
path.clone()
|
|
} else {
|
|
base.join(path)
|
|
}
|
|
}
|
|
|
|
/// Trim a thread name and return `None` if it is empty after trimming.
|
|
pub fn normalize_thread_name(name: &str) -> Option<String> {
|
|
let trimmed = name.trim();
|
|
if trimmed.is_empty() {
|
|
None
|
|
} else {
|
|
Some(trimmed.to_string())
|
|
}
|
|
}
|
|
|
|
pub fn resume_command(thread_name: Option<&str>, thread_id: Option<ThreadId>) -> Option<String> {
|
|
let resume_target = thread_name
|
|
.filter(|name| !name.is_empty())
|
|
.map(str::to_string)
|
|
.or_else(|| thread_id.map(|thread_id| thread_id.to_string()));
|
|
resume_target.map(|target| {
|
|
let needs_double_dash = target.starts_with('-');
|
|
let escaped = shlex_join(&[target]);
|
|
if needs_double_dash {
|
|
format!("codex resume -- {escaped}")
|
|
} else {
|
|
format!("codex resume {escaped}")
|
|
}
|
|
})
|
|
}
|
|
|
|
#[cfg(test)]
|
|
#[path = "util_tests.rs"]
|
|
mod tests;
|