mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-02-04 07:51:50 +00:00
* add sssd_info module * fix f-stings and remove support python2 * fix imports custom lib * fix whitespace and add missing_required_lib * fix str and add version * try add mock test * fix module and mock tests check * fix required in main module * fix spaces * fix linters * add final newline * fix version of module * fix description and error handling * swap literal to dict * fix str * remove comment in methods * remove _get in methods * fix name method in test * add botmeta * fix description of server_type * fix name of maintainer * remove choices * fix author * fix type hint * fix result * fix spaces * fix choices and empty returns * fix mypy test result * fix result * run andebox yaml-doc * remake simple try/exc for result * fix tests * add any type for testing mypy * ruff formated * fix docs * remove unittest.main * rename acc on git for official name --------- Co-authored-by: Александр Габидуллин <agabidullin@astralinux.ru>
203 lines
7.9 KiB
Python
203 lines
7.9 KiB
Python
# Copyright (c) 2025 Aleksandr Gabidullin <qualittv@gmail.com>
|
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import unittest
|
|
from unittest.mock import Mock, patch
|
|
|
|
|
|
class TestSssdInfo(unittest.TestCase):
|
|
"""Unit tests for the sssd_info module."""
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
"""Mock dbus module before importing the module."""
|
|
# Mock the entire dbus module
|
|
cls.mock_dbus = Mock()
|
|
cls.mock_dbus.SystemBus = Mock()
|
|
cls.mock_dbus.Interface = Mock()
|
|
|
|
# Create mock exceptions
|
|
class MockDBusException(Exception):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args)
|
|
self._dbus_error_name = kwargs.get("dbus_error_name", "org.freedesktop.DBus.Error.UnknownObject")
|
|
|
|
def get_dbus_name(self):
|
|
return self._dbus_error_name
|
|
|
|
cls.mock_dbus.exceptions = Mock()
|
|
cls.mock_dbus.exceptions.DBusException = MockDBusException
|
|
|
|
# Mock the dbus module in sys.modules
|
|
sys.modules["dbus"] = cls.mock_dbus
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
"""Clean up after all tests."""
|
|
# Remove the mocked dbus module
|
|
if "dbus" in sys.modules and sys.modules["dbus"] == cls.mock_dbus:
|
|
del sys.modules["dbus"]
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
# Ensure the mocked dbus is in sys.modules
|
|
sys.modules["dbus"] = self.mock_dbus
|
|
|
|
# Reset all mocks
|
|
self.mock_dbus.reset_mock()
|
|
self.mock_dbus.SystemBus.reset_mock()
|
|
self.mock_dbus.Interface.reset_mock()
|
|
|
|
# Create fresh mocks for each test
|
|
self.mock_bus = Mock()
|
|
self.mock_sssd_obj = Mock()
|
|
self.mock_infopipe_iface = Mock()
|
|
self.mock_domain_obj = Mock()
|
|
self.mock_domain_iface = Mock()
|
|
|
|
# Configure the mock chain
|
|
self.mock_dbus.SystemBus.return_value = self.mock_bus
|
|
self.mock_bus.get_object.return_value = self.mock_sssd_obj
|
|
|
|
# Fix the Interface mock to accept dbus_interface parameter
|
|
def interface_side_effect(obj, dbus_interface=None):
|
|
if dbus_interface == "org.freedesktop.sssd.infopipe":
|
|
return self.mock_infopipe_iface
|
|
elif dbus_interface == "org.freedesktop.sssd.infopipe.Domains.Domain":
|
|
return self.mock_domain_iface
|
|
return Mock()
|
|
|
|
self.mock_dbus.Interface.side_effect = interface_side_effect
|
|
|
|
def tearDown(self):
|
|
"""Clean up after test."""
|
|
# Restore the mocked dbus module in sys.modules
|
|
sys.modules["dbus"] = self.mock_dbus
|
|
|
|
def test_domain_list_success(self):
|
|
"""Test successful retrieval of domain list."""
|
|
# Mock the ListDomains response
|
|
self.mock_infopipe_iface.ListDomains.return_value = [
|
|
"/org/freedesktop/sssd/infopipe/Domains/ipa_2eexample_2ecom",
|
|
"/org/freedesktop/sssd/infopipe/Domains/ad_2eexample_2ecom",
|
|
]
|
|
|
|
# Import the module (dbus is already mocked in sys.modules)
|
|
from ansible_collections.community.general.plugins.modules import sssd_info
|
|
|
|
# Mock AnsibleModule
|
|
with patch.object(sssd_info, "AnsibleModule") as mock_module_class:
|
|
mock_module = Mock()
|
|
mock_module.params = {"action": "domain_list"}
|
|
mock_module.fail_json = Mock(side_effect=Exception("fail_json called"))
|
|
mock_module.exit_json = Mock()
|
|
mock_module_class.return_value = mock_module
|
|
|
|
# Run the module
|
|
sssd_info.main()
|
|
|
|
# Verify exit_json was called with correct results
|
|
mock_module.exit_json.assert_called_once()
|
|
result = (
|
|
mock_module.exit_json.call_args[0][0]
|
|
if mock_module.exit_json.call_args[0]
|
|
else mock_module.exit_json.call_args[1]
|
|
)
|
|
|
|
self.assertIn("domain_list", result)
|
|
self.assertEqual(result["domain_list"], ["ipa.example.com", "ad.example.com"])
|
|
|
|
def test_domain_status_online(self):
|
|
"""Test checking online domain status."""
|
|
# Mock domain status as online
|
|
self.mock_domain_iface.IsOnline.return_value = True
|
|
|
|
# Setup mock chain for domain object
|
|
self.mock_bus.get_object.return_value = self.mock_domain_obj
|
|
|
|
# Import the module
|
|
from ansible_collections.community.general.plugins.modules import sssd_info
|
|
|
|
# Mock AnsibleModule
|
|
with patch.object(sssd_info, "AnsibleModule") as mock_module_class:
|
|
mock_module = Mock()
|
|
mock_module.params = {"action": "domain_status", "domain": "example.com"}
|
|
mock_module.fail_json = Mock(side_effect=Exception("fail_json called"))
|
|
mock_module.exit_json = Mock()
|
|
mock_module_class.return_value = mock_module
|
|
|
|
# Run the module
|
|
sssd_info.main()
|
|
|
|
# Verify exit_json was called with correct results
|
|
mock_module.exit_json.assert_called_once()
|
|
result = (
|
|
mock_module.exit_json.call_args[0][0]
|
|
if mock_module.exit_json.call_args[0]
|
|
else mock_module.exit_json.call_args[1]
|
|
)
|
|
|
|
self.assertIn("online", result)
|
|
self.assertEqual(result["online"], "online")
|
|
|
|
def test_domain_status_offline(self):
|
|
"""Test checking offline domain status."""
|
|
# Mock domain status as offline
|
|
self.mock_domain_iface.IsOnline.return_value = False
|
|
|
|
# Setup mock chain for domain object
|
|
self.mock_bus.get_object.return_value = self.mock_domain_obj
|
|
|
|
# Import the module
|
|
from ansible_collections.community.general.plugins.modules import sssd_info
|
|
|
|
# Mock AnsibleModule
|
|
with patch.object(sssd_info, "AnsibleModule") as mock_module_class:
|
|
mock_module = Mock()
|
|
mock_module.params = {"action": "domain_status", "domain": "example.com"}
|
|
mock_module.fail_json = Mock(side_effect=Exception("fail_json called"))
|
|
mock_module.exit_json = Mock()
|
|
mock_module_class.return_value = mock_module
|
|
|
|
# Run the module
|
|
sssd_info.main()
|
|
|
|
# Verify exit_json was called with correct results
|
|
mock_module.exit_json.assert_called_once()
|
|
result = (
|
|
mock_module.exit_json.call_args[0][0]
|
|
if mock_module.exit_json.call_args[0]
|
|
else mock_module.exit_json.call_args[1]
|
|
)
|
|
|
|
self.assertIn("online", result)
|
|
self.assertEqual(result["online"], "offline")
|
|
|
|
def test_domain_not_found(self):
|
|
"""Test error when domain is not found."""
|
|
# Mock DBusException for domain not found
|
|
from ansible_collections.community.general.plugins.modules import sssd_info
|
|
|
|
# Mock AnsibleModule
|
|
with patch.object(sssd_info, "AnsibleModule") as mock_module_class:
|
|
mock_module = Mock()
|
|
mock_module.params = {"action": "domain_status", "domain": "nonexistent.com"}
|
|
mock_module.fail_json = Mock()
|
|
mock_module.exit_json = Mock()
|
|
mock_module_class.return_value = mock_module
|
|
|
|
# Mock the exception in domain_object
|
|
with patch.object(sssd_info.SSSDHandler, "domain_object") as mock_get_domain:
|
|
mock_get_domain.side_effect = Exception("Domain not found: nonexistent.com. Error: Domain not found")
|
|
|
|
# Run the module
|
|
sssd_info.main()
|
|
|
|
# Verify fail_json was called with error message
|
|
mock_module.fail_json.assert_called_once()
|
|
error_msg = mock_module.fail_json.call_args[1].get("msg", "")
|
|
self.assertIn("Domain not found: nonexistent.com", error_msg)
|