From 1f599d9385004328b65ed8b991ac85389daeba5e Mon Sep 17 00:00:00 2001 From: Federicorao <157750791+Federicorao@users.noreply.github.com> Date: Thu, 11 Jun 2026 22:04:41 +0000 Subject: [PATCH 1/3] Fix issue #66440 --- salt/states/beacon.py | 8 +++++ tests/pytests/unit/states/test_beacon.py | 40 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/salt/states/beacon.py b/salt/states/beacon.py index b83717ae2bdd..a867b6e5c619 100644 --- a/salt/states/beacon.py +++ b/salt/states/beacon.py @@ -99,6 +99,8 @@ def present(name, save=False, **kwargs): ret = {"name": name, "result": True, "changes": {}, "comment": []} current_beacons = __salt__["beacons.list"](return_yaml=False, **kwargs) + if current_beacons is None: + current_beacons = {} beacon_data = [{k: v} for k, v in kwargs.items()] if name in current_beacons: @@ -172,6 +174,8 @@ def absent(name, save=False, **kwargs): ret = {"name": name, "result": True, "changes": {}, "comment": []} current_beacons = __salt__["beacons.list"](return_yaml=False, **kwargs) + if current_beacons is None: + current_beacons = {} if name in current_beacons: if __opts__.get("test"): kwargs["test"] = True @@ -219,6 +223,8 @@ def enabled(name, **kwargs): ret = {"name": name, "result": True, "changes": {}, "comment": []} current_beacons = __salt__["beacons.list"](return_yaml=False, **kwargs) + if current_beacons is None: + current_beacons = {} if name in current_beacons: if __opts__.get("test"): kwargs["test"] = True @@ -259,6 +265,8 @@ def disabled(name, **kwargs): ret = {"name": name, "result": True, "changes": {}, "comment": []} current_beacons = __salt__["beacons.list"](return_yaml=False, **kwargs) + if current_beacons is None: + current_beacons = {} if name in current_beacons: if __opts__.get("test"): kwargs["test"] = True diff --git a/tests/pytests/unit/states/test_beacon.py b/tests/pytests/unit/states/test_beacon.py index a393190ec075..1feda8ff0e11 100644 --- a/tests/pytests/unit/states/test_beacon.py +++ b/tests/pytests/unit/states/test_beacon.py @@ -41,6 +41,27 @@ def test_present(): assert beacon.present(beacon_name) == ret +def test_present_none_beacons(): + """ + Test present when beacons.list returns None. + """ + beacon_name = "test_beacon" + + mock_mod = MagicMock(return_value={"name": beacon_name, "result": True, "changes": {}, "comment": []}) + mock_lst = MagicMock(return_value=None) + with patch.dict( + beacon.__salt__, + { + "beacons.list": mock_lst, + "beacons.add": mock_mod, + }, + ): + with patch.dict(beacon.__opts__, {"test": False}): + ret = beacon.present(beacon_name) + assert ret["result"] is True + assert ret["comment"] == f"Adding {beacon_name} to beacons" + + def test_absent(): """ Test to ensure a job is absent from the schedule. @@ -61,3 +82,22 @@ def test_absent(): comt = "ps not configured in beacons" ret.update({"comment": comt, "result": True}) assert beacon.absent(beacon_name) == ret + + +def test_absent_none_beacons(): + """ + Test absent when beacons.list returns None. + """ + beacon_name = "test_beacon" + + mock_lst = MagicMock(return_value=None) + with patch.dict( + beacon.__salt__, + { + "beacons.list": mock_lst, + }, + ): + with patch.dict(beacon.__opts__, {"test": False}): + ret = beacon.absent(beacon_name) + assert ret["result"] is True + assert f"{beacon_name} not configured in beacons" in ret["comment"] From 75281ec2a4925424024a0f05cbfd585e176fc28e Mon Sep 17 00:00:00 2001 From: Federicorao <157750791+Federicorao@users.noreply.github.com> Date: Fri, 12 Jun 2026 15:40:09 +0200 Subject: [PATCH 2/3] Apply black formatting to beacon state test --- tests/pytests/unit/states/test_beacon.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/pytests/unit/states/test_beacon.py b/tests/pytests/unit/states/test_beacon.py index 1feda8ff0e11..5f1f8499dd4c 100644 --- a/tests/pytests/unit/states/test_beacon.py +++ b/tests/pytests/unit/states/test_beacon.py @@ -47,7 +47,9 @@ def test_present_none_beacons(): """ beacon_name = "test_beacon" - mock_mod = MagicMock(return_value={"name": beacon_name, "result": True, "changes": {}, "comment": []}) + mock_mod = MagicMock( + return_value={"name": beacon_name, "result": True, "changes": {}, "comment": []} + ) mock_lst = MagicMock(return_value=None) with patch.dict( beacon.__salt__, From de5181fd8035963847a1d4f263aaca628f135a1f Mon Sep 17 00:00:00 2001 From: "Daniel A. Wozniak" Date: Sat, 13 Jun 2026 18:37:48 -0700 Subject: [PATCH 3/3] Add changelog for #66440 --- changelog/66440.fixed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/66440.fixed.md diff --git a/changelog/66440.fixed.md b/changelog/66440.fixed.md new file mode 100644 index 000000000000..d81a5712420b --- /dev/null +++ b/changelog/66440.fixed.md @@ -0,0 +1 @@ +Fixed ``TypeError: argument of type 'NoneType' is not iterable`` in beacon state functions (``present``, ``absent``, ``enabled``, ``disabled``) when ``beacons.list`` returns ``None`` due to event-system failure. The return value is now defaulted to an empty dict before iteration.