Remove test-support feature from codex-core and replace it with explicit test toggles (#11405)

## Why

`codex-core` was being built in multiple feature-resolved permutations
because test-only behavior was modeled as crate features. For a large
crate, those permutations increase compile cost and reduce cache reuse.

## Net Change

- Removed the `test-support` crate feature and related feature wiring so
`codex-core` no longer needs separate feature shapes for test consumers.
- Standardized cross-crate test-only access behind
`codex_core::test_support`.
- External test code now imports helpers from
`codex_core::test_support`.
- Underlying implementation hooks are kept internal (`pub(crate)`)
instead of broadly public.

## Outcome

- Fewer `codex-core` build permutations.
- Better incremental cache reuse across test targets.
- No intended production behavior change.
This commit is contained in:
Michael Bolin
2026-02-10 22:44:02 -08:00
committed by GitHub
parent f6dd9e37e7
commit 476c1a7160
36 changed files with 393 additions and 266 deletions
@@ -9,15 +9,10 @@ const COLLABORATION_MODE_DEFAULT: &str =
const KNOWN_MODE_NAMES_PLACEHOLDER: &str = "{{KNOWN_MODE_NAMES}}";
const REQUEST_USER_INPUT_AVAILABILITY_PLACEHOLDER: &str = "{{REQUEST_USER_INPUT_AVAILABILITY}}";
pub(super) fn builtin_collaboration_mode_presets() -> Vec<CollaborationModeMask> {
pub(crate) fn builtin_collaboration_mode_presets() -> Vec<CollaborationModeMask> {
vec![plan_preset(), default_preset()]
}
#[cfg(any(test, feature = "test-support"))]
pub fn test_builtin_collaboration_mode_presets() -> Vec<CollaborationModeMask> {
builtin_collaboration_mode_presets()
}
fn plan_preset() -> CollaborationModeMask {
CollaborationModeMask {
name: ModeKind::Plan.display_name().to_string(),
+41 -20
View File
@@ -336,9 +336,8 @@ impl ModelsManager {
}
}
#[cfg(any(test, feature = "test-support"))]
/// Construct a manager with a specific provider for testing.
pub fn with_provider(
pub(crate) fn with_provider_for_tests(
codex_home: PathBuf,
auth_manager: Arc<AuthManager>,
provider: ModelProviderInfo,
@@ -355,9 +354,8 @@ impl ModelsManager {
}
}
#[cfg(any(test, feature = "test-support"))]
/// Get model identifier without consulting remote state or cache.
pub fn get_model_offline(model: Option<&str>) -> String {
pub(crate) fn get_model_offline_for_tests(model: Option<&str>) -> String {
if let Some(model) = model {
return model.to_string();
}
@@ -370,9 +368,11 @@ impl ModelsManager {
.unwrap_or_default()
}
#[cfg(any(test, feature = "test-support"))]
/// Build `ModelInfo` without consulting remote state or cache.
pub fn construct_model_info_offline(model: &str, config: &Config) -> ModelInfo {
pub(crate) fn construct_model_info_offline_for_tests(
model: &str,
config: &Config,
) -> ModelInfo {
model_info::with_config_overrides(model_info::model_info_from_slug(model), config)
}
}
@@ -482,8 +482,11 @@ mod tests {
let auth_manager =
AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing());
let provider = provider_for(server.uri());
let manager =
ModelsManager::with_provider(codex_home.path().to_path_buf(), auth_manager, provider);
let manager = ModelsManager::with_provider_for_tests(
codex_home.path().to_path_buf(),
auth_manager,
provider,
);
manager
.refresh_available_models(&config, RefreshStrategy::OnlineIfUncached)
@@ -536,8 +539,11 @@ mod tests {
let auth_manager =
AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing());
let provider = provider_for(server.uri());
let manager =
ModelsManager::with_provider(codex_home.path().to_path_buf(), auth_manager, provider);
let manager = ModelsManager::with_provider_for_tests(
codex_home.path().to_path_buf(),
auth_manager,
provider,
);
manager
.refresh_available_models(&config, RefreshStrategy::OnlineIfUncached)
@@ -580,8 +586,11 @@ mod tests {
let auth_manager =
AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing());
let provider = provider_for(server.uri());
let manager =
ModelsManager::with_provider(codex_home.path().to_path_buf(), auth_manager, provider);
let manager = ModelsManager::with_provider_for_tests(
codex_home.path().to_path_buf(),
auth_manager,
provider,
);
manager
.refresh_available_models(&config, RefreshStrategy::OnlineIfUncached)
@@ -646,8 +655,11 @@ mod tests {
let auth_manager =
AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing());
let provider = provider_for(server.uri());
let manager =
ModelsManager::with_provider(codex_home.path().to_path_buf(), auth_manager, provider);
let manager = ModelsManager::with_provider_for_tests(
codex_home.path().to_path_buf(),
auth_manager,
provider,
);
manager
.refresh_available_models(&config, RefreshStrategy::OnlineIfUncached)
@@ -712,8 +724,11 @@ mod tests {
let auth_manager =
AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing());
let provider = provider_for(server.uri());
let mut manager =
ModelsManager::with_provider(codex_home.path().to_path_buf(), auth_manager, provider);
let mut manager = ModelsManager::with_provider_for_tests(
codex_home.path().to_path_buf(),
auth_manager,
provider,
);
manager.cache_manager.set_ttl(Duration::ZERO);
manager
@@ -784,8 +799,11 @@ mod tests {
AuthCredentialsStoreMode::File,
));
let provider = provider_for(server.uri());
let manager =
ModelsManager::with_provider(codex_home.path().to_path_buf(), auth_manager, provider);
let manager = ModelsManager::with_provider_for_tests(
codex_home.path().to_path_buf(),
auth_manager,
provider,
);
manager
.refresh_available_models(&config, RefreshStrategy::Online)
@@ -811,8 +829,11 @@ mod tests {
let auth_manager =
AuthManager::from_auth_for_testing(CodexAuth::from_api_key("Test API Key"));
let provider = provider_for("http://example.test".to_string());
let mut manager =
ModelsManager::with_provider(codex_home.path().to_path_buf(), auth_manager, provider);
let mut manager = ModelsManager::with_provider_for_tests(
codex_home.path().to_path_buf(),
auth_manager,
provider,
);
manager.local_models = Vec::new();
let hidden_model = remote_model_with_visibility("hidden", "Hidden", 0, "hide");
-3
View File
@@ -4,9 +4,6 @@ pub mod manager;
pub mod model_info;
pub mod model_presets;
#[cfg(any(test, feature = "test-support"))]
pub use collaboration_mode_presets::test_builtin_collaboration_mode_presets;
/// Convert the client version string to a whole version string (e.g. "1.2.3-alpha.4" -> "1.2.3").
pub fn client_version_to_whole() -> String {
format!(
@@ -11,7 +11,7 @@ pub const HIDE_GPT5_1_MIGRATION_PROMPT_CONFIG: &str = "hide_gpt5_1_migration_pro
pub const HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG: &str =
"hide_gpt-5.1-codex-max_migration_prompt";
static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
pub(crate) static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
vec![
ModelPreset {
id: "gpt-5.2-codex".to_string(),
@@ -359,11 +359,6 @@ pub(super) fn builtin_model_presets(_auth_mode: Option<AuthMode>) -> Vec<ModelPr
PRESETS.iter().cloned().collect()
}
#[cfg(any(test, feature = "test-support"))]
pub fn all_model_presets() -> &'static Vec<ModelPreset> {
&PRESETS
}
#[cfg(test)]
mod tests {
use super::*;