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):