libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anthonys...@apache.org
Subject [1/9] libcloud git commit: [LIBCLOUD-873] Updated ProfitBricks Compute Driver (REST api v3)
Date Mon, 14 Nov 2016 04:18:01 GMT
Repository: libcloud
Updated Branches:
  refs/heads/trunk 54050a418 -> df93d65f6


http://git-wip-us.apache.org/repos/asf/libcloud/blob/2569a5f2/libcloud/test/compute/test_profitbricks.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_profitbricks.py b/libcloud/test/compute/test_profitbricks.py
index 0a5c068..c246136 100644
--- a/libcloud/test/compute/test_profitbricks.py
+++ b/libcloud/test/compute/test_profitbricks.py
@@ -32,478 +32,5157 @@ class ProfitBricksTests(unittest.TestCase):
         ProfitBricks.connectionCls.conn_classes = (None, ProfitBricksMockHttp)
         self.driver = ProfitBricks(*PROFIT_BRICKS_PARAMS)
 
-    ''' Server Function Tests
     '''
-    def test_list_nodes(self):
-        nodes = self.driver.list_nodes()
-
-        self.assertEqual(len(nodes), 3)
+    Function tests for listing items
+    '''
 
-        node = nodes[0]
-        self.assertEqual(node.id, "c8e57d7b-e731-46ad-a913-1828c0562246")
-        self.assertEqual(node.name, "server001")
-        self.assertEqual(node.state, NodeState.RUNNING)
-        self.assertEqual(node.public_ips, ['162.254.25.197'])
-        self.assertEqual(node.private_ips, ['10.10.108.12', '10.13.198.11'])
-        self.assertEqual(node.extra['datacenter_id'], "e1e8ec0d-b47f-4d39-a91b-6e885483c899")
-        self.assertEqual(node.extra['datacenter_version'], "5")
-        self.assertEqual(node.extra['provisioning_state'], NodeState.RUNNING)
-        self.assertEqual(node.extra['creation_time'], "2014-07-14T20:52:20.839Z")
-        self.assertEqual(node.extra['last_modification_time'], "2014-07-14T22:11:09.324Z")
-        self.assertEqual(node.extra['os_type'], "LINUX")
-        self.assertEqual(node.extra['availability_zone'], "ZONE_1")
+    def test_list_sizes(self):
+        sizes = self.driver.list_sizes()
+        self.assertEqual(len(sizes), 7)
 
-    def test_ex_describe_node(self):
-        image = type('NodeImage', (object,),
-                     dict(id="cd59b162-0289-11e4-9f63-52540066fee9",
-                          name="Debian-7-server-2014-07-01"))
-        size = type('NodeSize', (object,),
-                    dict(id="2",
-                         name="Small Instance",
-                         ram=2048,
-                         disk=50,
-                         extra={'cores': 1}))
-
-        node = self.driver.create_node(name="SPC-Server",
-                                       image=image,
-                                       size=size)
-
-        self.assertEqual(node.id, "7b18b85f-cc93-4c2d-abcc-5ce732d35750")
+    def test_list_images(self):
 
-    def test_reboot_node(self):
-        node = type('Node', (object,),
-                    dict(id="c8e57d7b-e731-46ad-a913-1828c0562246"))
-        reboot = self.driver.reboot_node(node=node)
+        '''
+        Fetch all images and then fetch with filters
+        '''
+        all_images = self.driver.list_images()
+        hdd_images = self.driver.list_images('HDD')
+        cdd_images = self.driver.list_images('CDROM')
+        private_images = self.driver.list_images(is_public=False)
+
+        self.assertEqual(len(all_images), 4)
+        self.assertEqual(len(hdd_images), 2)
+        self.assertEqual(len(cdd_images), 2)
+        self.assertEqual(len(private_images), 2)
+
+        image = all_images[0]
+        extra = image.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(image.id, 'img-1')
+        self.assertEqual(image.name, 'Test-Image-Two-CDROM')
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(extra['created_date'], '2014-11-14T15:22:19Z')
+        self.assertEqual(extra['created_by'], 'System')
+        self.assertEqual(extra['etag'], '957e0eac7456fa7554e73bf0d18860eb')
+        self.assertEqual(extra['last_modified_date'], '2014-11-14T15:22:19Z')
+        self.assertEqual(extra['last_modified_by'], 'System')
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(extra['name'], 'Test-Image-Two-CDROM')
+        self.assertEqual(extra['description'], '')
+        self.assertEqual(extra['location'], 'us/las')
+        self.assertEqual(extra['size'], 4)
+        self.assertEqual(extra['cpu_hot_plug'], False)
+
+        self.assertEqual(extra['cpu_hot_unplug'], False)
+        self.assertEqual(extra['ram_hot_plug'], False)
+        self.assertEqual(extra['ram_hot_unplug'], False)
+        self.assertEqual(extra['nic_hot_plug'], False)
+        self.assertEqual(extra['nic_hot_unplug'], False)
+
+        self.assertEqual(extra['disc_virtio_hot_plug'], False)
+        self.assertEqual(extra['disc_virtio_hot_unplug'], False)
+        self.assertEqual(extra['disc_scsi_hot_plug'], False)
+        self.assertEqual(extra['disc_scsi_hot_unplug'], False)
+        self.assertEqual(extra['licence_type'], 'OTHER')
+
+        self.assertEqual(extra['image_type'], 'CDROM')
+        self.assertEqual(extra['public'], True)
 
-        self.assertTrue(reboot)
+    def test_list_locations(self):
 
-    def test_ex_stop_node(self):
-        node = type('Node', (object,),
-                    dict(id="c8e57d7b-e731-46ad-a913-1828c0562246"))
-        stop = self.driver.ex_stop_node(node=node)
+        locations = self.driver.list_locations()
 
-        self.assertTrue(stop)
+        self.assertEqual(len(locations), 3)
 
-    def test_ex_start_node(self):
-        node = type('Node', (object,),
-                    dict(id="c8e57d7b-e731-46ad-a913-1828c0562246"))
-        start = self.driver.ex_start_node(node=node)
+        '''
+        Standard properties
+        '''
+        location = locations[0]
+        self.assertEqual(location.id, 'de/fkb')
+        self.assertEqual(location.name, 'karlsruhe')
+        self.assertEqual(location.country, 'de')
 
-        self.assertTrue(start)
+    def test_list_nodes(self):
 
-    def test_destroy_node(self):
-        node = type('Node', (object,),
-                    dict(id="c8e57d7b-e731-46ad-a913-1828c0562246"))
-        destroy = self.driver.destroy_node(node=node)
+        nodes = self.driver.list_nodes()
 
-        self.assertTrue(destroy)
+        self.assertEqual(len(nodes), 2)
 
-    def test_ex_update_node(self):
-        node = type('Node', (object,),
-                    dict(id="c8e57d7b-e731-46ad-a913-1828c0562246"))
+        node = nodes[0]
+        extra = node.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            node.id,
+            'srv-1'
+        )
+        self.assertEqual(
+            node.name,
+            'Test Node.'
+        )
+        self.assertEqual(
+            node.state,
+            NodeState.RUNNING
+        )
+        self.assertEqual(
+            node.public_ips,
+            []
+        )
+        self.assertEqual(
+            node.private_ips,
+            []
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-18T07:28:05Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'e7cf186125f51f3d9511754a40dcd12c'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-18T07:28:05Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['availability_zone'],
+            'AUTO'
+        )
+        self.assertEqual(
+            extra['boot_cdrom'],
+            None
+        )
+        self.assertEqual(
+            extra['boot_volume']['id'],
+            'bvol-1'
+        )
+        self.assertEqual(
+            extra['boot_volume']['href'],
+            (
+                '/cloudapi/v3/datacenters/dc-1'
+                '/volumes/bvol-1'
+            )
+        )
+        self.assertEqual(
+            extra['boot_volume']['properties']['name'],
+            'Test Node Volume'
+        )
+        self.assertEqual(
+            extra['boot_volume']['properties']['type'],
+            'HDD'
+        )
+        self.assertEqual(
+            extra['boot_volume']['properties']['size'],
+            10
+        )
+        self.assertEqual(
+            extra['boot_volume']['properties']['image'],
+            'bvol-img'
+        )
+        self.assertEqual(
+            extra['cpu_family'],
+            'AMD_OPTERON'
+        )
+
+        '''
+        Other miscellaneous
+        '''
+        self.assertEqual(
+            len(extra['entities']),
+            3
+        )
+        self.assertNotIn(
+            'status_url',
+            extra
+        )
 
-        zone = type('ExProfitBricksAvailabilityZone', (object,),
-                    dict(name="ZONE_2"))
+    def test_ex_list_availability_zones(self):
 
-        update = self.driver.ex_update_node(node=node, ram=2048, cores=2, name="server002", availability_zone=zone)
+        zones = self.driver.ex_list_availability_zones()
+        self.assertEqual(len(zones), 3)
 
-        self.assertTrue(update)
+        zones_sorted = sorted(list(a.name for a in zones))
+        zones_expected = ['AUTO', 'ZONE_1', 'ZONE_2']
+        self.assertEqual(zones_sorted, zones_expected)
 
-    ''' Volume Function Tests
-    '''
     def test_list_volumes(self):
-        volumes = self.driver.list_volumes()
 
-        self.assertEqual(len(volumes), 4)
+        volumes = self.driver.list_volumes()
+        self.assertEqual(len(volumes), 3)
 
         volume = volumes[0]
-        self.assertEqual(volume.id, "453582cf-8d54-4ec8-bc0b-f9962f7fd232")
-        self.assertEqual(volume.name, "storage001")
-        self.assertEqual(volume.size, 50)
-        self.assertEqual(volume.extra['server_id'], "ebee7d83-912b-42f1-9b62-b953351a7e29")
-        self.assertEqual(volume.extra['provisioning_state'], NodeState.RUNNING)
-        self.assertEqual(volume.extra['creation_time'], "2014-07-15T03:19:38.252Z")
-        self.assertEqual(volume.extra['last_modification_time'], "2014-07-15T03:28:58.724Z")
-        self.assertEqual(volume.extra['image_id'], "d2f627c4-0289-11e4-9f63-52540066fee9")
-        self.assertEqual(volume.extra['image_name'], "CentOS-6-server-2014-07-01")
-        self.assertEqual(volume.extra['datacenter_id'], "06eac419-c2b3-4761-aeb9-10efdd2cf292")
+        extra = volume.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            volume.id,
+            'bvol-1'
+        )
+        self.assertEqual(
+            volume.name,
+            'Test Volume'
+        )
+        self.assertEqual(
+            volume.size,
+            10
+        )
+
+        '''
+        Extra
+        '''
+        self.assertEqual(
+            extra['provisioning_state'],
+            NodeState.RUNNING)
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-18T07:20:41Z'
+        )
+        self.assertEqual(
+            extra['etag'],
+            '33f6b8d506e7ad756e8554b915f29c61'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-18T07:20:41Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Test Volume'
+        )
+        self.assertEqual(
+            extra['type'],
+            'HDD'
+        )
+        self.assertEqual(
+            extra['size'],
+            10
+        )
+        self.assertEqual(
+            extra['availability_zone'],
+            'AUTO'
+        )
+        self.assertEqual(
+            extra['image'],
+            'bvol-img'
+        )
+        self.assertEqual(
+            extra['image_password'],
+            None
+        )
+        self.assertEqual(
+            extra['ssh_keys'],
+            None
+        )
+        self.assertEqual(
+            extra['bus'],
+            'VIRTIO'
+        )
+        self.assertEqual(
+            extra['licence_type'],
+            'LINUX'
+        )
+        self.assertEqual(
+            extra['cpu_hot_plug'],
+            True
+        )
+
+        self.assertEqual(
+            extra['cpu_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['ram_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['ram_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['nic_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['nic_hot_unplug'],
+            True
+        )
+
+        self.assertEqual(
+            extra['disc_virtio_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['disc_virtio_hot_unplug'],
+            True
+        )
+        self.assertEqual(
+            extra['disc_scsi_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            extra['disc_scsi_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['device_number'],
+            1
+        )
 
-    def test_create_volume(self):
-        datacenter = type('Datacenter', (object,),
-                          dict(id="8669a69f-2274-4520-b51e-dbdf3986a476"))
-
-        image = type('NodeImage', (object,),
-                     dict(id="cd59b162-0289-11e4-9f63-52540066fee9"))
+    def test_ex_list_datacenters(self):
 
-        create = self.driver.create_volume(name="StackPointCloudStorage001",
-                                           size=50,
-                                           ex_datacenter=datacenter,
-                                           ex_image=image)
+        datacenters = self.driver.ex_list_datacenters()
+        self.assertEqual(len(datacenters), 1)
+
+        datacenter = datacenters[0]
+        extra = datacenter.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            datacenter.id,
+            'dc-1'
+        )
+        self.assertEqual(
+            datacenter.href,
+            '/cloudapi/v3/datacenters/dc-1'
+        )
+        self.assertEqual(
+            datacenter.name,
+            'Test One.'
+        )
+        self.assertEqual(
+            datacenter.version,
+            3
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Test One.'
+        )
+        self.assertEqual(
+            extra['description'],
+            'A test data center'
+        )
+        self.assertEqual(
+            extra['location'],
+            'de/fra'
+        )
+        self.assertEqual(
+            extra['version'],
+            3
+        )
+        self.assertEqual(
+            extra['features'],
+            ['SSD', 'MULTIPLE_CPU']
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-14T07:24:59Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'bdddec2287cb7723e86ac088bf644606'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-17T15:27:25Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.test'
+        )
+
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+        self.assertEqual(
+            extra['provisioning_state'],
+            NodeState.RUNNING
+        )
+        self.assertEqual(
+            len(extra['entities']),
+            4
+        )
+        self.assertNotIn(
+            'status_url',
+            extra
+        )
+
+    def test_list_snapshots(self):
+
+        volume_snapshots = self.driver.list_snapshots()
+        self.assertEqual(len(volume_snapshots), 1)
+
+        snapshot = volume_snapshots[0]
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            snapshot.id,
+            'sshot'
+        )
+        self.assertEqual(
+            snapshot.size,
+            10
+        )
+        self.assertEqual(
+            snapshot.created,
+            '2016-10-26T11:38:45Z'
+        )
+        self.assertEqual(
+            snapshot.state,
+            NodeState.RUNNING)
+        self.assertEqual(
+            snapshot.name,
+            'Balancer Testing 1 Storage-Snapshot-10/26/2016'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            snapshot.extra['name'],
+            'Balancer Testing 1 Storage-Snapshot-10/26/2016'
+        )
+        self.assertEqual(
+            snapshot.extra['description'],
+            (
+                'Created from \"Balancer Testing 1'
+                ' Storage\" in Data Center \"Snapshot\"'
+            )
+        )
+        self.assertEqual(
+            snapshot.extra['location'],
+            'us/las'
+        )
+        self.assertEqual(
+            snapshot.extra['size'],
+            10
+        )
+        self.assertEqual(
+            snapshot.extra['cpu_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['cpu_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['ram_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['ram_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['nic_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['nic_hot_unplug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['disc_virtio_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['disc_virtio_hot_unplug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['disc_scsi_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['disc_scsi_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['licence_type'],
+            'LINUX'
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            snapshot.extra['created_date'],
+            '2016-10-26T11:38:45Z'
+        )
+        self.assertEqual(
+            snapshot.extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            snapshot.extra['etag'],
+            '01873262ac042b5f44ed33b4241225b4'
+        )
+        self.assertEqual(
+            snapshot.extra['last_modified_date'],
+            '2016-10-26T11:38:45Z'
+        )
+        self.assertEqual(
+            snapshot.extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            snapshot.extra['state'],
+            'AVAILABLE'
+        )
 
-        self.assertTrue(create)
+    '''
+    Function tests for operations on volume snapshots
+    '''
 
-    def test_attach_volume_general(self):
-        volume = type('StorageVolume', (object,),
-                      dict(id="8669a69f-2274-4520-b51e-dbdf3986a476"))
+    def test_create_volume_snapshot(self):
+        volume = self.driver.ex_describe_volume(
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'volumes/vol-2'
+            )
+        )
+        snapshot = self.driver.create_volume_snapshot(volume=volume)
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            snapshot.id,
+            'sshot'
+        )
+        self.assertEqual(
+            snapshot.size,
+            10
+        )
+        self.assertEqual(
+            snapshot.created,
+            '2016-10-26T11:38:45Z'
+        )
+        self.assertEqual(
+            snapshot.state,
+            NodeState.PENDING
+        )
+        self.assertEqual(
+            snapshot.name,
+            'Test Created Snapshot'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            snapshot.extra['name'],
+            'Test Created Snapshot'
+        )
+        self.assertEqual(
+            snapshot.extra['description'],
+            'Test Created Snapshot'
+        )
+        self.assertEqual(
+            snapshot.extra['location'],
+            'us/las'
+        )
+        self.assertEqual(
+            snapshot.extra['size'],
+            10
+        )
+        self.assertEqual(
+            snapshot.extra['cpu_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['cpu_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['ram_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['ram_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['nic_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['nic_hot_unplug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['disc_virtio_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['disc_virtio_hot_unplug'],
+            True
+        )
+
+        self.assertEqual(
+            snapshot.extra['disc_scsi_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['disc_scsi_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['licence_type'],
+            'LINUX'
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            snapshot.extra['created_date'],
+            '2016-10-26T11:38:45Z'
+        )
+        self.assertEqual(
+            snapshot.extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            snapshot.extra['etag'],
+            '01873262ac042b5f44ed33b4241225b4'
+        )
+        self.assertEqual(
+            snapshot.extra['last_modified_date'],
+            '2016-10-26T11:38:45Z'
+        )
+        self.assertEqual(
+            snapshot.extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            snapshot.extra['state'],
+            'BUSY'
+        )
+
+    def test_ex_describe_snapshot(self):
+        snapshot_w_href = self.driver.ex_describe_snapshot(
+            ex_href='/cloudapi/v3/snapshots/sshot'
+        )
+        snapshot_w_id = self.driver.ex_describe_snapshot(
+            ex_snapshot_id='sshot'
+        )
+        self._verify_snapshot(snapshot=snapshot_w_href)
+        self._verify_snapshot(snapshot=snapshot_w_id)
+
+    def _verify_snapshot(self, snapshot):
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            snapshot.id,
+            'sshot'
+        )
+        self.assertEqual(
+            snapshot.size,
+            10
+        )
+        self.assertEqual(
+            snapshot.created,
+            '2016-10-26T11:38:45Z'
+        )
+        self.assertEqual(
+            snapshot.state,
+            NodeState.RUNNING
+        )
+        self.assertEqual(
+            snapshot.name,
+            'Test Snapshot'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            snapshot.extra['name'],
+            'Test Snapshot'
+        )
+        self.assertEqual(
+            snapshot.extra['description'],
+            'Test Snapshot'
+        )
+        self.assertEqual(
+            snapshot.extra['location'],
+            'us/las'
+        )
+        self.assertEqual(
+            snapshot.extra['size'],
+            10
+        )
+        self.assertEqual(
+            snapshot.extra['cpu_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['cpu_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['ram_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['ram_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['nic_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['nic_hot_unplug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['disc_virtio_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['disc_virtio_hot_unplug'],
+            True
+        )
+        self.assertEqual(
+            snapshot.extra['disc_scsi_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['disc_scsi_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            snapshot.extra['licence_type'],
+            'LINUX'
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            snapshot.extra['created_date'],
+            '2016-10-26T11:38:45Z'
+        )
+        self.assertEqual(
+            snapshot.extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            snapshot.extra['etag'],
+            '01873262ac042b5f44ed33b4241225b4'
+        )
+        self.assertEqual(
+            snapshot.extra['last_modified_date'],
+            '2016-10-26T11:38:45Z'
+        )
+        self.assertEqual(
+            snapshot.extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            snapshot.extra['state'],
+            'AVAILABLE'
+        )
+
+    def test_ex_update_snapshot(self):
+        snapshot = self.driver.ex_describe_snapshot(
+            ex_href='/cloudapi/v3/snapshots/sshot'
+        )
+        updated = self.driver.ex_update_snapshot(
+            snapshot=snapshot,
+            name='Updated snapshot',
+            description='Upated snapshot',
+            cpu_hot_unplug=True
+        )
+
+        self.assertEqual(
+            updated.name,
+            'Updated snapshot'
+        )
+        self.assertEqual(
+            updated.extra['description'],
+            'Updated snapshot'
+        )
+        self.assertEqual(
+            updated.extra['cpu_hot_unplug'],
+            True
+        )
+
+    def test_destroy_volume_snapshot(self):
+        snapshot = self.driver.ex_describe_snapshot(
+            ex_href='/cloudapi/v3/snapshots/sshot'
+        )
+        destroyed = self.driver.destroy_volume_snapshot(snapshot)
+        self.assertTrue(destroyed)
 
-        node = type('Node', (object,),
-                    dict(id="cd59b162-0289-11e4-9f63-52540066fee9"))
+    '''
+    Function tests for operations on nodes (servers)
+    '''
 
-        attach = self.driver.attach_volume(node=node,
-                                           volume=volume,
-                                           device=None, ex_bus_type=None)
+    def test_reboot_node(self):
+        node = self.driver.ex_describe_node(
+            ex_href=(
+                '/cloudapi/v3/datacenters/dc-1'
+                '/servers/srv-1'
+            )
+        )
+        rebooted = self.driver.reboot_node(node=node)
+        self.assertTrue(rebooted)
+
+    def test_create_node(self):
+        image = self.driver.ex_describe_image(
+            ex_href='/cloudapi/v3/images/img-2'
+        )
+        datacenter = self.driver.ex_describe_datacenter(
+            ex_href='/cloudapi/v3/datacenters/dc-1'
+        )
+        sizes = self.driver.list_sizes()
 
-        self.assertTrue(attach)
+        with self.assertRaises(ValueError):
+            'Raises value error if no size or ex_ram'
+            self.driver.create_node(
+                name='Test',
+                image=image,
+                ex_disk=40,
+                ex_cores=1
+            )
+
+        with self.assertRaises(ValueError):
+            'Raises value error if no size or ex_cores'
+            self.driver.create_node(
+                name='Test',
+                image=image,
+                ex_disk=40,
+                ex_ram=1024
+            )
+
+        with self.assertRaises(ValueError):
+            'Raises value error if no size or ex_disk'
+            self.driver.create_node(
+                name='Test',
+                image=image,
+                ex_cores=2,
+                ex_ram=1024
+            )
+
+        with self.assertRaises(ValueError):
+            'Raises value error if no ssh keys or password'
+            self.driver.create_node(
+                name='Test',
+                image=image,
+                size=sizes[1],
+                datacenter=datacenter
+            )
+
+        node = self.driver.create_node(
+            name='Test',
+            image=image,
+            size=sizes[1],
+            ex_password='dummy1234',
+            datacenter=datacenter
+        )
+
+        extra = node.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            node.id,
+            'srv-2'
+        )
+        self.assertEqual(
+            node.name,
+            'Test'
+        )
+        self.assertEqual(
+            node.state,
+            NodeState.UNKNOWN
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-19T13:25:19Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            '9bea2412ac556b402a07260fc0d1603f'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-19T13:25:19Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'BUSY'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Test'
+        )
+        self.assertEqual(
+            extra['cores'],
+            1
+        )
+        self.assertEqual(
+            extra['ram'],
+            512
+        )
+        self.assertEqual(
+            extra['availability_zone'],
+            'ZONE_1'
+        )
+        self.assertEqual(
+            extra['vm_state'],
+            None
+        )
+
+        self.assertEqual(
+            extra['boot_cdrom'],
+            None
+        )
+        self.assertEqual(
+            extra['boot_volume'],
+            None
+        )
+        self.assertEqual(
+            extra['cpu_family'],
+            'INTEL_XEON'
+        )
+
+        '''
+        Extra entities
+        '''
+        self.assertEqual(
+            len(extra['entities']['volumes']['items']),
+            1
+        )
 
-    def test_attach_volume_device_defined(self):
-        volume = type('StorageVolume', (object,),
-                      dict(id="8669a69f-2274-4520-b51e-dbdf3986a476"))
+    def test_destroy_node(self):
+        node = self.driver.ex_describe_node(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/srv-1'
+            )
+        )
+        destroyed = self.driver.destroy_node(
+            node=node,
+            ex_remove_attached_disks=False
+        )
+        self.assertTrue(destroyed)
+
+    def test_ex_list_attached_volumes(self):
+
+        node = self.driver.ex_describe_node(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/servers/'
+                'srv-1'
+            )
+        )
+
+        attached_volumes = self.driver.ex_list_attached_volumes(node)
+        self.assertEqual(len(attached_volumes), 3)
+
+    def test_attach_volume(self):
+
+        node = self.driver.ex_describe_node(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/srv-1'
+            )
+        )
+        volume = self.driver.ex_describe_volume(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'volumes/vol-2'
+            )
+        )
+
+        attached = self.driver.attach_volume(node=node, volume=volume)
+        extra = attached.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            attached.id,
+            'vol-2'
+        )
+        self.assertEqual(
+            attached.name,
+            'Updated storage name'
+        )
+        self.assertEqual(
+            attached.size,
+            40
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-17T13:13:36Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'c1800ce349033f9cd2c095ea1ea4976a'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-17T13:47:52Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'BUSY'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Updated storage name'
+        )
+        self.assertEqual(
+            extra['type'],
+            'HDD'
+        )
+        self.assertEqual(
+            extra['size'],
+            40
+        )
+        self.assertEqual(
+            extra['image'],
+            'bvol-img'
+        )
+
+        self.assertEqual(
+            extra['image_password'],
+            None
+        )
+        self.assertEqual(
+            extra['ssh_keys'],
+            None
+        )
+        self.assertEqual(
+            extra['bus'],
+            'VIRTIO'
+        )
+        self.assertEqual(
+            extra['licence_type'],
+            'LINUX'
+        )
+        self.assertEqual(
+            extra['cpu_hot_plug'],
+            True
+        )
+
+        self.assertEqual(
+            extra['cpu_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['ram_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['ram_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['nic_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['nic_hot_unplug'],
+            True
+        )
+
+        self.assertEqual(
+            extra['disc_virtio_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['disc_virtio_hot_unplug'],
+            True
+        )
+        self.assertEqual(
+            extra['disc_scsi_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            extra['disc_scsi_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['device_number'],
+            3
+        )
+
+        self.assertNotIn(
+            'availability_zone',
+            extra
+        )
 
-        node = type('Node', (object,),
-                    dict(id="cd59b162-0289-11e4-9f63-52540066fee9"))
+    def test_detach_volume(self):
 
-        attach = self.driver.attach_volume(node=node, volume=volume, device=1, ex_bus_type=None)
+        node = self.driver.ex_describe_node(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/srv-1'
+            )
+        )
+        volume = self.driver.ex_describe_volume(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'volumes/vol-2'
+            )
+        )
+        detached = self.driver.detach_volume(
+            node=node,
+            volume=volume
+        )
+        self.assertTrue(detached)
 
-        self.assertTrue(attach)
+    def test_ex_stop_node(self):
 
-    def test_attach_volume_bus_type_defined(self):
-        volume = type('StorageVolume', (object,),
-                      dict(id="8669a69f-2274-4520-b51e-dbdf3986a476"))
+        node = self.driver.ex_describe_node(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/srv-1'
+            )
+        )
+        stopped = self.driver.ex_stop_node(node)
+        self.assertTrue(stopped)
 
-        node = type('Node', (object,),
-                    dict(id="cd59b162-0289-11e4-9f63-52540066fee9"))
+    def test_ex_start_node(self):
+        node = self.driver.ex_describe_node(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/srv-1'
+            )
+        )
+        started = self.driver.ex_start_node(node)
+        self.assertTrue(started)
 
-        attach = self.driver.attach_volume(node=node,
-                                           volume=volume,
-                                           device=None,
-                                           ex_bus_type="IDE")
+    def test_ex_describe_node(self):
+        node_w_href = self.driver.ex_describe_node(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/srv-1'
+            )
+        )
+        node_w_id = self.driver.ex_describe_node(
+            ex_datacenter_id='dc-1',
+            ex_node_id='srv-1'
+        )
+        self._verify_node(node=node_w_href)
+        self._verify_node(node=node_w_id)
+
+    def _verify_node(self, node):
+        extra = node.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            node.id,
+            'srv-1'
+        )
+        self.assertEqual(
+            node.name,
+            'A test node'
+        )
+        self.assertEqual(
+            node.state,
+            NodeState.RUNNING
+        )
+        self.assertEqual(
+            node.public_ips,
+            []
+        )
+        self.assertEqual(
+            node.private_ips,
+            []
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-18T07:28:05Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'e7cf186125f51f3d9511754a40dcd12c')
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-18T07:28:05Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['availability_zone'],
+            'AUTO'
+        )
+        self.assertEqual(
+            extra['boot_cdrom'],
+            None
+        )
+        self.assertEqual(
+            extra['boot_volume']['id'],
+            'bvol-1'
+        )
+        self.assertEqual(
+            extra['boot_volume']['href'],
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'volumes/bvol-1'
+            )
+        )
+        self.assertEqual(
+            extra['boot_volume']['properties']['name'],
+            'A test node boot volume'
+        )
+
+        self.assertEqual(
+            extra['boot_volume']['properties']['type'],
+            'HDD'
+        )
+        self.assertEqual(
+            extra['boot_volume']['properties']['size'],
+            10
+        )
+        self.assertEqual(
+            extra['boot_volume']['properties']['image'],
+            'bvol-img'
+        )
+        self.assertEqual(
+            extra['cpu_family'],
+            'AMD_OPTERON'
+        )
+
+        '''
+        Other miscellaneous
+        '''
+        self.assertEqual(
+            len(extra['entities']),
+            3
+        )
+        self.assertNotIn(
+            'status_url',
+            extra
+        )
 
-        self.assertTrue(attach)
+    def test_ex_update_node(self):
 
-    def test_attach_volume_options_defined(self):
-        volume = type('StorageVolume', (object,),
-                      dict(id="8669a69f-2274-4520-b51e-dbdf3986a476"))
+        node = self.driver.ex_describe_node(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/srv-1'
+            )
+        )
+        zones = self.driver.ex_list_availability_zones()
+        updated = self.driver.ex_update_node(
+            node=node,
+            name='Test update',
+            cores=4,
+            ram=4096,
+            availability_zone=zones[0],
+            ex_cpu_family='INTEL_XEON'
+        )
+
+        extra = updated.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            updated.id,
+            'srv-1'
+        )
+        self.assertEqual(
+            updated.name,
+            'A test node'
+        )
+        self.assertEqual(
+            updated.state,
+            NodeState.RUNNING
+        )
+        self.assertEqual(
+            updated.public_ips,
+            []
+        )
+        self.assertEqual(
+            updated.private_ips,
+            []
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-18T07:28:05Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'e7cf186125f51f3d9511754a40dcd12c'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-18T07:28:05Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['state'],
+            'BUSY'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['availability_zone'],
+            'AUTO'
+        )
+        self.assertEqual(
+            extra['boot_cdrom'],
+            None
+        )
+        self.assertEqual(
+            extra['boot_volume']['id'],
+            'bvol-1'
+        )
+        self.assertEqual(
+            extra['boot_volume']['href'],
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'volumes/bvol-1'
+            )
+        )
+        self.assertEqual(
+            extra['cpu_family'],
+            'AMD_OPTERON'
+        )
 
-        node = type('Node', (object,),
-                    dict(id="cd59b162-0289-11e4-9f63-52540066fee9"))
+    '''
+    Function tests for operations on volumes
+    '''
 
-        attach = self.driver.attach_volume(node=node, volume=volume,
-                                           device=1, ex_bus_type="IDE")
+    def test_create_volume(self):
 
-        self.assertTrue(attach)
+        datacenter = self.driver.ex_describe_datacenter(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1'
+            )
+        )
+        image = self.driver.ex_describe_image(
+            ex_href='/cloudapi/v3/images/img-2'
+        )
+        created = self.driver.create_volume(
+            size=30,
+            name='Test volume',
+            ex_type='HDD',
+            ex_bus_type='IDE',
+            ex_datacenter=datacenter,
+            image=image,
+            ex_password='dummyP8ssw0rdl33t'
+        )
+
+        self.assertTrue(created)
 
-    def test_detach_volume(self):
-        volume = type('StorageVolume', (object,),
-                      dict(id="8669a69f-2274-4520-b51e-dbdf3986a476",
-                           extra={'server_id': "cd59b162-0289-11e4-9f63-52540066fee9"}
-                           ))
+    def test_destroy_volume(self):
 
-        attach = self.driver.detach_volume(volume=volume)
+        volume = self.driver.ex_describe_volume(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/volumes/'
+                'vol-2'
+            )
+        )
+        destroyed = self.driver.destroy_volume(volume=volume)
+
+        self.assertTrue(destroyed)
+
+    def test_ex_update_volume(self):
+
+        volume = self.driver.ex_describe_volume(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'volumes/vol-2'
+            )
+
+        )
+        updated = self.driver.ex_update_volume(
+            volume=volume,
+            ex_storage_name='Updated volume',
+            size=48,
+            ex_bus_type='VIRTIO'
+        )
+
+        extra = updated.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            updated.id,
+            'vol-2'
+        )
+        self.assertEqual(
+            updated.name,
+            'Updated storage name'
+        )
+        self.assertEqual(
+            updated.size,
+            40
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-17T13:13:36Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'c1800ce349033f9cd2c095ea1ea4976a'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-17T13:47:52Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Updated storage name'
+        )
+        self.assertEqual(
+            extra['type'],
+            'HDD'
+        )
+        self.assertEqual(
+            extra['size'],
+            40
+        )
+        self.assertEqual(
+            extra['availability_zone'],
+            'AUTO'
+        )
+        self.assertEqual(
+            extra['image'],
+            'bvol-img'
+        )
+
+        self.assertEqual(
+            extra['image_password'],
+            None
+        )
+        self.assertEqual(
+            extra['ssh_keys'],
+            None
+        )
+        self.assertEqual(
+            extra['bus'],
+            'VIRTIO'
+        )
+        self.assertEqual(
+            extra['licence_type'],
+            'LINUX'
+        )
+        self.assertEqual(
+            extra['cpu_hot_plug'],
+            True
+        )
+
+        self.assertEqual(
+            extra['cpu_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['ram_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['ram_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['nic_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['nic_hot_unplug'],
+            True
+        )
+
+        self.assertEqual(
+            extra['disc_virtio_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['disc_virtio_hot_unplug'],
+            True
+        )
+        self.assertEqual(
+            extra['disc_scsi_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            extra['disc_scsi_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['device_number'],
+            3
+        )
+
+        return {}
 
-        self.assertTrue(attach)
+    def test_ex_describe_volume(self):
+        volume_w_href = self.driver.ex_describe_volume(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'volumes/vol-2'
+            )
+        )
+        volume_w_id = self.driver.ex_describe_volume(
+            ex_datacenter_id='dc-1',
+            ex_volume_id='vol-2'
+        )
+        self._verify_volume(volume=volume_w_href)
+        self._verify_volume(volume=volume_w_id)
+
+    def _verify_volume(self, volume):
+        extra = volume.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            volume.id,
+            'vol-2'
+        )
+        self.assertEqual(
+            volume.name,
+            'Updated storage name'
+        )
+        self.assertEqual(
+            volume.size,
+            40
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-17T13:13:36Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'c1800ce349033f9cd2c095ea1ea4976a'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-17T13:47:52Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Updated storage name'
+        )
+        self.assertEqual(
+            extra['type'],
+            'HDD'
+        )
+        self.assertEqual(
+            extra['size'],
+            40
+        )
+        self.assertEqual(
+            extra['availability_zone'],
+            'AUTO'
+        )
+        self.assertEqual(
+            extra['image'],
+            'bvol-img'
+        )
+
+        self.assertEqual(
+            extra['image_password'],
+            None
+        )
+        self.assertEqual(
+            extra['ssh_keys'],
+            None
+        )
+        self.assertEqual(
+            extra['bus'],
+            'VIRTIO'
+        )
+        self.assertEqual(
+            extra['licence_type'],
+            'LINUX'
+        )
+        self.assertEqual(
+            extra['cpu_hot_plug'],
+            True
+        )
+
+        self.assertEqual(
+            extra['cpu_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['ram_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['ram_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['nic_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['nic_hot_unplug'],
+            True
+        )
+
+        self.assertEqual(
+            extra['disc_virtio_hot_plug'],
+            True
+        )
+        self.assertEqual(
+            extra['disc_virtio_hot_unplug'],
+            True
+        )
+        self.assertEqual(
+            extra['disc_scsi_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            extra['disc_scsi_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['device_number'],
+            3
+        )
+
+        self.assertNotIn(
+            'status_url',
+            extra
+        )
 
-    def test_destroy_volume(self):
-        volume = type('StorageVolume', (object,),
-                      dict(id="8669a69f-2274-4520-b51e-dbdf3986a476"))
+    '''
+    Function tests for operations on data centers
+    '''
 
-        destroy = self.driver.destroy_volume(volume=volume)
+    def test_ex_create_datacenter(self):
+        location = self.driver.ex_describe_location(ex_location_id='de/fkb')
+        datacenter = self.driver.ex_create_datacenter(
+            name='Test Data Center',
+            location=location,
+            description='Test Data Center.'
+        )
+
+        extra = datacenter.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            datacenter.id,
+            'dc-1'
+        )
+        self.assertEqual(
+            datacenter.href,
+            '/cloudapi/v3/datacenters/dc-1'
+        )
+        self.assertEqual(
+            datacenter.name,
+            'Test Data Center'
+        )
+        self.assertEqual(
+            datacenter.version,
+            None
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-18T17:20:56Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'c2d3d4d9bbdc0fff7d3c5c3864a68a46'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-18T17:20:56Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'BUSY'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Test Data Center'
+        )
+        self.assertEqual(
+            extra['description'],
+            'Test Data Center.'
+        )
+        self.assertEqual(
+            extra['location'],
+            'us/las'
+        )
+        self.assertEqual(
+            extra['version'],
+            None
+        )
+        self.assertEqual(
+            extra['features'],
+            []
+        )
+
+        '''
+        Miscellaneous properties
+        '''
+        self.assertNotIn(
+            'entities',
+            extra
+        )
+        self.assertEqual(
+            extra['provisioning_state'],
+            NodeState.PENDING
+        )
 
-        self.assertTrue(destroy)
+    def test_ex_destroy_datacenter(self):
 
-    def test_update_volume(self):
-        volume = type('StorageVolume', (object,),
-                      dict(id="8669a69f-2274-4520-b51e-dbdf3986a476"))
+        datacenter = self.driver.ex_describe_datacenter(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1'
+            )
+        )
+        destroyed = self.driver.ex_destroy_datacenter(
+            datacenter=datacenter
+        )
+        self.assertTrue(destroyed)
 
-        destroy = self.driver.ex_update_volume(volume=volume)
+    def test_ex_describe_datacenter(self):
+        datacenter_w_href = self.driver.ex_describe_datacenter(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1'
+            )
+        )
+        datacenter_w_id = self.driver.ex_describe_datacenter(
+            ex_datacenter_id='dc-1'
+        )
+        self._verify_datacenter(datacenter=datacenter_w_href)
+        self._verify_datacenter(datacenter=datacenter_w_id)
+
+    def _verify_datacenter(self, datacenter):
+        extra = datacenter.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            datacenter.id,
+            'dc-1'
+        )
+        self.assertEqual(
+            datacenter.href,
+            '/cloudapi/v3/datacenters/dc-1'
+        )
+        self.assertEqual(
+            datacenter.name,
+            'Test Data Center'
+        )
+        self.assertEqual(
+            datacenter.version,
+            35
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-17T11:33:11Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['etag'],
+            '53b215b8ec0356a649955dab019845a4'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-18T15:13:44Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Test Data Center'
+        )
+        self.assertEqual(
+            extra['description'],
+            'This is a test data center.'
+        )
+        self.assertEqual(
+            extra['location'],
+            'de/fkb'
+        )
+        self.assertEqual(
+            extra['version'],
+            35
+        )
+        self.assertEqual(
+            extra['features'],
+            ['SSD', 'MULTIPLE_CPU']
+        )
+
+        self.assertNotIn(
+            'status_url',
+            extra
+        )
+        self.assertEqual(
+            extra['provisioning_state'],
+            NodeState.RUNNING
+        )
+        self.assertEqual(
+            len(extra['entities']),
+            4
+        )
 
-        self.assertTrue(destroy)
+    def test_ex_rename_datacenter(self):
 
-    def test_ex_describe_volume(self):
-        describe = self.driver.ex_describe_volume(volume_id="8669a69f-2274-4520-b51e-dbdf3986a476")
+        datacenter = self.driver.ex_describe_datacenter(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1'
+            )
+        )
+        renamed = self.driver.ex_rename_datacenter(
+            datacenter=datacenter,
+            name='Renamed data center'
+        )
+        extra = renamed.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            renamed.id,
+            'dc-1'
+        )
+        self.assertEqual(
+            renamed.href,
+            '/cloudapi/v3/datacenters/dc-1'
+        )
+        self.assertEqual(
+            renamed.name,
+            'Test Data Center'
+        )
+        self.assertEqual(
+            renamed.version,
+            35
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-17T11:33:11Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['etag'],
+            '53b215b8ec0356a649955dab019845a4'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-18T15:13:44Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.test'
+        )
+        self.assertEqual(
+            extra['state'],
+            'BUSY'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Test Data Center'
+        )
+        self.assertEqual(
+            extra['description'],
+            'This is a test data center.'
+        )
+        self.assertEqual(
+            extra['location'],
+            'de/fkb'
+        )
+        self.assertEqual(
+            extra['version'],
+            35
+        )
+        self.assertEqual(
+            extra['features'],
+            ['SSD', 'MULTIPLE_CPU']
+        )
+
+        self.assertNotIn(
+            'status_url',
+            extra
+        )
+        self.assertEqual(
+            extra['provisioning_state'],
+            NodeState.PENDING
+        )
+        self.assertEqual(
+            len(extra['entities']),
+            4
+        )
 
-        self.assertEqual(describe.id, "00d0b9e7-e016-456f-85a0-517aa9a34bf5")
-        self.assertEqual(describe.size, 50)
-        self.assertEqual(describe.name, "StackPointCloud-Volume")
-        self.assertEqual(describe.extra['provisioning_state'], NodeState.RUNNING)
+    '''
+    Function tests for operations on images
+    '''
+    def test_ex_describe_image(self):
+        image_w_href = self.driver.ex_describe_image(
+            ex_href=(
+                '/cloudapi/v3/images/'
+                'img-2'
+            )
+        )
+        image_w_id = self.driver.ex_describe_image(
+            ex_image_id='img-2'
+        )
+        self._verify_image(image=image_w_href)
+        self._verify_image(image=image_w_id)
+
+    def _verify_image(self, image):
+        extra = image.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            image.id,
+            'img-2'
+        )
+        self.assertEqual(
+            image.name,
+            'vivid-server-cloudimg-amd64-disk1.img'
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2015-10-09T12:06:34Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'bbf76112358af2fc5dd1bf21de8988db'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2015-11-11T15:23:20Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'vivid-server-cloudimg-amd64-disk1.img'
+        )
+        self.assertEqual(
+            extra['description'],
+            None
+        )
+        self.assertEqual(
+            extra['location'],
+            'de/fkb'
+        )
+        self.assertEqual(
+            extra['size'],
+            2
+        )
+        self.assertEqual(
+            extra['cpu_hot_plug'],
+            False
+        )
+
+        self.assertEqual(
+            extra['cpu_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['ram_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            extra['ram_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['nic_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            extra['nic_hot_unplug'],
+            False
+        )
+
+        self.assertEqual(
+            extra['disc_virtio_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            extra['disc_virtio_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['disc_scsi_hot_plug'],
+            False
+        )
+        self.assertEqual(
+            extra['disc_scsi_hot_unplug'],
+            False
+        )
+        self.assertEqual(
+            extra['licence_type'],
+            'UNKNOWN'
+        )
+
+        self.assertEqual(
+            extra['image_type'],
+            'HDD'
+        )
+        self.assertEqual(
+            extra['public'],
+            False
+        )
+        self.assertEqual(
+            extra['href'],
+            '/cloudapi/v3/images/img-2'
+        )
+
+    def test_ex_update_image(self):
+        image = self.driver.ex_describe_image(
+            ex_href=(
+                '/cloudapi/v3/images/'
+                'img-2'
+            )
+        )
+        updated = self.driver.ex_update_image(
+            image=image,
+            name='my-updated-image.img'
+        )
+        extra = updated.extra
+
+        self.assertEqual(
+            updated.name,
+            'my-updated-image.img'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-11-11T15:23:20Z'
+        )
+
+    def test_ex_delete_image(self):
+        image = self.driver.ex_describe_image(
+            ex_href=(
+                '/cloudapi/v3/images/'
+                'img-2'
+            )
+        )
+        deleted = self.driver.ex_delete_image(image)
+        self.assertTrue(deleted)
 
-    ''' Image Function Tests
     '''
-    def test_list_images(self):
-        images = self.driver.list_images()
+    Function tests for operations on network interfaces
+    '''
+
+    def test_ex_list_network_interfaces(self):
+
+        network_interfaces = self.driver.ex_list_network_interfaces()
+        self.assertEqual(
+            len(network_interfaces),
+            4
+        )
+
+        network_interface = network_interfaces[0]
+        extra = network_interface.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            network_interface.id,
+            'nic-1'
+        )
+        self.assertEqual(
+            network_interface.name,
+            'Test network interface'
+        )
+        self.assertEqual(
+            network_interface.href,
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/servers/'
+                's-3/nics/'
+                'nic-1'
+            )
+        )
+        self.assertEqual(
+            network_interface.state,
+            NodeState.RUNNING
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-17T15:46:38Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'dbd8216137cf0ec9951170f93fa8fa53'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-17T18:19:43Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Test network interface'
+        )
+        self.assertEqual(
+            extra['mac'],
+            '02:01:0b:9d:4d:ce'
+        )
+        self.assertEqual(
+            extra['ips'],
+            ['10.15.124.11']
+        )
+        self.assertEqual(
+            extra['dhcp'],
+            False
+        )
+        self.assertEqual(
+            extra['lan'],
+            2
+        )
+        self.assertEqual(
+            extra['firewall_active'],
+            True
+        )
+        self.assertEqual(
+            extra['nat'],
+            False
+        )
+
+    def test_ex_describe_network_interface(self):
+        nic_w_href = self.driver.ex_describe_network_interface(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3'
+                '/nics/nic-2'
+            )
+        )
+        nic_w_id = self.driver.ex_describe_network_interface(
+            ex_datacenter_id='dc-1',
+            ex_server_id='s-3',
+            ex_nic_id='nic-2'
+        )
+        self._verify_network_interface(network_interface=nic_w_href)
+        self._verify_network_interface(network_interface=nic_w_id)
+
+    def _verify_network_interface(self, network_interface):
+        extra = network_interface.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            network_interface.id,
+            'nic-2'
+        )
+        self.assertEqual(
+            network_interface.name,
+            'Updated from LibCloud'
+        )
+        self.assertEqual(
+            network_interface.href,
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3/'
+                'nics/nic-2'
+            )
+        )
+        self.assertEqual(
+            network_interface.state,
+            NodeState.RUNNING
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-17T15:46:38Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'dbd8216137cf0ec9951170f93fa8fa53'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-17T18:19:43Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Updated from LibCloud'
+        )
+        self.assertEqual(
+            extra['mac'],
+            '02:01:0b:9d:4d:ce'
+        )
+        self.assertEqual(
+            extra['ips'],
+            ['10.15.124.11']
+        )
+        self.assertEqual(
+            extra['dhcp'],
+            False
+        )
+        self.assertEqual(
+            extra['lan'],
+            2
+        )
+        self.assertEqual(
+            extra['firewall_active'],
+            True
+        )
+        self.assertEqual(
+            extra['nat'],
+            False
+        )
+
+        '''
+        Miscellaneous
+        '''
+        self.assertTrue(
+            len(extra['entities']),
+            1
+        )
+
+    def test_ex_create_network_interface(self):
 
