Browse Source

Fixed landscape warnings + readme formatting.

nuwan_ag 10 years ago
parent
commit
abc8f73ba4

+ 5 - 5
README.rst

@@ -102,11 +102,11 @@ Testing philosophy
 ~~~~~~~~~~~~~~~~~~
 Our testing goals are to:
 
- * Write one set of tests that all provider implementations must pass.
- * Make that set of tests a 'conformance' test suite, which validates that each implementation correctly implements the cloudbridge specification.
- * Make the test suite comprehensive enough that a provider which passes all the tests can be used safely by an application with no additional testing. In other words, the cloudbridge specification and accompanying test suite must be comprehensive enough that no provider specific workarounds, code or testing is required.
- * For development, mock providers may be used to speed up the feedback cycle, but providers must also pass the full suite of tests when run against actual cloud infrastructure to ensure that we are not testing against an idealised or imagined environment.
- * Aim for 100% code coverage.
+1. Write one set of tests that all provider implementations must pass.
+2. Make that set of tests a 'conformance' test suite, which validates that each implementation correctly implements the cloudbridge specification.
+3. Make the test suite comprehensive enough that a provider which passes all the tests can be used safely by an application with no additional testing. In other words, the cloudbridge specification and accompanying test suite must be comprehensive enough that no provider specific workarounds, code or testing is required.
+4. For development, mock providers may be used to speed up the feedback cycle, but providers must also pass the full suite of tests when run against actual cloud infrastructure to ensure that we are not testing against an idealised or imagined environment.
+5. Aim for 100% code coverage.
 
 .. _`bridge pattern`: https://en.wikipedia.org/wiki/Bridge_pattern
 .. _`tox`: https://tox.readthedocs.org/en/latest/

+ 10 - 10
cloudbridge/cloud/base.py

@@ -130,7 +130,7 @@ class BaseObjectLifeCycleMixin(ObjectLifeCycleMixin):
 
     def wait_for(self, target_states, terminal_states=None, timeout=600,
                  interval=5):
-        assert timeout > 0
+        assert timeout >= 0
         assert interval >= 0
         assert timeout >= interval
 
@@ -143,20 +143,20 @@ class BaseObjectLifeCycleMixin(ObjectLifeCycleMixin):
                     " and cannot be waited on.".format(self, self.state))
             else:
                 log.debug(
-                    "Object {0} is in state: {1}. Waiting another {2}"
-                    " seconds to reach target state(s): {3}...".format(
-                        self,
-                        self.state,
-                        int(end_time - time.time()),
-                        target_states))
+                    "Object %s is in state: %s. Waiting another %s"
+                    " seconds to reach target state(s): %s...",
+                    self,
+                    self.state,
+                    int(end_time - time.time()),
+                    target_states)
                 time.sleep(interval)
                 if time.time() > end_time:
                     raise WaitStateException(
                         "Waited too long for object: {0} to become ready. It's"
                         " still in state: {1}".format(self, self.state))
             self.refresh()
-        log.debug("Object: {0} successfully reached target state:"
-                  " {1}".format(self, self.state))
+        log.debug("Object: %s successfully reached target state: %s",
+                  self, self.state)
         return True
 
 
@@ -164,7 +164,7 @@ class BaseResultList(ResultList):
 
     def __init__(
             self, is_truncated, marker, supports_total, total=None, data=None):
-        list.__init__(self, data or [])
+        super(BaseResultList, self).__init__(data or [])
         self._marker = marker
         self._is_truncated = is_truncated
         self._supports_total = True if supports_total else False

+ 27 - 3
cloudbridge/cloud/interfaces/resources.py

@@ -348,6 +348,14 @@ class Instance(ObjectLifeCycleMixin):
         """
         pass
 
+    @name.setter
+    @abstractmethod
+    def name(self, value):
+        """
+        Set the instance name.
+        """
+        pass
+
     @abstractproperty
     def public_ips(self):
         """
@@ -722,6 +730,14 @@ class Volume(ObjectLifeCycleMixin):
         """
         pass
 
+    @name.setter
+    @abstractmethod
+    def name(self, value):
+        """
+        Set the volume name.
+        """
+        pass
+
     @abstractmethod
     def attach(self, instance_id, device):
         """
@@ -762,10 +778,13 @@ class Volume(ObjectLifeCycleMixin):
         pass
 
     @abstractmethod
-    def create_snapshot(self, description=None):
+    def create_snapshot(self, name, description=None):
         """
         Create a snapshot of this Volume.
 
+        :type name: str
+        :param name: The name of this snapshot.
+
         :type description: str
         :param description: A description of the snapshot.
                             Limited to 256 characters.
@@ -824,9 +843,14 @@ class Snapshot(ObjectLifeCycleMixin):
     def name(self):
         """
         Get the snapshot name.
