use anyhow::Result;
use ktstr::assert::{AssertResult, Phase, Verdict};
use ktstr::ktstr_test;
use ktstr::prelude::VmResult;
use ktstr::scenario::Ctx;
use ktstr::test_support::{Scheduler, SchedulerSpec};
const PERF_SCX: Scheduler =
Scheduler::named("perf_scx").binary(SchedulerSpec::Discover("scx-ktstr"));
const METRIC: &str = "wakeup_p99_latency_us";
fn assert_perphase_metrics_survive_detach(result: &VmResult) -> Result<()> {
let scx = Phase::step(0); let eevdf = Phase::step(1);
anyhow::ensure!(
result.phase_metric(scx, METRIC).is_some(),
"scx phase (Step[0]) produced no {METRIC} — per-phase carrier missing"
);
anyhow::ensure!(
result.phase_metric(eevdf, METRIC).is_some(),
"EEVDF phase (Step[1]) produced no {METRIC} — per-phase carrier missing across the detach"
);
let mut v = Verdict::new();
result
.better_across_phases(&mut v, eevdf, scx, METRIC)
.better_than();
anyhow::ensure!(
!v.is_inconclusive(),
"better_across_phases was inconclusive — could not read both phases or orient by polarity"
);
Ok(())
}
#[ktstr_test(
scheduler = PERF_SCX,
performance_mode = true,
llcs = 1,
cores = 2,
threads = 1,
memory_mib = 512,
duration_s = 24,
watchdog_timeout_s = 35,
cleanup_budget_ms = 5000,
num_snapshots = 3,
post_vm = assert_perphase_metrics_survive_detach,
)]
fn performance_mode_perphase_metrics_across_detach(ctx: &Ctx) -> Result<AssertResult> {
use ktstr::scenario::backdrop::Backdrop;
use ktstr::scenario::ops::{CgroupDef, HoldSpec, Op, Step, execute_scenario};
use ktstr::workload::{SchbenchConfig, WorkType};
use std::time::Duration;
let backdrop = Backdrop::new().push_cgroup(
CgroupDef::named("sched_bench")
.work_type(WorkType::schbench(SchbenchConfig::default()))
.workers(1),
);
let steps = vec![
Step::new(vec![], HoldSpec::fixed(Duration::from_secs(4))),
Step::new(
vec![Op::detach_scheduler()],
HoldSpec::fixed(Duration::from_secs(4)),
),
];
execute_scenario(ctx, backdrop, steps)
}
fn assert_schbench_steady_ran(result: &VmResult) -> Result<()> {
let steady = Phase::step(1); anyhow::ensure!(
result.phase_metric(steady, "schbench_loop_count").is_some(),
"steady phase (Step[1]) produced no schbench_loop_count — the workload did not run"
);
Ok(())
}
#[ktstr_test(
scheduler = PERF_SCX,
performance_mode = true,
llcs = 1,
cores = 2,
threads = 1,
memory_mib = 512,
duration_s = 25,
watchdog_timeout_s = 35,
cleanup_budget_ms = 5000,
num_snapshots = 3,
post_vm = assert_schbench_steady_ran,
)]
fn performance_mode_schbench_steady(ctx: &Ctx) -> Result<AssertResult> {
use ktstr::scenario::backdrop::Backdrop;
use ktstr::scenario::ops::{CgroupDef, HoldSpec, Step, execute_scenario};
use ktstr::workload::{SchbenchConfig, WorkType};
use std::time::Duration;
let backdrop = Backdrop::new().push_cgroup(
CgroupDef::named("sched_bench")
.work_type(WorkType::schbench(SchbenchConfig::default()))
.workers(1),
);
let steps = vec![
Step::new(vec![], HoldSpec::fixed(Duration::from_secs(3))),
Step::new(vec![], HoldSpec::fixed(Duration::from_secs(15))),
];
execute_scenario(ctx, backdrop, steps)
}