use super::path_utils::{EXPANDUSER_HOME_TOTAL, expanduser};
use crate::stdlib::config_types::HomeDirectory;
use metrics_util::MetricKind;
use metrics_util::debugging::{DebugValue, DebuggingRecorder};
use rstest::rstest;
fn samples_for(
home: &HomeDirectory,
read_env: impl Fn(&str) -> Option<String>,
) -> Vec<(String, String, u64)> {
let recorder = DebuggingRecorder::new();
let snapshotter = recorder.snapshotter();
metrics::with_local_recorder(&recorder, || {
drop(expanduser("~/x", home, read_env));
});
snapshotter
.snapshot()
.into_vec()
.into_iter()
.filter_map(|(key, _unit, _description, value)| {
if key.kind() != MetricKind::Counter || key.key().name() != EXPANDUSER_HOME_TOTAL {
return None;
}
let label = |name: &str| {
key.key()
.labels()
.find(|label| label.key() == name)
.map(|label| label.value().to_owned())
};
let DebugValue::Counter(count) = value else {
return None;
};
Some((label("outcome")?, label("source")?, count))
})
.collect()
}
#[rstest]
#[case::explicit(HomeDirectory::Explicit("/home/a".to_owned()), "explicit")]
#[case::ambient(HomeDirectory::Ambient, "home")]
fn a_resolved_home_is_counted_against_its_source(
#[case] home: HomeDirectory,
#[case] expected_source: &str,
) {
let read_env = |key: &str| (key == "HOME").then(|| "/home/a".to_owned());
let samples = samples_for(&home, read_env);
assert_eq!(
samples,
vec![("found".to_owned(), expected_source.to_owned(), 1)],
"one sample labelled by outcome and source",
);
}
#[rstest]
#[case::missing(HomeDirectory::Missing)]
#[case::ambient_with_an_empty_reader(HomeDirectory::Ambient)]
fn an_unresolvable_home_is_counted_once(#[case] home: HomeDirectory) {
let samples = samples_for(&home, |_| None);
assert_eq!(
samples,
vec![("home_unavailable".to_owned(), "missing".to_owned(), 1)],
"the failure path adds an event, not a second sample",
);
}