Переглянути джерело

Modified tests to skip if service unimplemented

Nuwan Goonasekera 9 роки тому
батько
коміт
e0a508639a

+ 6 - 4
test/helpers.py

@@ -50,7 +50,7 @@ def cleanup_action(cleanup_func):
         print("Error during cleanup: {0}".format(e))
 
 
-def skipIfNoService(service):
+def skipIfNoService(services):
     """
     A decorator for skipping tests if the provider
     does not implement a given service.
@@ -61,9 +61,11 @@ def skipIfNoService(service):
         """
         def wrapper(self, *args, **kwargs):
             provider = getattr(self, 'provider')
-            if provider and not provider.has_service(service):
-                self.skipTest("Skipping test because '%s' service is not"
-                              " implemented" % (service,))
+            if provider:
+                for service in services:
+                    if not provider.has_service(service):
+                        self.skipTest("Skipping test because '%s' service is"
+                                      " not implemented" % (service,))
             else:
                 func(self, *args, **kwargs)
         return wrapper

+ 6 - 0
test/test_block_store_service.py

@@ -3,6 +3,7 @@ import uuid
 
 import six
 
+from cloudbridge.cloud.interfaces.services import BlockStoreService
 from cloudbridge.cloud.interfaces import SnapshotState
 from cloudbridge.cloud.interfaces import VolumeState
 from cloudbridge.cloud.interfaces.resources import AttachmentInfo
@@ -17,6 +18,7 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
         super(CloudBlockStoreServiceTestCase, self).__init__(
             methodName=methodName, provider=provider)
 
+    @helpers.skipIfNoService(['block_store.volumes'])
     def test_crud_volume(self):
         """
         Create a new volume, check whether the expected values are set,
@@ -94,6 +96,7 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
             name)
 
     @skip("Until Moto supports 'state' for DescribeSubnets filter")
+    @helpers.skipIfNoService(['block_store.volumes'])
     def test_attach_detach_volume(self):
         """
         Create a new volume, and attempt to attach it to an instance
@@ -121,6 +124,7 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
                     terminal_states=[VolumeState.ERROR, VolumeState.DELETED])
 
     @skip("Until Moto supports 'state' for DescribeSubnets filter")
+    @helpers.skipIfNoService(['block_store.volumes'])
     def test_volume_properties(self):
         """
         Test volume properties
@@ -176,6 +180,7 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
                     [VolumeState.AVAILABLE],
                     terminal_states=[VolumeState.ERROR, VolumeState.DELETED])
 
+    @helpers.skipIfNoService(['block_store.snapshots'])
     def test_crud_snapshot(self):
         """
         Create a new volume, create a snapshot of the volume, and check
@@ -293,6 +298,7 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
                     "repr(obj) should contain the object id so that the object"
                     " can be reconstructed, but does not.")
 
+    @helpers.skipIfNoService(['block_store.snapshots'])
     def test_snapshot_properties(self):
         """
         Test snapshot properties

+ 8 - 0
test/test_compute_service.py

@@ -20,6 +20,7 @@ class CloudComputeServiceTestCase(ProviderTestBase):
         super(CloudComputeServiceTestCase, self).__init__(
             methodName=methodName, provider=provider)
 
+    @helpers.skipIfNoService(['compute.instances', 'network'])
     @skip("Until Moto supports 'state' for DescribeSubnets filter")
     def test_crud_instance(self):
         name = "CBInstCrud-{0}-{1}".format(
@@ -92,6 +93,9 @@ class CloudComputeServiceTestCase(ProviderTestBase):
             return False
         return True
 
+    @helpers.skipIfNoService(['compute.instances', 'network',
+                              'security.security_groups',
+                              'security.key_pairs'])
     @skip("Until Moto supports 'state' for DescribeSubnets filter")
     def test_instance_properties(self):
         name = "CBInstProps-{0}-{1}".format(
@@ -173,6 +177,8 @@ class CloudComputeServiceTestCase(ProviderTestBase):
                 "Instance type {0} does not match expected type {1}".format(
                     itype.name, expected_type))
 
+    @helpers.skipIfNoService(['compute.instances', 'compute.images',
+                              'compute.instance_types'])
     def test_block_device_mapping_launch_config(self):
         lc = self.provider.compute.instances.create_launch_config()
 
@@ -232,6 +238,8 @@ class CloudComputeServiceTestCase(ProviderTestBase):
             "Expected %d total block devices bit found %d" %
             (2 + inst_type.num_ephemeral_disks, len(lc.block_devices)))
 
+    @helpers.skipIfNoService(['compute.instances', 'compute.images',
+                              'compute.instance_types', 'block_store.volumes'])
     def test_block_device_mapping_attachments(self):
         name = "CBInstBlkAttch-{0}-{1}".format(
             self.provider.name,

+ 2 - 0
test/test_image_service.py

@@ -15,6 +15,8 @@ class CloudImageServiceTestCase(ProviderTestBase):
         super(CloudImageServiceTestCase, self).__init__(
             methodName=methodName, provider=provider)
 
+    @helpers.skipIfNoService(['compute.images', 'network',
+                              'compute.instances'])
     @skip("Until Moto supports 'state' for DescribeSubnets filter")
     def test_create_and_list_image(self):
         """

