Skip to content

Commit 37a7b27

Browse files
LookerStartPdtBuildOperator, LookerCheckPdtBuildSensor : fix empty materialization id handling (#23025)
* fix empty materialization id handling
1 parent 43bcfa1 commit 37a7b27

4 files changed

Lines changed: 39 additions & 1 deletion

File tree

airflow/providers/google/cloud/operators/looker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def execute(self, context: "Context") -> str:
8484

8585
self.materialization_id = resp.materialization_id
8686

87-
if self.materialization_id is None:
87+
if not self.materialization_id:
8888
raise AirflowException(
8989
f'No `materialization_id` was returned for model: {self.model}, view: {self.view}.'
9090
)

airflow/providers/google/cloud/sensors/looker.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ def poke(self, context: "Context") -> bool:
5353

5454
self.hook = LookerHook(looker_conn_id=self.looker_conn_id)
5555

56+
if not self.materialization_id:
57+
raise AirflowException('Invalid `materialization_id`.')
58+
5659
# materialization_id is templated var pulling output from start task
5760
status_dict = self.hook.pdt_build_status(materialization_id=self.materialization_id)
5861
status = status_dict['status']

tests/providers/google/cloud/operators/test_looker.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
from unittest import mock
2020
from unittest.mock import MagicMock
2121

22+
import pytest
23+
24+
from airflow.exceptions import AirflowException
2225
from airflow.models import DAG, DagBag
2326
from airflow.providers.google.cloud.operators.looker import LookerStartPdtBuildOperator
2427
from airflow.utils.timezone import datetime
@@ -146,3 +149,23 @@ def test_on_kill(self, mock_hook):
146149
task.cancel_on_kill = True
147150
task.on_kill()
148151
mock_hook.return_value.stop_pdt_build.assert_called_once_with(materialization_id=TEST_JOB_ID)
152+
153+
@mock.patch(OPERATOR_PATH.format("LookerHook"))
154+
def test_materialization_id_returned_as_empty_str(self, mock_hook):
155+
# mock return vals from hook
156+
mock_hook.return_value.start_pdt_build.return_value.materialization_id = ""
157+
mock_hook.return_value.wait_for_job.return_value = None
158+
159+
# run task in mock context (asynchronous=False)
160+
task = LookerStartPdtBuildOperator(
161+
task_id=TASK_ID,
162+
looker_conn_id=LOOKER_CONN_ID,
163+
model=MODEL,
164+
view=VIEW,
165+
)
166+
167+
# check AirflowException is raised
168+
with pytest.raises(
169+
AirflowException, match=f'No `materialization_id` was returned for model: {MODEL}, view: {VIEW}.'
170+
):
171+
task.execute(context=self.mock_context)

tests/providers/google/cloud/sensors/test_looker.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,15 @@ def test_cancelled(self, mock_hook):
105105

106106
# assert hook.pdt_build_status called once
107107
mock_hook.return_value.pdt_build_status.assert_called_once_with(materialization_id=TEST_JOB_ID)
108+
109+
def test_empty_materialization_id(self):
110+
111+
# run task in mock context
112+
sensor = LookerCheckPdtBuildSensor(
113+
task_id=TASK_ID,
114+
looker_conn_id=LOOKER_CONN_ID,
115+
materialization_id="",
116+
)
117+
118+
with pytest.raises(AirflowException, match="^Invalid `materialization_id`.$"):
119+
sensor.poke(context={})

0 commit comments

Comments
 (0)