helpers.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. from contextlib import contextmanager
  2. import os
  3. import sys
  4. import unittest
  5. from six import reraise
  6. from cloudbridge.providers.factory import CloudProviderFactory
  7. @contextmanager
  8. def exception_action(cleanup_func):
  9. """
  10. Context manager to carry out a given
  11. cleanup action when an exception occurs.
  12. If any errors occur during the cleanup
  13. action, those are ignored, and the original
  14. traceback is preserved.
  15. :params func: This function is called only
  16. if an exception occurs. Any exceptions raised
  17. by func are ignored.
  18. Usage:
  19. with exception_action(lambda e: print("Oops!")):
  20. do_something()
  21. """
  22. try:
  23. yield
  24. except Exception:
  25. ex_class, ex_val, ex_traceback = sys.exc_info()
  26. try:
  27. cleanup_func()
  28. except Exception as e:
  29. print("Error during cleanup: {0}".format(e))
  30. reraise(ex_class, ex_val, ex_traceback)
  31. TEST_DATA_CONFIG = {
  32. "AWSCloudProvider": {
  33. "image": os.environ.get('CB_IMAGE_AWS', 'ami-d85e75b0'),
  34. "instance_type": os.environ.get('CB_INSTANCE_TYPE_AWS',
  35. 't1.micro'),
  36. "placement": os.environ.get('CB_PLACEMENT_AWS', 'us-east-1a'),
  37. },
  38. "OpenStackCloudProvider": {
  39. "image": os.environ.get('CB_IMAGE_OS',
  40. 'd57696ba-5ed2-43fe-bf78-a587829973a9'),
  41. "instance_type": os.environ.get('CB_INSTANCE_TYPE_OS', 'm2.xsmall'),
  42. "placement": os.environ.get('CB_PLACEMENT_OS', 'NCI'),
  43. }
  44. }
  45. def get_provider_test_data(provider, key):
  46. if "AWSCloudProvider" in provider.name:
  47. return TEST_DATA_CONFIG.get("AWSCloudProvider").get(key)
  48. elif "OpenStackCloudProvider" in provider.name:
  49. return TEST_DATA_CONFIG.get("OpenStackCloudProvider").get(key)
  50. return None
  51. def create_test_instance(provider, instance_name):
  52. return provider.compute.create_instance(
  53. instance_name,
  54. get_provider_test_data(provider, 'image'),
  55. get_provider_test_data(provider, 'instance_type'))
  56. def get_test_instance(provider, name):
  57. instance = create_test_instance(provider, name)
  58. instance.wait_till_ready()
  59. return instance
  60. class ProviderTestBase(object):
  61. """
  62. A dummy base class for Test Cases. Does not inherit from unittest.TestCase
  63. to avoid confusing test discovery by unittest and nose2. unittest.TestCase
  64. is injected as a base class by the generator, so calling the unittest
  65. constructor works correctly.
  66. """
  67. def __init__(self, methodName, provider):
  68. unittest.TestCase.__init__(self, methodName=methodName)
  69. self.provider = provider
  70. class ProviderTestCaseGenerator():
  71. """
  72. Generates test cases for all provider - testcase combinations.
  73. Detailed docs at test/__init__.py
  74. """
  75. def __init__(self, test_classes):
  76. self.all_test_classes = test_classes
  77. def create_provider_instance(self, provider_class):
  78. """
  79. Instantiate a default provider instance. All required connection
  80. settings are expected to be set as environment variables.
  81. """
  82. return provider_class({})
  83. def generate_new_test_class(self, name, testcase_class):
  84. """
  85. Generates a new type which inherits from the given testcase_class and
  86. unittest.TestCase
  87. """
  88. class_name = "{0}{1}".format(name, testcase_class.__name__)
  89. return type(class_name, (testcase_class, unittest.TestCase), {})
  90. def generate_test_suite_for_provider_testcase(
  91. self, provider_class, testcase_class):
  92. """
  93. Generate and return a suite of tests for a specific provider class and
  94. testcase combination
  95. """
  96. testloader = unittest.TestLoader()
  97. testnames = testloader.getTestCaseNames(testcase_class)
  98. suite = unittest.TestSuite()
  99. for name in testnames:
  100. generated_cls = self.generate_new_test_class(
  101. provider_class.__name__,
  102. testcase_class)
  103. suite.addTest(
  104. generated_cls(
  105. name,
  106. self.create_provider_instance(provider_class)))
  107. return suite
  108. def generate_test_suite_for_provider(self, provider_class):
  109. """
  110. Generate and return a suite of all available tests for a given provider
  111. class
  112. """
  113. suite = unittest.TestSuite()
  114. suites = map(
  115. lambda test_class: self.generate_test_suite_for_provider_testcase(
  116. provider_class, test_class), self.all_test_classes)
  117. map(suite.addTest, suites)
  118. return suite
  119. def generate_tests(self):
  120. """
  121. Generate and return a suite of tests for all provider and test class
  122. combinations
  123. """
  124. factory = CloudProviderFactory()
  125. provider_name = os.environ.get("CB_TEST_PROVIDER", None)
  126. if provider_name:
  127. provider_classes = [factory.get_provider_class(provider_name)]
  128. if not provider_classes[0]:
  129. raise ValueError(
  130. "Could not find specified test provider %s" %
  131. provider_name)
  132. else:
  133. provider_classes = factory.get_all_provider_classes()
  134. suite = unittest.TestSuite()
  135. suites = map(self.generate_test_suite_for_provider, provider_classes)
  136. map(suite.addTest, suites)
  137. return suite