Merge pull request #762 from fabro-sh/refactor/shared-run-spec-test-fixture
Some checks are pending
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run

Add a shared RunSpec test fixture so additive fields stop churning tests
This commit is contained in:
Scott Werner 2026-08-19 17:55:59 -04:00 committed by GitHub
commit 2168d902f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 78 additions and 190 deletions

View file

@ -486,8 +486,7 @@ mod tests {
use fabro_types::{
Checkpoint, CheckpointRecord, Conclusion, RunDiff, RunSandbox, RunSandboxInstance,
RunSandboxPlan, RunStatus, SandboxProviderKind, StageCompletion, StageModelUsage,
StageOutcome, StartRecord, SuccessReason, WorkflowSettings, first_event_seq, fixtures,
test_support,
StageOutcome, StartRecord, SuccessReason, first_event_seq, fixtures, test_support,
};
use futures::executor;
@ -495,24 +494,18 @@ mod tests {
fn sample_run_spec() -> RunSpec {
RunSpec {
run_id: fixtures::RUN_1,
settings: WorkflowSettings::default(),
graph: Graph::new("ship"),
graph_source: Some("digraph Ship {}".to_string()),
workflow_slug: Some("demo".to_string()),
automation: None,
graph: Graph::new("ship"),
graph_source: Some("digraph Ship {}".to_string()),
workflow_slug: Some("demo".to_string()),
source_directory: Some("/tmp/project".to_string()),
git: Some(fabro_types::GitContext {
git: Some(fabro_types::GitContext {
origin_url: "https://github.com/fabro-sh/fabro.git".to_string(),
branch: "main".to_string(),
sha: None,
dirty: fabro_types::DirtyStatus::Clean,
}),
labels: HashMap::from([("team".to_string(), "platform".to_string())]),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
fork_source_ref: None,
labels: HashMap::from([("team".to_string(), "platform".to_string())]),
..test_support::test_run_spec()
}
}

View file

@ -2281,19 +2281,8 @@ mod tests {
fn test_run_spec() -> RunSpec {
RunSpec {
run_id: fixtures::RUN_1,
settings: WorkflowSettings::default(),
graph: Graph::new("test"),
graph_source: Some("digraph test {}".to_string()),
workflow_slug: None,
automation: None,
source_directory: None,
labels: HashMap::new(),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
git: None,
fork_source_ref: None,
graph_source: Some("digraph test {}".to_string()),
..test_support::test_run_spec()
}
}
@ -4086,19 +4075,9 @@ mod tests {
fn summary_synthesizes_submitted_when_run_exists_without_status() {
let mut state = initialized_projection();
state.spec = fabro_types::RunSpec {
run_id: fixtures::RUN_1,
settings: WorkflowSettings::default(),
graph: fabro_types::Graph::new("test"),
graph_source: None,
workflow_slug: Some("test".to_string()),
automation: None,
workflow_slug: Some("test".to_string()),
source_directory: Some("/tmp/repo".to_string()),
git: None,
labels: HashMap::new(),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
fork_source_ref: None,
..test_support::test_run_spec()
};
let summary_json = serde_json::to_value(build_summary(&state, &fixtures::RUN_1)).unwrap();
@ -4112,19 +4091,10 @@ mod tests {
fn summary_preserves_absent_workflow_name_and_reports_graph_name() {
let mut state = initialized_projection();
state.spec = fabro_types::RunSpec {
run_id: fixtures::RUN_1,
settings: WorkflowSettings::default(),
graph: fabro_types::Graph::new("GraphName"),
graph_source: None,
workflow_slug: Some("release-flow".to_string()),
automation: None,
graph: fabro_types::Graph::new("GraphName"),
workflow_slug: Some("release-flow".to_string()),
source_directory: Some("/tmp/repo".to_string()),
git: None,
labels: HashMap::new(),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
fork_source_ref: None,
..test_support::test_run_spec()
};
let summary = build_summary(&state, &fixtures::RUN_1);

View file

@ -8,30 +8,23 @@ use fabro_types::{
BilledModelUsage, BilledTokenCounts, Checkpoint, CheckpointRecord, InterviewQuestionRecord,
ParallelBranchResult, QuestionType, RunDiff, RunSandbox, RunSandboxInstance, RunSandboxPlan,
RunSandboxRuntime, RunStatus, SandboxProviderKind, StageCompletion, StageModelUsage,
StageOutcome, StartRecord, WorkflowSettings, first_event_seq, fixtures, test_support,
StageOutcome, StartRecord, first_event_seq, fixtures, test_support,
};
use serde_json::json;
fn sample_run_spec() -> RunSpec {
RunSpec {
run_id: fixtures::RUN_1,
settings: WorkflowSettings::default(),
graph: Graph::new("ship"),
graph_source: None,
workflow_slug: Some("demo".to_string()),
automation: None,
graph: Graph::new("ship"),
workflow_slug: Some("demo".to_string()),
source_directory: Some("/tmp/project".to_string()),
labels: HashMap::from([("team".to_string(), "platform".to_string())]),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
git: Some(fabro_types::GitContext {
labels: HashMap::from([("team".to_string(), "platform".to_string())]),
git: Some(fabro_types::GitContext {
origin_url: "https://github.com/fabro-sh/fabro.git".to_string(),
branch: "main".to_string(),
sha: None,
dirty: fabro_types::DirtyStatus::Clean,
}),
fork_source_ref: None,
..test_support::test_run_spec()
}
}

View file

@ -126,12 +126,10 @@ pub fn billing_rollup_from_projection(
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use fabro_model::{Catalog, ModelRef, ProviderId};
use fabro_types::{
AttrValue, BilledTokenCounts, Graph, Node, RunProjection, RunSpec, StageCompletion,
StageOutcome, WorkflowSettings, first_event_seq, fixtures, test_support,
StageOutcome, first_event_seq, test_support,
};
use super::billing_rollup_from_projection;
@ -311,19 +309,8 @@ mod tests {
});
RunSpec {
run_id: fixtures::RUN_1,
settings: WorkflowSettings::default(),
graph,
graph_source: None,
workflow_slug: None,
automation: None,
source_directory: None,
labels: HashMap::new(),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
git: None,
fork_source_ref: None,
..test_support::test_run_spec()
}
}
}

View file

@ -445,13 +445,11 @@ fn run_id_matches(run_id: RunId, prefix: &str) -> bool {
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use fabro_graphviz::graph::Graph;
use fabro_store::Database;
use fabro_types::{RunStatus, WorkflowSettings, fixtures, test_support};
use fabro_types::{RunStatus, fixtures, test_support};
use object_store::memory::InMemory;
use super::scan_runs_combined;
@ -470,24 +468,15 @@ mod tests {
fn sample_run_spec() -> RunSpec {
RunSpec {
run_id: fixtures::RUN_1,
settings: WorkflowSettings::default(),
graph: Graph::new("test"),
graph_source: None,
workflow_slug: Some("test".to_string()),
automation: None,
workflow_slug: Some("test".to_string()),
source_directory: Some("/tmp/project".to_string()),
git: Some(fabro_types::GitContext {
git: Some(fabro_types::GitContext {
origin_url: String::new(),
branch: "main".to_string(),
sha: None,
dirty: fabro_types::DirtyStatus::Clean,
}),
labels: HashMap::new(),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
fork_source_ref: None,
..test_support::test_run_spec()
}
}

View file

@ -112,15 +112,13 @@ impl RunStoreBackend for LocalRunStoreBackend {
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use chrono::Utc;
use fabro_graphviz::graph::Graph;
use fabro_store::Database;
use fabro_types::run_event::RunSubmittedProps;
use fabro_types::{EventBody, RunEvent, WorkflowSettings, fixtures, test_support};
use fabro_types::{EventBody, RunEvent, fixtures, test_support};
use object_store::memory::InMemory;
use super::RunStoreHandle;
@ -139,19 +137,9 @@ mod tests {
fn test_run_spec() -> RunSpec {
RunSpec {
run_id: fixtures::RUN_1,
settings: WorkflowSettings::default(),
graph: Graph::new("test"),
graph_source: None,
workflow_slug: Some("test".to_string()),
automation: None,
workflow_slug: Some("test".to_string()),
source_directory: Some("/tmp/test".to_string()),
git: None,
labels: HashMap::new(),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
fork_source_ref: None,
..test_support::test_run_spec()
}
}

View file

@ -1,7 +1,7 @@
use std::any::{TypeId, type_name};
use fabro_api::types::RunProjection as ApiRunProjection;
use fabro_types::{Graph, RunProjection, RunSpec, WorkflowSettings, test_support};
use fabro_types::{RunProjection, RunSpec, test_support};
use serde_json::json;
#[test]
fn run_projection_reuses_canonical_type() {
@ -129,19 +129,8 @@ fn run_projection_round_trips_with_pending_control_unset() {
fn run_spec_json() -> serde_json::Value {
serde_json::to_value(RunSpec {
run_id: fabro_types::fixtures::RUN_1,
settings: WorkflowSettings::default(),
graph: Graph::new("test"),
graph_source: Some("digraph test {}".to_string()),
workflow_slug: None,
automation: None,
source_directory: None,
labels: std::collections::HashMap::new(),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
git: None,
fork_source_ref: None,
graph_source: Some("digraph test {}".to_string()),
..test_support::test_run_spec()
})
.unwrap()
}

View file

@ -1061,11 +1061,9 @@ impl RunProjection {
#[cfg(test)]
mod title_tests {
use std::collections::HashMap;
use chrono::Utc;
use crate::{AttrValue, Graph, RunId, RunProjection, RunSpec, WorkflowSettings, test_support};
use crate::{AttrValue, Graph, RunProjection, RunSpec, test_support};
fn projection_with_goal(goal: Option<&str>) -> RunProjection {
let mut graph = Graph::new("test");
@ -1076,19 +1074,8 @@ mod title_tests {
}
let spec = RunSpec {
run_id: RunId::new(),
settings: WorkflowSettings::default(),
graph,
graph_source: None,
workflow_slug: None,
automation: None,
source_directory: None,
labels: HashMap::new(),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
git: None,
fork_source_ref: None,
..test_support::test_run_spec()
};
RunProjection::new(String::new(), spec, Utc::now())
}
@ -1129,7 +1116,6 @@ mod title_tests {
#[cfg(test)]
mod iter_stages_tests {
use std::collections::HashMap;
use std::num::NonZeroU32;
use chrono::Utc;
@ -1137,10 +1123,7 @@ mod iter_stages_tests {
use serde_json::json;
use super::RunProjection;
use crate::{
AgentControlState, BilledTokenCounts, Graph, RunId, RunSpec, StageProjection,
WorkflowSettings, test_support,
};
use crate::{AgentControlState, BilledTokenCounts, StageProjection, test_support};
fn seq(n: u32) -> NonZeroU32 {
NonZeroU32::new(n).unwrap()
@ -1149,21 +1132,7 @@ mod iter_stages_tests {
fn projection() -> RunProjection {
RunProjection::new(
"Test run".to_string(),
RunSpec {
run_id: RunId::new(),
settings: WorkflowSettings::default(),
graph: Graph::new("test"),
graph_source: None,
workflow_slug: None,
automation: None,
source_directory: None,
labels: HashMap::default(),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
git: None,
fork_source_ref: None,
},
test_support::test_run_spec(),
Utc::now(),
)
}
@ -1336,14 +1305,12 @@ mod iter_stages_tests {
#[cfg(test)]
mod live_timing_tests {
use std::collections::HashMap;
use chrono::{DateTime, TimeZone, Utc};
use super::{RunProjection, StageToolBatchProjection};
use crate::{
Graph, ModelRef, RunId, RunSpec, StageHandler, StageInferenceProjection, StageProjection,
StageState, StageTiming, StartRecord, WorkflowSettings, first_event_seq, test_support,
ModelRef, StageHandler, StageInferenceProjection, StageProjection, StageState, StageTiming,
StartRecord, first_event_seq, test_support,
};
fn at(seconds: i64) -> DateTime<Utc> {
@ -1351,25 +1318,7 @@ mod live_timing_tests {
}
fn projection() -> RunProjection {
RunProjection::new(
"Test run".to_string(),
RunSpec {
run_id: RunId::new(),
settings: WorkflowSettings::default(),
graph: Graph::new("test"),
graph_source: None,
workflow_slug: None,
automation: None,
source_directory: None,
labels: HashMap::default(),
provenance: test_support::test_run_provenance(),
manifest_blob: None,
definition_blob: None,
git: None,
fork_source_ref: None,
},
at(0),
)
RunProjection::new("Test run".to_string(), test_support::test_run_spec(), at(0))
}
/// In-flight stage that started at `at(0)`.

View file

@ -1,4 +1,8 @@
use crate::{AuthMethod, IdpIdentity, Principal, RunProvenance};
use std::collections::HashMap;
use crate::{
AuthMethod, Graph, IdpIdentity, Principal, RunProvenance, RunSpec, WorkflowSettings, fixtures,
};
#[must_use]
pub fn test_principal() -> Principal {
@ -17,3 +21,35 @@ pub fn test_run_provenance() -> RunProvenance {
subject: test_principal(),
}
}
/// Neutral [`RunSpec`] for tests: a fixed run id, default settings, a minimal
/// `test` graph, and every optional field unset.
///
/// Spread it so a test only spells out the fields it actually asserts on:
///
/// ```
/// # use fabro_types::{RunSpec, test_support};
/// let spec = RunSpec {
/// workflow_slug: Some("release-flow".to_string()),
/// ..test_support::test_run_spec()
/// };
/// # assert_eq!(spec.workflow_slug.as_deref(), Some("release-flow"));
/// ```
#[must_use]
pub fn test_run_spec() -> RunSpec {
RunSpec {
run_id: fixtures::RUN_1,
settings: WorkflowSettings::default(),
graph: Graph::new("test"),
graph_source: None,
workflow_slug: None,
automation: None,
source_directory: None,
labels: HashMap::new(),
provenance: test_run_provenance(),
manifest_blob: None,
definition_blob: None,
git: None,
fork_source_ref: None,
}
}

View file

@ -3,7 +3,7 @@ use std::collections::HashMap;
use fabro_types::graph::Graph;
use fabro_types::run::{DirtyStatus, GitContext, RunSpec};
use fabro_types::settings::{ProjectNamespace, WorkflowNamespace};
use fabro_types::test_support::test_run_provenance;
use fabro_types::test_support::test_run_spec;
use fabro_types::{WorkflowSettings, fixtures};
fn sample_run_spec() -> RunSpec {
@ -20,24 +20,18 @@ fn sample_run_spec() -> RunSpec {
};
RunSpec {
run_id: fixtures::RUN_1,
settings,
graph: Graph::new("ship"),
graph_source: None,
workflow_slug: Some("demo".to_string()),
automation: None,
source_directory: Some("/Users/client/project".to_string()),
labels: HashMap::from([("team".to_string(), "platform".to_string())]),
provenance: test_run_provenance(),
manifest_blob: None,
definition_blob: None,
git: Some(GitContext {
origin_url: "https://github.com/fabro-sh/fabro.git".to_string(),
branch: "main".to_string(),
sha: Some("abc123".to_string()),
dirty: DirtyStatus::Dirty,
}),
fork_source_ref: None,
..test_run_spec()
}
}