Merge "Add total runtime to summary output"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index a744339..23d4ebc 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -366,17 +366,19 @@
 #
 
 # If false, skip all nova v3 tests. (boolean value)
-#api_v3=true
+#api_v3=false
 
 # If false, skip disk config tests (boolean value)
 #disk_config=true
 
 # A list of enabled compute extensions with a special entry
-# all which indicates every extension is enabled (list value)
+# all which indicates every extension is enabled. Each
+# extension should be specified with alias name (list value)
 #api_extensions=all
 
 # A list of enabled v3 extensions with a special entry all
-# which indicates every extension is enabled (list value)
+# which indicates every extension is enabled. Each extension
+# should be specified with alias name (list value)
 #api_v3_extensions=all
 
 # Does the test environment support changing the admin
@@ -711,6 +713,10 @@
 # (integer value)
 #build_interval=1
 
+# List of dns servers whichs hould be used for subnet creation
+# (list value)
+#dns_servers=8.8.8.8,8.8.4.4
+
 
 [network-feature-enabled]
 
diff --git a/tempest/api/baremetal/base.py b/tempest/api/baremetal/base.py
index 021adaf..6f7e438 100644
--- a/tempest/api/baremetal/base.py
+++ b/tempest/api/baremetal/base.py
@@ -27,13 +27,12 @@
     def decorator(f):
         @functools.wraps(f)
         def wrapper(cls, *args, **kwargs):
-            result = f(cls, *args, **kwargs)
-            body = result[resource]
+            resp, body = f(cls, *args, **kwargs)
 
             if 'uuid' in body:
                 cls.created_objects[resource].add(body['uuid'])
 
-            return result
+            return resp, body
         return wrapper
     return decorator
 
@@ -51,7 +50,7 @@
 
         mgr = clients.AdminManager()
         cls.client = mgr.baremetal_client
-
+        cls.power_timeout = CONF.baremetal.power_timeout
         cls.created_objects = {'chassis': set(),
                                'port': set(),
                                'node': set()}
