helpers.py 4.9 KB

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