helpers.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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:
  25. ex_class, ex_val, ex_traceback = sys.exc_info()
  26. try:
  27. cleanup_func()
  28. except:
  29. pass
  30. # raise the original exception
  31. reraise(ex_class, ex_val, ex_traceback)
  32. def create_test_instance(provider):
  33. instance_name = "HelloCloudBridge-{0}".format(provider.name)
  34. if "AWSCloudProvider" in provider.name:
  35. ami = os.environ.get('CB_AMI', 'ami-d85e75b0')
  36. instance_type = os.environ.get('CB_INSTANCE_TYPE', 't1.micro')
  37. return provider.compute.create_instance(
  38. instance_name, ami, instance_type)
  39. elif "OpenStackCloudProvider" in provider.name:
  40. image_id = os.environ.get(
  41. 'CB_IMAGE',
  42. "d57696ba-5ed2-43fe-bf78-a587829973a9")
  43. instance_type = os.environ.get('CB_FLAVOR', "m2.xsmall")
  44. return provider.compute.create_instance(
  45. "{0}-{1}".format(instance_name, provider.name),
  46. image_id,
  47. instance_type)
  48. def get_test_instance(provider):
  49. instance = create_test_instance(provider)
  50. instance.wait_till_ready()
  51. return instance
  52. class ProviderTestBase(object):
  53. """
  54. A dummy base class for Test Cases. Does not inherit from unittest.TestCase
  55. to avoid confusing test discovery by unittest and nose2. unittest.TestCase
  56. is injected as a base class by the generator, so calling the unittest
  57. constructor works correctly.
  58. """
  59. def __init__(self, methodName, provider):
  60. unittest.TestCase.__init__(self, methodName=methodName)
  61. self.provider = provider
  62. class ProviderTestCaseGenerator():
  63. """
  64. Generates test cases for all provider - testcase combinations.
  65. Detailed docs at test/__init__.py
  66. """
  67. def __init__(self, test_classes):
  68. self.all_test_classes = test_classes
  69. def create_provider_instance(self, provider_class):
  70. """
  71. Instantiate a default provider instance. All required connection
  72. settings are expected to be set as environment variables.
  73. """
  74. return provider_class({})
  75. def generate_new_test_class(self, name, testcase_class):
  76. """
  77. Generates a new type which inherits from the given testcase_class and
  78. unittest.TestCase
  79. """
  80. class_name = "{0}{1}".format(name, testcase_class.__name__)
  81. return type(class_name, (testcase_class, unittest.TestCase), {})
  82. def generate_test_suite_for_provider_testcase(
  83. self, provider_class, testcase_class):
  84. """
  85. Generate and return a suite of tests for a specific provider class and
  86. testcase combination
  87. """
  88. testloader = unittest.TestLoader()
  89. testnames = testloader.getTestCaseNames(testcase_class)
  90. suite = unittest.TestSuite()
  91. for name in testnames:
  92. generated_cls = self.generate_new_test_class(
  93. provider_class.__name__,
  94. testcase_class)
  95. suite.addTest(
  96. generated_cls(
  97. name,
  98. self.create_provider_instance(provider_class)))
  99. return suite
  100. def generate_test_suite_for_provider(self, provider_class):
  101. """
  102. Generate and return a suite of all available tests for a given provider
  103. class
  104. """
  105. suite = unittest.TestSuite()
  106. suites = map(
  107. lambda test_class: self.generate_test_suite_for_provider_testcase(
  108. provider_class, test_class), self.all_test_classes)
  109. map(suite.addTest, suites)
  110. return suite
  111. def generate_tests(self):
  112. """
  113. Generate and return a suite of tests for all provider and test class
  114. combinations
  115. """
  116. factory = CloudProviderFactory()
  117. provider_name = os.environ.get("CB_TEST_PROVIDER", None)
  118. if provider_name:
  119. provider_classes = [factory.get_provider_class(provider_name)]
  120. if not provider_classes[0]:
  121. raise ValueError(
  122. "Could not find specified test provider %s" %
  123. provider_name)
  124. else:
  125. provider_classes = factory.get_all_provider_classes()
  126. suite = unittest.TestSuite()
  127. suites = map(self.generate_test_suite_for_provider, provider_classes)
  128. map(suite.addTest, suites)
  129. return suite