test_service_manager.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. # systemctl-mqtt - MQTT client triggering & reporting shutdown on systemd-based systems
  2. #
  3. # Copyright (C) 2024 Fabian Peter Hammerle <fabian@hammerle.me>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. import typing
  18. import unittest.mock
  19. import pytest
  20. import jeepney.io.asyncio
  21. import jeepney.low_level
  22. import systemctl_mqtt
  23. # pylint: disable=protected-access
  24. class DBusErrorResponseMock(jeepney.wrappers.DBusErrorResponse):
  25. # pylint: disable=missing-class-docstring,super-init-not-called
  26. def __init__(self, name: str, data: typing.Any):
  27. self.name = name
  28. self.data = data
  29. @pytest.mark.asyncio
  30. async def test__get_unit_path() -> None:
  31. router_mock = unittest.mock.AsyncMock()
  32. reply_mock = unittest.mock.MagicMock()
  33. expected_path = "/org/freedesktop/systemd1/unit/ssh_2eservice"
  34. reply_mock.body = (expected_path,)
  35. router_mock.send_and_get_reply.return_value = reply_mock
  36. service_manager = jeepney.io.asyncio.Proxy(
  37. msggen=systemctl_mqtt._dbus.service_manager.ServiceManager(),
  38. router=router_mock,
  39. )
  40. assert (
  41. await systemctl_mqtt._get_unit_path(
  42. service_manager=service_manager, unit_name="ssh.service"
  43. )
  44. == expected_path
  45. )
  46. router_mock.send_and_get_reply.assert_awaited_once()
  47. (msg,), send_kwargs = router_mock.send_and_get_reply.await_args
  48. assert isinstance(msg, jeepney.low_level.Message)
  49. assert msg.header.fields == {
  50. jeepney.low_level.HeaderFields.path: "/org/freedesktop/systemd1",
  51. jeepney.low_level.HeaderFields.destination: "org.freedesktop.systemd1",
  52. jeepney.low_level.HeaderFields.interface: "org.freedesktop.systemd1.Manager",
  53. jeepney.low_level.HeaderFields.member: "GetUnit",
  54. jeepney.low_level.HeaderFields.signature: "s",
  55. }
  56. assert msg.body == ("ssh.service",)
  57. assert not send_kwargs
  58. def test__restart_unit_proxy():
  59. mock_proxy = unittest.mock.MagicMock()
  60. with unittest.mock.patch(
  61. "systemctl_mqtt._dbus.service_manager.get_service_manager_proxy",
  62. return_value=mock_proxy,
  63. ):
  64. systemctl_mqtt._dbus.service_manager.restart_unit("foo.service")
  65. mock_proxy.RestartUnit.assert_called_once_with("foo.service", "replace")
  66. def test__restart_unit_method_call():
  67. with unittest.mock.patch(
  68. "jeepney.new_method_call", return_value=unittest.mock.MagicMock()
  69. ) as mock_method_call:
  70. service_manager = systemctl_mqtt._dbus.service_manager.ServiceManager()
  71. service_manager.RestartUnit("foo.service", "replace")
  72. mock_method_call.assert_called_once_with(
  73. remote_obj=service_manager,
  74. method="RestartUnit",
  75. signature="ss",
  76. body=("foo.service", "replace"),
  77. )
  78. def test_restart_unit_with_exception():
  79. mock_proxy = unittest.mock.MagicMock()
  80. mock_proxy.RestartUnit.side_effect = DBusErrorResponseMock(
  81. "DBus error", ("mocked",)
  82. )
  83. with unittest.mock.patch(
  84. "systemctl_mqtt._dbus.service_manager.get_service_manager_proxy",
  85. return_value=mock_proxy,
  86. ), unittest.mock.patch(
  87. "systemctl_mqtt._dbus.service_manager._LOGGER"
  88. ) as mock_logger:
  89. systemctl_mqtt._dbus.service_manager.restart_unit("example.service")
  90. mock_logger.error.assert_called_once_with(
  91. "Failed to restart unit: %s because %s ", "example.service", "DBus error"
  92. )