split Swap's Ok-tail into a first-class PostSwap DAG node (#2390)
This commit is contained in:
parent
e646241acd
commit
f2ff0deb6b
4 changed files with 126 additions and 43 deletions
|
|
@ -150,7 +150,13 @@ fn unknown_dep_is_rejected_at_submit() {
|
|||
fn rebuild_chain_claims_in_dep_order() {
|
||||
let q = JobQueue::new(1);
|
||||
let id = submit(&q, rebuild("agent-a", "r"));
|
||||
for expected in ["prebuild", "stop_for_update", "swap", "reconcile"] {
|
||||
for expected in [
|
||||
"prebuild",
|
||||
"stop_for_update",
|
||||
"swap",
|
||||
"post_swap",
|
||||
"reconcile",
|
||||
] {
|
||||
let c = claim_one(&q);
|
||||
assert_eq!(c.dag_id, id);
|
||||
assert_eq!(c.kind.as_str(), expected);
|
||||
|
|
@ -624,6 +630,7 @@ fn failed_node_cancels_downstream_but_afterany_reconcile_runs() {
|
|||
assert_eq!(by_kind("prebuild"), State::Failed);
|
||||
assert_eq!(by_kind("stop_for_update"), State::Cancelled);
|
||||
assert_eq!(by_kind("swap"), State::Cancelled);
|
||||
assert_eq!(by_kind("post_swap"), State::Cancelled);
|
||||
assert_eq!(by_kind("reconcile"), State::Done);
|
||||
assert_eq!(
|
||||
dag.nodes
|
||||
|
|
@ -634,9 +641,10 @@ fn failed_node_cancels_downstream_but_afterany_reconcile_runs() {
|
|||
);
|
||||
}
|
||||
|
||||
/// The swap-failure recovery: `Swap` fails → the `AfterAny` edge still
|
||||
/// runs `Reconcile`, which brings a wanted-up agent back on its old
|
||||
/// config.
|
||||
/// The swap-failure recovery: `Swap` fails → the `AfterOk` `PostSwap` is
|
||||
/// cancel-cascaded → its terminal state still satisfies `Reconcile`'s
|
||||
/// `AfterAny(PostSwap)` edge, so recovery-start runs and brings a wanted-up
|
||||
/// agent back on its old config.
|
||||
#[test]
|
||||
fn swap_failure_still_runs_reconcile() {
|
||||
let q = JobQueue::new(1);
|
||||
|
|
@ -648,12 +656,55 @@ fn swap_failure_still_runs_reconcile() {
|
|||
let swap = claim_one(&q);
|
||||
assert_eq!(swap.kind.as_str(), "swap");
|
||||
q.complete_node(id, swap.node_id, Err("update failed".to_owned()));
|
||||
// PostSwap (AfterOk on the failed Swap) is cancel-cascaded; Reconcile is
|
||||
// next-claimable via its AfterAny(PostSwap) edge.
|
||||
let reconcile = claim_one(&q);
|
||||
assert_eq!(reconcile.kind.as_str(), "reconcile");
|
||||
q.complete_node(id, reconcile.node_id, Ok(()));
|
||||
let all_dags = q.snapshot();
|
||||
let dag = all_dags.iter().find(|d| d.id == id).expect("dag");
|
||||
assert_eq!(
|
||||
dag.nodes
|
||||
.iter()
|
||||
.find(|n| n.kind == "post_swap")
|
||||
.expect("post_swap node")
|
||||
.state,
|
||||
State::Cancelled,
|
||||
"PostSwap must cancel-cascade when Swap fails"
|
||||
);
|
||||
assert_eq!(state_of(&q, id), State::Failed);
|
||||
}
|
||||
|
||||
/// The swap-success path: `Swap` ok → the `AfterOk` `PostSwap` (bookkeeping
|
||||
/// tail) runs, and only then does `Reconcile` fire — serialized behind
|
||||
/// `PostSwap` (not racing it) because `Reconcile` deps `AfterAny(PostSwap)`.
|
||||
#[test]
|
||||
fn swap_ok_runs_post_swap_before_reconcile() {
|
||||
let q = JobQueue::new(1);
|
||||
let id = submit(&q, rebuild("agent-a", "r"));
|
||||
// prebuild + stop_for_update
|
||||
for _ in 0..2 {
|
||||
let c = claim_one(&q);
|
||||
q.complete_node(id, c.node_id, Ok(()));
|
||||
}
|
||||
let swap = claim_one(&q);
|
||||
assert_eq!(swap.kind.as_str(), "swap");
|
||||
q.complete_node(id, swap.node_id, Ok(()));
|
||||
// PostSwap runs next, and nothing else is claimable while it does — the
|
||||
// tail serializes ahead of Reconcile.
|
||||
let post_swap = claim_one(&q);
|
||||
assert_eq!(post_swap.kind.as_str(), "post_swap");
|
||||
assert!(
|
||||
q.claim_ready().is_empty(),
|
||||
"Reconcile must wait for PostSwap, not race it"
|
||||
);
|
||||
q.complete_node(id, post_swap.node_id, Ok(()));
|
||||
let reconcile = claim_one(&q);
|
||||
assert_eq!(reconcile.kind.as_str(), "reconcile");
|
||||
q.complete_node(id, reconcile.node_id, Ok(()));
|
||||
assert_eq!(state_of(&q, id), State::Done);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_reconcile_marks_dag_failed() {
|
||||
let q = JobQueue::new(1);
|
||||
|
|
@ -903,6 +954,7 @@ fn perm_change_shape_prefixes_rebuild_chain() {
|
|||
"prebuild",
|
||||
"stop_for_update",
|
||||
"swap",
|
||||
"post_swap",
|
||||
"reconcile",
|
||||
] {
|
||||
let c = claim_one(&q);
|
||||
|
|
|
|||
Loading…
Reference in a new issue