bhtune_runtime/tune/
mod.rs1#![allow(rustdoc::broken_intra_doc_links)]
17
18mod actuation;
19mod config;
20mod outcome;
21mod poll;
22mod preflight;
23mod prepare;
24mod quality;
25mod recovery;
26mod request;
27mod restore;
28mod timing;
29mod writeback;
30
31#[cfg(test)]
32use crate::cancel::CtrlC;
33
34pub use actuation::MV_ACTUATION_CONFIRMATION_SECS;
35pub use config::validate_restore_timeout_secs;
36pub use outcome::{
37 AbortReason, RunOutcome, TuneOutcome, TuneRunReport, WriteBackOutcome, tune_outcome_for_run,
38};
39pub use preflight::{
40 PreflightCheck, PreflightCheckStatus, PreflightReport, PreflightTagRead, preflight,
41};
42pub use prepare::{PreparedTune, drive, drive_report, prepare, prepare_owned};
43pub use quality::sample_quality_from_driver;
44pub use recovery::{
45 RecoveryStepReport, RecoveryStepStatus, RestoreLoopReport, RestoreLoopRequest,
46 StartupOrphanSweepReport, recover_startup_orphans, restore_loop,
47};
48pub use request::{
49 DEFAULT_SIM_DEAD_TIME, DEFAULT_SIM_GAIN, DEFAULT_SIM_INITIAL_VALUE, DEFAULT_SIM_NOISE,
50 DEFAULT_SIM_SEED, DEFAULT_SIM_TAU, DriverKind, TuneRequest, TuneRequestValidationError,
51 UnsupportedDriverKind, ValidatedTuneRequest, validate_finite_f32, validate_positive_u32,
52};
53pub use writeback::{
54 PidWriteOutcome, PidWritePreview, WriteBackHandler, WriteBackSelection, WriteBackSkipReason,
55 controller_pid_for_result, pid_parameters_for_result, pid_write_preview, write_pid_values,
56 write_pid_values_with_owner,
57};
58#[allow(unused_imports)]
59pub(crate) use writeback::{read_previous_pid_values, write_and_verify_pid_value};
60
61trait RequireInvariant<T> {
66 fn require_invariant(self, message: &'static str) -> anyhow::Result<T>;
67}
68impl<T> RequireInvariant<T> for Option<T> {
69 fn require_invariant(self, message: &'static str) -> anyhow::Result<T> {
70 let Some(value) = self else {
71 return Err(anyhow::anyhow!(message));
72 };
73 Ok(value)
74 }
75}
76#[cfg(test)]
77async fn run(
78 pool: &bhtune_db::SqlitePool,
79 request: TuneRequest,
80 config: &crate::config::BhtuneConfig,
81) -> anyhow::Result<TuneOutcome> {
82 run_with_ctrl_c(pool, request, config, &mut CtrlC::never()).await
83}
84
85#[cfg(test)]
86async fn run_with_ctrl_c(
87 pool: &bhtune_db::SqlitePool,
88 request: TuneRequest,
89 config: &crate::config::BhtuneConfig,
90 ctrl_c: &mut CtrlC,
91) -> anyhow::Result<TuneOutcome> {
92 let prepared = prepare(pool, request, config).await?;
93 let report = drive_report(pool, prepared, ctrl_c, None).await?;
94 Ok(tune_outcome_for_run(&report.outcome))
95}
96
97#[cfg(test)]
98#[test]
99fn mv_actuation_abort_format_falls_back_for_other_abort_reasons() {
100 assert_eq!(
101 outcome::format_mv_actuation_abort_reason(&AbortReason::UserInterrupt),
102 "UserInterrupt"
103 );
104}
105
106#[test]
107fn require_invariant_returns_the_value_or_an_error() {
108 assert_eq!(Some(3).require_invariant("missing").unwrap(), 3);
109 let err = None::<i32>
110 .require_invariant("missing invariant")
111 .unwrap_err();
112 assert!(err.to_string().contains("missing invariant"));
113}
114
115#[cfg(test)]
116mod tests;