-        self.assertEqual(len(images), 3)
+        node = self.driver.ex_describe_node(
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/srv-1'
+            )
+        )
+        network_interface = self.driver.ex_create_network_interface(
+            node=node,
+            lan_id=1,
+            dhcp_active=True,
+            nic_name='Creating a test network interface.'
+        )
+        extra = network_interface.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            network_interface.id,
+            'nic-2'
+        )
+        self.assertEqual(
+            network_interface.name,
+            'Creating a test network interface.'
+        )
+        self.assertEqual(
+            network_interface.href,
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/srv-1'
+                '/nics/nic-2'
+            )
+        )
+        self.assertEqual(
+            network_interface.state,
+            NodeState.PENDING
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-19T08:18:50Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            '8679142b0b1b70c8b8c09a8b31e6ded9'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-19T08:18:50Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'BUSY'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Creating a test network interface.'
+        )
+        self.assertEqual(
+            extra['mac'],
+            None
+        )
+        self.assertEqual(
+            extra['ips'],
+            []
+        )
+        self.assertEqual(
+            extra['dhcp'],
+            True
+        )
+        self.assertEqual(
+            extra['lan'],
+            1
+        )
+        self.assertEqual(
+            extra['firewall_active'],
+            None
+        )
+        self.assertEqual(
+            extra['nat'],
+            None
+        )
+
+    def test_ex_update_network_interface(self):
 
