#![forbid(unsafe_code)]
pub use shigoto_budget::{BudgetError, BudgetSpec, BudgetTree};
pub use shigoto_rank::{pick, rank, PriorityClass, Schedulable, UrgencyWeights};
pub use shigoto_fsm::{assert_convergent_fsm, ConvergentFsm, DefectKind, FsmDefect};
pub use shigoto_dag::{Dag, DagError};
pub use shigoto_emit::{
AuditFileEmitter, InMemorySink, MultiEmitter, NullEmitter, NullSink, TransitionEmitter,
};
pub use shigoto_gate::{
self, AllUpstreamsTerminal, Gate, GateContext, GateOutcome, OperatorApproved,
};
pub use shigoto_retry::{FailureRecord, RetryDecider, RetryDecision, RetryPolicy};
pub use shigoto_scheduler::{InProcessScheduler, Scheduler, SchedulerError};
pub use shigoto_types::{
ErasedJob, GateAggregate, IllegalTransition, Job, JobError, JobId, JobInput, JobKindId,
JobOutput, JobPhase, JobScope, JobSubject, OutputSink, RecordingJob, RetryOutcome, Signal,
SkipReason, Snapshot, TickReceipt, TransitionEvent, TransitionReason, UnhealedDrift, advance,
};
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
#[derive(thiserror::Error, Debug)]
#[error("smoke")]
struct SmokeErr;
struct SmokeJob;
#[async_trait::async_trait]
impl Job for SmokeJob {
type Output = ();
type Error = SmokeErr;
fn id(&self) -> JobId {
JobId {
scope: JobScope::Global,
kind: JobKindId::new("smoke"),
subject: JobSubject::None,
}
}
fn kind(&self) -> JobKindId {
JobKindId::new("smoke")
}
async fn execute(&self) -> Result<(), SmokeErr> {
Ok(())
}
}
#[tokio::test]
async fn umbrella_consumer_reaches_full_surface() {
let scheduler =
InProcessScheduler::new("umbrella-smoke").with_emitter(Arc::new(NullEmitter::new()));
let job = Arc::new(SmokeJob);
let id = <SmokeJob as Job>::id(&job);
scheduler.register_job(job).await;
let mut dag = Dag::new();
dag.ensure_node(id.clone());
let receipt: TickReceipt = scheduler.tick(&mut dag).await.unwrap();
let snap: Snapshot = scheduler.snapshot(&dag).await;
assert_eq!(snap.phases.get(&id), Some(&JobPhase::Succeeded));
assert!(receipt.phase_counts.contains_key("succeeded"));
}
}