test_dimensiondata.py 6.4 KB

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