pub struct SensorReportBuilder { /* private fields */ }Expand description
Builder for constructing a SensorReport from a PerfgateReport.
This builder provides a fluent API for constructing sensor reports suitable for cockpit integration. It handles:
- Mapping verdict status (Pass/Warn/Fail) to sensor vocabulary (Pass/Warn/Error)
- Generating fingerprints for findings
- Truncating findings when limits are exceeded
- Aggregating multiple bench outcomes
- Sorting artifacts deterministically
§Example
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::{ToolInfo, PerfgateReport, VerdictStatus, Verdict, VerdictCounts, ReportSummary, REPORT_SCHEMA_V1};
let tool = ToolInfo {
name: "perfgate".to_string(),
version: "0.1.0".to_string(),
};
let report = PerfgateReport {
report_type: REPORT_SCHEMA_V1.to_string(),
verdict: Verdict {
status: VerdictStatus::Pass,
counts: VerdictCounts { pass: 2, warn: 0, fail: 0 },
reasons: vec![],
},
compare: None,
findings: vec![],
summary: ReportSummary { pass_count: 2, warn_count: 0, fail_count: 0, total_count: 2 },
};
let sensor_report = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.ended_at("2024-01-01T00:01:00Z".to_string(), 60000)
.baseline(true, None)
.artifact("report.json".to_string(), "sensor_report".to_string())
.build(&report);
assert_eq!(sensor_report.verdict.status, perfgate_types::SensorVerdictStatus::Pass);
assert_eq!(sensor_report.verdict.counts.info, 2);Implementations§
Source§impl SensorReportBuilder
impl SensorReportBuilder
Sourcepub fn new(tool: ToolInfo, started_at: String) -> Self
pub fn new(tool: ToolInfo, started_at: String) -> Self
Create a new SensorReportBuilder.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string());Sourcepub fn ended_at(self, ended_at: String, duration_ms: u64) -> Self
pub fn ended_at(self, ended_at: String, duration_ms: u64) -> Self
Set the end time and duration.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.ended_at("2024-01-01T00:01:00Z".to_string(), 60000);Sourcepub fn baseline(self, available: bool, reason: Option<String>) -> Self
pub fn baseline(self, available: bool, reason: Option<String>) -> Self
Set baseline availability.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
// Baseline available
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.baseline(true, None);Sourcepub fn engine(self, capability: Capability) -> Self
pub fn engine(self, capability: Capability) -> Self
Set engine capability explicitly.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::{ToolInfo, Capability, CapabilityStatus};
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.engine(Capability {
status: CapabilityStatus::Available,
reason: None,
});Sourcepub fn artifact(self, path: String, artifact_type: String) -> Self
pub fn artifact(self, path: String, artifact_type: String) -> Self
Add an artifact.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.artifact("report.json".to_string(), "sensor_report".to_string());Sourcepub fn max_findings(self, limit: usize) -> Self
pub fn max_findings(self, limit: usize) -> Self
Set the maximum number of findings to include.
When exceeded, findings are truncated and a meta-finding is appended.
findings_emitted in the output counts real findings only (excluding the truncation meta-finding).
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.max_findings(50);Sourcepub fn take_artifacts(&mut self) -> Vec<SensorArtifact>
pub fn take_artifacts(&mut self) -> Vec<SensorArtifact>
Take ownership of accumulated artifacts (for manual report building).
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let mut builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.artifact("report.json".to_string(), "sensor_report".to_string());
let artifacts = builder.take_artifacts();
assert_eq!(artifacts.len(), 1);
assert_eq!(artifacts[0].path, "report.json");Sourcepub fn build(self, report: &PerfgateReport) -> SensorReport
pub fn build(self, report: &PerfgateReport) -> SensorReport
Build the SensorReport from a PerfgateReport.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::{
ToolInfo, PerfgateReport, VerdictStatus, Verdict, VerdictCounts,
ReportSummary, SensorVerdictStatus, REPORT_SCHEMA_V1,
};
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let report = PerfgateReport {
report_type: REPORT_SCHEMA_V1.to_string(),
verdict: Verdict {
status: VerdictStatus::Pass,
counts: VerdictCounts { pass: 1, warn: 0, fail: 0 },
reasons: vec![],
},
compare: None,
findings: vec![],
summary: ReportSummary {
pass_count: 1, warn_count: 0, fail_count: 0, total_count: 1,
},
};
let sensor = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.ended_at("2024-01-01T00:01:00Z".to_string(), 60000)
.baseline(true, None)
.build(&report);
assert_eq!(sensor.verdict.status, SensorVerdictStatus::Pass);
assert_eq!(sensor.verdict.counts.info, 1);Sourcepub fn build_error(
self,
error_message: &str,
stage: &str,
error_kind: &str,
) -> SensorReport
pub fn build_error( self, error_message: &str, stage: &str, error_kind: &str, ) -> SensorReport
Build an error SensorReport for catastrophic failures.
This creates a report when the sensor itself failed to run properly.
stage indicates which phase failed (e.g. “config_parse”, “run_command”).
error_kind classifies the error (e.g. “io_error”, “parse_error”, “exec_error”).
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::{ToolInfo, SensorVerdictStatus};
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let sensor = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.build_error("config not found", "config_parse", "parse_error");
assert_eq!(sensor.verdict.status, SensorVerdictStatus::Fail);
assert_eq!(sensor.verdict.counts.error, 1);
assert_eq!(sensor.findings.len(), 1);Sourcepub fn build_aggregated(
self,
outcomes: &[BenchOutcome],
) -> (SensorReport, String)
pub fn build_aggregated( self, outcomes: &[BenchOutcome], ) -> (SensorReport, String)
Build an aggregated SensorReport from multiple bench outcomes.
This encapsulates the multi-bench cockpit aggregation logic:
- Maps findings from each bench’s
PerfgateReportto sensor findings - In multi-bench mode: prefixes messages with
[bench_name], injectsbench_nameinto finding data, includes bench_name in fingerprint seed - Aggregates counts (sum), verdict (worst-of), reasons (union/deduped)
- Registers per-bench artifacts
- Combines markdown with
\n---\n\nseparator in multi-bench - Applies truncation via
truncate_findings()usingself.max_findings - Returns
(SensorReport, combined_markdown)
§Examples
use perfgate_sensor::{SensorReportBuilder, BenchOutcome};
use perfgate_types::{
ToolInfo, PerfgateReport, VerdictStatus, Verdict, VerdictCounts,
ReportSummary, SensorVerdictStatus, REPORT_SCHEMA_V1,
};
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let report = PerfgateReport {
report_type: REPORT_SCHEMA_V1.to_string(),
verdict: Verdict {
status: VerdictStatus::Pass,
counts: VerdictCounts { pass: 1, warn: 0, fail: 0 },
reasons: vec![],
},
compare: None,
findings: vec![],
summary: ReportSummary {
pass_count: 1, warn_count: 0, fail_count: 0, total_count: 1,
},
};
let outcome = BenchOutcome::Success {
bench_name: "my-bench".to_string(),
report,
has_compare: false,
baseline_available: false,
markdown: "## Results\n".to_string(),
extras_prefix: "extras".to_string(),
};
let (sensor, markdown) = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.build_aggregated(&[outcome]);
assert_eq!(sensor.verdict.status, SensorVerdictStatus::Pass);
assert!(markdown.contains("Results"));