|
81 | 81 | }
|
82 | 82 | ],
|
83 | 83 | }
|
| 84 | +RESPONSE_WITHOUT_NAME = { |
| 85 | + "failures": [], |
| 86 | + "tasks": [ |
| 87 | + { |
| 88 | + "containers": [], |
| 89 | + "desiredStatus": "RUNNING", |
| 90 | + "lastStatus": "PENDING", |
| 91 | + "taskArn": f"arn:aws:ecs:us-east-1:012345678910:task/{TASK_ID}", |
| 92 | + "taskDefinitionArn": "arn:aws:ecs:us-east-1:012345678910:task-definition/hello_world:11", |
| 93 | + } |
| 94 | + ], |
| 95 | +} |
| 96 | + |
| 97 | + |
84 | 98 | WAITERS_TEST_CASES = [
|
85 | 99 | pytest.param(None, None, id="default-values"),
|
86 | 100 | pytest.param(3.14, None, id="set-delay-only"),
|
@@ -788,6 +802,54 @@ def test_container_name_in_log_stream(self, client_mock, log_fetcher_mock):
|
788 | 802 |
|
789 | 803 | assert self.ecs._get_logs_stream_name().startswith(f"{prefix}/{container_name}/")
|
790 | 804 |
|
| 805 | + @mock.patch.object(EcsBaseOperator, "client") |
| 806 | + @mock.patch("airflow.providers.amazon.aws.operators.ecs.sleep", return_value=None) |
| 807 | + def test_container_name_not_set(self, sleep_mock, client_mock): |
| 808 | + self.set_up_operator( |
| 809 | + awslogs_group="awslogs-group", |
| 810 | + awslogs_stream_prefix="prefix", |
| 811 | + container_name=None, |
| 812 | + ) |
| 813 | + client_mock.run_task.return_value = RESPONSE_WITHOUT_NAME |
| 814 | + client_mock.describe_tasks.side_effect = [ |
| 815 | + {"tasks": [{"containers": []}]}, |
| 816 | + {"tasks": [{"containers": [{"name": "resolved-container"}]}]}, |
| 817 | + ] |
| 818 | + self.ecs._start_task() |
| 819 | + assert client_mock.describe_tasks.call_count == 2 |
| 820 | + assert self.ecs.container_name == "resolved-container" |
| 821 | + |
| 822 | + @mock.patch.object(EcsBaseOperator, "client") |
| 823 | + @mock.patch.object(EcsBaseOperator, "log") |
| 824 | + @mock.patch("airflow.providers.amazon.aws.operators.ecs.sleep", return_value=None) |
| 825 | + def test_container_name_resolution_fails_logs_message(self, sleep_mock, log_mock, client_mock): |
| 826 | + self.set_up_operator( |
| 827 | + awslogs_group="test-group", |
| 828 | + awslogs_stream_prefix="prefix", |
| 829 | + container_name=None, |
| 830 | + ) |
| 831 | + client_mock.run_task.return_value = RESPONSE_WITHOUT_NAME |
| 832 | + client_mock.describe_tasks.return_value = {"tasks": [{"containers": [{"name": None}]}]} |
| 833 | + |
| 834 | + self.ecs._start_task() |
| 835 | + |
| 836 | + assert client_mock.describe_tasks.call_count == 2 |
| 837 | + assert self.ecs.container_name is None |
| 838 | + log_mock.info.assert_called_with( |
| 839 | + "Could not find container name, required for the log stream after 2 tries" |
| 840 | + ) |
| 841 | + |
| 842 | + @mock.patch.object(EcsBaseOperator, "client") |
| 843 | + def test_container_name_not_polled(self, client_mock): |
| 844 | + self.set_up_operator( |
| 845 | + awslogs_group=None, |
| 846 | + awslogs_stream_prefix=None, |
| 847 | + container_name=None, |
| 848 | + ) |
| 849 | + client_mock.run_task.return_value = RESPONSE_WITHOUT_NAME |
| 850 | + self.ecs._start_task() |
| 851 | + assert client_mock.describe_tasks.call_count == 0 |
| 852 | + |
791 | 853 |
|
792 | 854 | class TestEcsCreateClusterOperator(EcsBaseTestCase):
|
793 | 855 | @pytest.mark.parametrize("waiter_delay, waiter_max_attempts", WAITERS_TEST_CASES)
|
|
0 commit comments