mirror of
https://github.com/hatchet-dev/hatchet.git
synced 2025-12-31 13:49:48 -06:00
* feat: start wiring up defaults * feat: add test coverage * fix: test docs * feat: expand tests * fix: rm validators for now * chore: minor version * fix: skip prio tests in ci for now * chore: docs * debug: attempt to fix prio test by running with a single slot and no concurrency * fix: python script to apply patches * chore; gen * feat: atomic patches * fix: rm sed-based patches * fix: use current tz * fix: ordering
185 lines
5.4 KiB
Python
185 lines
5.4 KiB
Python
"""
|
|
IMPORTANT
|
|
----------
|
|
|
|
These tests are intended to prevent us from changing defaults in one place and
|
|
forgetting to change them in other places, or otherwise breaking the default handling logic.
|
|
If you get a failure here, you likely changed the default values for some of the params (below)
|
|
in one of the task decorators e.g. `Workflow.task`, etc.
|
|
|
|
The intention of these tests is to:
|
|
1. Ensure that the behavior of falling back to `TaskDefaults` works as expected, which means that
|
|
if no value for a certain parameter to one of these decorators is provided, it should fall back to the
|
|
value in `TaskDefaults` if one is set.
|
|
2. Ensure that the default values set in the rest of the codebase don't change, and are consistent with each other.
|
|
|
|
If you change the default values for any of these parameters, please update the tests accordingly.
|
|
"""
|
|
|
|
from datetime import timedelta
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
from hatchet_sdk import Context, DurableContext, EmptyModel, Hatchet, Task, TaskDefaults
|
|
|
|
|
|
def dummy_task(input: EmptyModel, context: Context) -> dict[str, str]:
|
|
return {"foo": "bar"}
|
|
|
|
|
|
def dummy_durable_task(input: EmptyModel, context: DurableContext) -> dict[str, str]:
|
|
return {"foo": "bar"}
|
|
|
|
|
|
DEFAULT_SCHEDULE_TIMEOUT = timedelta(minutes=5)
|
|
DEFAULT_EXECUTION_TIMEOUT = timedelta(seconds=60)
|
|
DEFAULT_RETRIES = 0
|
|
DEFAULT_BACKOFF_FACTOR = None
|
|
DEFAULT_BACKOFF_MAX_SECONDS = None
|
|
|
|
|
|
def task(
|
|
hatchet: Hatchet,
|
|
is_durable: bool,
|
|
task_defaults: TaskDefaults,
|
|
**kwargs: Any,
|
|
) -> Task[EmptyModel, dict[str, str]]:
|
|
workflow = hatchet.workflow(
|
|
name="foo",
|
|
task_defaults=task_defaults,
|
|
)
|
|
|
|
task_fn = workflow.durable_task if is_durable else workflow.task
|
|
|
|
return task_fn(**kwargs)(dummy_durable_task if is_durable else dummy_task) # type: ignore
|
|
|
|
|
|
def standalone_task(
|
|
hatchet: Hatchet,
|
|
is_durable: bool,
|
|
**kwargs: Any,
|
|
) -> Task[EmptyModel, dict[str, str]]:
|
|
task_fn = hatchet.durable_task if is_durable else hatchet.task
|
|
|
|
return task_fn(**kwargs)(dummy_durable_task if is_durable else task)._task # type: ignore
|
|
|
|
|
|
@pytest.mark.parametrize("is_durable", [False, True])
|
|
def test_task_defaults_applied_correctly(hatchet: Hatchet, is_durable: bool) -> None:
|
|
schedule_timeout = timedelta(seconds=3)
|
|
execution_timeout = timedelta(seconds=1)
|
|
retries = 4
|
|
backoff_factor = 1
|
|
backoff_max_seconds = 5
|
|
|
|
t = task(
|
|
hatchet=hatchet,
|
|
is_durable=is_durable,
|
|
task_defaults=TaskDefaults(
|
|
schedule_timeout=schedule_timeout,
|
|
execution_timeout=execution_timeout,
|
|
retries=retries,
|
|
backoff_factor=backoff_factor,
|
|
backoff_max_seconds=backoff_max_seconds,
|
|
),
|
|
)
|
|
|
|
assert t.schedule_timeout == schedule_timeout
|
|
assert t.execution_timeout == execution_timeout
|
|
assert t.retries == retries
|
|
assert t.backoff_factor == backoff_factor
|
|
assert t.backoff_max_seconds == backoff_max_seconds
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"is_durable,is_standalone",
|
|
[
|
|
(False, False),
|
|
(True, False),
|
|
(False, True),
|
|
(True, True),
|
|
],
|
|
)
|
|
def test_fallbacking_ensure_default_unchanged(
|
|
hatchet: Hatchet, is_durable: bool, is_standalone: bool
|
|
) -> None:
|
|
t = task(
|
|
hatchet=hatchet,
|
|
is_durable=is_durable,
|
|
task_defaults=TaskDefaults(),
|
|
)
|
|
|
|
"""If this test fails, it means that you changed the default values for the params to one of the `task` or `durable_task` decorators"""
|
|
assert t.schedule_timeout == DEFAULT_SCHEDULE_TIMEOUT
|
|
assert t.execution_timeout == DEFAULT_EXECUTION_TIMEOUT
|
|
assert t.retries == DEFAULT_RETRIES
|
|
assert t.backoff_factor == DEFAULT_BACKOFF_FACTOR
|
|
assert t.backoff_max_seconds == DEFAULT_BACKOFF_MAX_SECONDS
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"is_durable,is_standalone",
|
|
[
|
|
(False, False),
|
|
(True, False),
|
|
(False, True),
|
|
(True, True),
|
|
],
|
|
)
|
|
def test_defaults_correctly_overridden_by_params_passed_in(
|
|
hatchet: Hatchet, is_durable: bool, is_standalone: bool
|
|
) -> None:
|
|
t = task(
|
|
hatchet=hatchet,
|
|
is_durable=is_durable,
|
|
task_defaults=TaskDefaults(
|
|
schedule_timeout=timedelta(seconds=3),
|
|
execution_timeout=timedelta(seconds=1),
|
|
retries=4,
|
|
backoff_factor=1,
|
|
backoff_max_seconds=5,
|
|
),
|
|
schedule_timeout=timedelta(seconds=9),
|
|
execution_timeout=timedelta(seconds=2),
|
|
retries=6,
|
|
backoff_factor=3,
|
|
backoff_max_seconds=5,
|
|
)
|
|
|
|
assert t.schedule_timeout == timedelta(seconds=9)
|
|
assert t.execution_timeout == timedelta(seconds=2)
|
|
assert t.retries == 6
|
|
assert t.backoff_factor == 3
|
|
assert t.backoff_max_seconds == 5
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"is_durable,is_standalone",
|
|
[
|
|
(False, False),
|
|
(True, False),
|
|
(False, True),
|
|
(True, True),
|
|
],
|
|
)
|
|
def test_params_correctly_set_with_no_defaults(
|
|
hatchet: Hatchet, is_durable: bool, is_standalone: bool
|
|
) -> None:
|
|
t = task(
|
|
hatchet=hatchet,
|
|
is_durable=is_durable,
|
|
task_defaults=TaskDefaults(),
|
|
schedule_timeout=timedelta(seconds=9),
|
|
execution_timeout=timedelta(seconds=2),
|
|
retries=6,
|
|
backoff_factor=3,
|
|
backoff_max_seconds=5,
|
|
)
|
|
|
|
assert t.schedule_timeout == timedelta(seconds=9)
|
|
assert t.execution_timeout == timedelta(seconds=2)
|
|
assert t.retries == 6
|
|
assert t.backoff_factor == 3
|
|
assert t.backoff_max_seconds == 5
|