|
22 | 22 |
|
23 | 23 | from airflow.sdk.definitions.asset import Asset
|
24 | 24 | from airflow.sdk.definitions.asset.decorators import _AssetMainOperator, asset
|
| 25 | +from airflow.sdk.definitions.decorators import task |
25 | 26 | from airflow.sdk.execution_time.comms import AssetResult, GetAssetByName
|
26 | 27 |
|
27 | 28 |
|
@@ -159,6 +160,27 @@ def example_asset_func(self, /):
|
159 | 160 | == "positional-only argument 'self' without a default is not supported in @asset"
|
160 | 161 | )
|
161 | 162 |
|
| 163 | + def test_with_task_decorator(self, func_fixer): |
| 164 | + @task(retries=3) |
| 165 | + @func_fixer |
| 166 | + def _example_task_func(): |
| 167 | + return "This is example_task" |
| 168 | + |
| 169 | + asset_definition = asset(name="asset", dag_id="dag", schedule=None)(_example_task_func) |
| 170 | + assert asset_definition.name == "asset" |
| 171 | + assert asset_definition._source.dag_id == "dag" |
| 172 | + assert asset_definition._function == _example_task_func |
| 173 | + |
| 174 | + def test_with_task_decorator_and_outlets(self, func_fixer): |
| 175 | + @task(retries=3, outlets=Asset(name="a")) |
| 176 | + @func_fixer |
| 177 | + def _example_task_func(): |
| 178 | + return "This is example_task" |
| 179 | + |
| 180 | + with pytest.raises(TypeError) as err: |
| 181 | + asset(schedule=None)(_example_task_func) |
| 182 | + assert err.value.args[0] == "@task decorator with 'outlets' argument is not supported in @asset" |
| 183 | + |
162 | 184 | @pytest.mark.parametrize(
|
163 | 185 | "provided_uri, expected_uri",
|
164 | 186 | [
|
@@ -222,6 +244,36 @@ def test__attrs_post_init__(self, DAG, from_definition, example_asset_func_with_
|
222 | 244 | )
|
223 | 245 | from_definition.assert_called_once_with(asset_definition)
|
224 | 246 |
|
| 247 | + @mock.patch("airflow.sdk.bases.decorator._TaskDecorator.__call__") |
| 248 | + @mock.patch("airflow.sdk.definitions.dag.DAG") |
| 249 | + def test_with_task_decorator(self, DAG, __call__, func_fixer): |
| 250 | + @task(retries=3) |
| 251 | + @func_fixer |
| 252 | + def _example_task_func(): |
| 253 | + return "This is example_task" |
| 254 | + |
| 255 | + asset_definition = asset(schedule=None, uri="s3://bucket/object", group="MLModel", extra={"k": "v"})( |
| 256 | + _example_task_func |
| 257 | + ) |
| 258 | + |
| 259 | + DAG.assert_called_once_with( |
| 260 | + dag_id="example_asset_func", |
| 261 | + dag_display_name="example_asset_func", |
| 262 | + description=None, |
| 263 | + schedule=None, |
| 264 | + catchup=False, |
| 265 | + is_paused_upon_creation=None, |
| 266 | + on_failure_callback=None, |
| 267 | + on_success_callback=None, |
| 268 | + params=None, |
| 269 | + access_control=None, |
| 270 | + owner_links={}, |
| 271 | + tags=set(), |
| 272 | + auto_register=True, |
| 273 | + ) |
| 274 | + __call__.assert_called_once_with() |
| 275 | + assert asset_definition._function.kwargs["outlets"] == [asset_definition] |
| 276 | + |
225 | 277 |
|
226 | 278 | class TestMultiAssetDefinition:
|
227 | 279 | @mock.patch("airflow.sdk.definitions.asset.decorators._AssetMainOperator.from_definition")
|
@@ -249,6 +301,37 @@ def test__attrs_post_init__(self, DAG, from_definition, example_asset_func_with_
|
249 | 301 | )
|
250 | 302 | from_definition.assert_called_once_with(definition)
|
251 | 303 |
|
| 304 | + @mock.patch("airflow.sdk.bases.decorator._TaskDecorator.__call__") |
| 305 | + @mock.patch("airflow.sdk.definitions.dag.DAG") |
| 306 | + def test_with_task_decorator(self, DAG, __call__, func_fixer): |
| 307 | + @task(retries=3) |
| 308 | + @func_fixer |
| 309 | + def _example_task_func(): |
| 310 | + return "This is example_task" |
| 311 | + |
| 312 | + definition = asset.multi( |
| 313 | + schedule=None, |
| 314 | + outlets=[Asset(name="a"), Asset(name="b")], |
| 315 | + )(_example_task_func) |
| 316 | + |
| 317 | + DAG.assert_called_once_with( |
| 318 | + dag_id="example_asset_func", |
| 319 | + dag_display_name="example_asset_func", |
| 320 | + description=None, |
| 321 | + schedule=None, |
| 322 | + catchup=False, |
| 323 | + is_paused_upon_creation=None, |
| 324 | + on_failure_callback=None, |
| 325 | + on_success_callback=None, |
| 326 | + params=None, |
| 327 | + access_control=None, |
| 328 | + owner_links={}, |
| 329 | + tags=set(), |
| 330 | + auto_register=True, |
| 331 | + ) |
| 332 | + __call__.assert_called_once_with() |
| 333 | + assert definition._function.kwargs["outlets"] == [Asset(name="a"), Asset(name="b")] |
| 334 | + |
252 | 335 |
|
253 | 336 | class Test_AssetMainOperator:
|
254 | 337 | def test_from_definition(self, example_asset_func_with_valid_arg_as_inlet_asset):
|
|
0 commit comments