mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
55 lines
2.1 KiB
Python
55 lines
2.1 KiB
Python
"""A workflow the user deleted or switched off must not run from ANY path.
|
|
|
|
Eric: "if the workflow is toggled off or deleted, it shouldn't be able to run ever, even as a
|
|
detached head". Guarding individual call sites left every unguarded caller able to fire it, so the
|
|
invariant lives in the executor where all of them converge.
|
|
"""
|
|
|
|
import asyncio
|
|
from datetime import datetime
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from backend.apps.workflows import executor
|
|
from backend.apps.workflows.models import ScheduleConfig, Workflow, WorkflowStep
|
|
|
|
|
|
def p_wf(enabled: bool, deleted: bool = False) -> Workflow:
|
|
wf = Workflow(
|
|
title="t",
|
|
steps=[WorkflowStep(text="say hi", enabled=True)],
|
|
schedule=ScheduleConfig(enabled=enabled),
|
|
)
|
|
if deleted:
|
|
wf.deleted_at = datetime.now()
|
|
return wf
|
|
|
|
|
|
@pytest.mark.parametrize("trigger", ["schedule", "retry", "manual"])
|
|
def test_a_deleted_workflow_never_runs_from_any_trigger(trigger):
|
|
wf = p_wf(enabled=True, deleted=True)
|
|
with patch.object(executor.storage, "get_workflow", return_value=wf):
|
|
run = asyncio.run(executor.execute(wf, triggered_by=trigger))
|
|
assert run.status == "skipped"
|
|
assert run.error == "Workflow deleted"
|
|
|
|
|
|
@pytest.mark.parametrize("trigger", ["schedule", "retry", "manual"])
|
|
def test_a_paused_workflow_never_runs_from_any_trigger(trigger):
|
|
"""Off means off: even the Run Now route cannot start a workflow the user switched off."""
|
|
wf = p_wf(enabled=False)
|
|
with patch.object(executor.storage, "get_workflow", return_value=wf):
|
|
run = asyncio.run(executor.execute(wf, triggered_by=trigger))
|
|
assert run.status == "skipped"
|
|
assert run.error == "Workflow is paused"
|
|
|
|
|
|
def test_turning_it_back_on_lets_it_run_again():
|
|
"""The guard must be about state, not a permanent block."""
|
|
wf = p_wf(enabled=True)
|
|
with patch.object(executor.storage, "get_workflow", return_value=wf):
|
|
with patch.object(executor.storage, "record_run"):
|
|
with patch.object(executor, "_monthly_spend_so_far", return_value=0.0):
|
|
assert executor.storage.get_workflow(wf.id).schedule.enabled is True
|