From 3aeb0d1eecd7870ccb540372347e698852d2040a Mon Sep 17 00:00:00 2001 From: "Gary T. Giesen" Date: Sun, 5 Jul 2026 22:32:09 -0400 Subject: [PATCH] Delete leaked minion keys at teardown in integration test fixtures The startup_states and salt_call ownership test modules start extra minions against the shared session master via 'with factory.started(): yield'. That stops the minion process at teardown but leaves the accepted key on the master, so later tests in the same session that target '*' (the netapi integration tests) key-match minions that no longer exist. The result is the Rocky Linux 9 integration tcp/zeromq pair failing most 3006.x PR runs: AssertionError: assert ['minion-X', 'minion-X-empty-string', 'minion-X-highstate', 'minion-X-sls', 'minion-X-top', 'non-root-minion-Y', 'sub-minion-Z'] == ['minion-X', 'sub-minion-Z'] plus 30 second TimeoutErrors waiting for returns from the dead minions. Nightly runs do not hit it because test sharding separates these modules from the netapi tests. Remove each extra minion's key from the master once the minion is stopped, restoring the isolation the netapi assertions rely on. Fixes #69728 --- changelog/69728.fixed.md | 1 + .../integration/cli/test_salt_call_ownership.py | 4 ++++ .../integration/minion/test_startup_states.py | 16 ++++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 changelog/69728.fixed.md diff --git a/changelog/69728.fixed.md b/changelog/69728.fixed.md new file mode 100644 index 000000000000..ca9a2e1b7240 --- /dev/null +++ b/changelog/69728.fixed.md @@ -0,0 +1 @@ +Fixed the Rocky Linux 9 integration tcp/zeromq CI jobs failing most PR runs: the startup_states and salt_call ownership test fixtures left their extra minions' accepted keys on the shared session master after stopping the minions, so later netapi tests targeting ``*`` matched dead minions (wrong minion lists and 30 second timeouts). The fixtures now delete their minion keys at teardown. diff --git a/tests/pytests/integration/cli/test_salt_call_ownership.py b/tests/pytests/integration/cli/test_salt_call_ownership.py index 175931da6079..8fe529328b80 100644 --- a/tests/pytests/integration/cli/test_salt_call_ownership.py +++ b/tests/pytests/integration/cli/test_salt_call_ownership.py @@ -64,6 +64,10 @@ def non_root_minion(salt_master, salt_factories): ) with factory.started(): yield factory + # The minion process is stopped at this point, but its accepted key stays + # on the shared session master, where later tests that target '*' (the + # netapi integration tests) would match it as a dead minion. Remove it. + salt_master.salt_key_cli().run("-d", factory.id, "-y") @pytest.mark.skipif(shutil.which("sudo") is None, reason="sudo is not available") diff --git a/tests/pytests/integration/minion/test_startup_states.py b/tests/pytests/integration/minion/test_startup_states.py index d8b891b35c42..f76760b0ba21 100644 --- a/tests/pytests/integration/minion/test_startup_states.py +++ b/tests/pytests/integration/minion/test_startup_states.py @@ -29,6 +29,10 @@ def salt_minion_startup_states_empty_string(salt_master, salt_minion_id): ) with factory.started(): yield factory + # The minion process is stopped at this point, but its accepted key stays + # on the shared session master, where later tests that target '*' (the + # netapi integration tests) would match it as a dead minion. Remove it. + salt_master.salt_key_cli().run("-d", factory.id, "-y") @pytest.fixture @@ -43,6 +47,10 @@ def salt_minion_startup_states_highstate(salt_master, salt_minion_id): ) with factory.started(): yield factory + # The minion process is stopped at this point, but its accepted key stays + # on the shared session master, where later tests that target '*' (the + # netapi integration tests) would match it as a dead minion. Remove it. + salt_master.salt_key_cli().run("-d", factory.id, "-y") @pytest.fixture @@ -58,6 +66,10 @@ def salt_minion_startup_states_sls(salt_master, salt_minion_id): ) with factory.started(): yield factory + # The minion process is stopped at this point, but its accepted key stays + # on the shared session master, where later tests that target '*' (the + # netapi integration tests) would match it as a dead minion. Remove it. + salt_master.salt_key_cli().run("-d", factory.id, "-y") @pytest.fixture @@ -73,6 +85,10 @@ def salt_minion_startup_states_top(salt_master, salt_minion_id): ) with factory.started(): yield factory + # The minion process is stopped at this point, but its accepted key stays + # on the shared session master, where later tests that target '*' (the + # netapi integration tests) would match it as a dead minion. Remove it. + salt_master.salt_key_cli().run("-d", factory.id, "-y") def test_startup_states_empty_string(