Fix issue when timer start event is greater than a day (#303)
* Fix issue when start time is greater than a day * Add some cycle timer tests * Add some more tests * Getting ./bin/pyl to pass
This commit is contained in:
parent
122d1efbda
commit
27447e533c
|
@ -1,4 +1,5 @@
|
|||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
from typing import Any
|
||||
|
||||
from SpiffWorkflow.bpmn.parser.util import full_tag # type: ignore
|
||||
|
@ -39,24 +40,23 @@ class StartEvent(DefaultStartEvent): # type: ignore
|
|||
def configuration(self, my_task: SpiffTask, now_in_utc: datetime) -> StartConfiguration:
|
||||
evaluated_expression = self.evaluated_timer_expression(my_task)
|
||||
cycles = 0
|
||||
start_delay_in_seconds = 0
|
||||
duration = 0
|
||||
time_delta = timedelta(seconds=0)
|
||||
|
||||
if evaluated_expression is not None:
|
||||
if isinstance(self.timer_definition, TimeDateEventDefinition):
|
||||
parsed_duration = TimerEventDefinition.parse_time_or_duration(evaluated_expression)
|
||||
time_delta = parsed_duration - now_in_utc
|
||||
start_delay_in_seconds = time_delta.seconds
|
||||
elif isinstance(self.timer_definition, DurationTimerEventDefinition):
|
||||
parsed_duration = TimerEventDefinition.parse_iso_duration(evaluated_expression)
|
||||
time_delta = TimerEventDefinition.get_timedelta_from_start(parsed_duration, now_in_utc)
|
||||
start_delay_in_seconds = time_delta.seconds
|
||||
elif isinstance(self.timer_definition, CycleTimerEventDefinition):
|
||||
cycles, start, cycle_duration = TimerEventDefinition.parse_iso_recurring_interval(evaluated_expression)
|
||||
time_delta = start - now_in_utc + cycle_duration
|
||||
start_delay_in_seconds = time_delta.seconds
|
||||
duration = cycle_duration.seconds
|
||||
|
||||
start_delay_in_seconds = int(time_delta.total_seconds())
|
||||
|
||||
return (cycles, start_delay_in_seconds, duration)
|
||||
|
||||
def evaluated_timer_expression(self, my_task: SpiffTask) -> Any:
|
||||
|
|
|
@ -46,6 +46,14 @@ def example_start_datetime_minus_5_mins_in_utc(
|
|||
yield example_datetime - timedelta(minutes=5)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def example_start_datetime_minus_1_day_and_5_mins_in_utc(
|
||||
example_start_datetime_in_utc_str: str,
|
||||
) -> Generator[datetime, None, None]:
|
||||
example_datetime = datetime.fromisoformat(example_start_datetime_in_utc_str)
|
||||
yield example_datetime - timedelta(days=1, minutes=5)
|
||||
|
||||
|
||||
class CustomBpmnDmnParser(BpmnDmnParser): # type: ignore
|
||||
OVERRIDE_PARSER_CLASSES = {}
|
||||
OVERRIDE_PARSER_CLASSES.update(BpmnDmnParser.OVERRIDE_PARSER_CLASSES)
|
||||
|
@ -85,6 +93,25 @@ class TestWorkflowService(BaseTest):
|
|||
_, delay, _ = WorkflowService.next_start_event_configuration(workflow, now_in_utc) # type: ignore
|
||||
assert delay == 0
|
||||
|
||||
def regular_start_events_have_no_cycles(self, now_in_utc: datetime) -> None:
|
||||
workflow = workflow_from_fragment(
|
||||
"""
|
||||
<bpmn:process id="no_tasks" name="No Tasks" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_184umot</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:endEvent id="Event_0qq9il3">
|
||||
<bpmn:incoming>Flow_184umot</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_184umot" sourceRef="StartEvent_1" targetRef="Event_0qq9il3" />
|
||||
</bpmn:process>
|
||||
""",
|
||||
"no_tasks",
|
||||
)
|
||||
cycles, _, duration = WorkflowService.next_start_event_configuration(workflow, now_in_utc) # type: ignore
|
||||
assert cycles == 0
|
||||
assert duration == 0
|
||||
|
||||
def test_run_at_delay_is_30_for_30_second_duration_start_timer_event(self, now_in_utc: datetime) -> None:
|
||||
workflow = workflow_from_fragment(
|
||||
"""
|
||||
|
@ -106,6 +133,49 @@ class TestWorkflowService(BaseTest):
|
|||
_, delay, _ = WorkflowService.next_start_event_configuration(workflow, now_in_utc) # type: ignore
|
||||
assert delay == 30
|
||||
|
||||
def test_run_at_delay_is_10000_for_10000_second_duration_start_timer_event(self, now_in_utc: datetime) -> None:
|
||||
workflow = workflow_from_fragment(
|
||||
"""
|
||||
<bpmn:process id="Process_aldvgey" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1x1o335</bpmn:outgoing>
|
||||
<bpmn:timerEventDefinition id="TimerEventDefinition_1vi6a54">
|
||||
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression">"PT10000S"</bpmn:timeDuration>
|
||||
</bpmn:timerEventDefinition>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1x1o335" sourceRef="StartEvent_1" targetRef="Event_0upbokh" />
|
||||
<bpmn:endEvent id="Event_0upbokh">
|
||||
<bpmn:incoming>Flow_1x1o335</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
</bpmn:process>
|
||||
""",
|
||||
"Process_aldvgey",
|
||||
)
|
||||
_, delay, _ = WorkflowService.next_start_event_configuration(workflow, now_in_utc) # type: ignore
|
||||
assert delay == 10000
|
||||
|
||||
def test_duration_start_timer_event_have_no_cylces(self, now_in_utc: datetime) -> None:
|
||||
workflow = workflow_from_fragment(
|
||||
"""
|
||||
<bpmn:process id="Process_aldvgey" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1x1o335</bpmn:outgoing>
|
||||
<bpmn:timerEventDefinition id="TimerEventDefinition_1vi6a54">
|
||||
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression">"PT30S"</bpmn:timeDuration>
|
||||
</bpmn:timerEventDefinition>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1x1o335" sourceRef="StartEvent_1" targetRef="Event_0upbokh" />
|
||||
<bpmn:endEvent id="Event_0upbokh">
|
||||
<bpmn:incoming>Flow_1x1o335</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
</bpmn:process>
|
||||
""",
|
||||
"Process_aldvgey",
|
||||
)
|
||||
cycles, _, duration = WorkflowService.next_start_event_configuration(workflow, now_in_utc) # type: ignore
|
||||
assert cycles == 0
|
||||
assert duration == 0
|
||||
|
||||
def test_run_at_delay_is_300_if_5_mins_before_date_start_timer_event(
|
||||
self, example_start_datetime_in_utc_str: str, example_start_datetime_minus_5_mins_in_utc: datetime
|
||||
) -> None:
|
||||
|
@ -130,3 +200,100 @@ class TestWorkflowService(BaseTest):
|
|||
workflow, example_start_datetime_minus_5_mins_in_utc
|
||||
) # type: ignore
|
||||
assert delay == 300
|
||||
|
||||
def test_run_at_delay_is_86700_if_1_day_and_5_mins_before_date_start_timer_event(
|
||||
self, example_start_datetime_in_utc_str: str, example_start_datetime_minus_1_day_and_5_mins_in_utc: datetime
|
||||
) -> None:
|
||||
workflow = workflow_from_fragment(
|
||||
f"""
|
||||
<bpmn:process id="Process_aldvgey" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1x1o335</bpmn:outgoing>
|
||||
<bpmn:timerEventDefinition id="TimerEventDefinition_1vi6a54">
|
||||
<bpmn:timeDate xsi:type="bpmn:tFormalExpression">"{example_start_datetime_in_utc_str}"</bpmn:timeDate>
|
||||
</bpmn:timerEventDefinition>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1x1o335" sourceRef="StartEvent_1" targetRef="Event_0upbokh" />
|
||||
<bpmn:endEvent id="Event_0upbokh">
|
||||
<bpmn:incoming>Flow_1x1o335</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
</bpmn:process>
|
||||
""",
|
||||
"Process_aldvgey",
|
||||
)
|
||||
_, delay, _ = WorkflowService.next_start_event_configuration(
|
||||
workflow, example_start_datetime_minus_1_day_and_5_mins_in_utc
|
||||
) # type: ignore
|
||||
assert delay == 86700
|
||||
|
||||
def date_start_timer_event_has_no_cycles(
|
||||
self, example_start_datetime_in_utc_str: str, example_start_datetime_minus_1_day_and_5_mins_in_utc: datetime
|
||||
) -> None:
|
||||
workflow = workflow_from_fragment(
|
||||
f"""
|
||||
<bpmn:process id="Process_aldvgey" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1x1o335</bpmn:outgoing>
|
||||
<bpmn:timerEventDefinition id="TimerEventDefinition_1vi6a54">
|
||||
<bpmn:timeDate xsi:type="bpmn:tFormalExpression">"{example_start_datetime_in_utc_str}"</bpmn:timeDate>
|
||||
</bpmn:timerEventDefinition>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1x1o335" sourceRef="StartEvent_1" targetRef="Event_0upbokh" />
|
||||
<bpmn:endEvent id="Event_0upbokh">
|
||||
<bpmn:incoming>Flow_1x1o335</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
</bpmn:process>
|
||||
""",
|
||||
"Process_aldvgey",
|
||||
)
|
||||
cycles, _, duration = WorkflowService.next_start_event_configuration(
|
||||
workflow, example_start_datetime_minus_1_day_and_5_mins_in_utc
|
||||
) # type: ignore
|
||||
assert cycles == 0
|
||||
assert duration == 0
|
||||
|
||||
def test_5_cycles_of_30_second_cycle_start_timer_event(self, now_in_utc: datetime) -> None:
|
||||
workflow = workflow_from_fragment(
|
||||
"""
|
||||
<bpmn:process id="Process_aldvgey" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1x1o335</bpmn:outgoing>
|
||||
<bpmn:timerEventDefinition id="TimerEventDefinition_1vi6a54">
|
||||
<bpmn:timeCycle xsi:type="bpmn:tFormalExpression">"R5/PT30S"</bpmn:timeCycle>
|
||||
</bpmn:timerEventDefinition>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1x1o335" sourceRef="StartEvent_1" targetRef="Event_0upbokh" />
|
||||
<bpmn:endEvent id="Event_0upbokh">
|
||||
<bpmn:incoming>Flow_1x1o335</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
</bpmn:process>
|
||||
""",
|
||||
"Process_aldvgey",
|
||||
)
|
||||
cycles, delay, duration = WorkflowService.next_start_event_configuration(workflow, now_in_utc) # type: ignore
|
||||
assert cycles == 5
|
||||
assert delay == 30
|
||||
assert duration == 30
|
||||
|
||||
def test_5_cycles_of_10000_second_cycle_start_timer_event(self, now_in_utc: datetime) -> None:
|
||||
workflow = workflow_from_fragment(
|
||||
"""
|
||||
<bpmn:process id="Process_aldvgey" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1x1o335</bpmn:outgoing>
|
||||
<bpmn:timerEventDefinition id="TimerEventDefinition_1vi6a54">
|
||||
<bpmn:timeCycle xsi:type="bpmn:tFormalExpression">"R5/PT10000S"</bpmn:timeCycle>
|
||||
</bpmn:timerEventDefinition>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1x1o335" sourceRef="StartEvent_1" targetRef="Event_0upbokh" />
|
||||
<bpmn:endEvent id="Event_0upbokh">
|
||||
<bpmn:incoming>Flow_1x1o335</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
</bpmn:process>
|
||||
""",
|
||||
"Process_aldvgey",
|
||||
)
|
||||
cycles, delay, duration = WorkflowService.next_start_event_configuration(workflow, now_in_utc) # type: ignore
|
||||
assert cycles == 5
|
||||
assert delay == 10000
|
||||
assert duration == 10000
|
||||
|
|
Loading…
Reference in New Issue