Optionally back /tmp and /var/tmp with stable host directories

This commit is contained in:
2026-05-15 01:36:58 +02:00
parent 28e68b0fff
commit 3fb0da0577
13 changed files with 839 additions and 52 deletions
+163
View File
@@ -1066,6 +1066,169 @@ fn build_unsetenv_accumulates() {
assert_eq!(config.unsetenv, vec!["G", "P", "C"]);
}
#[test]
fn persistent_tmp_off_by_default() {
let config = build(args_with_command(), None).unwrap();
assert!(config.persistent_tmp_key.is_none());
}
#[test]
fn persistent_tmp_enabled_via_cli_derives_a_key() {
let args = Args {
persistent_tmp: true,
..args_with_command()
};
let config = build(args, None).unwrap();
let key = config.persistent_tmp_key.expect("expected derived key");
assert_eq!(key.len(), 12);
assert!(key.chars().all(|c| c.is_ascii_hexdigit()));
}
#[test]
fn persistent_tmp_enabled_via_config() {
let file_config = FileConfig {
options: Options {
persistent_tmp: Some(true),
..Options::default()
},
..FileConfig::default()
};
let config = build(args_with_command(), Some(file_config)).unwrap();
assert!(config.persistent_tmp_key.is_some());
}
#[test]
fn persistent_key_override_replaces_hash() {
let args = Args {
persistent_tmp: true,
persistent_key: Some("my-label".into()),
..args_with_command()
};
let config = build(args, None).unwrap();
assert_eq!(config.persistent_tmp_key.as_deref(), Some("my-label"));
}
#[test]
fn persistent_key_alone_is_ignored_without_persistent_tmp() {
let args = Args {
persistent_key: Some("my-label".into()),
..args_with_command()
};
let config = build(args, None).unwrap();
assert!(config.persistent_tmp_key.is_none());
}
#[test]
fn persistent_tmp_is_noop_in_blacklist_mode() {
let derived = build(
Args {
persistent_tmp: true,
blacklist: true,
..args_with_command()
},
None,
)
.unwrap();
assert!(derived.persistent_tmp_key.is_none());
let explicit = build(
Args {
persistent_tmp: true,
blacklist: true,
persistent_key: Some("explicit".into()),
..args_with_command()
},
None,
)
.unwrap();
assert!(explicit.persistent_tmp_key.is_none());
}
#[test]
fn persistent_tmp_cli_no_overrides_config() {
let file_config = FileConfig {
options: Options {
persistent_tmp: Some(true),
..Options::default()
},
..FileConfig::default()
};
let args = Args {
no_persistent_tmp: true,
..args_with_command()
};
let config = build(args, Some(file_config)).unwrap();
assert!(config.persistent_tmp_key.is_none());
}
#[test]
fn persistent_tmp_uses_leaf_profile_name() {
let file_config = FileConfig {
profiles: HashMap::from([
(
"parent".into(),
Options {
..Options::default()
},
),
(
"leaf".into(),
Options {
profile: Some("parent".into()),
persistent_tmp: Some(true),
..Options::default()
},
),
]),
..FileConfig::default()
};
let leaf_args = Args {
profile: Some("leaf".into()),
..args_with_command()
};
let parent_args = Args {
profile: Some("leaf".into()),
..args_with_command()
};
// Same profile selected: same key.
let key1 = build(leaf_args, Some(clone_file_config(&file_config)))
.unwrap()
.persistent_tmp_key
.unwrap();
let key2 = build(parent_args, Some(clone_file_config(&file_config)))
.unwrap()
.persistent_tmp_key
.unwrap();
assert_eq!(key1, key2);
// Selecting the parent directly (with persistent_tmp injected) should
// produce a different key because the leaf profile name differs.
let mut file_config2 = clone_file_config(&file_config);
file_config2
.profiles
.get_mut("parent")
.unwrap()
.persistent_tmp = Some(true);
let parent_direct = Args {
profile: Some("parent".into()),
..args_with_command()
};
let key3 = build(parent_direct, Some(file_config2))
.unwrap()
.persistent_tmp_key
.unwrap();
assert_ne!(key1, key3);
}
fn clone_file_config(src: &FileConfig) -> FileConfig {
FileConfig {
options: src.options.clone(),
profiles: src.profiles.clone(),
..FileConfig::default()
}
}
#[test]
fn build_mask_accumulates() {
let file_config = FileConfig {