test_libvirt_events.py 7.8 KB

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