test_libvirt_events.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. # -*- coding: utf-8 -*-
  2. """
  3. unit tests for the libvirt_events engine
  4. """
  5. # Import Python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. # Import Salt Libs
  8. import salt.engines.libvirt_events as libvirt_events
  9. # Import Salt Testing Libs
  10. from tests.support.mixins import LoaderModuleMockMixin
  11. from tests.support.mock import MagicMock, patch
  12. from tests.support.unit import TestCase
  13. # pylint: disable=protected-access,attribute-defined-outside-init,invalid-name,unused-argument,no-self-use
  14. class EngineLibvirtEventTestCase(TestCase, LoaderModuleMockMixin):
  15. """
  16. Test cases for salt.engine.libvirt_events
  17. """
  18. def setup_loader_modules(self):
  19. patcher = patch("salt.engines.libvirt_events.libvirt")
  20. self.mock_libvirt = patcher.start()
  21. self.mock_libvirt.getVersion.return_value = 2000000
  22. self.mock_libvirt.virEventRunDefaultImpl.return_value = (
  23. -1
  24. ) # Don't loop for ever
  25. self.mock_libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE = 0
  26. self.mock_libvirt.VIR_DOMAIN_EVENT_ID_REBOOT = 1
  27. self.addCleanup(patcher.stop)
  28. self.addCleanup(delattr, self, "mock_libvirt")
  29. return {libvirt_events: {}}
  30. @patch(
  31. "salt.engines.libvirt_events.libvirt",
  32. VIR_PREFIX_NONE=0,
  33. VIR_PREFIX_ONE=1,
  34. VIR_PREFIX_TWO=2,
  35. VIR_PREFIX_SUB_FOO=0,
  36. VIR_PREFIX_SUB_BAR=1,
  37. VIR_PREFIX_SUB_FOOBAR=2,
  38. )
  39. def test_get_libvirt_enum_string_subprefix(self, libvirt_mock):
  40. """
  41. Make sure the libvirt enum value to string works reliably with
  42. elements with a sub prefix, eg VIR_PREFIX_SUB_* in this case.
  43. """
  44. # Test case with a sub prefix
  45. assert libvirt_events._get_libvirt_enum_string("VIR_PREFIX_", 2) == "two"
  46. @patch(
  47. "salt.engines.libvirt_events.libvirt", VIR_PREFIX_FOO=0, VIR_PREFIX_BAR_FOO=1
  48. )
  49. def test_get_libvirt_enum_string_underscores(self, libvirt_mock):
  50. """
  51. Make sure the libvirt enum value to string works reliably and items
  52. with an underscore aren't confused with sub prefixes.
  53. """
  54. assert libvirt_events._get_libvirt_enum_string("VIR_PREFIX_", 1) == "bar foo"
  55. @patch(
  56. "salt.engines.libvirt_events.libvirt",
  57. VIR_DOMAIN_EVENT_CRASHED_PANICKED=0,
  58. VIR_DOMAIN_EVENT_DEFINED=0,
  59. VIR_DOMAIN_EVENT_UNDEFINED=1,
  60. VIR_DOMAIN_EVENT_CRASHED=2,
  61. VIR_DOMAIN_EVENT_DEFINED_ADDED=0,
  62. VIR_DOMAIN_EVENT_DEFINED_UPDATED=1,
  63. )
  64. def test_get_domain_event_detail(self, mock_libvirt):
  65. """
  66. Test get_domain_event_detail function
  67. """
  68. assert libvirt_events._get_domain_event_detail(1, 2) == ("undefined", "unknown")
  69. assert libvirt_events._get_domain_event_detail(0, 1) == ("defined", "updated")
  70. assert libvirt_events._get_domain_event_detail(4, 2) == ("unknown", "unknown")
  71. @patch("salt.engines.libvirt_events.libvirt", VIR_NETWORK_EVENT_ID_LIFECYCLE=1000)
  72. def test_event_register(self, mock_libvirt):
  73. """
  74. Test that the libvirt_events engine actually registers events catch them and cleans
  75. before leaving the place.
  76. """
  77. mock_cnx = MagicMock()
  78. mock_libvirt.openReadOnly.return_value = mock_cnx
  79. # Don't loop for ever
  80. mock_libvirt.virEventRunDefaultImpl.return_value = -1
  81. mock_cnx.networkEventRegisterAny.return_value = 10000
  82. libvirt_events.start("test:///", "test/prefix")
  83. # Check that the connection has been opened
  84. mock_libvirt.openReadOnly.assert_called_once_with("test:///")
  85. # Check that the connection has been closed
  86. mock_cnx.close.assert_called_once()
  87. # Check events registration and deregistration
  88. mock_cnx.domainEventRegisterAny.assert_any_call(
  89. None,
  90. mock_libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
  91. libvirt_events._domain_event_lifecycle_cb,
  92. {"prefix": "test/prefix", "object": "domain", "event": "lifecycle"},
  93. )
  94. mock_cnx.networkEventRegisterAny.assert_any_call(
  95. None,
  96. mock_libvirt.VIR_NETWORK_EVENT_ID_LIFECYCLE,
  97. libvirt_events._network_event_lifecycle_cb,
  98. {"prefix": "test/prefix", "object": "network", "event": "lifecycle"},
  99. )
  100. # Check that the deregister events are called with the result of register
  101. mock_cnx.networkEventDeregisterAny.assert_called_with(
  102. mock_cnx.networkEventRegisterAny.return_value
  103. )
  104. # Check that the default 'all' filter actually worked
  105. counts = {
  106. obj: len(callback_def)
  107. for obj, callback_def in libvirt_events.CALLBACK_DEFS.items()
  108. }
  109. for obj, count in counts.items():
  110. register = libvirt_events.REGISTER_FUNCTIONS[obj]
  111. assert getattr(mock_cnx, register).call_count == count
  112. def test_event_skipped(self):
  113. """
  114. Test that events are skipped if their ID isn't defined in the libvirt
  115. module (older libvirt)
  116. """
  117. self.mock_libvirt.mock_add_spec(
  118. [
  119. "openReadOnly",
  120. "virEventRegisterDefaultImpl",
  121. "virEventRunDefaultImpl",
  122. "VIR_DOMAIN_EVENT_ID_LIFECYCLE",
  123. ],
  124. spec_set=True,
  125. )
  126. libvirt_events.start("test:///", "test/prefix")
  127. # Check events registration and deregistration
  128. mock_cnx = self.mock_libvirt.openReadOnly.return_value
  129. mock_cnx.domainEventRegisterAny.assert_any_call(
  130. None,
  131. self.mock_libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
  132. libvirt_events._domain_event_lifecycle_cb,
  133. {"prefix": "test/prefix", "object": "domain", "event": "lifecycle"},
  134. )
  135. # Network events should have been skipped
  136. mock_cnx.networkEventRegisterAny.assert_not_called()
  137. def test_event_filtered(self):
  138. """
  139. Test that events are skipped if their ID isn't defined in the libvirt
  140. module (older libvirt)
  141. """
  142. libvirt_events.start("test", "test/prefix", "domain/lifecycle")
  143. # Check events registration and deregistration
  144. mock_cnx = self.mock_libvirt.openReadOnly.return_value
  145. mock_cnx.domainEventRegisterAny.assert_any_call(
  146. None,
  147. 0,
  148. libvirt_events._domain_event_lifecycle_cb,
  149. {"prefix": "test/prefix", "object": "domain", "event": "lifecycle"},
  150. )
  151. # Network events should have been filtered out
  152. mock_cnx.networkEventRegisterAny.assert_not_called()