1
0

virtualbox.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import, print_function, unicode_literals
  3. import logging
  4. import salt.utils.json
  5. import salt.utils.virtualbox
  6. import tests.integration.cloud.helpers
  7. from tests.support.case import ShellCase
  8. from tests.support.unit import TestCase, skipIf
  9. # Create the cloud instance name to be used throughout the tests
  10. INSTANCE_NAME = tests.integration.cloud.helpers.random_name()
  11. PROVIDER_NAME = "virtualbox"
  12. CONFIG_NAME = PROVIDER_NAME + "-config"
  13. PROFILE_NAME = PROVIDER_NAME + "-test"
  14. DEPLOY_PROFILE_NAME = PROVIDER_NAME + "-deploy-test"
  15. DRIVER_NAME = "virtualbox"
  16. BASE_BOX_NAME = "__temp_test_vm__"
  17. BOOTABLE_BASE_BOX_NAME = "SaltMiniBuntuTest"
  18. # Setup logging
  19. log = logging.getLogger(__name__)
  20. @skipIf(salt.utils.virtualbox.HAS_LIBS is False, "virtualbox has to be installed")
  21. class VirtualboxTestCase(TestCase):
  22. def setUp(self):
  23. self.vbox = salt.utils.virtualbox.vb_get_box()
  24. def assertMachineExists(self, name, msg=None):
  25. try:
  26. self.vbox.findMachine(name)
  27. except Exception as e: # pylint: disable=broad-except
  28. if msg:
  29. self.fail(msg)
  30. else:
  31. self.fail(e.message)
  32. def assertMachineDoesNotExist(self, name):
  33. self.assertRaisesRegex(
  34. Exception,
  35. "Could not find a registered machine",
  36. self.vbox.findMachine,
  37. name,
  38. )
  39. @skipIf(
  40. salt.utils.virtualbox.HAS_LIBS is False,
  41. "salt-cloud requires virtualbox to be installed",
  42. )
  43. class VirtualboxCloudTestCase(ShellCase):
  44. def run_cloud(self, arg_str, catch_stderr=False, timeout=None, config_dir=None):
  45. """
  46. Execute salt-cloud with json output and try to interpret it
  47. @return:
  48. @rtype: dict
  49. """
  50. arg_str = "--out=json {}".format(arg_str)
  51. log.debug("running salt-cloud with %s", arg_str)
  52. output = self.run_script(
  53. "salt-cloud", arg_str, catch_stderr, timeout=timeout, config_dir=config_dir
  54. )
  55. # Sometimes tuples are returned???
  56. if isinstance(output, tuple) and len(output) == 2:
  57. output = output[0]
  58. # Attempt to clean json output before fix of https://github.com/saltstack/salt/issues/27629
  59. valid_initial_chars = ["{", "[", '"']
  60. for line in output[:]:
  61. if len(line) == 0 or (line[0] not in valid_initial_chars):
  62. output.pop(0)
  63. else:
  64. break
  65. if len(output) == 0:
  66. return dict()
  67. else:
  68. return salt.utils.json.loads("".join(output))
  69. def run_cloud_function(self, function, kw_function_args=None, **kwargs):
  70. """
  71. A helper to call `salt-cloud -f function provider`
  72. @param function:
  73. @type function:
  74. @param kw_function_args: Keyword arguments for the argument string in the commandline
  75. @type dict:
  76. @param kwargs: For the `run_cloud` function
  77. @type kwargs:
  78. @return:
  79. @rtype: dict
  80. """
  81. args = []
  82. # Args converted in the form of key1='value1' ... keyN='valueN'
  83. if kw_function_args:
  84. args = [
  85. "{0}='{1}'".format(key, value)
  86. for key, value in kw_function_args.items()
  87. ]
  88. output = self.run_cloud(
  89. "-f {0} {1} {2}".format(function, CONFIG_NAME, " ".join(args)), **kwargs
  90. )
  91. return output.get(CONFIG_NAME, {}).get(PROVIDER_NAME, {})
  92. def run_cloud_action(self, action, instance_name, **kwargs):
  93. """
  94. A helper to call `salt-cloud -a action instance_name`
  95. @param action:
  96. @type action: str
  97. @param instance_name:
  98. @type instance_name: str
  99. @return:
  100. @rtype: dict
  101. """
  102. output = self.run_cloud(
  103. "-a {0} {1} --assume-yes".format(action, instance_name), **kwargs
  104. )
  105. return output.get(CONFIG_NAME, {}).get(PROVIDER_NAME, {})