test_dimensiondata.py 6.4 KB

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