+ 3 - 0
test/test_instance_types_service.py

@@ -12,6 +12,7 @@ class CloudInstanceTypesServiceTestCase(ProviderTestBase):
         super(CloudInstanceTypesServiceTestCase, self).__init__(
             methodName=methodName, provider=provider)
 
+    @helpers.skipIfNoService(['compute.instance_types'])
     def test_instance_types(self):
         instance_types = self.provider.compute.instance_types.list()
         # check iteration
@@ -69,6 +70,7 @@ class CloudInstanceTypesServiceTestCase(ProviderTestBase):
                     inst_type.extra_data, dict),
                 "InstanceType extra_data must be None or a dict")
 
+    @helpers.skipIfNoService(['compute.instance_types'])
     def test_instance_types_find(self):
         """
         Searching for an instance by name should return an
@@ -91,6 +93,7 @@ class CloudInstanceTypesServiceTestCase(ProviderTestBase):
             self.provider.compute.instance_types.find(
                 non_existent_param="random_value")
 
+    @helpers.skipIfNoService(['compute.instance_types'])
     def test_instance_types_get(self):
         """
         Searching for an instance by id should return an

+ 3 - 0
test/test_network_service.py

@@ -10,6 +10,7 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
         super(CloudNetworkServiceTestCase, self).__init__(
             methodName=methodName, provider=provider)
 
+    @helpers.skipIfNoService(['network'])
     def test_crud_network_service(self):
         name = 'cbtestnetworkservice-{0}'.format(uuid.uuid4())
         subnet_name = 'cbtestsubnetservice-{0}'.format(uuid.uuid4())
@@ -99,6 +100,7 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
             "Network {0} should have been deleted but still exists."
             .format(name))
 
+    @helpers.skipIfNoService(['network'])
     def test_crud_network(self):
         name = 'cbtestnetwork-{0}'.format(uuid.uuid4())
         subnet_name = 'cbtestsubnet-{0}'.format(uuid.uuid4())
@@ -139,6 +141,7 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
                     "Subnet's CIDR %s should match the specified one %s." % (
                         sn.cidr_block, cidr))
 
+    @helpers.skipIfNoService(['network.routers'])
     def test_crud_router(self):
 
         def _cleanup(net, subnet, router):

+ 1 - 0
test/test_object_life_cycle.py

@@ -12,6 +12,7 @@ class CloudObjectLifeCycleTestCase(ProviderTestBase):
         super(CloudObjectLifeCycleTestCase, self).__init__(
             methodName=methodName, provider=provider)
 
+    @helpers.skipIfNoService(['block_store.volumes'])
     def test_object_life_cycle(self):
         """
         Test object life cycle methods by using a volume.

+ 3 - 0
test/test_object_store_service.py

@@ -13,6 +13,7 @@ class CloudObjectStoreServiceTestCase(ProviderTestBase):
         super(CloudObjectStoreServiceTestCase, self).__init__(
             methodName=methodName, provider=provider)
 
+    @helpers.skipIfNoService(['object_store'])
     def test_crud_bucket(self):
         """
         Create a new bucket, check whether the expected values are set,
@@ -66,6 +67,7 @@ class CloudObjectStoreServiceTestCase(ProviderTestBase):
             "Bucket %s should have been deleted but still exists." %
             name)
 
