pub struct PerfDeltaAssertion { /* private fields */ }Expand description
A per-test performance-regression assertion that
cargo ktstr perf-delta --noise-adjust enforces when this test is compared
across two commits — and that a normal cargo ktstr test run IGNORES.
Enforced ONLY under --noise-adjust. A declared gate is a CI-gating perf
assertion; gating on a single-run scalar comparison would flip CI on noise,
so the multi-run --noise-adjust path (Welch + disjoint-band separation) is
the only statistically sound basis. Plain perf-delta (scalar) does NOT
evaluate declared gates — it warns that they were skipped. Declaring a gate
also REQUIRES performance_mode (validated at compile time by the macro and
at discovery time by KtstrTestEntry::validate) so the compared data is
pinned.
Inert-as-a-test / active-under-perf-delta is by CONSTRUCTION, not a runtime
flag: the in-VM verdict path consults only crate::assert::Assert, never a
PerfDeltaAssertion, so declaring one changes no normal-run verdict or exit
code. It becomes active only because perf-delta serializes the declaration
into the sidecar and consults it in the host-side --noise-adjust compare.
A declaration names a registry metric and OVERRIDES, for this test, the gate
that decides a confident regression on it: a tighter relative threshold, an
absolute floor, a pinned direction, and/or a phase scope. It LAYERS ON TOP of
the --noise-adjust default all-metrics regression net (which still runs, to
catch unknown-unknown regressions) — it is an explicit contract check, not a
whitelist that narrows the net.
Declare by binding each gate to a const and listing it on the macro:
const RPS_GATE: PerfDeltaAssertion = PerfDeltaAssertion::new("rps_p50").with_max_regression_pct(5.0); then
#[ktstr_test(performance_mode = true, perf_delta_assertions = [RPS_GATE])].
Or directly on a programmatically-built KtstrTestEntry:
perf_delta_assertions: &[&RPS_GATE] — bind the const first; a chained inline
&PerfDeltaAssertion::new(..).with_*(..) does NOT rvalue-promote to 'static
in a non-const KtstrTestEntry { .. } literal (E0716). Construct via
PerfDeltaAssertion::new + the const fn with_* builders; fields are
crate-private so every value passes the compile-time format gate. The type is
Copy over a &'static str metric (no Drop, E0493-safe); the owned form
the sidecar serializes is a separate internal mirror,
crate::test_support::PerfDeltaAssertionRecord.
Implementations§
Source§impl PerfDeltaAssertion
impl PerfDeltaAssertion
Sourcepub const fn new(metric: &'static str) -> Self
pub const fn new(metric: &'static str) -> Self
Const constructor for use in static/const context. metric is a
registry metric name (see cargo ktstr stats list-metrics); the
remaining knobs default to the registry values and are set via the
builders below.
§Panics
Panics at compile time when metric is empty, contains whitespace or a
path separator (/, \), or a non-printable / high-bit byte. That the
name RESOLVES in the metric registry is checked at run time by
KtstrTestEntry::validate (the registry is not const-accessible).
Sourcepub const fn with_max_regression_pct(self, pct: f64) -> Self
pub const fn with_max_regression_pct(self, pct: f64) -> Self
Override the relative-regression gate (percent) for this metric: a
worsening move larger than pct% of the baseline gates. None (unset)
inherits the registry default_rel. pct must be finite and >= 0
(enforced at discovery time by KtstrTestEntry::validate).
Sourcepub const fn with_min_abs(self, min: f64) -> Self
pub const fn with_min_abs(self, min: f64) -> Self
Override the absolute-materiality floor for this metric: a move smaller
than min in absolute units never gates, regardless of the relative
threshold. None (unset) inherits the registry default_abs. min must
be finite and >= 0 (enforced at discovery time by
KtstrTestEntry::validate).
Sourcepub const fn with_direction(self, polarity: Polarity) -> Self
pub const fn with_direction(self, polarity: Polarity) -> Self
Pin the regression DIRECTION for this metric instead of inheriting the
registry polarity (e.g. assert a metric the registry treats as
Informational as LowerBetter for this test).
§Panics
Panics at compile time on crate::test_support::Polarity::TargetValue:
symmetric target-distance gating is not implemented, and the compare
polarity path would silently treat it as increase-is-worse. Use
HigherBetter, LowerBetter, or Informational.
Sourcepub const fn with_phase(self, step_index: u16) -> Self
pub const fn with_phase(self, step_index: u16) -> Self
Scope the assertion to a single phase (step_index: 0 = BASELINE,
1..=N = scenario Step ordinals). None (unset) gates the aggregate
(whole-run) value. Unlike the render-only per-phase spread tables, a
phase-scoped assertion DOES contribute to the perf-delta --noise-adjust
exit code (the scalar perf-delta path warns and skips all declared
gates, phase-scoped included).
Sourcepub const fn direction(&self) -> Option<Polarity>
pub const fn direction(&self) -> Option<Polarity>
The pinned regression direction, or None to inherit the registry
polarity.
Sourcepub const fn max_regression_pct(&self) -> Option<f64>
pub const fn max_regression_pct(&self) -> Option<f64>
The relative-regression override (percent), or None for the registry
default_rel.
Trait Implementations§
Source§impl Clone for PerfDeltaAssertion
impl Clone for PerfDeltaAssertion
Source§fn clone(&self) -> PerfDeltaAssertion
fn clone(&self) -> PerfDeltaAssertion
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for PerfDeltaAssertion
impl Debug for PerfDeltaAssertion
Source§impl From<&PerfDeltaAssertion> for PerfDeltaAssertionRecord
impl From<&PerfDeltaAssertion> for PerfDeltaAssertionRecord
Source§fn from(a: &PerfDeltaAssertion) -> Self
fn from(a: &PerfDeltaAssertion) -> Self
Source§impl PartialEq for PerfDeltaAssertion
impl PartialEq for PerfDeltaAssertion
impl Copy for PerfDeltaAssertion
impl StructuralPartialEq for PerfDeltaAssertion
Auto Trait Implementations§
impl Freeze for PerfDeltaAssertion
impl RefUnwindSafe for PerfDeltaAssertion
impl Send for PerfDeltaAssertion
impl Sync for PerfDeltaAssertion
impl Unpin for PerfDeltaAssertion
impl UnwindSafe for PerfDeltaAssertion
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more