Files
codex/codex-rs/config/src/shell_environment_policy_tests.rs
Abhinav 7442f5f932 Add keyed shell environment policy filters (#34590)
## What changed

- Add `shell_environment_policy.filters`, mapping environment-variable patterns to `include` or `exclude`, while continuing to accept the legacy `exclude` and `include_only` arrays.
- Merge filter keys case-insensitively across config layers so higher-precedence entries can override individual patterns. Switching representations replaces the other representation instead of combining them.
- Reject mixed, duplicate, or malformed filter definitions in enabled layers, config writes, and reloads, while retaining the previous session configuration when a reload is invalid.
- Make config-manager reads and writes representation-aware and preserve existing formatting when updating individual policy values.

## Testing

Add coverage for parsing, schema constraints, layered merging, validation and diagnostics, config writes, override metadata, and invalid session reloads.

GitOrigin-RevId: e15464bca53e6e7ef31fcc97537fda60ed5d670a
2026-07-21 18:23:26 +00:00

110 lines
2.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn shell_environment_policy_accepts_legacy_lists_or_filters() {
let legacy: ShellEnvironmentPolicyToml = toml::from_str(
r#"
exclude = ["LEGACY_*", "SHARED_*"]
include_only = ["PATH", "HOME"]
"#,
)
.expect("legacy arrays should remain valid in config.toml");
assert_eq!(
legacy,
ShellEnvironmentPolicyToml {
exclude: Some(vec!["LEGACY_*".to_string(), "SHARED_*".to_string()]),
include_only: Some(vec!["PATH".to_string(), "HOME".to_string()]),
..Default::default()
}
);
let filtered: ShellEnvironmentPolicyToml = toml::from_str(
r#"
[filters]
"FLIP_TO_EXCLUDE" = "exclude"
"FLIP_TO_INCLUDE" = "include"
"#,
)
.expect("filters should be valid in config.toml");
assert_eq!(
filtered,
ShellEnvironmentPolicyToml {
filters: Some(BTreeMap::from([
(
"FLIP_TO_EXCLUDE".to_string(),
ShellEnvironmentPolicyFilter::Exclude,
),
(
"FLIP_TO_INCLUDE".to_string(),
ShellEnvironmentPolicyFilter::Include,
),
])),
..Default::default()
}
);
assert_eq!(
ShellEnvironmentPolicy::from(filtered),
ShellEnvironmentPolicy::from(ShellEnvironmentPolicyToml {
exclude: Some(vec!["FLIP_TO_EXCLUDE".to_string()]),
include_only: Some(vec!["FLIP_TO_INCLUDE".to_string()]),
..Default::default()
})
);
}
#[test]
fn shell_environment_policy_rejects_mixed_legacy_lists_and_filters() {
let error = toml::from_str::<ShellEnvironmentPolicyToml>(
r#"
exclude = ["LEGACY_*"]
[filters]
"CANONICAL_*" = "include"
"#,
)
.expect_err("one config layer must not mix legacy lists and filters");
assert!(
error
.to_string()
.contains("cannot mix `filters` with legacy `exclude` or `include_only`")
);
}
#[test]
fn shell_environment_policy_rejects_case_variant_filters_within_layer() {
let error = toml::from_str::<ShellEnvironmentPolicyToml>(
r#"
[filters]
"AWS_*" = "exclude"
"aws_*" = "include"
"#,
)
.expect_err("case-variant filters in one layer should be rejected");
assert!(
error
.to_string()
.contains("duplicate shell environment filter")
);
}
#[test]
fn shell_environment_policy_rejects_unicode_case_variant_filters_within_layer() {
let error = toml::from_str::<ShellEnvironmentPolicyToml>(
r#"
[filters]
"СЕКРЕТ_*" = "exclude"
"секрет_*" = "include"
"#,
)
.expect_err("Unicode case-variant filters in one layer should be rejected");
assert!(
error
.to_string()
.contains("duplicate shell environment filter")
);
}