test_azurearm.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. # -*- coding: utf-8 -*-
  2. import types
  3. from salt.cloud.clouds import azurearm as azure
  4. from tests.support.mixins import LoaderModuleMockMixin
  5. from tests.support.mock import MagicMock, create_autospec
  6. from tests.support.unit import TestCase, skipIf
  7. def copy_func(func, globals=None):
  8. # I do not know that this is complete, but it's sufficient for now.
  9. # The key to "moving" the function to another module (or stubbed module)
  10. # is to update __globals__.
  11. copied_func = types.FunctionType(
  12. func.__code__, globals, func.__name__, func.__defaults__, func.__closure__
  13. )
  14. copied_func.__module__ = func.__module__
  15. copied_func.__doc__ = func.__doc__
  16. copied_func.__kwdefaults__ = func.__kwdefaults__
  17. copied_func.__dict__.update(func.__dict__)
  18. return copied_func
  19. def mock_module(mod, sut=None):
  20. if sut is None:
  21. sut = [None]
  22. mock = create_autospec(mod)
  23. # we need to provide a '__globals__' so functions being tested behave correctly.
  24. mock_globals = {}
  25. # exclude the system under test
  26. for name in sut:
  27. attr = getattr(mod, name)
  28. if isinstance(attr, types.FunctionType):
  29. attr = copy_func(attr, mock_globals)
  30. setattr(mock, name, attr)
  31. # fully populate our mock_globals
  32. for name in mod.__dict__:
  33. if name in mock.__dict__:
  34. mock_globals[name] = mock.__dict__[name]
  35. elif type(getattr(mod, name)) is type(types): # is a module
  36. mock_globals[name] = getattr(mock, name)
  37. else:
  38. mock_globals[name] = mod.__dict__[name]
  39. return mock
  40. class AzureTestCase(TestCase, LoaderModuleMockMixin):
  41. def setup_loader_modules(self):
  42. return {azure: {"__opts__": {}, "__active_provider_name__": None}}
  43. @skipIf(not azure.HAS_LIBS, "azure not available")
  44. def test_function_signatures(self):
  45. mock_azure = mock_module(
  46. azure, sut=["request_instance", "six", "__opts__", "__utils__"]
  47. )
  48. mock_azure.create_network_interface.return_value = [
  49. MagicMock(),
  50. MagicMock(),
  51. MagicMock(),
  52. ]
  53. mock_azure.salt.utils.stringutils.to_str.return_value = "P4ssw0rd"
  54. mock_azure.salt.utils.cloud.gen_keys.return_value = [MagicMock(), MagicMock()]
  55. mock_azure.__opts__["pki_dir"] = None
  56. mock_azure.request_instance.__globals__[
  57. "__builtins__"
  58. ] = mock_azure.request_instance.__globals__["__builtins__"].copy()
  59. mock_azure.request_instance.__globals__["__builtins__"]["getattr"] = MagicMock()
  60. mock_azure.__utils__[
  61. "cloud.fire_event"
  62. ] = mock_azure.salt.utils.cloud.fire_event
  63. mock_azure.__utils__[
  64. "cloud.filter_event"
  65. ] = mock_azure.salt.utils.cloud.filter_event
  66. mock_azure.__opts__["sock_dir"] = MagicMock()
  67. mock_azure.__opts__["transport"] = MagicMock()
  68. mock_azure.request_instance(
  69. {"image": "http://img", "storage_account": "blah", "size": ""}
  70. )
  71. # we literally only check that a final creation call occurred.
  72. mock_azure.get_conn.return_value.virtual_machines.create_or_update.assert_called_once()
  73. def test_get_configured_provider(self):
  74. mock_azure = mock_module(
  75. azure, sut=["get_configured_provider", "six", "__opts__", "__utils__"]
  76. )
  77. good_combos = [
  78. {
  79. "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617",
  80. "tenant": "ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF",
  81. "client_id": "ABCDEFAB-1234-ABCD-1234-ABCDEFABCDEF",
  82. "secret": "XXXXXXXXXXXXXXXXXXXXXXXX",
  83. },
  84. {
  85. "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617",
  86. "username": "larry",
  87. "password": "123pass",
  88. },
  89. {"subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617"},
  90. ]
  91. for combo in good_combos:
  92. mock_azure.__opts__["providers"] = {"azure_test": {"azurearm": combo}}
  93. self.assertEqual(azure.get_configured_provider(), combo)
  94. bad_combos = [
  95. {"subscrption": "3287abc8-f98a-c678-3bde-326766fd3617"},
  96. {},
  97. ]
  98. for combo in bad_combos:
  99. mock_azure.__opts__["providers"] = {"azure_test": {"azurearm": combo}}
  100. self.assertFalse(azure.get_configured_provider())
  101. def test_get_conn(self):
  102. mock_azure = mock_module(
  103. azure, sut=["get_conn", "six", "__opts__", "__utils__"]
  104. )
  105. mock_azure.__utils__["azurearm.get_client"] = lambda client_type, **kw: kw
  106. mock_azure.__opts__["providers"] = {
  107. "azure_test": {
  108. "azurearm": {
  109. "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617",
  110. "driver": "azurearm",
  111. "password": "monkeydonkey",
  112. }
  113. }
  114. }
  115. # password is stripped if username not provided
  116. expected = {"subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617"}
  117. self.assertEqual(azure.get_conn(client_type="compute"), expected)
  118. mock_azure.__opts__["providers"] = {
  119. "azure_test": {
  120. "azurearm": {
  121. "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617",
  122. "driver": "azurearm",
  123. "username": "donkeymonkey",
  124. "password": "monkeydonkey",
  125. }
  126. }
  127. }
  128. # username and password via provider config
  129. expected = {
  130. "subscription_id": "3287abc8-f98a-c678-3bde-326766fd3617",
  131. "username": "donkeymonkey",
  132. "password": "monkeydonkey",
  133. }
  134. self.assertEqual(azure.get_conn(client_type="compute"), expected)