This is an automated email from the ASF dual-hosted git repository.
bugraoz 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 e17ca631f8b airflowctl: fix flaky xcom add test by using unique keys
per test run (#63832)
e17ca631f8b is described below
commit e17ca631f8b8c534deb88c26bb5996c7e1b60927
Author: Dev-iL <[email protected]>
AuthorDate: Tue Mar 17 23:15:47 2026 +0200
airflowctl: fix flaky xcom add test by using unique keys per test run
(#63832)
The xcom add test used a hardcoded key (`test_xcom_key`) which could
collide with leftover state from a previous failed run where xcom delete never
executed. Derive the key from the randomized `date_param` so each parametrize
set gets a unique key.
---
.../airflowctl_tests/test_airflowctl_commands.py | 39 ++++++++++++++++++----
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git
a/airflow-ctl-tests/tests/airflowctl_tests/test_airflowctl_commands.py
b/airflow-ctl-tests/tests/airflowctl_tests/test_airflowctl_commands.py
index 73a2b28c3f0..4aea60dca68 100644
--- a/airflow-ctl-tests/tests/airflowctl_tests/test_airflowctl_commands.py
+++ b/airflow-ctl-tests/tests/airflowctl_tests/test_airflowctl_commands.py
@@ -93,11 +93,11 @@ TEST_COMMANDS = [
# DAG Run commands
"dagrun list --dag-id example_bash_operator --state success --limit=1",
# XCom commands - need a DAG run with completed tasks
- 'xcom add --dag-id=example_bash_operator
--dag-run-id="manual__{date_param}" --task-id=runme_0 --key=test_xcom_key
--value=\'{{"test": "value"}}\'',
- 'xcom get --dag-id=example_bash_operator
--dag-run-id="manual__{date_param}" --task-id=runme_0 --key=test_xcom_key',
+ 'xcom add --dag-id=example_bash_operator
--dag-run-id="manual__{date_param}" --task-id=runme_0 --key={xcom_key}
--value=\'{{"test": "value"}}\'',
+ 'xcom get --dag-id=example_bash_operator
--dag-run-id="manual__{date_param}" --task-id=runme_0 --key={xcom_key}',
'xcom list --dag-id=example_bash_operator
--dag-run-id="manual__{date_param}" --task-id=runme_0',
- 'xcom edit --dag-id=example_bash_operator
--dag-run-id="manual__{date_param}" --task-id=runme_0 --key=test_xcom_key
--value=\'{{"updated": "value"}}\'',
- 'xcom delete --dag-id=example_bash_operator
--dag-run-id="manual__{date_param}" --task-id=runme_0 --key=test_xcom_key',
+ 'xcom edit --dag-id=example_bash_operator
--dag-run-id="manual__{date_param}" --task-id=runme_0 --key={xcom_key}
--value=\'{{"updated": "value"}}\'',
+ 'xcom delete --dag-id=example_bash_operator
--dag-run-id="manual__{date_param}" --task-id=runme_0 --key={xcom_key}',
# Jobs commands
"jobs list",
# Pools commands
@@ -128,12 +128,39 @@ TEST_COMMANDS = [
DATE_PARAM_1 = date_param()
DATE_PARAM_2 = date_param()
-TEST_COMMANDS_DEBUG_MODE = [LOGIN_COMMAND] +
[test.format(date_param=DATE_PARAM_1) for test in TEST_COMMANDS]
+
+# Unique xcom key per test run to avoid "already exists" errors from leftover
state
+_XCOM_KEY_1 = f"test_xcom_key_{DATE_PARAM_1.replace(':', '').replace('+',
'').replace('-', '')[:16]}"
+_XCOM_KEY_2 = f"test_xcom_key_{DATE_PARAM_2.replace(':', '').replace('+',
'').replace('-', '')[:16]}"
+TEST_COMMANDS_DEBUG_MODE = [LOGIN_COMMAND] + [
+ test.format(date_param=DATE_PARAM_1, xcom_key=_XCOM_KEY_1) for test in
TEST_COMMANDS
+]
TEST_COMMANDS_SKIP_KEYRING = [LOGIN_COMMAND_SKIP_KEYRING] + [
- test.format(date_param=DATE_PARAM_2) for test in TEST_COMMANDS
+ test.format(date_param=DATE_PARAM_2, xcom_key=_XCOM_KEY_2) for test in
TEST_COMMANDS
]
+def test_hardcoded_xcom_key_would_collide():
+ """Regression: a hardcoded xcom key produces identical 'xcom add' commands
+ across parametrize sets, causing 'already exists' errors when both run
+ against the same Airflow instance (the bug that was fixed)."""
+ xcom_add_template = [t for t in TEST_COMMANDS if "xcom add" in t]
+ assert xcom_add_template, "xcom add must be in TEST_COMMANDS"
+
+ hardcoded = xcom_add_template[0].format(date_param=DATE_PARAM_1,
xcom_key="test_xcom_key")
+ also_hardcoded = xcom_add_template[0].format(date_param=DATE_PARAM_2,
xcom_key="test_xcom_key")
+ # With a hardcoded key, only the dag-run-id differs — but if the same date
+ # is reused (e.g. across retries), the commands are fully identical →
collision.
+ assert "test_xcom_key" in hardcoded
+ assert "test_xcom_key" in also_hardcoded
+
+ # The fix: derived keys are unique per set, so commands always differ.
+ debug_cmd = xcom_add_template[0].format(date_param=DATE_PARAM_1,
xcom_key=_XCOM_KEY_1)
+ keyring_cmd = xcom_add_template[0].format(date_param=DATE_PARAM_2,
xcom_key=_XCOM_KEY_2)
+ assert _XCOM_KEY_1 != _XCOM_KEY_2, "derived xcom keys must differ between
sets"
+ assert debug_cmd != keyring_cmd, "xcom add commands must differ to avoid
collisions"
+
+
@pytest.mark.parametrize(
"command",
TEST_COMMANDS_DEBUG_MODE,