+        """
+        pass
 
-        :rtype: ``str``
-        :return: Name for this snapshot as returned by the cloud middleware.
+    @name.setter
+    @abstractmethod
+    def name(self, value):
+        """
+        set the snapshot name.
         """
         pass
 

+ 8 - 8
cloudbridge/cloud/interfaces/services.py

@@ -235,7 +235,7 @@ class VolumeService(PageableObjectMixin, ProviderService):
         pass
 
     @abstractmethod
-    def list(self):
+    def list(self, limit=None, marker=None):
         """
         List all volumes.
 
@@ -298,7 +298,7 @@ class SnapshotService(PageableObjectMixin, ProviderService):
         pass
 
     @abstractmethod
-    def list(self):
+    def list(self, limit=None, marker=None):
         """
         List all snapshots.
 
@@ -386,7 +386,7 @@ class ImageService(PageableObjectMixin, ProviderService):
         pass
 
     @abstractmethod
-    def list(self):
+    def list(self, limit=None, marker=None):
         """
         List all images.
 
@@ -425,7 +425,7 @@ class ObjectStoreService(PageableObjectMixin, ProviderService):
         pass
 
     @abstractmethod
-    def list(self):
+    def list(self, limit=None, marker=None):
         """
         List all containers.
 
@@ -487,7 +487,7 @@ class KeyPairService(PageableObjectMixin, ProviderService):
     __metaclass__ = ABCMeta
 
     @abstractmethod
-    def list(self):
+    def list(self, limit=None, marker=None):
         """
         List all key pairs associated with this account.
 
@@ -543,7 +543,7 @@ class SecurityGroupService(PageableObjectMixin, ProviderService):
     __metaclass__ = ABCMeta
 
     @abstractmethod
-    def list(self):
+    def list(self, limit=None, marker=None):
         """
         List all security groups associated with this account.
 
@@ -610,7 +610,7 @@ class InstanceTypesService(PageableObjectMixin, ProviderService):
     __metaclass__ = ABCMeta
 
     @abstractmethod
-    def list(self):
+    def list(self, limit=None, marker=None):
         """
         List all instance types.
 
@@ -649,7 +649,7 @@ class RegionService(PageableObjectMixin, ProviderService):
         pass
 
     @abstractmethod
-    def list(self):
+    def list(self, limit=None, marker=None):
         """
         List all regions.
 

+ 2 - 1
cloudbridge/cloud/providers/aws/resources.py

@@ -246,7 +246,8 @@ class AWSInstance(BaseInstance):
         """
         Get the instance type.
         """
-        return AWSInstanceType(self._ec2_instance.instance_type)
+        return next(self._provider.compute.instance_types.find(
+            name=self._ec2_instance.instance_type))
 
     def reboot(self):
         """

+ 2 - 0
test/test_compute_service.py

@@ -6,6 +6,7 @@ import ipaddress
 from cloudbridge.cloud.interfaces \
     import InvalidConfigurationException
 from cloudbridge.cloud.interfaces import InstanceState
+from cloudbridge.cloud.interfaces.resources import InstanceType
 from cloudbridge.cloud.interfaces.resources import WaitStateException
 from test.helpers import ProviderTestBase
 import test.helpers as helpers
@@ -111,6 +112,7 @@ class CloudComputeServiceTestCase(ProviderTestBase):
             self.assertTrue(
                 self._is_valid_ip(ip_address),
                 "Instance must have a valid IP address")
+            self.assertIsInstance(test_instance.instance_type, InstanceType)
 
     def test_block_device_mappings(self):
         name = "CBInstBlkMap-{0}-{1}".format(

+ 1 - 1
test/test_object_life_cycle.py

@@ -42,4 +42,4 @@ class CloudObjectLifeCycleTestCase(ProviderTestBase):
 
             # Hitting the timeout should raise an exception
             with self.assertRaises(WaitStateException):
-                test_vol.wait_for([VolumeState.ERROR], timeout=1, interval=1)
+                test_vol.wait_for([VolumeState.ERROR], timeout=0, interval=0)

+ 3 - 0
test/test_region_service.py

@@ -28,6 +28,9 @@ class CloudRegionServiceTestCase(ProviderTestBase):
                 region,
                 Region,
                 "regions.list() should return a cloudbridge Region")
+            self.assertTrue(
+                region.name,
+                "Region name should be a non-empty string")
 
         region = self.provider.compute.regions.get(regions[0].id)
         self.assertEqual(