#![allow(dead_code)]
use std::sync::Arc;
use fmeca::{
Domain, Engine, EntityRef, EvidenceRef, FailureMode, FilesystemStore, Level, Mitigation,
MitigationKind, Rescore,
};
pub fn failure_mode_obs(
session: &str,
id: &str,
severity_observations: Vec<String>,
probability_observations: Vec<String>,
) -> FailureMode {
FailureMode {
id: id.to_string(),
session_id: session.to_string(),
component: EntityRef::new("comp:svc"),
description: format!("failure mode {id}"),
cause: Some("a cause".to_string()),
effect: Some("an effect".to_string()),
severity_observations,
probability_observations,
domain: Domain::Runtime,
scope: None,
source: EvidenceRef::new("turn-1"),
parent: None,
refs: Vec::new(),
local_effect: None,
next_effect: None,
single_point: false,
}
}
pub fn temp_engine() -> (Engine, tempfile::TempDir) {
let dir = tempfile::tempdir().expect("tempdir");
let store = FilesystemStore::new(dir.path()).expect("store");
(Engine::new(Arc::new(store)), dir)
}
pub fn severity_obs(level: Level) -> String {
match level {
Level::High => "data_loss",
Level::Medium => "user_facing_degradation",
Level::Low => "cosmetic",
}
.to_string()
}
pub fn probability_obs(level: Level) -> String {
match level {
Level::High => "happens_in_normal_use",
Level::Medium => "occasional",
Level::Low => "rare_edge_case",
}
.to_string()
}
pub fn failure_mode(session: &str, id: &str, severity: Level, probability: Level) -> FailureMode {
FailureMode {
id: id.to_string(),
session_id: session.to_string(),
component: EntityRef::new("comp:svc"),
description: format!("failure mode {id}"),
cause: Some("a cause".to_string()),
effect: Some("an effect".to_string()),
severity_observations: vec![severity_obs(severity)],
probability_observations: vec![probability_obs(probability)],
domain: Domain::Runtime,
scope: None,
source: EvidenceRef::new("turn-1"),
parent: None,
refs: Vec::new(),
local_effect: None,
next_effect: None,
single_point: false,
}
}
pub fn mitigation(
session: &str,
id: &str,
fm_id: &str,
kind: MitigationKind,
residual_severity: Level,
residual_probability: Level,
) -> Mitigation {
Mitigation {
id: id.to_string(),
session_id: session.to_string(),
failure_mode_id: fm_id.to_string(),
kind,
description: format!("mitigation {id}"),
residual_severity_observations: vec![severity_obs(residual_severity)],
residual_probability_observations: vec![probability_obs(residual_probability)],
source: EvidenceRef::new("turn-2"),
}
}
pub fn rescore(session: &str, fm_id: &str, severity: Level, probability: Level) -> Rescore {
Rescore {
failure_mode_id: fm_id.to_string(),
session_id: session.to_string(),
severity_observations: vec![severity_obs(severity)],
probability_observations: vec![probability_obs(probability)],
source: EvidenceRef::new("turn-3"),
}
}
pub fn evidence(kind: fmeca::EvidenceKind, reference: &str) -> fmeca::ResolutionEvidence {
fmeca::ResolutionEvidence {
kind,
reference: reference.to_string(),
basis: None,
}
}
pub fn status_change(
session: &str,
mitigation_id: &str,
status: fmeca::MitigationStatus,
evidence: Vec<fmeca::ResolutionEvidence>,
) -> fmeca::MitigationStatusChange {
fmeca::MitigationStatusChange {
session_id: session.to_string(),
mitigation_id: mitigation_id.to_string(),
status,
evidence,
note: None,
at: None,
}
}
pub fn disposition_change(
session: &str,
fm_id: &str,
disposition: fmeca::Disposition,
approver: Option<&str>,
evidence: Vec<fmeca::ResolutionEvidence>,
) -> fmeca::DispositionChange {
fmeca::DispositionChange {
session_id: session.to_string(),
failure_mode_id: fm_id.to_string(),
disposition,
rationale: "a rationale".to_string(),
approver: approver.map(String::from),
evidence,
at: None,
}
}