Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,6 @@ def __init__(
self.task_execution_kwargs = task_execution_kwargs or {}
self.delete_task_after_execution = delete_task_after_execution

# Validations
valid = False
if self.task_arn:
valid = True
if self.source_location_uri and self.destination_location_uri:
valid = True
if not valid:
raise AirflowException(
f"Either specify task_arn or both source_location_uri and destination_location_uri. "
f"task_arn={task_arn!r}, source_location_uri={source_location_uri!r}, "
f"destination_location_uri={destination_location_uri!r}"
)

# Candidates - these are found in AWS as possible things
# for us to use
self.candidate_source_location_arns: list[str] | None = None
Expand All @@ -202,6 +189,8 @@ def _hook_parameters(self) -> dict[str, Any]:
return {**super()._hook_parameters, "wait_interval_seconds": self.wait_interval_seconds}

def execute(self, context: Context):
self._validate_inputs()

# If task_arn was not specified then try to
# find 0, 1 or many candidate DataSync Tasks to run
if not self.task_arn:
Expand Down Expand Up @@ -253,6 +242,19 @@ def execute(self, context: Context):

return {"TaskArn": self.task_arn, "TaskExecutionArn": self.task_execution_arn}

def _validate_inputs(self) -> None:
valid = False
if self.task_arn:
valid = True
if self.source_location_uri and self.destination_location_uri:
valid = True
if not valid:
raise AirflowException(
f"Either specify task_arn or both source_location_uri and destination_location_uri. "
f"task_arn={self.task_arn!r}, source_location_uri={self.source_location_uri!r}, "
f"destination_location_uri={self.destination_location_uri!r}"
)

def _get_tasks_and_locations(self) -> None:
"""Find existing DataSync Task based on source and dest Locations."""
self.candidate_source_location_arns = self._get_location_arns(self.source_location_uri)
Expand Down
69 changes: 40 additions & 29 deletions providers/amazon/tests/unit/amazon/aws/operators/test_datasync.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,18 +206,25 @@ def test_init(self, mock_get_conn):
# ### Check mocks:
mock_get_conn.assert_not_called()

def test_init_fails(self, mock_get_conn):
# ### Set up mocks:
def test_execute_fails_with_missing_location_inputs(self, mock_get_conn):
mock_get_conn.return_value = self.client
# ### Begin tests:

self.set_up_operator(task_id="missing_source_location_uri", source_location_uri=None)
with pytest.raises(AirflowException):
self.set_up_operator(source_location_uri=None)
self.datasync.execute(None)

self.set_up_operator(task_id="missing_destination_location_uri", destination_location_uri=None)
with pytest.raises(AirflowException):
self.set_up_operator(destination_location_uri=None)
self.datasync.execute(None)

self.set_up_operator(
task_id="missing_source_and_destination_location_uri",
source_location_uri=None,
destination_location_uri=None,
)
with pytest.raises(AirflowException):
self.set_up_operator(source_location_uri=None, destination_location_uri=None)
# ### Check mocks:
self.datasync.execute(None)

mock_get_conn.assert_not_called()

def test_create_task(self, mock_get_conn):
Expand Down Expand Up @@ -430,18 +437,25 @@ def test_init(self, mock_get_conn):
# ### Check mocks:
mock_get_conn.assert_not_called()

def test_init_fails(self, mock_get_conn):
# ### Set up mocks:
def test_execute_fails_with_missing_location_inputs(self, mock_get_conn):
mock_get_conn.return_value = self.client
# ### Begin tests:

self.set_up_operator(task_id="missing_source_location_uri", source_location_uri=None)
with pytest.raises(AirflowException):
self.set_up_operator(source_location_uri=None)
self.datasync.execute(None)

self.set_up_operator(task_id="missing_destination_location_uri", destination_location_uri=None)
with pytest.raises(AirflowException):
self.set_up_operator(destination_location_uri=None)
self.datasync.execute(None)

self.set_up_operator(
task_id="missing_source_and_destination_location_uri",
source_location_uri=None,
destination_location_uri=None,
)
with pytest.raises(AirflowException):
self.set_up_operator(source_location_uri=None, destination_location_uri=None)
# ### Check mocks:
self.datasync.execute(None)

mock_get_conn.assert_not_called()

def test_get_no_location(self, mock_get_conn):
Expand Down Expand Up @@ -640,14 +654,13 @@ def test_init(self, mock_get_conn):
# ### Check mocks:
mock_get_conn.assert_not_called()

def test_init_fails(self, mock_get_conn):
# ### Set up mocks:
def test_execute_fails_with_missing_task_arn(self, mock_get_conn):
mock_get_conn.return_value = self.client
# ### Begin tests:

self.set_up_operator(task_arn=None)
with pytest.raises(AirflowException):
self.set_up_operator(task_arn=None)
# ### Check mocks:
self.datasync.execute(None)

mock_get_conn.assert_not_called()

def test_update_task(self, mock_get_conn):
Expand Down Expand Up @@ -761,14 +774,13 @@ def test_init(self, mock_get_conn):
# ### Check mocks:
mock_get_conn.assert_not_called()

def test_init_fails(self, mock_get_conn):
# ### Set up mocks:
def test_execute_fails_with_missing_task_arn(self, mock_get_conn):
mock_get_conn.return_value = self.client
# ### Begin tests:

self.set_up_operator(task_arn=None)
with pytest.raises(AirflowException):
self.set_up_operator(task_arn=None)
# ### Check mocks:
self.datasync.execute(None)

mock_get_conn.assert_not_called()

def test_task_extra_links(self, mock_get_conn):
Expand Down Expand Up @@ -973,14 +985,13 @@ def test_init(self, mock_get_conn):
# ### Check mocks:
mock_get_conn.assert_not_called()

def test_init_fails(self, mock_get_conn):
# ### Set up mocks:
def test_execute_fails_with_missing_task_arn(self, mock_get_conn):
mock_get_conn.return_value = self.client
# ### Begin tests:

self.set_up_operator(task_arn=None)
with pytest.raises(AirflowException):
self.set_up_operator(task_arn=None)
# ### Check mocks:
self.datasync.execute(None)

mock_get_conn.assert_not_called()

def test_delete_task(self, mock_get_conn):
Expand Down
1 change: 0 additions & 1 deletion scripts/ci/prek/validate_operators_init_exemptions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
providers/amazon/src/airflow/providers/amazon/aws/operators/appflow.py::AppflowBaseOperator
providers/amazon/src/airflow/providers/amazon/aws/operators/bedrock.py::BedrockCreateKnowledgeBaseOperator
providers/amazon/src/airflow/providers/amazon/aws/operators/bedrock.py::BedrockRaGOperator
providers/amazon/src/airflow/providers/amazon/aws/operators/datasync.py::DataSyncOperator
providers/amazon/src/airflow/providers/amazon/aws/operators/dms.py::DmsModifyTaskOperator
providers/amazon/src/airflow/providers/amazon/aws/operators/dms.py::DmsStartReplicationOperator
providers/amazon/src/airflow/providers/amazon/aws/operators/ecs.py::EcsRunTaskOperator
Expand Down