test_libvirt_events.py 6.7 KB

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