-        image = images[0]
-        self.assertEqual(image.extra['cpu_hotpluggable'], "false")
-        self.assertEqual(image.id, "03b6c3e7-f2ad-11e3-a036-52540066fee9")
-        self.assertEqual(image.name, "windows-2012-r2-server-2014-06")
-        self.assertEqual(image.extra['image_size'], "11264")
-        self.assertEqual(image.extra['image_type'], "HDD")
-        self.assertEqual(image.extra['memory_hotpluggable'], "false")
-        self.assertEqual(image.extra['os_type'], "WINDOWS")
-        self.assertEqual(image.extra['public'], "true")
-        self.assertEqual(image.extra['location'], None)
-        self.assertEqual(image.extra['writeable'], "true")
+        network_interface = self.driver.ex_describe_network_interface(
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3'
+                '/nics/nic-2'
+            )
+        )
+        updated = self.driver.ex_update_network_interface(
+            network_interface=network_interface,
+            name='New network interface', dhcp_active=False
+        )
+
+        extra = updated.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            updated.id,
+            'nic-2'
+        )
+        self.assertEqual(
+            updated.name,
+            'Updated from LibCloud'
+        )
+        self.assertEqual(
+            updated.href,
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3/'
+                'nics/nic-2'
+            )
+        )
+        self.assertEqual(
+            updated.state,
+            NodeState.PENDING
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-19T08:18:55Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            '56f8d8bbdc84faad4188f647a49a565b'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-19T09:44:59Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'BUSY'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Updated from LibCloud'
+        )
+        self.assertEqual(
+            extra['mac'],
+            '02:01:68:c1:e8:88'
+        )
+        self.assertEqual(
+            extra['ips'],
+            ['11.12.13.14']
+        )
+        self.assertEqual(
+            extra['dhcp'],
+            True
+        )
+        self.assertEqual(
+            extra['lan'],
+            1
+        )
+        self.assertEqual(
+            extra['firewall_active'],
+            False
+        )
+        self.assertEqual(
+            extra['nat'],
+            False
+        )
+
+        self.assertTrue(updated)
+
+    def test_ex_destroy_network_interface(self):
+
+        network_interface = self.driver.ex_describe_network_interface(
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3'
+                '/nics/nic-2'
+            )
+        )
+        destroyed = self.driver.ex_destroy_network_interface(
+            network_interface=network_interface
+        )
+
+        self.assertTrue(destroyed)
+
+    def test_ex_set_inet_access(self):
+        network_interface = self.driver.ex_describe_network_interface(
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3'
+                '/nics/nic-2'
+            )
+        )
+        updated = self.driver.ex_set_inet_access(
+            network_interface=network_interface,
+            internet_access=False)
+
+        self.assertTrue(updated)
+
+        return {}
 
