#[derive(Payload)]
{
// Attributes available to this derive:
#[payload]
#[default_args]
#[default_check]
#[metric]
#[include_files]
}
Expand description
Derive macro that generates a Payload const from an annotated
struct for a userspace binary workload (stress-ng, fio, and
similar tools test authors compose under a scheduler).
§Required struct-level attributes (#[payload(...)])
binary = "..."— the binary name resolved by the guest’s include-files infrastructure (required). BecomesPayloadKind::Binary(name)(ktstr::test_support::PayloadKind::Binary), and is also auto-prepended to the emittedinclude_filesslice so the binary is packaged into the initramfs without needing a separate#[include_files("...")]entry. Extra auxiliary files (helpers, configs, fixtures) still go on#[include_files(...)].
§Optional struct-level attributes
name = "..."— short name used in logs and sidecar records. Defaults to the binary name.output = Json | ExitCode— how the framework extracts metrics from the payload’s stdout. The variant names match theOutputFormatenum and thePolaritykwarg grammar. Defaults toExitCode.
§Optional outer attributes
#[default_args("--a", "--b", ...)]— variadic string literals appended to the binary’s argv when the payload runs. May repeat across multiple#[default_args(...)]attrs; entries accumulate in source order.#[default_check(...)]— oneMetricCheck(ktstr::test_support::MetricCheck) construction expression (e.g.min("iops", 1000.0),exit_code_eq(0)). May repeat; entries accumulate in source order. Bothmin(...)andMetricCheck::min(...)are accepted: the macro prepends::ktstr::test_support::MetricCheck::when the expression doesn’t already spellMetricCheck::on its callee path, so bare constructors work without an import and qualified constructors read naturally in modules that already haveMetricCheckin scope.#[metric(name = "...", polarity = ..., unit = "...")]— kwarg form.polarityis one ofHigherBetter,LowerBetter,TargetValue(f64),Unknown. May repeat; entries accumulate.#[include_files("helper", "config.json", ...)]— variadic string literals appended to the emittedinclude_filesslice after the auto-injected binary entry. Each entry passes through the same resolver used by the CLI-iflag (bare names search hostPATH; explicit paths must exist; directories are walked). The primary binary is already packaged automatically, so this attribute is only needed for auxiliary files the payload depends on.
§Const name derivation
Strip trailing "Payload" suffix (if present), then convert to
SCREAMING_SNAKE_CASE. FioPayload → FIO,
StressNgPayload → STRESS_NG, Fio (no suffix) → FIO.
§Example
ⓘ
use ktstr::prelude::*;
#[derive(Payload)]
#[payload(binary = "fio", output = Json)]
#[default_args("--output-format=json", "--minimal")]
#[default_check(exit_code_eq(0))]
#[metric(name = "jobs.0.read.iops", polarity = HigherBetter, unit = "iops")]
struct FioPayload;