@@ -81,8 +80,7 @@
         """
         description = description or data_utils.rand_name('test-chassis-')
         resp, body = cls.client.create_chassis(description=description)
-
-        return {'chassis': body, 'response': resp}
+        return resp, body
 
     @classmethod
     @creates('node')
@@ -102,7 +100,7 @@
                                             cpu_num=cpu_num, storage=storage,
                                             memory=memory, driver=driver)
 
-        return {'node': body, 'response': resp}
+        return resp, body
 
     @classmethod
     @creates('port')
@@ -121,7 +119,7 @@
         resp, body = cls.client.create_port(address=address, node_id=node_id,
                                             extra=extra, uuid=uuid)
 
-        return {'port': body, 'response': resp}
+        return resp, body
 
     @classmethod
     def delete_chassis(cls, chassis_id):
diff --git a/tempest/api/baremetal/test_api_discovery.py b/tempest/api/baremetal/test_api_discovery.py
index e594b3e..bee10b9 100644
--- a/tempest/api/baremetal/test_api_discovery.py
+++ b/tempest/api/baremetal/test_api_discovery.py
@@ -20,6 +20,7 @@
     @test.attr(type='smoke')
     def test_api_versions(self):
         resp, descr = self.client.get_api_description()
+        self.assertEqual('200', resp['status'])
         expected_versions = ('v1',)
 
         versions = [version['id'] for version in descr['versions']]
@@ -30,6 +31,7 @@
     @test.attr(type='smoke')
     def test_default_version(self):
         resp, descr = self.client.get_api_description()
+        self.assertEqual('200', resp['status'])
         default_version = descr['default_version']
 
         self.assertEqual(default_version['id'], 'v1')
@@ -37,6 +39,7 @@
     @test.attr(type='smoke')
     def test_version_1_resources(self):
         resp, descr = self.client.get_version_description(version='v1')
+        self.assertEqual('200', resp['status'])
         expected_resources = ('nodes', 'chassis',
                               'ports', 'links', 'media_types')
 
diff --git a/tempest/api/baremetal/test_chassis.py b/tempest/api/baremetal/test_chassis.py
index 7af1336..4ab86c2 100644
--- a/tempest/api/baremetal/test_chassis.py
+++ b/tempest/api/baremetal/test_chassis.py
@@ -20,57 +20,64 @@
 class TestChassis(base.BaseBaremetalTest):
     """Tests for chassis."""
 
+    @classmethod
+    def setUpClass(cls):
+        super(TestChassis, cls).setUpClass()
+        _, cls.chassis = cls.create_chassis()
+
+    def _assertExpected(self, expected, actual):
+        # Check if not expected keys/values exists in actual response body
+        for key, value in expected.iteritems():
+            if key not in ('created_at', 'updated_at'):
+                self.assertIn(key, actual)
+                self.assertEqual(value, actual[key])
+
     @test.attr(type='smoke')
     def test_create_chassis(self):
         descr = data_utils.rand_name('test-chassis-')
-        ch = self.create_chassis(description=descr)['chassis']
-
-        self.assertEqual(ch['description'], descr)
+        resp, chassis = self.create_chassis(description=descr)
+        self.assertEqual('201', resp['status'])
+        self.assertEqual(chassis['description'], descr)
 
     @test.attr(type='smoke')
     def test_create_chassis_unicode_description(self):
         # Use a unicode string for testing:
         # 'We ♡ OpenStack in Ukraine'
         descr = u'В Україні ♡ OpenStack!'
-        ch = self.create_chassis(description=descr)['chassis']
-
-        self.assertEqual(ch['description'], descr)
+        resp, chassis = self.create_chassis(description=descr)
+        self.assertEqual('201', resp['status'])
+        self.assertEqual(chassis['description'], descr)
 
     @test.attr(type='smoke')
     def test_show_chassis(self):
-        descr = data_utils.rand_name('test-chassis-')
-        uuid = self.create_chassis(description=descr)['chassis']['uuid']
-
-        resp, chassis = self.client.show_chassis(uuid)
-
-        self.assertEqual(chassis['uuid'], uuid)
-        self.assertEqual(chassis['description'], descr)
+        resp, chassis = self.client.show_chassis(self.chassis['uuid'])
+        self.assertEqual('200', resp['status'])
+        self._assertExpected(self.chassis, chassis)
 
     @test.attr(type="smoke")
     def test_list_chassis(self):
-        created_ids = [self.create_chassis()['chassis']['uuid']
-                       for i in range(0, 5)]
-
         resp, body = self.client.list_chassis()
-        loaded_ids = [ch['uuid'] for ch in body['chassis']]
-
-        for i in created_ids:
-            self.assertIn(i, loaded_ids)
+        self.assertEqual('200', resp['status'])
+        self.assertIn(self.chassis['uuid'],
+                      [i['uuid'] for i in body['chassis']])
 
     @test.attr(type='smoke')
     def test_delete_chassis(self):
-        uuid = self.create_chassis()['chassis']['uuid']
+        resp, body = self.create_chassis()
+        uuid = body['uuid']
 
-        self.delete_chassis(uuid)
-
+        resp = self.delete_chassis(uuid)
+        self.assertEqual('204', resp['status'])
         self.assertRaises(exc.NotFound, self.client.show_chassis, uuid)
 
     @test.attr(type='smoke')
     def test_update_chassis(self):
-        chassis_id = self.create_chassis()['chassis']['uuid']
+        resp, body = self.create_chassis()
+        uuid = body['uuid']
 
         new_description = data_utils.rand_name('new-description-')
-        self.client.update_chassis(chassis_id, description=new_description)
-
-        resp, chassis = self.client.show_chassis(chassis_id)
+        resp, body = (self.client.update_chassis(uuid,
+                      description=new_description))
+        self.assertEqual('200', resp['status'])
+        resp, chassis = self.client.show_chassis(uuid)
         self.assertEqual(chassis['description'], new_description)
diff --git a/tempest/api/baremetal/test_nodes.py b/tempest/api/baremetal/test_nodes.py
index 0f585cb..b6432ad 100644
--- a/tempest/api/baremetal/test_nodes.py
+++ b/tempest/api/baremetal/test_nodes.py
@@ -23,7 +23,15 @@
     def setUp(self):
         super(TestNodes, self).setUp()
 
-        self.chassis = self.create_chassis()['chassis']
+        _, self.chassis = self.create_chassis()
+        _, self.node = self.create_node(self.chassis['uuid'])
+
+    def _assertExpected(self, expected, actual):
+        # Check if not expected keys/values exists in actual response body
+        for key, value in six.iteritems(expected):
+            if key not in ('created_at', 'updated_at'):
+                self.assertIn(key, actual)
+                self.assertEqual(value, actual[key])
 
     @test.attr(type='smoke')
     def test_create_node(self):
@@ -32,45 +40,32 @@
                   'storage': '10240',
                   'memory': '1024'}
 
-        node = self.create_node(self.chassis['uuid'], **params)['node']
-
-        for key in params:
-            self.assertEqual(node['properties'][key], params[key])
+        resp, body = self.create_node(self.chassis['uuid'], **params)
+        self.assertEqual('201', resp['status'])
+        self._assertExpected(params, body['properties'])
 
     @test.attr(type='smoke')
     def test_delete_node(self):
-        node = self.create_node(self.chassis['uuid'])['node']
-        node_id = node['uuid']
+        resp, node = self.create_node(self.chassis['uuid'])
+        self.assertEqual('201', resp['status'])
 
-        resp = self.delete_node(node_id)
+        resp = self.delete_node(node['uuid'])
 
         self.assertEqual(resp['status'], '204')
-        self.assertRaises(exc.NotFound, self.client.show_node, node_id)
+        self.assertRaises(exc.NotFound, self.client.show_node, node['uuid'])
 
     @test.attr(type='smoke')
     def test_show_node(self):
-        params = {'cpu_arch': 'x86_64',
-                  'cpu_num': '4',
-                  'storage': '100',
-                  'memory': '512'}
-
-        created_node = self.create_node(self.chassis['uuid'], **params)['node']
-        resp, loaded_node = self.client.show_node(created_node['uuid'])
-
-        for key, val in created_node.iteritems():
-            if key not in ('created_at', 'updated_at'):
-                self.assertEqual(loaded_node[key], val)
+        resp, loaded_node = self.client.show_node(self.node['uuid'])
+        self.assertEqual('200', resp['status'])
+        self._assertExpected(self.node, loaded_node)
 
     @test.attr(type='smoke')
     def test_list_nodes(self):
-        uuids = [self.create_node(self.chassis['uuid'])['node']['uuid']
-                 for i in range(0, 5)]
-
         resp, body = self.client.list_nodes()
-        loaded_uuids = [n['uuid'] for n in body['nodes']]
-
-        for u in uuids:
-            self.assertIn(u, loaded_uuids)
+        self.assertEqual('200', resp['status'])
+        self.assertIn(self.node['uuid'],
+                      [i['uuid'] for i in body['nodes']])
 
     @test.attr(type='smoke')
     def test_update_node(self):
@@ -79,17 +74,16 @@
                  'storage': '10',
                  'memory': '128'}
 
-        node = self.create_node(self.chassis['uuid'], **props)['node']
-        node_id = node['uuid']
+        resp, node = self.create_node(self.chassis['uuid'], **props)
+        self.assertEqual('201', resp['status'])
 
-        new_props = {'cpu_arch': 'x86',
-                     'cpu_num': '1',
-                     'storage': '10000',
-                     'memory': '12300'}
+        new_p = {'cpu_arch': 'x86',
+                 'cpu_num': '1',
+                 'storage': '10000',
+                 'memory': '12300'}
 
-        self.client.update_node(node_id, properties=new_props)
-        resp, node = self.client.show_node(node_id)
-
-        for name, value in six.iteritems(new_props):
-            if name not in ('created_at', 'updated_at'):
-                self.assertEqual(node['properties'][name], value)
+        resp, body = self.client.update_node(node['uuid'], properties=new_p)
+        self.assertEqual('200', resp['status'])
+        resp, node = self.client.show_node(node['uuid'])
+        self.assertEqual('200', resp['status'])
+        self._assertExpected(new_p, node['properties'])
diff --git a/tempest/api/baremetal/test_nodestates.py b/tempest/api/baremetal/test_nodestates.py
index c658d7f..3044bc6 100644
--- a/tempest/api/baremetal/test_nodestates.py
+++ b/tempest/api/baremetal/test_nodestates.py
@@ -13,6 +13,8 @@
 #    under the License.
 
 from tempest.api.baremetal import base
+from tempest import exceptions
+from tempest.openstack.common import timeutils
 from tempest import test
 
 
@@ -20,10 +22,25 @@
     """Tests for baremetal NodeStates."""
 
     @classmethod
-    def setUpClass(self):
-        super(TestNodeStates, self).setUpClass()
-        chassis = self.create_chassis()['chassis']
-        self.node = self.create_node(chassis['uuid'])['node']
+    def setUpClass(cls):
+        super(TestNodeStates, cls).setUpClass()
+        resp, cls.chassis = cls.create_chassis()
+        resp, cls.node = cls.create_node(cls.chassis['uuid'])
+
+    def _validate_power_state(self, node_uuid, power_state):
+        # Validate that power state is set within timeout
+        if power_state == 'rebooting':
+            power_state = 'power on'
+        start = timeutils.utcnow()
+        while timeutils.delta_seconds(
+                start, timeutils.utcnow()) < self.power_timeout:
+            resp, node = self.client.show_node(node_uuid)
+            self.assertEqual(200, resp.status)
+            if node['power_state'] == power_state:
+                return
+        message = ('Failed to set power state within '
+                   'the required time: %s sec.' % self.power_timeout)
+        raise exceptions.TimeoutException(message)
 
     @test.attr(type='smoke')
     def test_list_nodestates(self):
@@ -31,3 +48,16 @@
         self.assertEqual('200', resp['status'])
         for key in nodestates:
             self.assertEqual(nodestates[key], self.node[key])
+
+    @test.attr(type='smoke')
+    def test_set_node_power_state(self):
+        resp, node = self.create_node(self.chassis['uuid'])
+        self.assertEqual('201', resp['status'])
+        states = ["power on", "rebooting", "power off"]
+        for state in states:
+            # Set power state
+            resp, _ = self.client.set_node_power_state(node['uuid'],
+                                                       state)
+            self.assertEqual('202', resp['status'])
+            # Check power state after state is set
+            self._validate_power_state(node['uuid'], state)
diff --git a/tempest/api/baremetal/test_ports.py b/tempest/api/baremetal/test_ports.py
index aeb77e3..c2af29a 100644
--- a/tempest/api/baremetal/test_ports.py
+++ b/tempest/api/baremetal/test_ports.py
@@ -22,25 +22,30 @@
     def setUp(self):
         super(TestPorts, self).setUp()
 
-        chassis = self.create_chassis()['chassis']
-        self.node = self.create_node(chassis['uuid'])['node']
+        _, self.chassis = self.create_chassis()
+        _, self.node = self.create_node(self.chassis['uuid'])
+        _, self.port = self.create_port(self.node['uuid'],
+                                        data_utils.rand_mac_address())
+
+    def _assertExpected(self, expected, actual):
+        # Check if not expected keys/values exists in actual response body
+        for key, value in expected.iteritems():
+            if key not in ('created_at', 'updated_at'):
+                self.assertIn(key, actual)
+                self.assertEqual(value, actual[key])
 
     @test.attr(type='smoke')
     def test_create_port(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        result = self.create_port(node_id=node_id, address=address)
-
-        port = result['port']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual(201, resp.status)
 
         resp, body = self.client.show_port(port['uuid'])
 
         self.assertEqual(200, resp.status)
-        self.assertEqual(port['uuid'], body['uuid'])
-        self.assertEqual(address, body['address'])
-        self.assertEqual({}, body['extra'])
-        self.assertEqual(node_id, body['node_uuid'])
+        self._assertExpected(port, body)
 
     @test.attr(type='smoke')
     def test_create_port_specifying_uuid(self):
@@ -48,15 +53,13 @@
         address = data_utils.rand_mac_address()
         uuid = data_utils.rand_uuid()
 
-        self.create_port(node_id=node_id, address=address, uuid=uuid)
+        resp, port = self.create_port(node_id=node_id,
+                                      address=address, uuid=uuid)
+        self.assertEqual(201, resp.status)
 
         resp, body = self.client.show_port(uuid)
-
         self.assertEqual(200, resp.status)
-        self.assertEqual(uuid, body['uuid'])
-        self.assertEqual(address, body['address'])
-        self.assertEqual({}, body['extra'])
-        self.assertEqual(node_id, body['node_uuid'])
+        self._assertExpected(port, body)
 
     @test.attr(type='smoke')
     def test_create_port_with_extra(self):
@@ -64,76 +67,46 @@
         address = data_utils.rand_mac_address()
         extra = {'key': 'value'}
 
-        result = self.create_port(node_id=node_id, address=address,
-                                  extra=extra)
-        port = result['port']
+        resp, port = self.create_port(node_id=node_id, address=address,
+                                      extra=extra)
+        self.assertEqual(201, resp.status)
 
         resp, body = self.client.show_port(port['uuid'])
-
         self.assertEqual(200, resp.status)
-        self.assertEqual(port['uuid'], body['uuid'])
-        self.assertEqual(address, body['address'])
-        self.assertEqual(extra, body['extra'])
-        self.assertEqual(node_id, body['node_uuid'])
+        self._assertExpected(port, body)
 
     @test.attr(type='smoke')
     def test_delete_port(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
-        port_id = self.create_port(node_id=node_id, address=address)['port'][
-            'uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual(201, resp.status)
 
-        resp = self.delete_port(port_id)
+        resp = self.delete_port(port['uuid'])
 
         self.assertEqual(204, resp.status)
-        self.assertRaises(exc.NotFound, self.client.show_port, port_id)
+        self.assertRaises(exc.NotFound, self.client.show_port, port['uuid'])
 
     @test.attr(type='smoke')
     def test_show_port(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        extra = {'key': 'value'}
-
-        port_id = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)['port']['uuid']
-
-        resp, port = self.client.show_port(port_id)
-
+        resp, port = self.client.show_port(self.port['uuid'])
         self.assertEqual(200, resp.status)
-        self.assertEqual(port_id, port['uuid'])
-        self.assertEqual(address, port['address'])
-        self.assertEqual(extra, port['extra'])
+        self._assertExpected(self.port, port)
 
     @test.attr(type='smoke')
     def test_show_port_with_links(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        port_id = self.create_port(node_id=node_id, address=address)['port'][
-            'uuid']
-
-        resp, body = self.client.show_port(port_id)
-
+        resp, port = self.client.show_port(self.port['uuid'])
         self.assertEqual(200, resp.status)
-        self.assertIn('links', body.keys())
-        self.assertEqual(2, len(body['links']))
-        self.assertIn(port_id, body['links'][0]['href'])
+        self.assertIn('links', port.keys())
+        self.assertEqual(2, len(port['links']))
+        self.assertIn(port['uuid'], port['links'][0]['href'])
 
     @test.attr(type='smoke')
     def test_list_ports(self):
-        node_id = self.node['uuid']
-
-        uuids = [self.create_port(node_id=node_id,
-                                  address=data_utils.rand_mac_address())
-                 ['port']['uuid'] for i in xrange(5)]
-
         resp, body = self.client.list_ports()
         self.assertEqual(200, resp.status)
-        loaded_uuids = [p['uuid'] for p in body['ports']]
-
-        for uuid in uuids:
-            self.assertIn(uuid, loaded_uuids)
-
+        self.assertIn(self.port['uuid'],
+                      [i['uuid'] for i in body['ports']])
         # Verify self links.
         for port in body['ports']:
             self.validate_self_link('ports', port['uuid'],
@@ -141,15 +114,8 @@
 
     @test.attr(type='smoke')
     def test_list_with_limit(self):
-        node_id = self.node['uuid']
-
-        for i in xrange(5):
-            self.create_port(node_id=node_id,
-                             address=data_utils.rand_mac_address())
-
         resp, body = self.client.list_ports(limit=3)
         self.assertEqual(200, resp.status)
-        self.assertEqual(3, len(body['ports']))
 
         next_marker = body['ports'][-1]['uuid']
         self.assertIn(next_marker, body['next'])
@@ -160,7 +126,7 @@
         uuids = [
             self.create_port(node_id=node_id,
                              address=data_utils.rand_mac_address())
-            ['port']['uuid'] for i in range(0, 5)]
+            [1]['uuid'] for i in range(0, 5)]
 
         resp, body = self.client.list_ports_detail()
         self.assertEqual(200, resp.status)
@@ -185,8 +151,9 @@
         address = data_utils.rand_mac_address()
         extra = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
 
-        port_id = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)['port']['uuid']
+        resp, port = self.create_port(node_id=node_id, address=address,
+                                      extra=extra)
+        self.assertEqual(201, resp.status)
 
         new_address = data_utils.rand_mac_address()
         new_extra = {'key1': 'new-value1', 'key2': 'new-value2',
@@ -205,9 +172,10 @@
                   'op': 'replace',
                   'value': new_extra['key3']}]
 
-        self.client.update_port(port_id, patch)
+        resp, _ = self.client.update_port(port['uuid'], patch)
+        self.assertEqual(200, resp.status)
 
-        resp, body = self.client.show_port(port_id)
+        resp, body = self.client.show_port(port['uuid'])
         self.assertEqual(200, resp.status)
         self.assertEqual(new_address, body['address'])
         self.assertEqual(new_extra, body['extra'])
@@ -218,23 +186,25 @@
         address = data_utils.rand_mac_address()
         extra = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
 
-        port_id = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)['port']['uuid']
+        resp, port = self.create_port(node_id=node_id, address=address,
+                                      extra=extra)
+        self.assertEqual(201, resp.status)
 
         # Removing one item from the collection
-        resp, _ = self.client.update_port(port_id, [{'path': '/extra/key2',
-                                                     'op': 'remove'}])
+        resp, _ = self.client.update_port(port['uuid'],
+                                          [{'path': '/extra/key2',
+                                           'op': 'remove'}])
         self.assertEqual(200, resp.status)
         extra.pop('key2')
-        resp, body = self.client.show_port(port_id)
+        resp, body = self.client.show_port(port['uuid'])
         self.assertEqual(200, resp.status)
         self.assertEqual(extra, body['extra'])
 
         # Removing the collection
-        resp, _ = self.client.update_port(port_id, [{'path': '/extra',
-                                                     'op': 'remove'}])
+        resp, _ = self.client.update_port(port['uuid'], [{'path': '/extra',
+                                                         'op': 'remove'}])
         self.assertEqual(200, resp.status)
-        resp, body = self.client.show_port(port_id)
+        resp, body = self.client.show_port(port['uuid'])
         self.assertEqual(200, resp.status)
         self.assertEqual({}, body['extra'])
 
@@ -247,8 +217,8 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id, address=address)['port'][
-            'uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual(201, resp.status)
 
         extra = {'key1': 'value1', 'key2': 'value2'}
 
@@ -259,9 +229,10 @@
                   'op': 'add',
                   'value': extra['key2']}]
 
-        self.client.update_port(port_id, patch)
+        resp, _ = self.client.update_port(port['uuid'], patch)
+        self.assertEqual(200, resp.status)
 
-        resp, body = self.client.show_port(port_id)
+        resp, body = self.client.show_port(port['uuid'])
         self.assertEqual(200, resp.status)
         self.assertEqual(extra, body['extra'])
 
@@ -271,8 +242,9 @@
         address = data_utils.rand_mac_address()
         extra = {'key1': 'value1', 'key2': 'value2'}
 
-        port_id = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)['port']['uuid']
+        resp, port = self.create_port(node_id=node_id, address=address,
+                                      extra=extra)
+        self.assertEqual(201, resp.status)
 
         new_address = data_utils.rand_mac_address()
         new_extra = {'key1': 'new-value1', 'key3': 'new-value3'}
@@ -289,9 +261,10 @@
                   'op': 'add',
                   'value': new_extra['key3']}]
 
-        self.client.update_port(port_id, patch)
+        resp, _ = self.client.update_port(port['uuid'], patch)
+        self.assertEqual(200, resp.status)
 
-        resp, body = self.client.show_port(port_id)
+        resp, body = self.client.show_port(port['uuid'])
         self.assertEqual(200, resp.status)
         self.assertEqual(new_address, body['address'])
         self.assertEqual(new_extra, body['extra'])
diff --git a/tempest/api/baremetal/test_ports_negative.py b/tempest/api/baremetal/test_ports_negative.py
index 4cbe00e..3e77a5f 100644
--- a/tempest/api/baremetal/test_ports_negative.py
+++ b/tempest/api/baremetal/test_ports_negative.py
@@ -22,8 +22,11 @@
     def setUp(self):
         super(TestPortsNegative, self).setUp()
 
-        chassis = self.create_chassis()['chassis']
-        self.node = self.create_node(chassis['uuid'])['node']
+        resp, self.chassis = self.create_chassis()
+        self.assertEqual('201', resp['status'])
+
+        resp, self.node = self.create_node(self.chassis['uuid'])
+        self.assertEqual('201', resp['status'])
 
     @test.attr(type=['negative', 'smoke'])
     def test_create_port_malformed_mac(self):
@@ -134,9 +137,13 @@
         address = data_utils.rand_mac_address()
         extra = {'key': 'value'}
 
-        port_id = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)['port']['uuid']
-        self.client.delete_port(port_id)
+        resp, port = self.create_port(node_id=node_id, address=address,
+                                      extra=extra)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
+
+        resp, body = self.client.delete_port(port_id)
+        self.assertEqual('204', resp['status'])
 
         patch = [{'path': '/extra/key',
                   'op': 'replace',
@@ -162,8 +169,9 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id, address=address)['port'][
-            'uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
 
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
                           [{'path': '/extra/key', ' op': 'add',
@@ -174,8 +182,9 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id, address=address)['port'][
-            'uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
 
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
                           [{'path': '/extra',
@@ -187,8 +196,10 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id, address=address)['port'][
-            'uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
+
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
                           [{'path': '/nonexistent', ' op': 'add',
                             'value': 'value'}])
@@ -198,8 +209,9 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id,
-                                   address=address)['port']['uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
 
         patch = [{'path': '/node_uuid',
                   'op': 'replace',
@@ -213,9 +225,13 @@
         address1 = data_utils.rand_mac_address()
         address2 = data_utils.rand_mac_address()
 
-        self.create_port(node_id=node_id, address=address1)
-        port_id = self.create_port(node_id=node_id,
-                                   address=address2)['port']['uuid']
+        resp, port1 = self.create_port(node_id=node_id, address=address1)
+        self.assertEqual('201', resp['status'])
+
+        resp, port2 = self.create_port(node_id=node_id, address=address2)
+        self.assertEqual('201', resp['status'])
+        port_id = port2['uuid']
+
         patch = [{'path': '/address',
                   'op': 'replace',
                   'value': address1}]
@@ -227,8 +243,9 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id,
-                                   address=address)['port']['uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
 
         patch = [{'path': '/node_uuid',
                   'op': 'replace',
@@ -241,8 +258,10 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id,
-                                   address=address)['port']['uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
+
         patch = [{'path': '/address',
                   'op': 'replace',
                   'value': 'malformed:mac'}]
@@ -256,13 +275,14 @@
         address = data_utils.rand_mac_address()
         extra = {'key': 'value'}
 
-        port_id = self.create_port(node_id=node_id,
-                                   address=address,
-                                   extra=extra)['port']['uuid']
+        resp, port = self.create_port(node_id=node_id, address=address,
+                                      extra=extra)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
+
         patch = [{'path': '/extra/key',
                   'op': 'replace',
                   'value': 0.123}]
-
         self.assertRaises(exc.BadRequest,
                           self.client.update_port, port_id, patch)
 
@@ -270,11 +290,11 @@
     def test_update_port_replace_whole_extra_with_malformed(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
-        extra = {'key': 'value'}
 
-        port_id = self.create_port(node_id=node_id,
-                                   address=address,
-                                   extra=extra)['port']['uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
+
         patch = [{'path': '/extra',
                   'op': 'replace',
                   'value': [1, 2, 3, 4, 'a']}]
@@ -287,8 +307,9 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id,
-                                   address=address)['port']['uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
 
         patch = [{'path': '/nonexistent', ' op': 'replace', 'value': 'value'}]
 
@@ -300,8 +321,10 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id, address=address)['port'][
-            'uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
+
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
                           [{'path': '/address', 'op': 'remove'}])
 
@@ -310,8 +333,10 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id, address=address)['port'][
-            'uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
+
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
                           [{'path': '/uuid', 'op': 'remove'}])
 
@@ -320,8 +345,10 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        port_id = self.create_port(node_id=node_id, address=address)['port'][
-            'uuid']
+        resp, port = self.create_port(node_id=node_id, address=address)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
+
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
                           [{'path': '/nonexistent', 'op': 'remove'}])
 
@@ -339,8 +366,10 @@
         address = data_utils.rand_mac_address()
         extra = {'key1': 'value1', 'key2': 'value2'}
 
-        port_id = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)['port']['uuid']
+        resp, port = self.create_port(node_id=node_id, address=address,
+                                      extra=extra)
+        self.assertEqual('201', resp['status'])
+        port_id = port['uuid']
 
         new_address = data_utils.rand_mac_address()
         new_extra = {'key1': 'new-value1', 'key3': 'new-value3'}
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index 111ac9c..a8a9bb4 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -30,8 +30,8 @@
     @classmethod
     def setUpClass(cls):
         super(FlavorsAdminTestJSON, cls).setUpClass()
-        if not test.is_extension_enabled('FlavorExtraData', 'compute'):
-            msg = "FlavorExtraData extension not enabled."
+        if not test.is_extension_enabled('OS-FLV-EXT-DATA', 'compute'):
+            msg = "OS-FLV-EXT-DATA extension not enabled."
             raise cls.skipException(msg)
 
         cls.client = cls.os_adm.flavors_client
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 3ba7314..f2554ea 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -28,8 +28,8 @@
     @classmethod
     def setUpClass(cls):
         super(FlavorsAccessTestJSON, cls).setUpClass()
-        if not test.is_extension_enabled('FlavorExtraData', 'compute'):
-            msg = "FlavorExtraData extension not enabled."
+        if not test.is_extension_enabled('OS-FLV-EXT-DATA', 'compute'):
+            msg = "OS-FLV-EXT-DATA extension not enabled."
             raise cls.skipException(msg)
 
         # Compute admin flavor client
diff --git a/tempest/api/compute/admin/test_flavors_access_negative.py b/tempest/api/compute/admin/test_flavors_access_negative.py
index 73834e9..b636ccd 100644
--- a/tempest/api/compute/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/admin/test_flavors_access_negative.py
@@ -31,8 +31,8 @@
     @classmethod
     def setUpClass(cls):
         super(FlavorsAccessNegativeTestJSON, cls).setUpClass()
-        if not test.is_extension_enabled('FlavorExtraData', 'compute'):
-            msg = "FlavorExtraData extension not enabled."
+        if not test.is_extension_enabled('OS-FLV-EXT-DATA', 'compute'):
+            msg = "OS-FLV-EXT-DATA extension not enabled."
             raise cls.skipException(msg)
 
         cls.client = cls.os_adm.flavors_client
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs.py b/tempest/api/compute/admin/test_flavors_extra_specs.py
index 91145ec..56daf96 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs.py
@@ -29,8 +29,8 @@
     @classmethod
     def setUpClass(cls):
         super(FlavorsExtraSpecsTestJSON, cls).setUpClass()
-        if not test.is_extension_enabled('FlavorExtraData', 'compute'):
-            msg = "FlavorExtraData extension not enabled."
+        if not test.is_extension_enabled('OS-FLV-EXT-DATA', 'compute'):
+            msg = "OS-FLV-EXT-DATA extension not enabled."
             raise cls.skipException(msg)
 
         cls.client = cls.os_adm.flavors_client
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
index a139c2f..1e5695f 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
@@ -30,8 +30,8 @@
     @classmethod
     def setUpClass(cls):
         super(FlavorsExtraSpecsNegativeTestJSON, cls).setUpClass()
-        if not test.is_extension_enabled('FlavorExtraData', 'compute'):
-            msg = "FlavorExtraData extension not enabled."
+        if not test.is_extension_enabled('OS-FLV-EXT-DATA', 'compute'):
+            msg = "OS-FLV-EXT-DATA extension not enabled."
             raise cls.skipException(msg)
 
         cls.client = cls.os_adm.flavors_client
diff --git a/tempest/api/compute/admin/test_flavors_negative.py b/tempest/api/compute/admin/test_flavors_negative.py
index b37d32c..9e4412f 100644
--- a/tempest/api/compute/admin/test_flavors_negative.py
+++ b/tempest/api/compute/admin/test_flavors_negative.py
@@ -32,8 +32,8 @@
     @classmethod
     def setUpClass(cls):
         super(FlavorsAdminNegativeTestJSON, cls).setUpClass()
-        if not test.is_extension_enabled('FlavorExtraData', 'compute'):
-            msg = "FlavorExtraData extension not enabled."
+        if not test.is_extension_enabled('OS-FLV-EXT-DATA', 'compute'):
+            msg = "OS-FLV-EXT-DATA extension not enabled."
             raise cls.skipException(msg)
 
         cls.client = cls.os_adm.flavors_client
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 5ac667e..6343ead 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -45,7 +45,10 @@
     def setUpClass(cls):
         super(ServersNegativeTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
-        cls.alt_os = clients.AltManager()
+        if CONF.compute.allow_tenant_isolation:
+            cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
+        else:
+            cls.alt_os = clients.AltManager()
         cls.alt_client = cls.alt_os.servers_client
         resp, server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
diff --git a/tempest/api/compute/v3/servers/test_servers_negative.py b/tempest/api/compute/v3/servers/test_servers_negative.py
index 827c4c4..90deaa9 100644
--- a/tempest/api/compute/v3/servers/test_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_servers_negative.py
@@ -45,7 +45,10 @@
     def setUpClass(cls):
         super(ServersNegativeV3Test, cls).setUpClass()
         cls.client = cls.servers_client
-        cls.alt_os = clients.AltManager()
+        if CONF.compute.allow_tenant_isolation:
+            cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
+        else:
+            cls.alt_os = clients.AltManager()
         cls.alt_client = cls.alt_os.servers_v3_client
         resp, server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 4585912..5a64544 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -53,28 +53,28 @@
     def _create_and_attach(self):
         # Start a server and wait for it to become ready
         admin_pass = self.image_ssh_password
-        resp, server = self.create_test_server(wait_until='ACTIVE',
-                                               adminPass=admin_pass)
-        self.server = server
+        _, self.server = self.create_test_server(wait_until='ACTIVE',
+                                                 adminPass=admin_pass)
 
         # Record addresses so that we can ssh later
-        resp, server['addresses'] = \
-            self.servers_client.list_addresses(server['id'])
+        _, self.server['addresses'] = \
+            self.servers_client.list_addresses(self.server['id'])
 
         # Create a volume and wait for it to become ready
-        resp, volume = self.volumes_client.create_volume(1,
-                                                         display_name='test')
-        self.volume = volume
+        _, self.volume = self.volumes_client.create_volume(
+            1, display_name='test')
         self.addCleanup(self._delete_volume)
-        self.volumes_client.wait_for_volume_status(volume['id'], 'available')
+        self.volumes_client.wait_for_volume_status(self.volume['id'],
+                                                   'available')
 
         # Attach the volume to the server
-        self.servers_client.attach_volume(server['id'], volume['id'],
+        self.servers_client.attach_volume(self.server['id'],
+                                          self.volume['id'],
                                           device='/dev/%s' % self.device)
-        self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
+        self.volumes_client.wait_for_volume_status(self.volume['id'], 'in-use')
 
         self.attached = True
-        self.addCleanup(self._detach, server['id'], volume['id'])
+        self.addCleanup(self._detach, self.server['id'], self.volume['id'])
 
     @testtools.skipUnless(CONF.compute.run_ssh, 'SSH required for this test')
     @test.attr(type='gate')
@@ -82,31 +82,33 @@
         # Stop and Start a server with an attached volume, ensuring that
         # the volume remains attached.
         self._create_and_attach()
-        server = self.server
-        volume = self.volume
 
-        self.servers_client.stop(server['id'])
-        self.servers_client.wait_for_server_status(server['id'], 'SHUTOFF')
+        self.servers_client.stop(self.server['id'])
+        self.servers_client.wait_for_server_status(self.server['id'],
+                                                   'SHUTOFF')
 
-        self.servers_client.start(server['id'])
-        self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
+        self.servers_client.start(self.server['id'])
+        self.servers_client.wait_for_server_status(self.server['id'], 'ACTIVE')
 
-        linux_client = remote_client.RemoteClient(server, self.image_ssh_user,
-                                                  server['adminPass'])
+        linux_client = remote_client.RemoteClient(self.server,
+                                                  self.image_ssh_user,
+                                                  self.server['adminPass'])
         partitions = linux_client.get_partitions()
         self.assertIn(self.device, partitions)
 
-        self._detach(server['id'], volume['id'])
+        self._detach(self.server['id'], self.volume['id'])
         self.attached = False
 
-        self.servers_client.stop(server['id'])
-        self.servers_client.wait_for_server_status(server['id'], 'SHUTOFF')
+        self.servers_client.stop(self.server['id'])
+        self.servers_client.wait_for_server_status(self.server['id'],
+                                                   'SHUTOFF')
 
-        self.servers_client.start(server['id'])
-        self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
+        self.servers_client.start(self.server['id'])
+        self.servers_client.wait_for_server_status(self.server['id'], 'ACTIVE')
 
-        linux_client = remote_client.RemoteClient(server, self.image_ssh_user,
-                                                  server['adminPass'])
+        linux_client = remote_client.RemoteClient(self.server,
+                                                  self.image_ssh_user,
+                                                  self.server['adminPass'])
         partitions = linux_client.get_partitions()
         self.assertNotIn(self.device, partitions)
 
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index cc76880..0d6773c 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -39,6 +39,7 @@
         cls._cluster_templates = []
         cls._data_sources = []
         cls._job_binary_internals = []
+        cls._job_binaries = []
 
     @classmethod
     def tearDownClass(cls):
@@ -50,6 +51,8 @@
                               cls.client.delete_data_source)
         cls.cleanup_resources(getattr(cls, '_job_binary_internals', []),
                               cls.client.delete_job_binary_internal)
+        cls.cleanup_resources(getattr(cls, '_job_binaries', []),
+                              cls.client.delete_job_binary)
         cls.clear_isolated_creds()
         super(BaseDataProcessingTest, cls).tearDownClass()
 
@@ -128,3 +131,16 @@
         cls._job_binary_internals.append(body['id'])
 
         return resp, body
+
+    def create_job_binary(cls, name, url, extra=None, **kwargs):
+        """Creates watched job binary with specified params.
+
+        It supports passing additional params using kwargs and returns created
+        object. All resources created in this method will be automatically
+        removed in tearDownClass method.
+        """
+        resp, body = cls.client.create_job_binary(name, url, extra, **kwargs)
+        # store id of created job binary
+        cls._job_binaries.append(body['id'])
+
+        return resp, body
diff --git a/tempest/api/data_processing/test_job_binary_internals.py b/tempest/api/data_processing/test_job_binary_internals.py
new file mode 100644
index 0000000..6d59177
--- /dev/null
+++ b/tempest/api/data_processing/test_job_binary_internals.py
@@ -0,0 +1,88 @@
+# Copyright (c) 2014 Mirantis Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.data_processing import base as dp_base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class JobBinaryInternalTest(dp_base.BaseDataProcessingTest):
+    """Link to the API documentation is http://docs.openstack.org/developer/
+    sahara/restapi/rest_api_v1.1_EDP.html#job-binary-internals
+    """
+    @classmethod
+    def setUpClass(cls):
+        super(JobBinaryInternalTest, cls).setUpClass()
+        cls.job_binary_internal_data = 'Some script may be data'
+
+    def _create_job_binary_internal(self, binary_name=None):
+        """Creates Job Binary Internal with optional name specified.
+
+        It puts data into Sahara database and ensures response status and
+        job binary internal name. Returns id and name of created job binary
+        internal.
+        """
+        if not binary_name:
+            # generate random name if it's not specified
+            binary_name = data_utils.rand_name('sahara-job-binary-internal')
+
+        # create job binary internal
+        resp, body = self.create_job_binary_internal(
+            binary_name, self.job_binary_internal_data)
+
+        # ensure that job binary internal created successfully
+        self.assertEqual(202, resp.status)
+        self.assertEqual(binary_name, body['name'])
+
+        return body['id'], binary_name
+
+    @test.attr(type='smoke')
+    def test_job_binary_internal_create(self):
+        self._create_job_binary_internal()
+
+    @test.attr(type='smoke')
+    def test_job_binary_internal_list(self):
+        binary_info = self._create_job_binary_internal()
+
+        # check for job binary internal in list
+        resp, binaries = self.client.list_job_binary_internals()
+        self.assertEqual(200, resp.status)
+        binaries_info = [(binary['id'], binary['name']) for binary in binaries]
+        self.assertIn(binary_info, binaries_info)
+
+    @test.attr(type='smoke')
+    def test_job_binary_internal_get(self):
+        binary_id, binary_name = self._create_job_binary_internal()
+
+        # check job binary internal fetch by id
+        resp, binary = self.client.get_job_binary_internal(binary_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(binary_name, binary['name'])
+
+    @test.attr(type='smoke')
+    def test_job_binary_internal_delete(self):
+        binary_id = self._create_job_binary_internal()[0]
+
+        # delete the job binary internal by id
+        resp = self.client.delete_job_binary_internal(binary_id)[0]
+        self.assertEqual(204, resp.status)
+
+    @test.attr(type='smoke')
+    def test_job_binary_internal_get_data(self):
+        binary_id = self._create_job_binary_internal()[0]
+
+        # get data of job binary internal by id
+        resp, data = self.client.get_job_binary_internal_data(binary_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(data, self.job_binary_internal_data)
diff --git a/tempest/api/database/base.py b/tempest/api/database/base.py
index cf70d11..b68c84a 100644
--- a/tempest/api/database/base.py
+++ b/tempest/api/database/base.py
@@ -41,4 +41,5 @@
         os = cls.get_client_manager()
         cls.os = os
         cls.database_flavors_client = cls.os.database_flavors_client
+        cls.os_flavors_client = cls.os.flavors_client
         cls.database_versions_client = cls.os.database_versions_client
diff --git a/tempest/api/database/flavors/test_flavors.py b/tempest/api/database/flavors/test_flavors.py
index a591e8e..64d71b9 100644
--- a/tempest/api/database/flavors/test_flavors.py
+++ b/tempest/api/database/flavors/test_flavors.py
@@ -28,6 +28,7 @@
     def test_get_db_flavor(self):
         # The expected flavor details should be returned
         resp, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
+        self.assertEqual(200, resp.status)
         self.assertEqual(self.db_flavor_ref, str(flavor['id']))
         self.assertIn('ram', flavor)
         self.assertIn('links', flavor)
@@ -36,6 +37,36 @@
     @test.attr(type='smoke')
     def test_list_db_flavors(self):
         resp, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
+        self.assertEqual(200, resp.status)
         # List of all flavors should contain the expected flavor
         resp, flavors = self.client.list_db_flavors()
+        self.assertEqual(200, resp.status)
         self.assertIn(flavor, flavors)
+
+    def _check_values(self, names, db_flavor, os_flavor, in_db=True):
+        for name in names:
+            self.assertIn(name, os_flavor)
+            if in_db:
+                self.assertIn(name, db_flavor)
+                self.assertEqual(str(db_flavor[name]), str(os_flavor[name]),
+                                 "DB flavor differs from OS on '%s' value"
+                                 % name)
+            else:
+                self.assertNotIn(name, db_flavor)
+
+    @test.attr(type='smoke')
+    def test_compare_db_flavors_with_os(self):
+        resp, db_flavors = self.client.list_db_flavors()
+        self.assertEqual(200, resp.status)
+        resp, os_flavors = self.os_flavors_client.list_flavors_with_detail()
+        self.assertEqual(200, resp.status)
+        self.assertEqual(len(os_flavors), len(db_flavors),
+                         "OS flavors %s do not match DB flavors %s" %
+                         (os_flavors, db_flavors))
+        for os_flavor in os_flavors:
+            resp, db_flavor =\
+                self.client.get_db_flavor_details(os_flavor['id'])
+            self.assertEqual(200, resp.status)
+            self._check_values(['id', 'name', 'ram'], db_flavor, os_flavor)
+            self._check_values(['disk', 'vcpus', 'swap'], db_flavor, os_flavor,
+                               in_db=False)
diff --git a/tempest/api/identity/test_extension.py b/tempest/api/identity/test_extension.py
new file mode 100644
index 0000000..67f20f4
--- /dev/null
+++ b/tempest/api/identity/test_extension.py
@@ -0,0 +1,37 @@
+# Copyright 2014 NEC Corporation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.identity import base
+from tempest import test
+
+
+class ExtensionTestJSON(base.BaseIdentityV2AdminTest):
+    _interface = 'json'
+
+    @test.attr(type='gate')
+    def test_list_extensions(self):
+        # List all the extensions
+        resp, body = self.non_admin_client.list_extensions()
+        self.assertEqual(200, resp.status)
+        self.assertNotEmpty(body)
+        keys = ['name', 'updated', 'alias', 'links',
+                'namespace', 'description']
+        for value in body:
+            for key in keys:
+                self.assertIn(key, value)
+
+
+class ExtensionTestXML(ExtensionTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index dcd9bff..cc768fd 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -81,9 +81,13 @@
         cls.metering_label_rules = []
         cls.fw_rules = []
         cls.fw_policies = []
+        cls.ipsecpolicies = []
 
     @classmethod
     def tearDownClass(cls):
+        # Clean up ipsec policies
+        for ipsecpolicy in cls.ipsecpolicies:
+            cls.client.delete_ipsecpolicy(ipsecpolicy['id'])
         # Clean up firewall policies
         for fw_policy in cls.fw_policies:
             cls.client.delete_firewall_policy(fw_policy['id'])
@@ -145,15 +149,16 @@
         return network
 
     @classmethod
-    def create_subnet(cls, network, gateway=None):
+    def create_subnet(cls, network, gateway=None, cidr=None, mask_bits=None):
         """Wrapper utility that returns a test subnet."""
         # The cidr and mask_bits depend on the ip version.
         if cls._ip_version == 4:
-            cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-            mask_bits = CONF.network.tenant_network_mask_bits
+            cidr = cidr or netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+            mask_bits = mask_bits or CONF.network.tenant_network_mask_bits
         elif cls._ip_version == 6:
-            cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
-            mask_bits = CONF.network.tenant_network_v6_mask_bits
+            cidr = (
+                cidr or netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr))
+            mask_bits = mask_bits or CONF.network.tenant_network_v6_mask_bits
         # Find a cidr that is not in use yet and create a subnet with it
         for subnet_cidr in cidr.subnet(mask_bits):
             if not gateway:
@@ -342,6 +347,14 @@
                 router['id'], i['fixed_ips'][0]['subnet_id'])
         cls.client.delete_router(router['id'])
 
+    @classmethod
+    def create_ipsecpolicy(cls, name):
+        """Wrapper utility that returns a test ipsec policy."""
+        _, body = cls.client.create_ipsecpolicy(name=name)
+        ipsecpolicy = body['ipsecpolicy']
+        cls.ipsecpolicies.append(ipsecpolicy)
+        return ipsecpolicy
+
 
 class BaseAdminNetworkTest(BaseNetworkTest):
 
diff --git a/tempest/api/network/base_routers.py b/tempest/api/network/base_routers.py
index b278002..1303bcf 100644
--- a/tempest/api/network/base_routers.py
+++ b/tempest/api/network/base_routers.py
@@ -37,6 +37,15 @@
             routers_list.append(router['id'])
         self.assertNotIn(router_id, routers_list)
 
+    def _add_router_interface_with_subnet_id(self, router_id, subnet_id):
+        resp, interface = self.client.add_router_interface_with_subnet_id(
+            router_id, subnet_id)
+        self.assertEqual('200', resp['status'])
+        self.addCleanup(self._remove_router_interface_with_subnet_id,
+                        router_id, subnet_id)
+        self.assertEqual(subnet_id, interface['subnet_id'])
+        return interface
+
     def _remove_router_interface_with_subnet_id(self, router_id, subnet_id):
         resp, body = self.client.remove_router_interface_with_subnet_id(
             router_id, subnet_id)
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 7605b8a..d38633f 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -300,9 +300,13 @@
 
     @test.attr(type='smoke')
     def test_add_multiple_router_interfaces(self):
-        network = self.create_network()
-        subnet01 = self.create_subnet(network)
-        subnet02 = self.create_subnet(network)
+        network01 = self.create_network(
+            network_name=data_utils.rand_name('router-network01-'))
+        network02 = self.create_network(
+            network_name=data_utils.rand_name('router-network02-'))
+        subnet01 = self.create_subnet(network01)
+        sub02_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr).next()
+        subnet02 = self.create_subnet(network02, cidr=sub02_cidr)
         router = self._create_router(data_utils.rand_name('router-'))
         interface01 = self._add_router_interface_with_subnet_id(router['id'],
                                                                 subnet01['id'])
@@ -313,15 +317,6 @@
         self._verify_router_interface(router['id'], subnet02['id'],
                                       interface02['port_id'])
 
-    def _add_router_interface_with_subnet_id(self, router_id, subnet_id):
-        resp, interface = self.client.add_router_interface_with_subnet_id(
-            router_id, subnet_id)
-        self.assertEqual('200', resp['status'])
-        self.addCleanup(self._remove_router_interface_with_subnet_id,
-                        router_id, subnet_id)
-        self.assertEqual(subnet_id, interface['subnet_id'])
-        return interface
-
     def _verify_router_interface(self, router_id, subnet_id, port_id):
         resp, show_port_body = self.client.show_port(port_id)
         self.assertEqual('200', resp['status'])
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index 91ab9d6..feee51b 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -13,11 +13,16 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import netaddr
+
 from tempest.api.network import base_routers as base
 from tempest.common.utils import data_utils
+from tempest import config
 from tempest import exceptions
 from tempest import test
 
+CONF = config.CONF
+
 
 class RoutersNegativeTest(base.BaseRouterTest):
     _interface = 'json'
@@ -43,12 +48,30 @@
 
     @test.attr(type=['negative', 'smoke'])
     def test_router_add_gateway_net_not_external_returns_400(self):
-        self.create_subnet(self.network)
+        alt_network = self.create_network(
+            network_name=data_utils.rand_name('router-negative-'))
+        sub_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr).next()
+        self.create_subnet(alt_network, cidr=sub_cidr)
         self.assertRaises(exceptions.BadRequest,
                           self.client.update_router,
                           self.router['id'],
                           external_gateway_info={
-                              'network_id': self.network['id']})
+                              'network_id': alt_network['id']})
+
+    @test.attr(type=['negative', 'smoke'])
+    def test_add_router_interfaces_on_overlapping_subnets_returns_400(self):
+        network01 = self.create_network(
+            network_name=data_utils.rand_name('router-network01-'))
+        network02 = self.create_network(
+            network_name=data_utils.rand_name('router-network02-'))
+        subnet01 = self.create_subnet(network01)
+        subnet02 = self.create_subnet(network02)
+        self._add_router_interface_with_subnet_id(self.router['id'],
+                                                  subnet01['id'])
+        self.assertRaises(exceptions.BadRequest,
+                          self._add_router_interface_with_subnet_id,
+                          self.router['id'],
+                          subnet02['id'])
 
     @test.attr(type=['negative', 'smoke'])
     def test_router_remove_interface_in_use_returns_409(self):
diff --git a/tempest/api/network/test_vpnaas_extensions.py b/tempest/api/network/test_vpnaas_extensions.py
index a49e944..d1fe15c 100644
--- a/tempest/api/network/test_vpnaas_extensions.py
+++ b/tempest/api/network/test_vpnaas_extensions.py
@@ -16,6 +16,7 @@
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -53,6 +54,8 @@
                                                cls.router['id'])
         cls.ikepolicy = cls.create_ikepolicy(
             data_utils.rand_name("ike-policy-"))
+        cls.ipsecpolicy = cls.create_ipsecpolicy(
+            data_utils.rand_name("ipsec-policy-"))
 
     def _delete_ike_policy(self, ike_policy_id):
         # Deletes a ike policy and verifies if it is deleted or not
@@ -70,6 +73,20 @@
                 ike_id_list.append(i['id'])
             self.assertNotIn(ike_policy_id, ike_id_list)
 
+    def _delete_ipsec_policy(self, ipsec_policy_id):
+        # Deletes an ike policy if it exists
+        try:
+            self.client.delete_ipsecpolicy(ipsec_policy_id)
+
+        except exceptions.NotFound:
+            pass
+
+    def _assertExpected(self, expected, actual):
+        # Check if not expected keys/values exists in actual response body
+        for key, value in expected.iteritems():
+            self.assertIn(key, actual)
+            self.assertEqual(value, actual[key])
+
     @test.attr(type='smoke')
     def test_list_vpn_services(self):
         # Verify the VPN service exists in the list of all VPN services
@@ -177,6 +194,51 @@
         self.assertEqual(self.ikepolicy['ike_version'],
                          ikepolicy['ike_version'])
 
+    @test.attr(type='smoke')
+    def test_list_ipsec_policies(self):
+        # Verify the ipsec policy exists in the list of all ipsec policies
+        resp, body = self.client.list_ipsecpolicies()
+        self.assertEqual('200', resp['status'])
+        ipsecpolicies = body['ipsecpolicies']
+        self.assertIn(self.ipsecpolicy['id'], [i['id'] for i in ipsecpolicies])
+
+    @test.attr(type='smoke')
+    def test_create_update_delete_ipsec_policy(self):
+        # Creates an ipsec policy
+        ipsec_policy_body = {'name': data_utils.rand_name('ipsec-policy'),
+                             'pfs': 'group5',
+                             'encryption_algorithm': "aes-128",
+                             'auth_algorithm': 'sha1'}
+        resp, resp_body = self.client.create_ipsecpolicy(**ipsec_policy_body)
+        self.assertEqual('201', resp['status'])
+        ipsecpolicy = resp_body['ipsecpolicy']
+        self.addCleanup(self._delete_ipsec_policy, ipsecpolicy['id'])
+        self._assertExpected(ipsec_policy_body, ipsecpolicy)
+        # Verification of ipsec policy update
+        new_ipsec = {'description': 'Updated ipsec policy',
+                     'pfs': 'group2',
+                     'name': data_utils.rand_name("New-IPSec"),
+                     'encryption_algorithm': "aes-256",
+                     'lifetime': {'units': "seconds", 'value': '2000'}}
+        resp, body = self.client.update_ipsecpolicy(ipsecpolicy['id'],
+                                                    **new_ipsec)
+        self.assertEqual('200', resp['status'])
+        updated_ipsec_policy = body['ipsecpolicy']
+        self._assertExpected(new_ipsec, updated_ipsec_policy)
+        # Verification of ipsec policy delete
+        resp, _ = self.client.delete_ipsecpolicy(ipsecpolicy['id'])
+        self.assertEqual('204', resp['status'])
+        self.assertRaises(exceptions.NotFound,
+                          self.client.delete_ipsecpolicy, ipsecpolicy['id'])
+
+    @test.attr(type='smoke')
+    def test_show_ipsec_policy(self):
+        # Verifies the details of an ipsec policy
+        resp, body = self.client.show_ipsecpolicy(self.ipsecpolicy['id'])
+        self.assertEqual('200', resp['status'])
+        ipsecpolicy = body['ipsecpolicy']
+        self._assertExpected(self.ipsecpolicy, ipsecpolicy)
+
 
 class VPNaaSTestXML(VPNaaSTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/orchestration/stacks/templates/neutron_basic.yaml b/tempest/api/orchestration/stacks/templates/neutron_basic.yaml
index 63b03f4..878ff68 100644
--- a/tempest/api/orchestration/stacks/templates/neutron_basic.yaml
+++ b/tempest/api/orchestration/stacks/templates/neutron_basic.yaml
@@ -8,10 +8,12 @@
     type: string
   ImageId:
     type: string
-  ExternalRouterId:
+  SubNetCidr:
     type: string
   ExternalNetworkId:
     type: string
+  DNSServers:
+    type: comma_delimited_list
   timeout:
     type: number
 resources:
@@ -25,21 +27,19 @@
       network_id: {Ref: Network}
       name: NewSubnet
       ip_version: 4
-      cidr: 10.0.3.0/24
-      dns_nameservers: ["8.8.8.8"]
-      allocation_pools:
-      - {end: 10.0.3.150, start: 10.0.3.20}
+      cidr: { get_param: SubNetCidr }
+      dns_nameservers: { get_param: DNSServers }
   Router:
     type: OS::Neutron::Router
     properties:
       name: NewRouter
-      admin_state_up: false
+      admin_state_up: true
       external_gateway_info:
         network: {get_param: ExternalNetworkId}
   RouterInterface:
     type: OS::Neutron::RouterInterface
     properties:
-      router_id: {get_param: ExternalRouterId}
+      router_id: {get_resource: Router}
       subnet_id: {get_resource: Subnet}
   Server:
     type: OS::Nova::Server
@@ -56,8 +56,8 @@
           template: |
             #!/bin/bash -v
 
-            /opt/aws/bin/cfn-signal -e 0 -r "SmokeServerNeutron created" \
-            'wait_handle'
+            while ! /opt/aws/bin/cfn-signal -e 0 -r "SmokeServerNeutron created" \
+            'wait_handle' ; do sleep 3; done
           params:
             wait_handle: {get_resource: WaitHandleNeutron}
   WaitHandleNeutron:
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 3086d78..e92b945 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -12,6 +12,7 @@
 
 
 import logging
+import netaddr
 
 from tempest.api.orchestration import base
 from tempest import clients
@@ -41,9 +42,12 @@
         template = cls.load_template('neutron_basic')
         cls.keypair_name = (CONF.orchestration.keypair_name or
                             cls._create_keypair()['name'])
-        cls.external_router_id = cls._get_external_router_id()
         cls.external_network_id = CONF.network.public_network_id
 
+        tenant_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+        mask_bits = CONF.network.tenant_network_mask_bits
+        cls.subnet_cidr = tenant_cidr.subnet(mask_bits).next()
+
         # create the stack
         cls.stack_identifier = cls.create_stack(
             cls.stack_name,
@@ -52,9 +56,10 @@
                 'KeyName': cls.keypair_name,
                 'InstanceType': CONF.orchestration.instance_type,
                 'ImageId': CONF.orchestration.image_ref,
-                'ExternalRouterId': cls.external_router_id,
                 'ExternalNetworkId': cls.external_network_id,
-                'timeout': CONF.orchestration.build_timeout
+                'timeout': CONF.orchestration.build_timeout,
+                'DNSServers': CONF.network.dns_servers,
+                'SubNetCidr': str(cls.subnet_cidr)
             })
         cls.stack_id = cls.stack_identifier.split('/')[1]
         try:
@@ -77,14 +82,6 @@
         for resource in resources:
             cls.test_resources[resource['logical_resource_id']] = resource
 
-    @classmethod
-    def _get_external_router_id(cls):
-        resp, body = cls.network_client.list_ports()
-        ports = body['ports']
-        router_ports = filter(lambda port: port['device_owner'] ==
-                              'network:router_interface', ports)
-        return router_ports[0]['device_id']
-
     @test.attr(type='slow')
     def test_created_resources(self):
         """Verifies created neutron resources."""
@@ -121,11 +118,10 @@
         self.assertEqual(subnet_id, subnet['id'])
         self.assertEqual(network_id, subnet['network_id'])
         self.assertEqual('NewSubnet', subnet['name'])
-        self.assertEqual('8.8.8.8', subnet['dns_nameservers'][0])
-        self.assertEqual('10.0.3.20', subnet['allocation_pools'][0]['start'])
-        self.assertEqual('10.0.3.150', subnet['allocation_pools'][0]['end'])
+        self.assertEqual(sorted(CONF.network.dns_servers),
+                         sorted(subnet['dns_nameservers']))
         self.assertEqual(4, subnet['ip_version'])
-        self.assertEqual('10.0.3.0/24', subnet['cidr'])
+        self.assertEqual(str(self.subnet_cidr), subnet['cidr'])
 
     @test.attr(type='slow')
     def test_created_router(self):
@@ -137,18 +133,19 @@
         self.assertEqual('NewRouter', router['name'])
         self.assertEqual(self.external_network_id,
                          router['external_gateway_info']['network_id'])
-        self.assertEqual(False, router['admin_state_up'])
+        self.assertEqual(True, router['admin_state_up'])
 
     @test.attr(type='slow')
     def test_created_router_interface(self):
         """Verifies created router interface."""
+        router_id = self.test_resources.get('Router')['physical_resource_id']
         network_id = self.test_resources.get('Network')['physical_resource_id']
         subnet_id = self.test_resources.get('Subnet')['physical_resource_id']
         resp, body = self.network_client.list_ports()
         self.assertEqual('200', resp['status'])
         ports = body['ports']
         router_ports = filter(lambda port: port['device_id'] ==
-                              self.external_router_id, ports)
+                              router_id, ports)
         created_network_ports = filter(lambda port: port['network_id'] ==
                                        network_id, router_ports)
         self.assertEqual(1, len(created_network_ports))
@@ -158,7 +155,8 @@
                                   subnet_id, fixed_ips)
         self.assertEqual(1, len(subnet_fixed_ips))
         router_interface_ip = subnet_fixed_ips[0]['ip_address']
-        self.assertEqual('10.0.3.1', router_interface_ip)
+        self.assertEqual(str(self.subnet_cidr.iter_hosts().next()),
+                         router_interface_ip)
 
     @test.attr(type='slow')
     def test_created_server(self):
@@ -170,8 +168,4 @@
         self.assertEqual('ACTIVE', server['status'])
         network = server['addresses']['NewNetwork'][0]
         self.assertEqual(4, network['version'])
-        ip_addr_prefix = network['addr'][:7]
-        ip_addr_suffix = int(network['addr'].split('.')[3])
-        self.assertEqual('10.0.3.', ip_addr_prefix)
-        self.assertTrue(ip_addr_suffix >= 20)
-        self.assertTrue(ip_addr_suffix <= 150)
+        self.assertIn(netaddr.IPAddress(network['addr']), self.subnet_cidr)
diff --git a/tempest/api_schema/compute/servers.py b/tempest/api_schema/compute/servers.py
index 4e8c201..33992b1 100644
--- a/tempest/api_schema/compute/servers.py
+++ b/tempest/api_schema/compute/servers.py
@@ -92,7 +92,8 @@
                              'user_id', 'tenant_id', 'created', 'updated',
                              'metadata', 'links', 'addresses']
             }
-        }
+        },
+        'required': ['server']
     }
 }
 
diff --git a/tempest/api_schema/compute/v2/servers.py b/tempest/api_schema/compute/v2/servers.py
index 981d8f7..f7ed94e 100644
--- a/tempest/api_schema/compute/v2/servers.py
+++ b/tempest/api_schema/compute/v2/servers.py
@@ -142,3 +142,38 @@
         'required': ['addresses']
     }
 }
+
+common_server_group = {
+    'type': 'object',
+    'properties': {
+        'id': {'type': 'string'},
+        'name': {'type': 'string'},
+        'policies': {
+            'type': 'array',
+            'items': {'type': 'string'}
+        },
+        # 'members' attribute contains the array of instance's UUID of
+        # instances present in server group
+        'members': {
+            'type': 'array',
+            'items': {'type': 'string'}
+        },
+        'metadata': {'type': 'object'}
+    },
+    'required': ['id', 'name', 'policies', 'members', 'metadata']
+}
+
+create_get_server_group = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'server_group': common_server_group
+        },
+        'required': ['server_group']
+    }
+}
+
+delete_server_group = {
+    'status_code': [204]
+}
diff --git a/tempest/cli/simple_read_only/test_cinder.py b/tempest/cli/simple_read_only/test_cinder.py
index 723333b..9001302 100644
--- a/tempest/cli/simple_read_only/test_cinder.py
+++ b/tempest/cli/simple_read_only/test_cinder.py
@@ -118,6 +118,12 @@
     def test_cinder_bash_completion(self):
         self.cinder('bash-completion')
 
+    def test_cinder_qos_list(self):
+        self.cinder('qos-list')
+
+    def test_cinder_encryption_type_list(self):
+        self.cinder('encryption-type-list')
+
     def test_admin_help(self):
         help_text = self.cinder('help')
         lines = help_text.split('\n')
diff --git a/tempest/cli/simple_read_only/test_keystone.py b/tempest/cli/simple_read_only/test_keystone.py
index 1efbede..dda65c1 100644
--- a/tempest/cli/simple_read_only/test_keystone.py
+++ b/tempest/cli/simple_read_only/test_keystone.py
@@ -117,6 +117,11 @@
     def test_admin_bashcompletion(self):
         self.keystone('bash-completion')
 
+    def test_admin_ec2_credentials_list(self):
+        creds = self.keystone('ec2-credentials-list')
+        creds = self.parser.listing(creds)
+        self.assertTableStruct(creds, ['tenant', 'access', 'secret'])
+
     # Optional arguments:
 
     def test_admin_version(self):
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 7b2e60b..3bf05e1 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -160,11 +160,10 @@
     extensions_client = get_extension_client(os, service)
     __, resp = extensions_client.list_extensions()
     if isinstance(resp, dict):
-        # Neutron's extension 'name' field has is not a single word (it has
-        # spaces in the string) Since that can't be used for list option the
-        # api_extension option in the network-feature-enabled group uses alias
-        # instead of name.
-        if service == 'neutron':
+        # For both Nova and Neutron we use the alias name rather than the
+        # 'name' field because the alias is considered to be the canonical
+        # name.
+        if service in ['nova', 'nova_v3', 'neutron']:
             extensions = map(lambda x: x['alias'], resp['extensions'])
         elif service == 'swift':
             # Remove Swift general information from extensions list
diff --git a/tempest/common/glance_http.py b/tempest/common/glance_http.py
index 9358851..55aca5a 100644
--- a/tempest/common/glance_http.py
+++ b/tempest/common/glance_http.py
@@ -160,6 +160,9 @@
     def json_request(self, method, url, **kwargs):
         kwargs.setdefault('headers', {})
         kwargs['headers'].setdefault('Content-Type', 'application/json')
+        if kwargs['headers']['Content-Type'] != 'application/json':
+            msg = "Only application/json content-type is supported."
+            raise exc.InvalidContentType(msg)
 
         if 'body' in kwargs:
             kwargs['body'] = json.dumps(kwargs['body'])
@@ -173,7 +176,8 @@
             except ValueError:
                 LOG.error('Could not decode response body as JSON')
         else:
-            body = None
+            msg = "Only json/application content-type is supported."
+            raise exc.InvalidContentType(msg)
 
         return resp, body
 
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 95b6833..57a14a2 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -57,11 +57,6 @@
         actual_hostname = self.exec_command("hostname").rstrip()
         return expected_hostname == actual_hostname
 
-    def get_files(self, path):
-        # Return a list of comma separated files
-        command = "ls -m " + path
-        return self.exec_command(command).rstrip('\n').split(', ')
-
     def get_ram_size_in_mb(self):
         output = self.exec_command('free -m | grep Mem')
         if output:
diff --git a/tempest/config.py b/tempest/config.py
index 94a725b..1366361 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -255,7 +255,7 @@
 
 ComputeFeaturesGroup = [
     cfg.BoolOpt('api_v3',
-                default=True,
+                default=False,
                 help="If false, skip all nova v3 tests."),
     cfg.BoolOpt('disk_config',
                 default=True,
@@ -263,11 +263,13 @@
     cfg.ListOpt('api_extensions',
                 default=['all'],
                 help='A list of enabled compute extensions with a special '
-                     'entry all which indicates every extension is enabled'),
+                     'entry all which indicates every extension is enabled. '
+                     'Each extension should be specified with alias name'),
     cfg.ListOpt('api_v3_extensions',
                 default=['all'],
                 help='A list of enabled v3 extensions with a special entry all'
-                     ' which indicates every extension is enabled'),
+                     ' which indicates every extension is enabled. '
+                     'Each extension should be specified with alias name'),
     cfg.BoolOpt('change_password',
                 default=False,
                 help="Does the test environment support changing the admin "
@@ -415,6 +417,10 @@
                default=1,
                help="Time in seconds between network operation status "
                     "checks."),
+    cfg.ListOpt('dns_servers',
+                default=["8.8.8.8", "8.8.4.4"],
+                help="List of dns servers whichs hould be used"
+                     " for subnet creation")
 ]
 
 network_feature_group = cfg.OptGroup(name='network-feature-enabled',
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index 82c6b5d..f197c15 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -31,8 +31,6 @@
         * Boots an instance using the keypair
         * Monitors the associated Ironic node for power and
           expected state transitions
-        * Validates Ironic node's driver_info has been properly
-          updated
         * Validates Ironic node's port data has been properly updated
         * Verifies SSH connectivity using created keypair via fixed IP
         * Associates a floating ip
@@ -46,17 +44,6 @@
         self.instance.add_floating_ip(floating_ip)
         return floating_ip.ip
 
-    def validate_driver_info(self):
-        f_id = self.instance.flavor['id']
-        flavor_extra = self.compute_client.flavors.get(f_id).get_keys()
-        driver_info = self.node.driver_info
-        self.assertEqual(driver_info['pxe_deploy_kernel'],
-                         flavor_extra['baremetal:deploy_kernel_id'])
-        self.assertEqual(driver_info['pxe_deploy_ramdisk'],
-                         flavor_extra['baremetal:deploy_ramdisk_id'])
-        self.assertEqual(driver_info['pxe_image_source'],
-                         self.instance.image['id'])
-
     def validate_ports(self):
         for port in self.get_ports(self.node.uuid):
             n_port_id = port.extra['vif_port_id']
@@ -68,7 +55,6 @@
     def test_baremetal_server_ops(self):
         self.add_keypair()
         self.boot_instance()
-        self.validate_driver_info()
         self.validate_ports()
         self.verify_connectivity()
         floating_ip = self.add_floating_ip()
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 21782ee..c84d4b9 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -87,6 +87,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # Create no network resources for these tests.
+        cls.set_network_resources()
         super(TestNetworkBasicOps, cls).setUpClass()
         for ext in ['router', 'security-group']:
             if not test.is_extension_enabled(ext, 'network'):
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 4616b82..b4e509a 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -134,6 +134,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # Create no network resources for these tests.
+        cls.set_network_resources()
         super(TestSecurityGroupsBasicOps, cls).setUpClass()
         cls.alt_creds = cls.alt_credentials()
         cls.alt_manager = clients.OfficialClientManager(cls.alt_creds)
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index 2af287f..321b08b 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -199,3 +199,14 @@
 
         """
         return self._list_request(version, permanent=True)
+
+    def _put_request(self, resource, put_object):
+        """
+        Update specified object with JSON-patch.
+
+        """
+        uri = self._get_uri(resource)
+        put_body = json.dumps(put_object)
+
+        resp, body = self.put(uri, body=put_body)
+        return resp, body
diff --git a/tempest/services/baremetal/v1/base_v1.py b/tempest/services/baremetal/v1/base_v1.py
index 296a199..52479b5 100644
--- a/tempest/services/baremetal/v1/base_v1.py
+++ b/tempest/services/baremetal/v1/base_v1.py
@@ -226,3 +226,16 @@
         """
 
         return self._patch_request('ports', uuid, patch)
+
+    @base.handle_errors
+    def set_node_power_state(self, node_uuid, state):
+        """
+        Set power state of the specified node.
+
+        :param node_uuid: The unique identifier of the node.
+        :state: desired state to set (on/off/reboot).
+
+        """
+        target = {'target': state}
+        return self._put_request('nodes/%s/states/power' % node_uuid,
+                                 target)
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 36bb02f..9d3b3b6 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -57,6 +57,7 @@
         max_count: Count of maximum number of instances to launch.
         disk_config: Determines if user or admin controls disk configuration.
         return_reservation_id: Enable/Disable the return of reservation id
+        block_device_mapping: Block device mapping for the server.
         """
         post_body = {
             'name': name,
@@ -69,7 +70,7 @@
                        'availability_zone', 'accessIPv4', 'accessIPv6',
                        'min_count', 'max_count', ('metadata', 'meta'),
                        ('OS-DCF:diskConfig', 'disk_config'),
-                       'return_reservation_id']:
+                       'return_reservation_id', 'block_device_mapping']:
             if isinstance(option, tuple):
                 post_param = option[0]
                 key = option[1]
@@ -508,11 +509,14 @@
         resp, body = self.post('os-server-groups', post_body)
 
         body = json.loads(body)
+        self.validate_response(schema.create_get_server_group, resp, body)
         return resp, body['server_group']
 
     def delete_server_group(self, server_group_id):
         """Delete the given server-group."""
-        return self.delete("os-server-groups/%s" % str(server_group_id))
+        resp, body = self.delete("os-server-groups/%s" % str(server_group_id))
+        self.validate_response(schema.delete_server_group, resp, body)
+        return resp, body
 
     def list_server_groups(self):
         """List the server-groups."""
@@ -524,4 +528,5 @@
         """Get the details of given server_group."""
         resp, body = self.get("os-server-groups/%s" % str(server_group_id))
         body = json.loads(body)
+        self.validate_response(schema.create_get_server_group, resp, body)
         return resp, body['server_group']
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index eed85c7..0ccbe7f 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -55,6 +55,7 @@
         max_count: Count of maximum number of instances to launch.
         disk_config: Determines if user or admin controls disk configuration.
         return_reservation_id: Enable/Disable the return of reservation id
+        block_device_mapping: Block device mapping for the server.
         """
         post_body = {
             'name': name,
@@ -75,7 +76,9 @@
                        ('metadata', 'meta'),
                        ('os-disk-config:disk_config', 'disk_config'),
                        ('os-multiple-create:return_reservation_id',
-                        'return_reservation_id')]:
+                        'return_reservation_id'),
+                       ('os-block-device-mapping:block_device_mapping',
+                        'block_device_mapping')]:
             if isinstance(option, tuple):
                 post_param = option[0]
                 key = option[1]
@@ -432,6 +435,9 @@
         return self.action(server_id, 'shelve_offload', None, **kwargs)
 
     def get_console_output(self, server_id, length):
+        if length is None:
+            # NOTE(mriedem): -1 means optional/unlimited in the nova v3 API.
+            length = -1
         return self.action(server_id, 'get_console_output', 'output',
                            common_schema.get_console_output, length=length)
 
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index c1105f9..626e655 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -318,6 +318,7 @@
         min_count: Count of minimum number of instances to launch.
         max_count: Count of maximum number of instances to launch.
         disk_config: Determines if user or admin controls disk configuration.
+        block_device_mapping: Block device mapping for the server.
         """
         server = xml_utils.Element("server",
                                    xmlns=xml_utils.XMLNS_11,
@@ -327,7 +328,8 @@
 
         for attr in ["adminPass", "accessIPv4", "accessIPv6", "key_name",
                      "user_data", "availability_zone", "min_count",
-                     "max_count", "return_reservation_id"]:
+                     "max_count", "return_reservation_id",
+                     "block_device_mapping"]:
             if attr in kwargs:
                 server.add_attr(attr, kwargs[attr])
 
diff --git a/tempest/services/data_processing/v1_1/client.py b/tempest/services/data_processing/v1_1/client.py
index 73e67c3..c2c7fd1 100644
--- a/tempest/services/data_processing/v1_1/client.py
+++ b/tempest/services/data_processing/v1_1/client.py
@@ -186,3 +186,49 @@
 
         uri = 'job-binary-internals/%s' % job_binary_id
         return self.delete(uri)
+
+    def get_job_binary_internal_data(self, job_binary_id):
+        """Returns data of a single job binary internal."""
+
+        uri = 'job-binary-internals/%s/data' % job_binary_id
+        return self.get(uri)
+
+    def list_job_binaries(self):
+        """List all job binaries for a user."""
+
+        uri = 'job-binaries'
+        return self._request_and_parse(self.get, uri, 'binaries')
+
+    def get_job_binary(self, job_binary_id):
+        """Returns the details of a single job binary."""
+
+        uri = 'job-binaries/%s' % job_binary_id
+        return self._request_and_parse(self.get, uri, 'job_binary')
+
+    def create_job_binary(self, name, url, extra=None, **kwargs):
+        """Creates job binary with specified params.
+
+        It supports passing additional params using kwargs and returns created
+        object.
+        """
+        uri = 'job-binaries'
+        body = kwargs.copy()
+        body.update({
+            'name': name,
+            'url': url,
+            'extra': extra or dict(),
+        })
+        return self._request_and_parse(self.post, uri, 'job_binary',
+                                       body=json.dumps(body))
+
+    def delete_job_binary(self, job_binary_id):
+        """Deletes the specified job binary by id."""
+
+        uri = 'job-binaries/%s' % job_binary_id
+        return self.delete(uri)
+
+    def get_job_binary_data(self, job_binary_id):
+        """Returns data of a single job binary."""
+
+        uri = 'job-binaries/%s/data' % job_binary_id
+        return self.get(uri)
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index 479a289..b0cab8e 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -27,7 +27,8 @@
         self.endpoint_url = 'adminURL'
 
         # Needed for xml service client
-        self.list_tags = ["roles", "tenants", "users", "services"]
+        self.list_tags = ["roles", "tenants", "users", "services",
+                          "extensions"]
 
     def has_admin_extensions(self):
         """
@@ -237,6 +238,12 @@
         resp, body = self.put('users/%s/OS-KSADM/password' % user_id, put_body)
         return resp, self._parse_resp(body)
 
+    def list_extensions(self):
+        """List all the extensions."""
+        resp, body = self.get('/extensions')
+        body = json.loads(body)
+        return resp, body['extensions']['values']
+
 
 class TokenClientJSON(IdentityClientJSON):
 
diff --git a/tempest/services/identity/xml/identity_client.py b/tempest/services/identity/xml/identity_client.py
index b213c1a..886ce7b 100644
--- a/tempest/services/identity/xml/identity_client.py
+++ b/tempest/services/identity/xml/identity_client.py
@@ -127,6 +127,11 @@
                               str(xml.Document(put_body)))
         return resp, self._parse_resp(body)
 
+    def list_extensions(self):
+        """List all the extensions."""
+        resp, body = self.get('/extensions')
+        return resp, self._parse_resp(body)
+
 
 class TokenClientXML(identity_client.TokenClientJSON):
     TYPE = "xml"
diff --git a/tempest/services/network/network_client_base.py b/tempest/services/network/network_client_base.py
index 2a797b2..81792c4 100644
--- a/tempest/services/network/network_client_base.py
+++ b/tempest/services/network/network_client_base.py
@@ -30,6 +30,7 @@
     'members': 'lb',
     'vpnservices': 'vpn',
     'ikepolicies': 'vpn',
+    'ipsecpolicies': 'vpn',
     'metering_labels': 'metering',
     'metering_label_rules': 'metering',
     'firewall_rules': 'fw',
@@ -47,6 +48,7 @@
     'security_groups': 'security_groups',
     'security_group_rules': 'security_group_rules',
     'ikepolicy': 'ikepolicies',
+    'ipsecpolicy': 'ipsecpolicies',
     'quotas': 'quotas',
     'firewall_policy': 'firewall_policies'
 }
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 40caf30..d0140dd 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -15,6 +15,7 @@
 import json
 
 import mock
+from oslo.config import cfg
 
 from tempest.cmd import verify_tempest_config
 from tempest import config
@@ -152,6 +153,7 @@
                                            False, True)
 
     def test_verify_nova_versions(self):
+        cfg.CONF.set_default('api_v3', True, 'compute-feature-enabled')
         self.useFixture(mockpatch.PatchObject(
             verify_tempest_config, '_get_unversioned_endpoint',
             return_value='http://fake_endpoint:5000'))
@@ -280,9 +282,9 @@
 
     def test_verify_extensions_nova(self):
         def fake_list_extensions():
-            return (None, {'extensions': [{'name': 'fake1'},
-                                          {'name': 'fake2'},
-                                          {'name': 'not_fake'}]})
+            return (None, {'extensions': [{'alias': 'fake1'},
+                                          {'alias': 'fake2'},
+                                          {'alias': 'not_fake'}]})
         fake_os = mock.MagicMock()
         fake_os.extensions_client.list_extensions = fake_list_extensions
         self.useFixture(mockpatch.PatchObject(
@@ -302,9 +304,9 @@
 
     def test_verify_extensions_nova_all(self):
         def fake_list_extensions():
-            return (None, {'extensions': [{'name': 'fake1'},
-                                          {'name': 'fake2'},
-                                          {'name': 'not_fake'}]})
+            return (None, {'extensions': [{'alias': 'fake1'},
+                                          {'alias': 'fake2'},
+                                          {'alias': 'not_fake'}]})
         fake_os = mock.MagicMock()
         fake_os.extensions_client.list_extensions = fake_list_extensions
         self.useFixture(mockpatch.PatchObject(
@@ -319,9 +321,9 @@
 
     def test_verify_extensions_nova_v3(self):
         def fake_list_extensions():
-            return (None, {'extensions': [{'name': 'fake1'},
-                                          {'name': 'fake2'},
-                                          {'name': 'not_fake'}]})
+            return (None, {'extensions': [{'alias': 'fake1'},
+                                          {'alias': 'fake2'},
+                                          {'alias': 'not_fake'}]})
         fake_os = mock.MagicMock()
         fake_os.extensions_v3_client.list_extensions = fake_list_extensions
         self.useFixture(mockpatch.PatchObject(
@@ -341,9 +343,9 @@
 
     def test_verify_extensions_nova_v3_all(self):
         def fake_list_extensions():
-            return (None, {'extensions': [{'name': 'fake1'},
-                                          {'name': 'fake2'},
-                                          {'name': 'not_fake'}]})
+            return (None, {'extensions': [{'alias': 'fake1'},
+                                          {'alias': 'fake2'},
+                                          {'alias': 'not_fake'}]})
         fake_os = mock.MagicMock()
         fake_os.extensions_v3_client.list_extensions = fake_list_extensions
         self.useFixture(mockpatch.PatchObject(
diff --git a/tempest/tests/common/utils/linux/__init__.py b/tempest/tests/common/utils/linux/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/tests/common/utils/linux/__init__.py
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
new file mode 100644
index 0000000..0db4cfa
--- /dev/null
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -0,0 +1,150 @@
+# Copyright 2014 IBM Corp.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import time
+
+from oslo.config import cfg
+
+from tempest.common.utils.linux import remote_client
+from tempest import config
+from tempest.openstack.common.fixture import mockpatch
+from tempest.tests import base
+from tempest.tests import fake_config
+
+
+class TestRemoteClient(base.TestCase):
+    def setUp(self):
+        super(TestRemoteClient, self).setUp()
+        self.useFixture(fake_config.ConfigFixture())
+        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
+        cfg.CONF.set_default('ip_version_for_ssh', 4, group='compute')
+        cfg.CONF.set_default('network_for_ssh', 'public', group='compute')
+        cfg.CONF.set_default('ssh_channel_timeout', 1, group='compute')
+
+        self.conn = remote_client.RemoteClient('127.0.0.1', 'user', 'pass')
+        self.ssh_mock = self.useFixture(mockpatch.PatchObject(self.conn,
+                                                              'ssh_client'))
+
+    def test_hostname_equals_servername_for_expected_names(self):
+        self.ssh_mock.mock.exec_command.return_value = 'fake_hostname'
+        self.assertTrue(self.conn.hostname_equals_servername('fake_hostname'))
+
+    def test_hostname_equals_servername_for_unexpected_names(self):
+        self.ssh_mock.mock.exec_command.return_value = 'fake_hostname'
+        self.assertFalse(
+            self.conn.hostname_equals_servername('unexpected_hostname'))
+
+    def test_get_ram_size(self):
+        free_output = "Mem:         48294      45738       2555          0" \
+                      "402      40346"
+        self.ssh_mock.mock.exec_command.return_value = free_output
+        self.assertEqual(self.conn.get_ram_size_in_mb(), '48294')
+
+    def test_write_to_console_regular_str(self):
+        self.conn.write_to_console('test')
+        self._assert_exec_called_with(
+            'sudo sh -c "echo \\"test\\" >/dev/console"')
+
+    def _test_write_to_console_helper(self, message, expected_call):
+        self.conn.write_to_console(message)
+        self._assert_exec_called_with(expected_call)
+
+    def test_write_to_console_special_chars(self):
+        self._test_write_to_console_helper(
+            '\`',
+            'sudo sh -c "echo \\"\\\\\\`\\" >/dev/console"')
+        self.conn.write_to_console('$')
+        self._assert_exec_called_with(
+            'sudo sh -c "echo \\"\\\\$\\" >/dev/console"')
+
+    # NOTE(maurosr): The tests below end up closer to an output format
+    # assurance than a test since it's basically using comand_exec to format
+    # the information using gnu/linux tools.
+
+    def _assert_exec_called_with(self, cmd):
+        self.ssh_mock.mock.exec_command.assert_called_with(cmd)
+
+    def test_get_number_of_vcpus(self):
+        self.ssh_mock.mock.exec_command.return_value = '16'
+        self.assertEqual(self.conn.get_number_of_vcpus(), 16)
+        self._assert_exec_called_with(
+            'cat /proc/cpuinfo | grep processor | wc -l')
+
+    def test_get_partitions(self):
+        proc_partitions = """major minor  #blocks  name
+
+8        0  1048576 vda"""
+        self.ssh_mock.mock.exec_command.return_value = proc_partitions
+        self.assertEqual(self.conn.get_partitions(), proc_partitions)
+        self._assert_exec_called_with('cat /proc/partitions')
+
+    def test_get_boot_time(self):
+        booted_at = 10000
+        uptime_sec = 5000.02
+        self.ssh_mock.mock.exec_command.return_value = uptime_sec
+        self.useFixture(mockpatch.PatchObject(
+            time, 'time', return_value=booted_at + uptime_sec))
+        self.assertEqual(self.conn.get_boot_time(),
+                         time.localtime(booted_at))
+        self._assert_exec_called_with('cut -f1 -d. /proc/uptime')
+
+    def test_ping_host(self):
+        ping_response = """PING localhost (127.0.0.1) 56(84) bytes of data.
+64 bytes from localhost (127.0.0.1): icmp_req=1 ttl=64 time=0.048 ms
+
+--- localhost ping statistics ---
+1 packets transmitted, 1 received, 0% packet loss, time 0ms
+rtt min/avg/max/mdev = 0.048/0.048/0.048/0.000 ms"""
+        self.ssh_mock.mock.exec_command.return_value = ping_response
+        self.assertEqual(self.conn.ping_host('127.0.0.1'), ping_response)
+        self._assert_exec_called_with('ping -c1 -w1 127.0.0.1')
+
+    def test_get_mac_address(self):
+        macs = """0a:0b:0c:0d:0e:0f
+a0:b0:c0:d0:e0:f0"""
+        self.ssh_mock.mock.exec_command.return_value = macs
+
+        self.assertEqual(self.conn.get_mac_address(), macs)
+        self._assert_exec_called_with(
+            "/sbin/ifconfig | awk '/HWaddr/ {print $5}'")
+
+    def test_get_ip_list(self):
+        ips = """1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue
+    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+    inet 127.0.0.1/8 scope host lo
+    inet6 ::1/128 scope host
+       valid_lft forever preferred_lft forever
+2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
+    link/ether fa:16:3e:6e:26:3b brd ff:ff:ff:ff:ff:ff
+    inet 10.0.0.4/24 brd 10.0.0.255 scope global eth0
+    inet6 fd55:faaf:e1ab:3d9:f816:3eff:fe6e:263b/64 scope global dynamic
+       valid_lft 2591936sec preferred_lft 604736sec
+    inet6 fe80::f816:3eff:fe6e:263b/64 scope link
+       valid_lft forever preferred_lft forever"""
+        self.ssh_mock.mock.exec_command.return_value = ips
+        self.assertEqual(self.conn.get_ip_list(), ips)
+        self._assert_exec_called_with('/bin/ip address')
+
+    def test_assign_static_ip(self):
+        self.ssh_mock.mock.exec_command.return_value = ''
+        ip = '10.0.0.2'
+        nic = 'eth0'
+        self.assertEqual(self.conn.assign_static_ip(nic, ip), '')
+        self._assert_exec_called_with(
+            "sudo /bin/ip addr add %s/%s dev %s" % (ip, '28', nic))
+
+    def test_turn_nic_on(self):
+        nic = 'eth0'
+        self.conn.turn_nic_on(nic)
+        self._assert_exec_called_with('sudo /bin/ip link set %s up' % nic)
diff --git a/tempest/tests/test_glance_http.py b/tempest/tests/test_glance_http.py
index bb2df43..88b8129 100644
--- a/tempest/tests/test_glance_http.py
+++ b/tempest/tests/test_glance_http.py
@@ -54,26 +54,37 @@
                         return_value=resp))
         return resp
 
-    def test_json_request_without_content_type_header(self):
+    def test_json_request_without_content_type_header_in_response(self):
         self._set_response_fixture({}, 200, 'fake_response_body')
-        resp, body = self.client.json_request('GET', '/images')
-        self.assertEqual(200, resp.status)
-        self.assertIsNone(body)
+        self.assertRaises(exceptions.InvalidContentType,
+                          self.client.json_request, 'GET', '/images')
 
-    def test_json_request_with_xml_content_type_header(self):
+    def test_json_request_with_xml_content_type_header_in_request(self):
+        self.assertRaises(exceptions.InvalidContentType,
+                          self.client.json_request, 'GET', '/images',
+                          headers={'Content-Type': 'application/xml'})
+
+    def test_json_request_with_xml_content_type_header_in_response(self):
         self._set_response_fixture({'content-type': 'application/xml'},
                                    200, 'fake_response_body')
-        resp, body = self.client.json_request('GET', '/images')
-        self.assertEqual(200, resp.status)
-        self.assertIsNone(body)
+        self.assertRaises(exceptions.InvalidContentType,
+                          self.client.json_request, 'GET', '/images')
 
-    def test_json_request_with_content_type_header(self):
+    def test_json_request_with_json_content_type_header_only_in_resp(self):
         self._set_response_fixture({'content-type': 'application/json'},
                                    200, 'fake_response_body')
         resp, body = self.client.json_request('GET', '/images')
         self.assertEqual(200, resp.status)
         self.assertEqual('fake_response_body', body)
 
+    def test_json_request_with_json_content_type_header_in_req_and_resp(self):
+        self._set_response_fixture({'content-type': 'application/json'},
+                                   200, 'fake_response_body')
+        resp, body = self.client.json_request('GET', '/images', headers={
+            'Content-Type': 'application/json'})
+        self.assertEqual(200, resp.status)
+        self.assertEqual('fake_response_body', body)
+
     def test_json_request_fails_to_json_loads(self):
         self._set_response_fixture({'content-type': 'application/json'},
                                    200, 'fake_response_body')