use super::*;
use crate::workflow::{
test_support::{agent_node, id, state, workflow},
WorkspaceAccess,
};
#[test]
fn terminal_nodes_cannot_return_to_ready() {
assert!(matches!(
validate_transition(
&id("node"),
&NodeState::Terminal {
outcome: NodeTerminalState::Success
},
&NodeState::Ready
),
Err(WorkflowError::IllegalTransition { .. })
));
}
#[test]
fn allowed_failure_does_not_change_workflow_outcome() {
let mut optional = agent_node("optional", &[], WorkspaceAccess::Mutating);
optional.allow_failure = true;
let workflow = workflow(vec![
agent_node("required", &[], WorkspaceAccess::Mutating),
optional,
]);
let mut state = state(&workflow);
state.lifecycle = RunLifecycle::Completed;
state.nodes.insert(
id("required"),
NodeState::Terminal {
outcome: NodeTerminalState::Success,
},
);
state.nodes.insert(
id("optional"),
NodeState::Terminal {
outcome: NodeTerminalState::Failure,
},
);
assert_eq!(
derive_workflow_outcome(&workflow, &state),
Some(WorkflowOutcome::Success)
);
}
#[test]
fn completed_lifecycle_requires_every_node_to_be_terminal() {
let workflow = workflow(vec![agent_node("required", &[], WorkspaceAccess::Mutating)]);
let mut state = state(&workflow);
state.lifecycle = RunLifecycle::Running;
assert!(matches!(
validate_lifecycle_transition(&workflow, &state, RunLifecycle::Completed),
Err(WorkflowError::Scheduler(message))
if message == "completed workflow contains non-terminal nodes"
));
}
#[test]
fn optional_node_cancellation_derives_cancellation_without_request() {
let mut optional = agent_node("optional", &[], WorkspaceAccess::Mutating);
optional.allow_failure = true;
let workflow = workflow(vec![
agent_node("required", &[], WorkspaceAccess::Mutating),
optional,
]);
let mut state = state(&workflow);
state.lifecycle = RunLifecycle::Completed;
state.nodes.insert(
id("required"),
NodeState::Terminal {
outcome: NodeTerminalState::Success,
},
);
state.nodes.insert(
id("optional"),
NodeState::Terminal {
outcome: NodeTerminalState::Cancellation,
},
);
assert_eq!(
derive_workflow_outcome(&workflow, &state),
Some(WorkflowOutcome::Cancellation)
);
}
#[test]
fn required_node_cancellation_derives_cancellation() {
let workflow = workflow(vec![agent_node("required", &[], WorkspaceAccess::Mutating)]);
let mut state = state(&workflow);
state.lifecycle = RunLifecycle::Completed;
state.nodes.insert(
id("required"),
NodeState::Terminal {
outcome: NodeTerminalState::Cancellation,
},
);
assert_eq!(
derive_workflow_outcome(&workflow, &state),
Some(WorkflowOutcome::Cancellation)
);
}