Files
codex/codex-rs/config/src/cloud_config_bundle_tests.rs
T
joeflorencio-openai d45cd26248 Switch runtime to cloud config bundle (#24622)
## Summary

- Adapts the moved `codex-cloud-config` crate from the legacy cloud
requirements endpoint to the new config bundle endpoint.
- Switches runtime consumers from `CloudRequirementsLoader` to
`CloudConfigBundleLoader` so one shared bundle supplies cloud-delivered
config and requirements.
- Removes the legacy cloud requirements domain loader path.

## Details

This intentionally keeps `codex-cloud-config` monolithic for review
lineage: the previous PR establishes the crate move, and this PR shows
the behavior change against that moved implementation. A follow-up PR
splits the module back into focused files.

The new bundle path preserves the important cloud requirements loader
semantics where intended: account-scoped signed cache, 30 minute TTL, 5
minute refresh cadence, retry/backoff, auth recovery, and fail-closed
startup loading. The cached payload changes from a single requirements
TOML string to the backend-delivered bundle, and validation rejects
malformed config or requirements fragments before cache write/use.
2026-06-02 13:18:59 -07:00

126 lines
4.4 KiB
Rust

use super::*;
use crate::ConfigLayerSource;
use crate::ConfigRequirementsToml;
use crate::compose_requirements;
use codex_protocol::protocol::AskForApproval;
use pretty_assertions::assert_eq;
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use tempfile::tempdir;
#[tokio::test]
async fn shared_future_runs_once() {
let counter = Arc::new(AtomicUsize::new(0));
let counter_clone = Arc::clone(&counter);
let loader = CloudConfigBundleLoader::new(async move {
counter_clone.fetch_add(1, Ordering::SeqCst);
Ok(Some(CloudConfigBundle::default()))
});
let (first, second) = tokio::join!(loader.get(), loader.get());
assert_eq!(first, second);
assert_eq!(counter.load(Ordering::SeqCst), 1);
}
#[test]
fn bundle_layers_preserve_enterprise_managed_bucket_order() {
let tempdir = tempdir().expect("tempdir");
let base_dir = AbsolutePathBuf::from_absolute_path(tempdir.path()).expect("absolute path");
let layers = CloudConfigBundleLayers::from_bundle(
CloudConfigBundle {
config_toml: CloudConfigTomlBundle {
enterprise_managed: vec![
CloudConfigFragment {
id: "cfg_high".to_string(),
name: "High config".to_string(),
contents: "model = \"high\"".to_string(),
},
CloudConfigFragment {
id: "cfg_low".to_string(),
name: "Low config".to_string(),
contents: "model = \"low\"".to_string(),
},
],
},
requirements_toml: CloudRequirementsTomlBundle {
enterprise_managed: vec![
CloudRequirementsFragment {
id: "req_high".to_string(),
name: "High requirements".to_string(),
contents: "allowed_approval_policies = [\"on-request\"]".to_string(),
},
CloudRequirementsFragment {
id: "req_low".to_string(),
name: "Low requirements".to_string(),
contents: "allowed_approval_policies = [\"never\"]".to_string(),
},
],
},
},
&base_dir,
)
.expect("bundle should be converted into layers");
assert_eq!(
layers
.enterprise_managed_config
.iter()
.map(|layer| layer.name.clone())
.collect::<Vec<_>>(),
vec![
ConfigLayerSource::EnterpriseManaged {
id: "cfg_low".to_string(),
name: "Low config".to_string(),
},
ConfigLayerSource::EnterpriseManaged {
id: "cfg_high".to_string(),
name: "High config".to_string(),
},
]
);
assert_eq!(
compose_requirements(layers.enterprise_managed_requirements)
.expect("requirements should compose")
.expect("requirements should be present")
.into_toml(),
ConfigRequirementsToml {
allowed_approval_policies: Some(vec![AskForApproval::OnRequest]),
..Default::default()
}
);
}
#[test]
fn bundle_layers_can_strict_validate_enterprise_managed_config() {
let tempdir = tempdir().expect("tempdir");
let base_dir = AbsolutePathBuf::from_absolute_path(tempdir.path()).expect("absolute path");
let err = CloudConfigBundleLayers::from_bundle_strict_config(
CloudConfigBundle {
config_toml: CloudConfigTomlBundle {
enterprise_managed: vec![CloudConfigFragment {
id: "cfg".to_string(),
name: "Cloud config".to_string(),
contents: "unknown_key = true".to_string(),
}],
},
requirements_toml: CloudRequirementsTomlBundle {
enterprise_managed: Vec::new(),
},
},
&base_dir,
)
.expect_err("strict config should reject unknown fields");
assert_eq!(
err,
CloudConfigLayerError::Invalid {
fragment: crate::CloudConfigFragmentSource {
id: "cfg".to_string(),
name: "Cloud config".to_string(),
},
message: "unknown configuration field `unknown_key`".to_string(),
}
);
}