test_dimensiondata.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. """
  2. :codeauthor: `Anthony Shaw <anthonyshaw@apache.org>`
  3. tests.unit.cloud.clouds.dimensiondata_test
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5. """
  6. from salt.cloud.clouds import dimensiondata
  7. from salt.exceptions import SaltCloudSystemExit
  8. from salt.utils.versions import LooseVersion
  9. from tests.support.mixins import LoaderModuleMockMixin
  10. from tests.support.mock import MagicMock
  11. from tests.support.mock import __version__ as mock_version
  12. from tests.support.mock import patch
  13. from tests.support.unit import TestCase, skipIf
  14. from tests.unit.cloud.clouds import _preferred_ip
  15. try:
  16. import libcloud.security
  17. HAS_LIBCLOUD = True
  18. except ImportError:
  19. HAS_LIBCLOUD = False
  20. VM_NAME = "winterfell"
  21. # Use certifi if installed
  22. try:
  23. if HAS_LIBCLOUD:
  24. # This work-around for Issue #32743 is no longer needed for libcloud >=
  25. # 1.4.0. However, older versions of libcloud must still be supported
  26. # with this work-around. This work-around can be removed when the
  27. # required minimum version of libcloud is 2.0.0 (See PR #40837 - which
  28. # is implemented in Salt 2018.3.0).
  29. if LooseVersion(libcloud.__version__) < LooseVersion("1.4.0"):
  30. import certifi
  31. libcloud.security.CA_CERTS_PATH.append(certifi.where())
  32. except (ImportError, NameError):
  33. pass
  34. class ExtendedTestCase(TestCase):
  35. """
  36. Extended TestCase class containing additional helper methods.
  37. """
  38. def assertRaisesWithMessage(self, exc_type, exc_msg, func, *args, **kwargs):
  39. try:
  40. func(*args, **kwargs)
  41. self.assertFail()
  42. except Exception as exc: # pylint: disable=broad-except
  43. self.assertEqual(type(exc), exc_type)
  44. self.assertEqual(exc.message, exc_msg)
  45. class DimensionDataTestCase(ExtendedTestCase, LoaderModuleMockMixin):
  46. """
  47. Unit TestCase for salt.cloud.clouds.dimensiondata module.
  48. """
  49. def setup_loader_modules(self):
  50. return {
  51. dimensiondata: {
  52. "__active_provider_name__": "",
  53. "__opts__": {
  54. "providers": {
  55. "my-dimensiondata-cloud": {
  56. "dimensiondata": {
  57. "driver": "dimensiondata",
  58. "region": "dd-au",
  59. "user_id": "jon_snow",
  60. "key": "IKnowNothing",
  61. }
  62. }
  63. }
  64. },
  65. }
  66. }
  67. def test_avail_images_call(self):
  68. """
  69. Tests that a SaltCloudSystemExit is raised when trying to call avail_images
  70. with --action or -a.
  71. """
  72. self.assertRaises(
  73. SaltCloudSystemExit, dimensiondata.avail_images, call="action"
  74. )
  75. def test_avail_locations_call(self):
  76. """
  77. Tests that a SaltCloudSystemExit is raised when trying to call avail_locations
  78. with --action or -a.
  79. """
  80. self.assertRaises(
  81. SaltCloudSystemExit, dimensiondata.avail_locations, call="action"
  82. )
  83. def test_avail_sizes_call(self):
  84. """
  85. Tests that a SaltCloudSystemExit is raised when trying to call avail_sizes
  86. with --action or -a.
  87. """
  88. self.assertRaises(SaltCloudSystemExit, dimensiondata.avail_sizes, call="action")
  89. def test_list_nodes_call(self):
  90. """
  91. Tests that a SaltCloudSystemExit is raised when trying to call list_nodes
  92. with --action or -a.
  93. """
  94. self.assertRaises(SaltCloudSystemExit, dimensiondata.list_nodes, call="action")
  95. def test_destroy_call(self):
  96. """
  97. Tests that a SaltCloudSystemExit is raised when trying to call destroy
  98. with --function or -f.
  99. """
  100. self.assertRaises(
  101. SaltCloudSystemExit, dimensiondata.destroy, name=VM_NAME, call="function"
  102. )
  103. @skipIf(
  104. HAS_LIBCLOUD is False, "Install 'libcloud' to be able to run this unit test."
  105. )
  106. def test_avail_sizes(self):
  107. """
  108. Tests that avail_sizes returns an empty dictionary.
  109. """
  110. sizes = dimensiondata.avail_sizes(call="foo")
  111. self.assertEqual(len(sizes), 1)
  112. self.assertEqual(sizes["default"]["name"], "default")
  113. def test_import(self):
  114. """
  115. Test that the module picks up installed deps
  116. """
  117. with patch("salt.config.check_driver_dependencies", return_value=True) as p:
  118. get_deps = dimensiondata.get_dependencies()
  119. self.assertEqual(get_deps, True)
  120. if LooseVersion(mock_version) >= LooseVersion("2.0.0"):
  121. self.assertTrue(p.call_count >= 1)
  122. def test_provider_matches(self):
  123. """
  124. Test that the first configured instance of a dimensiondata driver is matched
  125. """
  126. p = dimensiondata.get_configured_provider()
  127. self.assertNotEqual(p, None)
  128. def test_query_node_data_filter_preferred_ip_addresses(self):
  129. """
  130. Test if query node data is filtering out unpreferred IP addresses.
  131. """
  132. zero_ip = "0.0.0.0"
  133. private_ips = [zero_ip, "1.1.1.1", "2.2.2.2"]
  134. vm = {"name": None}
  135. data = MagicMock()
  136. data.public_ips = []
  137. # pylint: disable=blacklisted-unmocked-patching
  138. dimensiondata.NodeState = MagicMock()
  139. # pylint: enable=blacklisted-unmocked-patching
  140. dimensiondata.NodeState.RUNNING = True
  141. with patch(
  142. "salt.cloud.clouds.dimensiondata.show_instance",
  143. MagicMock(
  144. return_value={
  145. "state": True,
  146. "name": "foo",
  147. "public_ips": [],
  148. "private_ips": private_ips,
  149. }
  150. ),
  151. ):
  152. with patch(
  153. "salt.cloud.clouds.dimensiondata.preferred_ip",
  154. _preferred_ip(private_ips, [zero_ip]),
  155. ):
  156. with patch(
  157. "salt.cloud.clouds.dimensiondata.ssh_interface",
  158. MagicMock(return_value="private_ips"),
  159. ):
  160. self.assertEqual(
  161. dimensiondata._query_node_data(vm, data).public_ips, [zero_ip]
  162. )