-    ''' Datacenter Function Tests
     '''
-    def test_ex_create_datacenter(self):
-        datacenter = self.driver.ex_create_datacenter(name="StackPointCloud",
-                                                      location="us/la")
+    Function tests for operations on locations
+    '''
 
-        self.assertEqual(datacenter.id, '0c793dd1-d4cd-4141-86f3-8b1a24b2d604')
-        self.assertEqual(datacenter.extra['location'], 'us/las')
-        self.assertEqual(datacenter.version, '1')
+    def test_ex_describe_location(self):
+        location_w_href = self.driver.ex_describe_location(
+            ex_href=(
+                '/cloudapi/v3/locations/de/fkb'
+            )
+        )
+        location_w_id = self.driver.ex_describe_location(
+            ex_location_id='de/fkb'
+        )
+        self._verify_location(location=location_w_href)
+        self._verify_location(location=location_w_id)
+
+    def _verify_location(self, location):
+        self.assertEqual(
+            location.id,
+            'de/fkb'
+        )
+        self.assertEqual(
+            location.name,
+            'karlsruhe'
+        )
+        self.assertEqual(
+            location.country,
+            'de'
+        )
 
-    def test_ex_destroy_datacenter(self):
-        datacenter = type('Datacenter', (object,),
-                          dict(id="8669a69f-2274-4520-b51e-dbdf3986a476"))
-        destroy = self.driver.ex_destroy_datacenter(datacenter=datacenter)
+    '''
+    Function tests for operations on firewall rules
+    '''
 
-        self.assertTrue(destroy)
+    def test_ex_list_firewall_rules(self):
+        network_interface = self.driver.ex_describe_network_interface(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3/'
+                'nics/nic-2'
+            )
+        )
+        firewall_rules = self.driver.ex_list_firewall_rules(network_interface)
+        self.assertEqual(
+            len(firewall_rules),
+            3
+        )
+
+        firewall_rule = firewall_rules[0]
+        extra = firewall_rule.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            firewall_rule.id,
+            'fwr-1'
+        )
+        self.assertEqual(
+            firewall_rule.name,
+            'Test updated firewall rule'
+        )
+        self.assertEqual(
+            firewall_rule.href,
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3/'
+                'nics/nic-2/'
+                'firewallrules/fwr-1'
+            )
+        )
+        self.assertEqual(
+            firewall_rule.state,
+            NodeState.RUNNING
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-19T11:08:10Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            'b91a2e082a7422dafb79d84a07fb2a28'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-19T11:19:04Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Test updated firewall rule'
+        )
+        self.assertEqual(
+            extra['protocol'],
+            'TCP'
+        )
+        self.assertEqual(
+            extra['source_mac'],
+            None
+        )
+        self.assertEqual(
+            extra['source_ip'],
+            None
+        )
+        self.assertEqual(
+            extra['target_ip'],
+            None
+        )
+
+        self.assertEqual(
+            extra['icmp_code'],
+            None
+        )
+        self.assertEqual(
+            extra['icmp_type'],
+            None
+        )
+        self.assertEqual(
+            extra['port_range_start'],
+            80
+        )
+        self.assertEqual(
+            extra['port_range_end'],
+            80
+        )
+
+    def test_ex_describe_firewall_rule(self):
+        firewall_rule_w_href = self.driver.ex_describe_firewall_rule(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/servers/'
+                's-3/nics/'
+                'nic-2/firewallrules'
+                '/fw2'
+            )
+        )
+        firewall_rule_w_id = self.driver.ex_describe_firewall_rule(
+            ex_datacenter_id='dc-1',
+            ex_server_id='s-3',
+            ex_nic_id='nic-2',
+            ex_firewall_rule_id='fw2'
+        )
+        self._verify_firewall_rule(firewall_rule=firewall_rule_w_href)
+        self._verify_firewall_rule(firewall_rule=firewall_rule_w_id)
+
+    def _verify_firewall_rule(self, firewall_rule):
+        extra = firewall_rule.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            firewall_rule.id,
+            'fw2'
+        )
+        self.assertEqual(
+            firewall_rule.name,
+            'HTTPs (SSL)'
+        )
+        self.assertEqual(
+            firewall_rule.href,
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/servers/'
+                's-3/nics/'
+                'nic-2/'
+                'firewallrules/fw2'
+            )
+        )
+        self.assertEqual(
+            firewall_rule.state,
+            NodeState.RUNNING
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-19T09:55:10Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            '00bb5b86562db1ed19ca38697e485160'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-19T09:55:10Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'AVAILABLE'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'HTTPs (SSL)'
+        )
+        self.assertEqual(
+            extra['protocol'],
+            'TCP'
+        )
+        self.assertEqual(
+            extra['source_mac'],
+            None
+        )
+        self.assertEqual(
+            extra['source_ip'],
+            None
+        )
+        self.assertEqual(
+            extra['target_ip'],
+            None
+        )
+
+        self.assertEqual(
+            extra['icmp_code'],
+            None
+        )
+        self.assertEqual(
+            extra['icmp_type'],
+            None
+        )
+        self.assertEqual(
+            extra['port_range_start'],
+            443
+        )
+        self.assertEqual(
+            extra['port_range_end'],
+            443
+        )
+
+    def test_ex_create_firewall_rule(self):
+
+        network_interface = self.driver.ex_describe_network_interface(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3/'
+                'nics/nic-2'
+            )
+        )
+
+        firewall_rule = self.driver.ex_create_firewall_rule(
+            network_interface=network_interface,
+            protocol='TCP',
+            name='Test created firewall rule',
+            port_range_start=80,
+            port_range_end=80
+        )
+
+        extra = firewall_rule.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            firewall_rule.id,
+            'fwr-1'
+        )
+        self.assertEqual(
+            firewall_rule.name,
+            'Test created firewall rule'
+        )
+        self.assertEqual(
+            firewall_rule.href,
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3/'
+                'nics/nic-2/'
+                'firewallrules/fwr-1'
+            )
+        )
+        self.assertEqual(
+            firewall_rule.state,
+            NodeState.PENDING
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-19T11:08:04Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            '2a21551ba4adf85d9fb04b05a6938bcc'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-19T11:08:04Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'BUSY'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'Test created firewall rule'
+        )
+        self.assertEqual(
+            extra['protocol'],
+            'TCP'
+        )
+        self.assertEqual(
+            extra['source_mac'],
+            None
+        )
+        self.assertEqual(
+            extra['source_ip'],
+            None
+        )
+        self.assertEqual(
+            extra['target_ip'],
+            None
+        )
+
+        self.assertEqual(
+            extra['icmp_code'],
+            None
+        )
+        self.assertEqual(
+            extra['icmp_type'],
+            None
+        )
+        self.assertEqual(
+            extra['port_range_start'],
+            80
+        )
+        self.assertEqual(
+            extra['port_range_end'],
+            80
+        )
+
+    def test_ex_update_firewall_rule(self):
+
+        firewall_rule = self.driver.ex_describe_firewall_rule(
+            ex_href=(
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3/'
+                'nics/nic-2/'
+                'firewallrules/fw2'
+            )
+        )
+        updated = self.driver.ex_update_firewall_rule(
+            firewall_rule=firewall_rule,
+            name='Test updated firewall rule',
+            port_range_start=8080,
+            port_range_end=8080
+        )
+
+        extra = updated.extra
+
+        '''
+        Standard properties
+        '''
+        self.assertEqual(
+            updated.id,
+            'fw2'
+        )
+        self.assertEqual(
+            updated.name,
+            'HTTPs (SSL)'
+        )
+        self.assertEqual(
+            updated.href,
+            (
+                '/cloudapi/v3/datacenters/'
+                'dc-1/'
+                'servers/s-3'
+                '/nics/nic-2/'
+                'firewallrules/fw2'
+            )
+        )
+        self.assertEqual(
+            updated.state,
+            NodeState.PENDING
+        )
+
+        '''
+        Extra metadata
+        '''
+        self.assertEqual(
+            extra['created_date'],
+            '2016-10-19T09:55:10Z'
+        )
+        self.assertEqual(
+            extra['created_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['etag'],
+            '00bb5b86562db1ed19ca38697e485160'
+        )
+        self.assertEqual(
+            extra['last_modified_date'],
+            '2016-10-19T09:55:10Z'
+        )
+        self.assertEqual(
+            extra['last_modified_by'],
+            'test@test.te'
+        )
+        self.assertEqual(
+            extra['state'],
+            'BUSY'
+        )
+
+        '''
+        Extra properties
+        '''
+        self.assertEqual(
+            extra['name'],
+            'HTTPs (SSL)'
+        )
+        self.assertEqual(
+            extra['protocol'],
+            'TCP'
+        )
+        self.assertEqual(
+            extra['source_mac'],
+            None
+        )
+        self.assertEqual(
+            extra['source_ip'],
+            None
+        )
+     

<TRUNCATED>

Mime
View raw message