Skip to content

Commit f89d7b9

Browse files
authored
Poke once before defer for GCSObjectsWithPrefixExistenceSensor (#30939)
1 parent 626f045 commit f89d7b9

File tree

2 files changed

+33
-16
lines changed
  • airflow/providers/google/cloud/sensors
  • tests/providers/google/cloud/sensors

2 files changed

+33
-16
lines changed

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

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -323,19 +323,20 @@ def execute(self, context: Context):
323323
super().execute(context)
324324
return self._matches
325325
else:
326-
self.defer(
327-
timeout=timedelta(seconds=self.timeout),
328-
trigger=GCSPrefixBlobTrigger(
329-
bucket=self.bucket,
330-
prefix=self.prefix,
331-
poke_interval=self.poke_interval,
332-
google_cloud_conn_id=self.google_cloud_conn_id,
333-
hook_params={
334-
"impersonation_chain": self.impersonation_chain,
335-
},
336-
),
337-
method_name="execute_complete",
338-
)
326+
if not self.poke(context=context):
327+
self.defer(
328+
timeout=timedelta(seconds=self.timeout),
329+
trigger=GCSPrefixBlobTrigger(
330+
bucket=self.bucket,
331+
prefix=self.prefix,
332+
poke_interval=self.poke_interval,
333+
google_cloud_conn_id=self.google_cloud_conn_id,
334+
hook_params={
335+
"impersonation_chain": self.impersonation_chain,
336+
},
337+
),
338+
method_name="execute_complete",
339+
)
339340

340341
def execute_complete(self, context: dict[str, Any], event: dict[str, str | list[str]]) -> str | list[str]:
341342
"""

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,21 @@ def test_execute_timeout(self, mock_hook):
369369
task.execute(mock.MagicMock)
370370
mock_hook.return_value.list.assert_called_once_with(TEST_BUCKET, prefix=TEST_PREFIX)
371371

372+
@mock.patch("airflow.providers.google.cloud.sensors.gcs.GCSHook")
373+
@mock.patch("airflow.providers.google.cloud.sensors.gcs.GCSObjectsWithPrefixExistenceSensor.defer")
374+
def test_gcs_object_prefix_existence_sensor_finish_before_deferred(self, mock_defer, mock_hook):
375+
task = GCSObjectsWithPrefixExistenceSensor(
376+
task_id="task-id",
377+
bucket=TEST_BUCKET,
378+
prefix=TEST_PREFIX,
379+
google_cloud_conn_id=TEST_GCP_CONN_ID,
380+
impersonation_chain=TEST_IMPERSONATION_CHAIN,
381+
deferrable=True,
382+
)
383+
mock_hook.return_value.list.return_value = True
384+
task.execute(mock.MagicMock())
385+
assert not mock_defer.called
386+
372387

373388
class TestGCSObjectsWithPrefixExistenceSensorAsync:
374389
OPERATOR = GCSObjectsWithPrefixExistenceSensor(
@@ -379,14 +394,15 @@ class TestGCSObjectsWithPrefixExistenceSensorAsync:
379394
deferrable=True,
380395
)
381396

382-
def test_gcs_object_with_prefix_existence_sensor_async(self, context):
397+
@mock.patch("airflow.providers.google.cloud.sensors.gcs.GCSHook")
398+
def test_gcs_object_with_prefix_existence_sensor_async(self, mock_hook):
383399
"""
384400
Asserts that a task is deferred and a GCSPrefixBlobTrigger will be fired
385401
when the GCSObjectsWithPrefixExistenceSensorAsync is executed.
386402
"""
387-
403+
mock_hook.return_value.list.return_value = False
388404
with pytest.raises(TaskDeferred) as exc:
389-
self.OPERATOR.execute(context)
405+
self.OPERATOR.execute(mock.MagicMock())
390406
assert isinstance(exc.value.trigger, GCSPrefixBlobTrigger), "Trigger is not a GCSPrefixBlobTrigger"
391407

392408
def test_gcs_object_with_prefix_existence_sensor_async_execute_failure(self, context):

0 commit comments

Comments
 (0)