+    @helpers.skipIfNoService(['object_store'])
     def test_crud_bucket_objects(self):
         """
         Create a new bucket, upload some contents into the bucket, and
@@ -137,6 +139,7 @@ class CloudObjectStoreServiceTestCase(ProviderTestBase):
                 "Object %s should have been deleted but still exists." %
                 obj_name)
 
+    @helpers.skipIfNoService(['object_store'])
     def test_upload_download_bucket_content(self):
 
         name = "cbtestbucketobjs-{0}".format(uuid.uuid4())

+ 124 - 0
test/test_provider_auth.py

@@ -0,0 +1,124 @@
+import unittest
+
+from cloudbridge.cloud import factory
+from cloudbridge.cloud import interfaces
+from cloudbridge.cloud.factory import CloudProviderFactory
+from cloudbridge.cloud.interfaces import TestMockHelperMixin
+from cloudbridge.cloud.interfaces.provider import CloudProvider
+from cloudbridge.cloud.providers.aws import AWSCloudProvider
+from cloudbridge.cloud.providers.aws.provider import MockAWSCloudProvider
+import test.helpers as helpers
+
+
+class CloudProviderAuthTestCase(unittest.TestCase):
+
+    def test_create_provider_valid(self):
+        """
+        Creating a provider with a known name should return
+        a valid implementation
+        """
+        self.assertIsInstance(CloudProviderFactory().create_provider(
+            factory.ProviderList.AWS, {}),
+            interfaces.CloudProvider,
+            "create_provider did not return a valid instance type")
+
+    def test_create_provider_invalid(self):
+        """
+        Creating a provider with an invalid name should raise a
+        NotImplementedError
+        """
+        with self.assertRaises(NotImplementedError):
+            CloudProviderFactory().create_provider("ec23", {})
+
+    def test_find_provider_mock_valid(self):
+        """
+        Searching for a provider with a known mock driver should return
+        an implementation implementing helpers.TestMockHelperMixin
+        """
+        mock = CloudProviderFactory().get_provider_class(
+            factory.ProviderList.AWS, get_mock=True)
+        self.assertTrue(
+            issubclass(
+                mock,
+                helpers.TestMockHelperMixin),
+            "Expected mock for AWS but class does not implement mock provider")
+        for cls in CloudProviderFactory().get_all_provider_classes(
+                get_mock=False):
+            self.assertTrue(
+                not issubclass(
+                    cls,
+                    TestMockHelperMixin),
+                "Did not expect mock but %s implements mock provider" %
+                cls)
+
+    def test_get_provider_class_valid(self):
+        """
+        Searching for a provider class with a known name should return a valid
+        class
+        """
+        self.assertEqual(CloudProviderFactory().get_provider_class(
+            factory.ProviderList.AWS), AWSCloudProvider)
+
+    def test_get_provider_class_invalid(self):
+        """
+        Searching for a provider class with an invalid name should
+        return None
+        """
+        self.assertIsNone(CloudProviderFactory().get_provider_class("aws1"))
+
+    def test_register_provider_class_invalid(self):
+        """
+        Attempting to register an invalid test class should be ignored
+        """
+        class DummyClass(object):
+            PROVIDER_ID = 'aws'
+
+        factory = CloudProviderFactory()
+        factory.register_provider_class(DummyClass)
+        self.assertTrue(DummyClass not in
+                        factory.get_all_provider_classes(get_mock=False))
+
+    def test_register_provider_class_double(self):
+        """
+        Attempting to register the same class twice should register second
+        instance
+        """
+        class DummyClass(CloudProvider):
+            PROVIDER_ID = 'aws'
+
+        factory = CloudProviderFactory()
+        factory.list_providers()
+        factory.register_provider_class(DummyClass)
+        self.assertTrue(DummyClass in
+                        factory.get_all_provider_classes(get_mock=False))
+        self.assertTrue(AWSCloudProvider not in
+                        factory.get_all_provider_classes(get_mock=False))
+
+    def test_register_mock_provider_class_double(self):
+        """
+        Attempting to register the same mock provider twice should register
+        only the second instance
+        """
+        class DummyClass(CloudProvider, TestMockHelperMixin):
+            PROVIDER_ID = 'aws'
+
+        factory = CloudProviderFactory()
+        factory.list_providers()
+        factory.register_provider_class(DummyClass)
+        self.assertTrue(DummyClass in
+                        factory.get_all_provider_classes(get_mock=True))
+        self.assertTrue(MockAWSCloudProvider not in
+                        factory.get_all_provider_classes(get_mock=True))
+
+    def test_register_provider_class_without_id(self):
+        """
+        Attempting to register a class without a PROVIDER_ID attribute
+        should be ignored.
+        """
+        class DummyClass(CloudProvider):
+            pass
+
+        factory = CloudProviderFactory()
+        factory.register_provider_class(DummyClass)
+        self.assertTrue(DummyClass not in
+                        factory.get_all_provider_classes(get_mock=False))

+ 4 - 0
test/test_region_service.py

@@ -11,6 +11,7 @@ class CloudRegionServiceTestCase(ProviderTestBase):
         super(CloudRegionServiceTestCase, self).__init__(
             methodName=methodName, provider=provider)
 
+    @helpers.skipIfNoService(['compute.regions'])
     def test_get_and_list_regions(self):
         """
         Test whether the region listing methods work,
