use super::*;
#[test]
fn group_and_average_dynamic_counter_ext_keys_sum_fold() {
let mk = |lb: f64, bpf_ctr: f64, bpf_gauge: f64| {
let mut r = make_row("t", "tiny-1llc", true, 0.0);
r.ext_metrics.insert("lb_count_mc".into(), lb);
r.ext_metrics.insert("scx_x_allocs".into(), bpf_ctr);
r.ext_counter_keys.insert("lb_count_mc".into());
r.ext_counter_keys.insert("scx_x_allocs".into());
r.ext_metrics.insert("scx_x_lat_avg".into(), bpf_gauge);
r
};
let out = group_and_average_by(
&[mk(1000.0, 50.0, 4.0), mk(1000.0, 70.0, 8.0)],
LEGACY_PAIRING_DIMS,
);
assert_eq!(out.len(), 1);
let row = &out[0].row;
assert_eq!(row.ext_metrics.get("lb_count_mc").copied(), Some(2000.0));
assert_eq!(row.ext_metrics.get("scx_x_allocs").copied(), Some(120.0));
assert_eq!(row.ext_metrics.get("scx_x_lat_avg").copied(), Some(6.0));
assert!(row.ext_counter_keys.contains("lb_count_mc"));
assert!(row.ext_counter_keys.contains("scx_x_allocs"));
assert!(!row.ext_counter_keys.contains("scx_x_lat_avg"));
}
#[test]
fn group_and_average_dynamic_counter_single_run_emits_value() {
let mut r = make_row("t", "tiny-1llc", true, 0.0);
r.ext_metrics.insert("lb_count_mc".into(), 1000.0);
r.ext_counter_keys.insert("lb_count_mc".into());
let out = group_and_average_by(&[r], LEGACY_PAIRING_DIMS);
assert_eq!(out.len(), 1);
let row = &out[0].row;
assert_eq!(row.ext_metrics.get("lb_count_mc").copied(), Some(1000.0));
assert!(row.ext_counter_keys.contains("lb_count_mc"));
}
#[test]
fn group_and_average_dynamic_counter_partial_presence_sums_present_only() {
let with = |v: f64| {
let mut r = make_row("t", "tiny-1llc", true, 0.0);
r.ext_metrics.insert("scx_x_allocs".into(), v);
r.ext_counter_keys.insert("scx_x_allocs".into());
r
};
let without = make_row("t", "tiny-1llc", true, 0.0);
let out = group_and_average_by(&[with(50.0), with(70.0), without], LEGACY_PAIRING_DIMS);
assert_eq!(out.len(), 1);
let row = &out[0].row;
assert_eq!(row.ext_metrics.get("scx_x_allocs").copied(), Some(120.0));
assert!(row.ext_counter_keys.contains("scx_x_allocs"));
}
#[test]
fn gauntlet_row_ext_counter_keys_serde() {
let mut r = make_row("t", "tiny-1llc", true, 0.0);
r.ext_counter_keys.insert("lb_count_mc".into());
let json = serde_json::to_string(&r).unwrap();
assert!(
json.contains("ext_counter_keys"),
"populated set is serialized"
);
let back: GauntletRow = serde_json::from_str(&json).unwrap();
assert!(back.ext_counter_keys.contains("lb_count_mc"));
let empty = make_row("t", "tiny-1llc", true, 0.0);
let json_empty = serde_json::to_string(&empty).unwrap();
assert!(
!json_empty.contains("ext_counter_keys"),
"empty set is omitted (skip_serializing_if)"
);
let back_empty: GauntletRow = serde_json::from_str(&json_empty).unwrap();
assert!(
back_empty.ext_counter_keys.is_empty(),
"absent field -> empty set"
);
}