Skip to content

Commit c355832

Browse files
VladaZakharovadabla
authored andcommitted
Fix ValueError in def operators in google provider (apache#55821)
1 parent 5755343 commit c355832

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

providers/google/src/airflow/providers/google/cloud/links/base.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from __future__ import annotations
1919

2020
from typing import TYPE_CHECKING, ClassVar
21+
from urllib.parse import urlparse
2122

2223
from airflow.providers.google.version_compat import (
2324
AIRFLOW_V_3_0_PLUS,
@@ -109,6 +110,14 @@ def get_link(
109110
if TYPE_CHECKING:
110111
assert isinstance(operator, (GoogleCloudBaseOperator, BaseSensorOperator))
111112

113+
# In cases when worker passes execution to trigger, the value that is put to XCom
114+
# already contains link to the object in string format. In this case we don't want to execute
115+
# get_config() again. Instead we can leave this value without any changes
116+
link_value = XCom.get_value(key=self.key, ti_key=ti_key)
117+
if link_value and isinstance(link_value, str):
118+
if urlparse(link_value).scheme in ("http", "https"):
119+
return link_value
120+
112121
conf = self.get_config(operator, ti_key)
113122
if not conf:
114123
return ""

providers/google/tests/unit/google/cloud/links/test_base_link.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929

3030
if AIRFLOW_V_3_0_PLUS:
3131
from airflow.sdk.execution_time.comms import XComResult
32+
from airflow.sdk.execution_time.xcom import XCom
33+
else:
34+
from airflow.models.xcom import XCom # type: ignore[no-redef]
3235

3336
TEST_LOCATION = "test-location"
3437
TEST_CLUSTER_ID = "test-cluster-id"
@@ -128,3 +131,73 @@ def test_get_link(self, create_task_instance_of_operator, session, mock_supervis
128131
)
129132
actual_url = link.get_link(operator=ti.task, ti_key=ti.key)
130133
assert actual_url == expected_url
134+
135+
@pytest.mark.db_test
136+
@mock.patch.object(XCom, "get_value")
137+
def test_get_link_uses_xcom_url_and_skips_get_config(
138+
self,
139+
mock_get_value,
140+
create_task_instance_of_operator,
141+
session,
142+
):
143+
xcom_url = "https://console.cloud.google.com/some/service?project=test-proj"
144+
mock_get_value.return_value = xcom_url
145+
146+
link = GoogleLink()
147+
ti = create_task_instance_of_operator(
148+
MyOperator,
149+
dag_id="test_link_dag",
150+
task_id="test_link_task",
151+
location=TEST_LOCATION,
152+
cluster_id=TEST_CLUSTER_ID,
153+
project_id=TEST_PROJECT_ID,
154+
)
155+
session.add(ti)
156+
session.commit()
157+
158+
with mock.patch.object(GoogleLink, "get_config", autospec=True) as m_get_config:
159+
actual_url = link.get_link(operator=ti.task, ti_key=ti.key)
160+
161+
assert actual_url == xcom_url
162+
m_get_config.assert_not_called()
163+
164+
@pytest.mark.db_test
165+
@mock.patch.object(XCom, "get_value")
166+
def test_get_link_falls_back_to_get_config_when_xcom_not_http(
167+
self,
168+
mock_get_value,
169+
create_task_instance_of_operator,
170+
session,
171+
):
172+
mock_get_value.return_value = "gs://bucket/path"
173+
174+
link = GoogleLink()
175+
ti = create_task_instance_of_operator(
176+
MyOperator,
177+
dag_id="test_link_dag",
178+
task_id="test_link_task",
179+
location=TEST_LOCATION,
180+
cluster_id=TEST_CLUSTER_ID,
181+
project_id=TEST_PROJECT_ID,
182+
)
183+
session.add(ti)
184+
session.commit()
185+
186+
expected_formatted = "https://console.cloud.google.com/expected/link?project=test-proj"
187+
with (
188+
mock.patch.object(
189+
GoogleLink,
190+
"get_config",
191+
return_value={
192+
"project_id": ti.task.project_id,
193+
"location": ti.task.location,
194+
"cluster_id": ti.task.cluster_id,
195+
},
196+
) as m_get_config,
197+
mock.patch.object(GoogleLink, "_format_link", return_value=expected_formatted) as m_fmt,
198+
):
199+
actual_url = link.get_link(operator=ti.task, ti_key=ti.key)
200+
201+
assert actual_url == expected_formatted
202+
m_get_config.assert_called_once()
203+
m_fmt.assert_called_once()

0 commit comments

Comments
 (0)