@@ -47,6 +48,7 @@ class CloudRegionServiceTestCase(ProviderTestBase):
             "Region name {0} not in JSON representation {1}".format(
                 region.name, region.to_json()))
 
+    @helpers.skipIfNoService(['compute.regions'])
     def test_regions_unique(self):
         """
         Regions should not return duplicate items
@@ -55,6 +57,7 @@ class CloudRegionServiceTestCase(ProviderTestBase):
         unique_regions = set([region.id for region in regions])
         self.assertTrue(len(regions) == len(list(unique_regions)))
 
+    @helpers.skipIfNoService(['compute.regions'])
     def test_current_region(self):
         """
         RegionService.current should return a valid region
@@ -63,6 +66,7 @@ class CloudRegionServiceTestCase(ProviderTestBase):
         self.assertIsInstance(current_region, Region)
         self.assertTrue(current_region in self.provider.compute.regions.list())
 
+    @helpers.skipIfNoService(['compute.regions'])
     def test_zones(self):
         """
         Test whether regions return the correct zone information

+ 6 - 0
test/test_security_service.py

@@ -12,6 +12,7 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
         super(CloudSecurityServiceTestCase, self).__init__(
             methodName=methodName, provider=provider)
 
+    @helpers.skipIfNoService(['security.key_pairs'])
     def test_crud_key_pair_service(self):
         name = 'cbtestkeypairA-{0}'.format(uuid.uuid4())
         kp = self.provider.security.key_pairs.create(name=name)
@@ -63,6 +64,7 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
             no_kp,
             "Found a key pair {0} that should not exist?".format(no_kp))
 
+    @helpers.skipIfNoService(['security.key_pairs'])
     def test_key_pair(self):
         name = 'cbtestkeypairB-{0}'.format(uuid.uuid4())
         kp = self.provider.security.key_pairs.create(name=name)
@@ -102,6 +104,7 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
                 lambda: self.provider.network.delete(network_id=net.id)):
             self.provider.security.security_groups.delete(group_id=sg.id)
 
+    @helpers.skipIfNoService(['security.security_groups'])
     def test_crud_security_group_service(self):
         name = 'cbtestsecuritygroupA-{0}'.format(uuid.uuid4())
         net = self.provider.network.create(name=name)
@@ -155,6 +158,7 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
             len(no_sg) == 0,
             "Found a bogus security group?!?".format(no_sg))
 
+    @helpers.skipIfNoService(['security.security_groups'])
     def test_security_group(self):
         """Test for proper creation of a security group."""
         name = 'cbtestsecuritygroupB-{0}'.format(uuid.uuid4())
@@ -205,6 +209,7 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
             "Security group {0} should have been deleted but still exists."
             .format(name))
 
+    @helpers.skipIfNoService(['security.security_groups'])
     def test_security_group_rule_add_twice(self):
         """Test whether adding the same rule twice succeeds."""
         name = 'cbtestsecuritygroupB-{0}'.format(uuid.uuid4())
@@ -222,6 +227,7 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
                 "Expected rule {0} not found in security group: {0}".format(
                     same_rule, sg.rules))
 
+    @helpers.skipIfNoService(['security.security_groups'])
     def test_security_group_group_rule(self):
         """Test for proper creation of a security group rule."""
         name = 'cbtestsecuritygroupC-{0}'.format(uuid.uuid4())