2121import logging
2222import os
2323from unittest import mock
24+ from unittest .mock import call
2425
2526import pytest
2627import yaml
@@ -194,8 +195,9 @@ def test_execute(self, mock_executor):
194195 mock_executor .batch .submit_job .assert_called_once ()
195196 assert len (mock_executor .active_workers ) == 1
196197
198+ @mock .patch .object (AwsBatchExecutor , "send_message_to_task_logs" )
197199 @mock .patch .object (batch_executor , "calculate_next_attempt_delay" , return_value = dt .timedelta (seconds = 0 ))
198- def test_attempt_all_jobs_when_some_jobs_fail (self , _ , mock_executor , caplog ):
200+ def test_attempt_all_jobs_when_some_jobs_fail (self , _ , mock_send_message_to_task_logs , mock_executor ):
199201 """
200202 Test how jobs are tried when one job fails, but others pass.
201203
@@ -206,7 +208,6 @@ def test_attempt_all_jobs_when_some_jobs_fail(self, _, mock_executor, caplog):
206208 airflow_key = mock .Mock (spec = tuple )
207209 airflow_cmd1 = mock .Mock (spec = list )
208210 airflow_cmd2 = mock .Mock (spec = list )
209- caplog .set_level ("ERROR" )
210211 airflow_commands = [airflow_cmd1 , airflow_cmd2 ]
211212 responses = [Exception ("Failure 1" ), {"jobId" : "job-2" }]
212213
@@ -229,13 +230,10 @@ def test_attempt_all_jobs_when_some_jobs_fail(self, _, mock_executor, caplog):
229230 for i in range (2 ):
230231 submit_job_args ["containerOverrides" ]["command" ] = airflow_commands [i ]
231232 assert mock_executor .batch .submit_job .call_args_list [i ].kwargs == submit_job_args
232- assert "Pending Batch jobs failed to launch for the following reasons" in caplog .messages [0 ]
233233 assert len (mock_executor .pending_jobs ) == 1
234234 mock_executor .pending_jobs [0 ].command == airflow_cmd1
235235 assert len (mock_executor .active_workers .get_all_jobs ()) == 1
236236
237- caplog .clear ()
238-
239237 # Add more tasks to pending_jobs. This simulates tasks being scheduled by Airflow
240238 airflow_cmd3 = mock .Mock (spec = list )
241239 airflow_cmd4 = mock .Mock (spec = list )
@@ -252,26 +250,27 @@ def test_attempt_all_jobs_when_some_jobs_fail(self, _, mock_executor, caplog):
252250 for i in range (2 , 5 ):
253251 submit_job_args ["containerOverrides" ]["command" ] = airflow_commands [i ]
254252 assert mock_executor .batch .submit_job .call_args_list [i ].kwargs == submit_job_args
255- assert "Pending Batch jobs failed to launch for the following reasons" in caplog .messages [0 ]
256253 assert len (mock_executor .pending_jobs ) == 1
257254 mock_executor .pending_jobs [0 ].command == airflow_cmd1
258255 assert len (mock_executor .active_workers .get_all_jobs ()) == 3
259256
260- caplog .clear ()
261-
262257 airflow_commands .append (airflow_cmd1 )
263258 responses .append (Exception ("Failure 1" ))
264259
265260 mock_executor .attempt_submit_jobs ()
266261 submit_job_args ["containerOverrides" ]["command" ] = airflow_commands [0 ]
267262 assert mock_executor .batch .submit_job .call_args_list [5 ].kwargs == submit_job_args
268- assert (
269- "This job has been unsuccessfully attempted too many times (3). Dropping the task."
270- == caplog .messages [0 ]
263+ mock_send_message_to_task_logs .assert_called_once_with (
264+ logging .ERROR ,
265+ "This job has been unsuccessfully attempted too many times (%s). Dropping the task. Reason: %s" ,
266+ 3 ,
267+ "Failure 1" ,
268+ ti = airflow_key ,
271269 )
272270
271+ @mock .patch .object (AwsBatchExecutor , "send_message_to_task_logs" )
273272 @mock .patch .object (batch_executor , "calculate_next_attempt_delay" , return_value = dt .timedelta (seconds = 0 ))
274- def test_attempt_all_jobs_when_jobs_fail (self , _ , mock_executor , caplog ):
273+ def test_attempt_all_jobs_when_jobs_fail (self , _ , mock_send_message_to_task_logs , mock_executor ):
275274 """
276275 Test job retry behaviour when jobs fail validation.
277276
@@ -282,7 +281,6 @@ def test_attempt_all_jobs_when_jobs_fail(self, _, mock_executor, caplog):
282281 airflow_key = mock .Mock (spec = tuple )
283282 airflow_cmd1 = mock .Mock (spec = list )
284283 airflow_cmd2 = mock .Mock (spec = list )
285- caplog .set_level ("ERROR" )
286284 commands = [airflow_cmd1 , airflow_cmd2 ]
287285 failures = [Exception ("Failure 1" ), Exception ("Failure 2" )]
288286 submit_job_args = {
@@ -304,29 +302,29 @@ def test_attempt_all_jobs_when_jobs_fail(self, _, mock_executor, caplog):
304302 for i in range (2 ):
305303 submit_job_args ["containerOverrides" ]["command" ] = commands [i ]
306304 assert mock_executor .batch .submit_job .call_args_list [i ].kwargs == submit_job_args
307- assert "Pending Batch jobs failed to launch for the following reasons" in caplog .messages [0 ]
308305 assert len (mock_executor .pending_jobs ) == 2
309306
310- caplog .clear ()
311-
312307 mock_executor .batch .submit_job .side_effect = failures
313308 mock_executor .attempt_submit_jobs ()
314309 for i in range (2 ):
315310 submit_job_args ["containerOverrides" ]["command" ] = commands [i ]
316311 assert mock_executor .batch .submit_job .call_args_list [i ].kwargs == submit_job_args
317- assert "Pending Batch jobs failed to launch for the following reasons" in caplog .messages [0 ]
318312 assert len (mock_executor .pending_jobs ) == 2
319313
320- caplog .clear ()
321-
322314 mock_executor .batch .submit_job .side_effect = failures
323315 mock_executor .attempt_submit_jobs ()
324- assert len ( caplog . messages ) == 3
316+ calls = []
325317 for i in range (2 ):
326- assert (
327- "This job has been unsuccessfully attempted too many times (3). Dropping the task."
328- == caplog .messages [i ]
318+ calls .append (
319+ call (
320+ logging .ERROR ,
321+ "This job has been unsuccessfully attempted too many times (%s). Dropping the task. Reason: %s" ,
322+ 3 ,
323+ f"Failure { i + 1 } " ,
324+ ti = airflow_key ,
325+ )
329326 )
327+ mock_send_message_to_task_logs .assert_has_calls (calls )
330328
331329 def test_attempt_submit_jobs_failure (self , mock_executor ):
332330 mock_executor .batch .submit_job .side_effect = NoCredentialsError ()
@@ -467,8 +465,9 @@ def test_sync(self, success_mock, fail_mock, mock_airflow_key, mock_executor):
467465
468466 @mock .patch .object (BaseExecutor , "fail" )
469467 @mock .patch .object (BaseExecutor , "success" )
468+ @mock .patch .object (AwsBatchExecutor , "send_message_to_task_logs" )
470469 @mock .patch .object (batch_executor , "calculate_next_attempt_delay" , return_value = dt .timedelta (seconds = 0 ))
471- def test_failed_sync (self , _ , success_mock , fail_mock , mock_airflow_key , mock_executor ):
470+ def test_failed_sync (self , _ , _2 , success_mock , fail_mock , mock_airflow_key , mock_executor ):
472471 """Test failure states"""
473472 self ._mock_sync (
474473 executor = mock_executor , airflow_key = mock_airflow_key (), status = "FAILED" , attempt_number = 2
0 commit comments