This is an automated email from the ASF dual-hosted git repository.

shahar1 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 3318b88ba4c Exit non-zero when airflowctl connections test fails 
(#76281)
3318b88ba4c is described below

commit 3318b88ba4c6fddef6cfe62b7cc50f1113cff6bd
Author: Andrew Chang <[email protected]>
AuthorDate: Tue Nov 3 02:36:30 2026 +0800

    Exit non-zero when airflowctl connections test fails (#76281)
    
    The API server reports a failed connection test with HTTP 200 and
    "status": false in the response body. airflowctl exits 1 only on HTTP
    errors, so a failed test exited 0 and a script could not detect it.
    `airflow connections test` already exits 1 in this case.
---
 airflow-ctl/src/airflowctl/ctl/cli_config.py         |  5 +++++
 airflow-ctl/tests/airflow_ctl/ctl/test_cli_config.py | 16 ++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/airflow-ctl/src/airflowctl/ctl/cli_config.py 
b/airflow-ctl/src/airflowctl/ctl/cli_config.py
index b7702e68d07..c837a268f2a 100755
--- a/airflow-ctl/src/airflowctl/ctl/cli_config.py
+++ b/airflow-ctl/src/airflowctl/ctl/cli_config.py
@@ -1087,6 +1087,11 @@ class CommandFactory:
                 ),
                 output=args.output,
             )
+            if (
+                isinstance(method_output, 
generated_datamodels.ConnectionTestResponse)
+                and not method_output.status
+            ):
+                raise SystemExit(1)
 
         for operation in self.operations:
             self.func_map[(operation.get("name"), 
operation.get("parent").name)] = partial(
diff --git a/airflow-ctl/tests/airflow_ctl/ctl/test_cli_config.py 
b/airflow-ctl/tests/airflow_ctl/ctl/test_cli_config.py
index 27bfcab1467..f0397cf65e8 100644
--- a/airflow-ctl/tests/airflow_ctl/ctl/test_cli_config.py
+++ b/airflow-ctl/tests/airflow_ctl/ctl/test_cli_config.py
@@ -1440,6 +1440,22 @@ class TestCliConfigMethods:
 
         assert mocked_print_as.call_args.kwargs["output"] == "json"
 
+    @mock.patch.object(AirflowConsole, "print_as", autospec=True)
+    @mock.patch.object(ConnectionsOperations, "test", autospec=True)
+    def test_failed_connections_test_prints_result_and_exits_non_zero(self, 
mocked_test, mocked_print_as):
+        mocked_test.return_value = ConnectionTestResponse(status=False, 
message="Connection refused")
+        args = cli_parser.get_parser().parse_args(
+            ["connections", "test", "--connection-id", "my_conn", 
"--conn-type", "http"]
+        )
+
+        with pytest.raises(SystemExit) as exc_info:
+            args.func(args, api_client=mock.MagicMock(spec=Client))
+
+        assert exc_info.value.code == 1
+        assert mocked_print_as.call_args.kwargs["data"] == [
+            {"status": False, "message": "Connection refused"}
+        ]
+
     @mock.patch.object(AirflowConsole, "print_as", autospec=True)
     @mock.patch.object(ConnectionsOperations, "create_defaults", autospec=True)
     def test_operation_returning_none_prints_success(self, 
mocked_create_defaults, mocked_print_as):

Reply via email to