Skip to content

Commit 6b03645

Browse files
committed
[v3-0-test] Bugfix: Logical date isn't populated in Context vars: (#50898)
The tests was overusing mocking so the error was hidden! I found that while migrating `ti.run()` to Task SDK execution path. (cherry picked from commit e52e8ac) Co-authored-by: Kaxil Naik <kaxilnaik@gmail.com>
1 parent e3e1c4a commit 6b03645

File tree

2 files changed

+34
-45
lines changed

2 files changed

+34
-45
lines changed

task-sdk/src/airflow/sdk/execution_time/context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ def context_to_airflow_vars(context: Mapping[str, Any], in_env_var_format: bool
688688
(task, "owner", "AIRFLOW_CONTEXT_DAG_OWNER"),
689689
(task_instance, "dag_id", "AIRFLOW_CONTEXT_DAG_ID"),
690690
(task_instance, "task_id", "AIRFLOW_CONTEXT_TASK_ID"),
691-
(task_instance, "logical_date", "AIRFLOW_CONTEXT_LOGICAL_DATE"),
691+
(dag_run, "logical_date", "AIRFLOW_CONTEXT_LOGICAL_DATE"),
692692
(task_instance, "try_number", "AIRFLOW_CONTEXT_TRY_NUMBER"),
693693
(dag_run, "run_id", "AIRFLOW_CONTEXT_DAG_RUN_ID"),
694694
]

task-sdk/tests/task_sdk/execution_time/test_context.py

Lines changed: 33 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717

1818
from __future__ import annotations
1919

20-
from datetime import datetime
2120
from unittest import mock
2221
from unittest.mock import MagicMock, patch
2322

2423
import pytest
2524

26-
from airflow.sdk import get_current_context
25+
from airflow.sdk import BaseOperator, get_current_context
2726
from airflow.sdk.api.datamodels._generated import AssetEventResponse, AssetResponse
2827
from airflow.sdk.definitions.asset import (
2928
Asset,
@@ -117,75 +116,65 @@ def test_convert_variable_result_to_variable_with_deserialize_json():
117116

118117

119118
class TestAirflowContextHelpers:
120-
def setup_method(self):
121-
self.dag_id = "dag_id"
122-
self.task_id = "task_id"
123-
self.try_number = 1
124-
self.logical_date = "2017-05-21T00:00:00"
125-
self.dag_run_id = "dag_run_id"
126-
self.owner = ["owner1", "owner2"]
127-
self.email = ["email1@test.com"]
128-
self.context = {
129-
"dag_run": mock.MagicMock(
130-
name="dag_run",
131-
run_id=self.dag_run_id,
132-
logical_date=datetime.strptime(self.logical_date, "%Y-%m-%dT%H:%M:%S"),
133-
),
134-
"task_instance": mock.MagicMock(
135-
name="task_instance",
136-
task_id=self.task_id,
137-
dag_id=self.dag_id,
138-
try_number=self.try_number,
139-
logical_date=datetime.strptime(self.logical_date, "%Y-%m-%dT%H:%M:%S"),
140-
),
141-
"task": mock.MagicMock(name="task", owner=self.owner, email=self.email),
142-
}
143-
144119
def test_context_to_airflow_vars_empty_context(self):
145120
assert context_to_airflow_vars({}) == {}
146121

147-
def test_context_to_airflow_vars_all_context(self):
148-
assert context_to_airflow_vars(self.context) == {
149-
"airflow.ctx.dag_id": self.dag_id,
150-
"airflow.ctx.logical_date": self.logical_date,
151-
"airflow.ctx.task_id": self.task_id,
152-
"airflow.ctx.dag_run_id": self.dag_run_id,
153-
"airflow.ctx.try_number": str(self.try_number),
122+
def test_context_to_airflow_vars_all_context(self, create_runtime_ti):
123+
task = BaseOperator(
124+
task_id="test_context_vars",
125+
owner=["owner1", "owner2"],
126+
email="email1@test.com",
127+
)
128+
129+
rti = create_runtime_ti(
130+
task=task,
131+
dag_id="dag_id",
132+
run_id="dag_run_id",
133+
logical_date="2017-05-21T00:00:00Z",
134+
try_number=1,
135+
)
136+
context = rti.get_template_context()
137+
assert context_to_airflow_vars(context) == {
138+
"airflow.ctx.dag_id": "dag_id",
139+
"airflow.ctx.logical_date": "2017-05-21T00:00:00+00:00",
140+
"airflow.ctx.task_id": "test_context_vars",
141+
"airflow.ctx.dag_run_id": "dag_run_id",
142+
"airflow.ctx.try_number": "1",
154143
"airflow.ctx.dag_owner": "owner1,owner2",
155144
"airflow.ctx.dag_email": "email1@test.com",
156145
}
157146

158-
assert context_to_airflow_vars(self.context, in_env_var_format=True) == {
159-
"AIRFLOW_CTX_DAG_ID": self.dag_id,
160-
"AIRFLOW_CTX_LOGICAL_DATE": self.logical_date,
161-
"AIRFLOW_CTX_TASK_ID": self.task_id,
162-
"AIRFLOW_CTX_TRY_NUMBER": str(self.try_number),
163-
"AIRFLOW_CTX_DAG_RUN_ID": self.dag_run_id,
147+
assert context_to_airflow_vars(context, in_env_var_format=True) == {
148+
"AIRFLOW_CTX_DAG_ID": "dag_id",
149+
"AIRFLOW_CTX_LOGICAL_DATE": "2017-05-21T00:00:00+00:00",
150+
"AIRFLOW_CTX_TASK_ID": "test_context_vars",
151+
"AIRFLOW_CTX_TRY_NUMBER": "1",
152+
"AIRFLOW_CTX_DAG_RUN_ID": "dag_run_id",
164153
"AIRFLOW_CTX_DAG_OWNER": "owner1,owner2",
165154
"AIRFLOW_CTX_DAG_EMAIL": "email1@test.com",
166155
}
167156

168-
def test_context_to_airflow_vars_with_default_context_vars(self):
157+
def test_context_to_airflow_vars_from_policy(self):
169158
with mock.patch("airflow.settings.get_airflow_context_vars") as mock_method:
170159
airflow_cluster = "cluster-a"
171160
mock_method.return_value = {"airflow_cluster": airflow_cluster}
172161

173-
context_vars = context_to_airflow_vars(self.context)
162+
context_vars = context_to_airflow_vars({})
174163
assert context_vars["airflow.ctx.airflow_cluster"] == airflow_cluster
175164

176-
context_vars = context_to_airflow_vars(self.context, in_env_var_format=True)
165+
context_vars = context_to_airflow_vars({}, in_env_var_format=True)
177166
assert context_vars["AIRFLOW_CTX_AIRFLOW_CLUSTER"] == airflow_cluster
178167

179168
with mock.patch("airflow.settings.get_airflow_context_vars") as mock_method:
180169
mock_method.return_value = {"airflow_cluster": [1, 2]}
181170
with pytest.raises(TypeError) as error:
182-
context_to_airflow_vars(self.context)
171+
context_to_airflow_vars({})
183172
assert str(error.value) == "value of key <airflow_cluster> must be string, not <class 'list'>"
184173

185174
with mock.patch("airflow.settings.get_airflow_context_vars") as mock_method:
186175
mock_method.return_value = {1: "value"}
187176
with pytest.raises(TypeError) as error:
188-
context_to_airflow_vars(self.context)
177+
context_to_airflow_vars({})
189178
assert str(error.value) == "key <1> must be string"
190179

191180

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy