# --- Test 1: both branches succeed, sync:all --- - parallel: name: Both branches pass key: $(test)_PASS sync: all branches: - name: Branch A steps: - let: name: Set A done values: - branch_a_done: true - name: Branch B steps: - let: name: Set B done values: - branch_b_done: true - check: name: Both branches ran key: $(test)_PASS values: - <| $(branch_a_done) == True |> - <| $(branch_b_done) == True |> # --- Test 2: one branch fails, sync:all + no_fail → parallel forced to PASS --- - parallel: name: One branch fails key: $(test)_PASS sync: all no_fail: true branches: - name: Pass branch steps: - let: name: Set pass flag values: - pass_branch_ran: true - name: Fail branch steps: - py_func: name: Raise exception file: $(test_path)$(psep)parallel.py func_name: sleep_func param: [0] expected_result: fail - check: name: Pass branch still ran key: $(test)_PASS values: - <| $(pass_branch_ran) == True |> # --- Test 3: sync:any — first branch done stops the rest --- - let: name: Reset slow flag values: - slow_done: false - parallel: name: sync any - first wins key: $(test)_PASS sync: any branches: - name: Fast branch steps: - let: name: Fast done values: - fast_done: true - name: Slow branch steps: - py_func: name: Sleep 2s file: $(test_path)$(psep)parallel.py func_name: sleep_func param: [2] - let: name: Slow done values: - slow_done: true - check: name: Fast branch ran, slow branch was stopped key: $(test)_PASS values: - <| $(fast_done) == True |> - <| $(slow_done) == False |> # --- Test 4: wait_for — branch B waits for A to set a flag --- - let: name: Reset sync flag values: - sync_flag: "" - waiter_ran: false - parallel: name: wait_for synchronization key: $(test)_PASS sync: all branches: - name: Setter branch steps: - py_func: name: Sleep 0.3s then set flag file: $(test_path)$(psep)parallel.py func_name: sleep_func param: [0.3] - let: name: Set sync flag values: - sync_flag: ready - name: Waiter branch wait_for: condition: <| "$(sync_flag)" == "ready" |> timeout: 10 steps: - let: name: Got flag values: - waiter_ran: true - check: name: Waiter branch ran after flag was set key: $(test)_PASS values: - <| $(waiter_ran) == True |> # --- Test 5: parallel is faster than sequential (timing) --- # Two 1s sleeps in parallel → ~1s total, not ~2s sequential - parallel: name: Timing test key: $(test)_PASS sync: all branches: - name: Sleep A steps: - sleep: name: Sleep 1s A timeout: 1 - name: Sleep B steps: - sleep: name: Sleep 1s B timeout: 1 - let: name: Capture parallel duration values: - parallel_duration: $(ts_duration_Timing test) - check: name: Duration < 1.8s (would be 2s if sequential) key: $(test)_PASS values: - <| float("$(parallel_duration)") < 1.8 |> # --- Test 6: more than two branches --- - let: name: Reset N flags values: - n_a: false - n_b: false - n_c: false - n_d: false - parallel: name: Four branches key: $(test)_PASS sync: all branches: - name: NA steps: - let: {name: set n_a, values: [{n_a: true}]} - name: NB steps: - let: {name: set n_b, values: [{n_b: true}]} - name: NC steps: - let: {name: set n_c, values: [{n_c: true}]} - name: ND steps: - let: {name: set n_d, values: [{n_d: true}]} - check: name: Four branches all set their flag key: $(test)_PASS values: - <| $(n_a) == True |> - <| $(n_b) == True |> - <| $(n_c) == True |> - <| $(n_d) == True |> # --- Test 7: nested parallel --- - let: name: Reset nested flags values: - outer_x: false - inner_x_1: false - inner_x_2: false - parallel: name: Outer parallel key: $(test)_PASS sync: all branches: - name: Outer X steps: - let: {name: set outer_x, values: [{outer_x: true}]} - parallel: name: Inner parallel sync: all branches: - name: Inner X1 steps: - let: {name: set inner_x_1, values: [{inner_x_1: true}]} - name: Inner X2 steps: - let: {name: set inner_x_2, values: [{inner_x_2: true}]} - name: Outer Y steps: - sleep: name: brief sleep timeout: 0 - check: name: Nested parallel set all flags key: $(test)_PASS values: - <| $(outer_x) == True |> - <| $(inner_x_1) == True |> - <| $(inner_x_2) == True |> # --- Test 9: wait_for timeout --- - let: name: Reset waiter timeout flag values: - waiter_timeout_ran: false - parallel: name: wait_for timeout key: $(test)_PASS sync: all no_fail: true branches: - name: Quick branch steps: - sleep: name: brief sleep timeout: 0 - name: Doomed waiter wait_for: condition: <| "never" == "ready" |> timeout: 1 steps: - let: {name: should not run, values: [{waiter_timeout_ran: true}]} - check: name: Doomed waiter never ran its steps key: $(test)_PASS values: - <| $(waiter_timeout_ran) == False |> # --- Test 10: sync:all with a real branch failure (parallel must FAIL) --- - parallel: name: One branch really fails key: $(test)_FAIL sync: all branches: - name: ok branch steps: - let: {name: noop, values: [{noop_var: 1}]} - name: broken branch steps: - py_func: name: Forced fail file: $(test_path)$(psep)parallel.py func_name: sleep_func param: [0] expected_result: fail # --- Test 11: branch with unmet condition is skipped, not failing the parallel --- - let: name: Reset branch condition flag values: - cond_branch_ran: false - other_branch_ran: false - parallel: name: Condition-skipped branch key: $(test)_PASS sync: all branches: - name: Skipped branch condition: <| "always" == "false" |> steps: - let: {name: should not run, values: [{cond_branch_ran: true}]} - name: Other branch steps: - let: {name: ran, values: [{other_branch_ran: true}]} - check: name: Skipped condition branch did not run key: $(test)_PASS values: - <| $(cond_branch_ran) == False |> - <| $(other_branch_ran) == True |> # --- Test 8: parallel inside loop (re-execution) --- - let: name: Reset loop counters values: - loop_count_a: 0 - loop_count_b: 0 - loop: name: Loop wrapping parallel iterator: 3 steps: - parallel: name: Per-iteration parallel sync: all branches: - name: LA steps: - let: name: bump A values: - loop_count_a: <| int("$(loop_count_a)") + 1 |> - name: LB steps: - let: name: bump B values: - loop_count_b: <| int("$(loop_count_b)") + 1 |> - check: name: Both branches ran 3 times key: $(test)_PASS values: - <| int("$(loop_count_a)") == 3 |> - <| int("$(loop_count_b)") == 3 |>