wfe_core/primitives/
sequence.rs1use async_trait::async_trait;
2use serde_json::json;
3
4use crate::models::ExecutionResult;
5use crate::traits::step::{StepBody, StepExecutionContext};
6
7#[derive(Default)]
10pub struct SequenceStep;
11
12#[async_trait]
13impl StepBody for SequenceStep {
14 async fn run(&mut self, context: &StepExecutionContext<'_>) -> crate::Result<ExecutionResult> {
15 let mut scope = context.execution_pointer.scope.clone();
16 scope.push(context.execution_pointer.id.clone());
17
18 if context.workflow.is_branch_complete(&scope) {
19 Ok(ExecutionResult::next())
20 } else {
21 Ok(ExecutionResult::persist(json!({"children_active": true})))
22 }
23 }
24}
25
26#[cfg(test)]
27mod tests {
28 use super::*;
29 use crate::models::{ExecutionPointer, PointerStatus};
30 use crate::primitives::test_helpers::*;
31
32 #[tokio::test]
33 async fn children_complete_proceeds() {
34 let mut step = SequenceStep;
35 let pointer = ExecutionPointer::new(0);
36 let wf_step = default_step();
37
38 let mut workflow = default_workflow();
39 let mut child = ExecutionPointer::new(1);
40 child.scope = vec![pointer.id.clone()];
41 child.status = PointerStatus::Complete;
42 workflow.execution_pointers.push(child);
43
44 let ctx = make_context(&pointer, &wf_step, &workflow);
45 let result = step.run(&ctx).await.unwrap();
46 assert!(result.proceed);
47 }
48
49 #[tokio::test]
50 async fn children_incomplete_persists() {
51 let mut step = SequenceStep;
52 let pointer = ExecutionPointer::new(0);
53 let wf_step = default_step();
54
55 let mut workflow = default_workflow();
56 let mut child = ExecutionPointer::new(1);
57 child.scope = vec![pointer.id.clone()];
58 child.status = PointerStatus::Running;
59 workflow.execution_pointers.push(child);
60
61 let ctx = make_context(&pointer, &wf_step, &workflow);
62 let result = step.run(&ctx).await.unwrap();
63 assert!(!result.proceed);
64 assert_eq!(
65 result.persistence_data,
66 Some(json!({"children_active": true}))
67 );
68 }
69
70 #[tokio::test]
71 async fn no_children_in_scope_proceeds() {
72 let mut step = SequenceStep;
73 let pointer = ExecutionPointer::new(0);
74 let wf_step = default_step();
75 let workflow = default_workflow();
76
77 let ctx = make_context(&pointer, &wf_step, &workflow);
78 let result = step.run(&ctx).await.unwrap();
79 assert!(result.proceed);
81 }
82}