Merge "Use ephemeral=0 to create flavor without ephemeral disk"
diff --git a/releasenotes/notes/remove-baremetal-tests-65186d9e15d5b8fb.yaml b/releasenotes/notes/remove-baremetal-tests-65186d9e15d5b8fb.yaml
new file mode 100644
index 0000000..ca2635e
--- /dev/null
+++ b/releasenotes/notes/remove-baremetal-tests-65186d9e15d5b8fb.yaml
@@ -0,0 +1,4 @@
+---
+upgrade:
+  - All tests for the Ironic project have been removed from Tempest. Those
+    exist as a Tempest plugin in the Ironic project.
diff --git a/tempest/api/baremetal/README.rst b/tempest/api/baremetal/README.rst
deleted file mode 100644
index 759c937..0000000
--- a/tempest/api/baremetal/README.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-Tempest Field Guide to Baremetal API tests
-==========================================
-
-
-What are these tests?
----------------------
-
-These tests stress the OpenStack baremetal provisioning API provided by
-Ironic.
-
-
-Why are these tests in tempest?
-------------------------------
-
-The purpose of these tests is to exercise the various APIs provided by Ironic
-for managing baremetal nodes.
-
-
-Scope of these tests
---------------------
-
-The baremetal API test perform basic CRUD operations on the Ironic node
-inventory.  They do not actually perform hardware provisioning. It is important
-to note that all Ironic API actions are admin operations meant to be used
-either by cloud operators or other OpenStack services (i.e., Nova).
diff --git a/tempest/api/baremetal/__init__.py b/tempest/api/baremetal/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/baremetal/__init__.py
+++ /dev/null
diff --git a/tempest/api/baremetal/admin/__init__.py b/tempest/api/baremetal/admin/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/baremetal/admin/__init__.py
+++ /dev/null
diff --git a/tempest/api/baremetal/admin/base.py b/tempest/api/baremetal/admin/base.py
deleted file mode 100644
index ac5986c..0000000
--- a/tempest/api/baremetal/admin/base.py
+++ /dev/null
@@ -1,206 +0,0 @@
-#    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 functools
-
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest.lib import exceptions as lib_exc
-from tempest import test
-
-CONF = config.CONF
-
-
-# NOTE(adam_g): The baremetal API tests exercise operations such as enroll
-# node, power on, power off, etc.  Testing against real drivers (ie, IPMI)
-# will require passing driver-specific data to Tempest (addresses,
-# credentials, etc).  Until then, only support testing against the fake driver,
-# which has no external dependencies.
-SUPPORTED_DRIVERS = ['fake']
-
-# NOTE(jroll): resources must be deleted in a specific order, this list
-# defines the resource types to clean up, and the correct order.
-RESOURCE_TYPES = ['port', 'node', 'chassis']
-
-
-def creates(resource):
-    """Decorator that adds resources to the appropriate cleanup list."""
-
-    def decorator(f):
-        @functools.wraps(f)
-        def wrapper(cls, *args, **kwargs):
-            resp, body = f(cls, *args, **kwargs)
-
-            if 'uuid' in body:
-                cls.created_objects[resource].add(body['uuid'])
-
-            return resp, body
-        return wrapper
-    return decorator
-
-
-class BaseBaremetalTest(test.BaseTestCase):
-    """Base class for Baremetal API tests."""
-
-    credentials = ['admin']
-
-    @classmethod
-    def skip_checks(cls):
-        super(BaseBaremetalTest, cls).skip_checks()
-        if not CONF.service_available.ironic:
-            skip_msg = ('%s skipped as Ironic is not available' % cls.__name__)
-            raise cls.skipException(skip_msg)
-
-        if CONF.baremetal.driver not in SUPPORTED_DRIVERS:
-            skip_msg = ('%s skipped as Ironic driver %s is not supported for '
-                        'testing.' %
-                        (cls.__name__, CONF.baremetal.driver))
-            raise cls.skipException(skip_msg)
-
-    @classmethod
-    def setup_clients(cls):
-        super(BaseBaremetalTest, cls).setup_clients()
-        cls.client = cls.os_admin.baremetal_client
-
-    @classmethod
-    def resource_setup(cls):
-        super(BaseBaremetalTest, cls).resource_setup()
-
-        cls.driver = CONF.baremetal.driver
-        cls.power_timeout = CONF.baremetal.power_timeout
-        cls.created_objects = {}
-        for resource in RESOURCE_TYPES:
-            cls.created_objects[resource] = set()
-
-    @classmethod
-    def resource_cleanup(cls):
-        """Ensure that all created objects get destroyed."""
-
-        try:
-            for resource in RESOURCE_TYPES:
-                uuids = cls.created_objects[resource]
-                delete_method = getattr(cls.client, 'delete_%s' % resource)
-                for u in uuids:
-                    delete_method(u, ignore_errors=lib_exc.NotFound)
-        finally:
-            super(BaseBaremetalTest, cls).resource_cleanup()
-
-    @classmethod
-    @creates('chassis')
-    def create_chassis(cls, description=None):
-        """Wrapper utility for creating test chassis.
-
-        :param description: A description of the chassis. If not supplied,
-            a random value will be generated.
-        :return: Created chassis.
-
-        """
-        description = description or data_utils.rand_name('test-chassis')
-        resp, body = cls.client.create_chassis(description=description)
-        return resp, body
-
-    @classmethod
-    @creates('node')
-    def create_node(cls, chassis_id, cpu_arch='x86', cpus=8, local_gb=10,
-                    memory_mb=4096):
-        """Wrapper utility for creating test baremetal nodes.
-
-        :param chassis_id: The unique identifier of the chassis.
-        :param cpu_arch: CPU architecture of the node. Default: x86.
-        :param cpus: Number of CPUs. Default: 8.
-        :param local_gb: Disk size. Default: 10.
-        :param memory_mb: Available RAM. Default: 4096.
-        :return: Created node.
-
-        """
-        resp, body = cls.client.create_node(chassis_id, cpu_arch=cpu_arch,
-                                            cpus=cpus, local_gb=local_gb,
-                                            memory_mb=memory_mb,
-                                            driver=cls.driver)
-
-        return resp, body
-
-    @classmethod
-    @creates('port')
-    def create_port(cls, node_id, address, extra=None, uuid=None):
-        """Wrapper utility for creating test ports.
-
-        :param node_id: The unique identifier of the node.
-        :param address: MAC address of the port.
-        :param extra: Meta data of the port. If not supplied, an empty
-            dictionary will be created.
-        :param uuid: UUID of the port.
-        :return: Created port.
-
-        """
-        extra = extra or {}
-        resp, body = cls.client.create_port(address=address, node_id=node_id,
-                                            extra=extra, uuid=uuid)
-
-        return resp, body
-
-    @classmethod
-    def delete_chassis(cls, chassis_id):
-        """Deletes a chassis having the specified UUID.
-
-        :param chassis_id: The unique identifier of the chassis.
-        :return: Server response.
-
-        """
-
-        resp, body = cls.client.delete_chassis(chassis_id)
-
-        if chassis_id in cls.created_objects['chassis']:
-            cls.created_objects['chassis'].remove(chassis_id)
-
-        return resp
-
-    @classmethod
-    def delete_node(cls, node_id):
-        """Deletes a node having the specified UUID.
-
-        :param node_id: The unique identifier of the node.
-        :return: Server response.
-
-        """
-
-        resp, body = cls.client.delete_node(node_id)
-
-        if node_id in cls.created_objects['node']:
-            cls.created_objects['node'].remove(node_id)
-
-        return resp
-
-    @classmethod
-    def delete_port(cls, port_id):
-        """Deletes a port having the specified UUID.
-
-        :param port_id: The unique identifier of the port.
-        :return: Server response.
-
-        """
-
-        resp, body = cls.client.delete_port(port_id)
-
-        if port_id in cls.created_objects['port']:
-            cls.created_objects['port'].remove(port_id)
-
-        return resp
-
-    def validate_self_link(self, resource, uuid, link):
-        """Check whether the given self link formatted correctly."""
-        expected_link = "{base}/{pref}/{res}/{uuid}".format(
-                        base=self.client.base_url,
-                        pref=self.client.uri_prefix,
-                        res=resource,
-                        uuid=uuid)
-        self.assertEqual(expected_link, link)
diff --git a/tempest/api/baremetal/admin/test_api_discovery.py b/tempest/api/baremetal/admin/test_api_discovery.py
deleted file mode 100644
index 41388ad..0000000
--- a/tempest/api/baremetal/admin/test_api_discovery.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#    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.baremetal.admin import base
-from tempest import test
-
-
-class TestApiDiscovery(base.BaseBaremetalTest):
-    """Tests for API discovery features."""
-
-    @test.idempotent_id('a3c27e94-f56c-42c4-8600-d6790650b9c5')
-    def test_api_versions(self):
-        _, descr = self.client.get_api_description()
-        expected_versions = ('v1',)
-        versions = [version['id'] for version in descr['versions']]
-
-        for v in expected_versions:
-            self.assertIn(v, versions)
-
-    @test.idempotent_id('896283a6-488e-4f31-af78-6614286cbe0d')
-    def test_default_version(self):
-        _, descr = self.client.get_api_description()
-        default_version = descr['default_version']
-        self.assertEqual(default_version['id'], 'v1')
-
-    @test.idempotent_id('abc0b34d-e684-4546-9728-ab7a9ad9f174')
-    def test_version_1_resources(self):
-        _, descr = self.client.get_version_description(version='v1')
-        expected_resources = ('nodes', 'chassis',
-                              'ports', 'links', 'media_types')
-
-        for res in expected_resources:
-            self.assertIn(res, descr)
diff --git a/tempest/api/baremetal/admin/test_chassis.py b/tempest/api/baremetal/admin/test_chassis.py
deleted file mode 100644
index 339aaea..0000000
--- a/tempest/api/baremetal/admin/test_chassis.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# -*- coding: utf-8 -*-
-#    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 six
-
-from tempest.api.baremetal.admin import base
-from tempest.common.utils import data_utils
-from tempest.lib import exceptions as lib_exc
-from tempest import test
-
-
-class TestChassis(base.BaseBaremetalTest):
-    """Tests for chassis."""
-
-    @classmethod
-    def resource_setup(cls):
-        super(TestChassis, cls).resource_setup()
-        _, 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 six.iteritems(expected):
-            if key not in ('created_at', 'updated_at'):
-                self.assertIn(key, actual)
-                self.assertEqual(value, actual[key])
-
-    @test.idempotent_id('7c5a2e09-699c-44be-89ed-2bc189992d42')
-    def test_create_chassis(self):
-        descr = data_utils.rand_name('test-chassis')
-        _, chassis = self.create_chassis(description=descr)
-        self.assertEqual(chassis['description'], descr)
-
-    @test.idempotent_id('cabe9c6f-dc16-41a7-b6b9-0a90c212edd5')
-    def test_create_chassis_unicode_description(self):
-        # Use a unicode string for testing:
-        # 'We ♡ OpenStack in Ukraine'
-        descr = u'В Україні ♡ OpenStack!'
-        _, chassis = self.create_chassis(description=descr)
-        self.assertEqual(chassis['description'], descr)
-
-    @test.idempotent_id('c84644df-31c4-49db-a307-8942881f41c0')
-    def test_show_chassis(self):
-        _, chassis = self.client.show_chassis(self.chassis['uuid'])
-        self._assertExpected(self.chassis, chassis)
-
-    @test.idempotent_id('29c9cd3f-19b5-417b-9864-99512c3b33b3')
-    def test_list_chassis(self):
-        _, body = self.client.list_chassis()
-        self.assertIn(self.chassis['uuid'],
-                      [i['uuid'] for i in body['chassis']])
-
-    @test.idempotent_id('5ae649ad-22d1-4fe1-bbc6-97227d199fb3')
-    def test_delete_chassis(self):
-        _, body = self.create_chassis()
-        uuid = body['uuid']
-
-        self.delete_chassis(uuid)
-        self.assertRaises(lib_exc.NotFound, self.client.show_chassis, uuid)
-
-    @test.idempotent_id('cda8a41f-6be2-4cbf-840c-994b00a89b44')
-    def test_update_chassis(self):
-        _, body = self.create_chassis()
-        uuid = body['uuid']
-
-        new_description = data_utils.rand_name('new-description')
-        _, body = (self.client.update_chassis(uuid,
-                   description=new_description))
-        _, chassis = self.client.show_chassis(uuid)
-        self.assertEqual(chassis['description'], new_description)
-
-    @test.idempotent_id('76305e22-a4e2-4ab3-855c-f4e2368b9335')
-    def test_chassis_node_list(self):
-        _, node = self.create_node(self.chassis['uuid'])
-        _, body = self.client.list_chassis_nodes(self.chassis['uuid'])
-        self.assertIn(node['uuid'], [n['uuid'] for n in body['nodes']])
diff --git a/tempest/api/baremetal/admin/test_drivers.py b/tempest/api/baremetal/admin/test_drivers.py
deleted file mode 100644
index f08d7ab..0000000
--- a/tempest/api/baremetal/admin/test_drivers.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# 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.baremetal.admin import base
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class TestDrivers(base.BaseBaremetalTest):
-    """Tests for drivers."""
-    @classmethod
-    def resource_setup(cls):
-        super(TestDrivers, cls).resource_setup()
-        cls.driver_name = CONF.baremetal.driver
-
-    @test.idempotent_id('5aed2790-7592-4655-9b16-99abcc2e6ec5')
-    def test_list_drivers(self):
-        _, drivers = self.client.list_drivers()
-        self.assertIn(self.driver_name,
-                      [d['name'] for d in drivers['drivers']])
-
-    @test.idempotent_id('fb3287a3-c4d7-44bf-ae9d-1eef906d78ce')
-    def test_show_driver(self):
-        _, driver = self.client.show_driver(self.driver_name)
-        self.assertEqual(self.driver_name, driver['name'])
diff --git a/tempest/api/baremetal/admin/test_nodes.py b/tempest/api/baremetal/admin/test_nodes.py
deleted file mode 100644
index 2c44665..0000000
--- a/tempest/api/baremetal/admin/test_nodes.py
+++ /dev/null
@@ -1,169 +0,0 @@
-#    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 six
-
-from tempest.api.baremetal.admin import base
-from tempest.common.utils import data_utils
-from tempest.common import waiters
-from tempest.lib import exceptions as lib_exc
-from tempest import test
-
-
-class TestNodes(base.BaseBaremetalTest):
-    """Tests for baremetal nodes."""
-
-    def setUp(self):
-        super(TestNodes, self).setUp()
-
-        _, 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])
-
-    def _associate_node_with_instance(self):
-        self.client.set_node_power_state(self.node['uuid'], 'power off')
-        waiters.wait_for_bm_node_status(self.client, self.node['uuid'],
-                                        'power_state', 'power off')
-        instance_uuid = data_utils.rand_uuid()
-        self.client.update_node(self.node['uuid'],
-                                instance_uuid=instance_uuid)
-        self.addCleanup(self.client.update_node,
-                        uuid=self.node['uuid'], instance_uuid=None)
-        return instance_uuid
-
-    @test.idempotent_id('4e939eb2-8a69-4e84-8652-6fffcbc9db8f')
-    def test_create_node(self):
-        params = {'cpu_arch': 'x86_64',
-                  'cpus': '12',
-                  'local_gb': '10',
-                  'memory_mb': '1024'}
-
-        _, body = self.create_node(self.chassis['uuid'], **params)
-        self._assertExpected(params, body['properties'])
-
-    @test.idempotent_id('9ade60a4-505e-4259-9ec4-71352cbbaf47')
-    def test_delete_node(self):
-        _, node = self.create_node(self.chassis['uuid'])
-
-        self.delete_node(node['uuid'])
-
-        self.assertRaises(lib_exc.NotFound, self.client.show_node,
-                          node['uuid'])
-
-    @test.idempotent_id('55451300-057c-4ecf-8255-ba42a83d3a03')
-    def test_show_node(self):
-        _, loaded_node = self.client.show_node(self.node['uuid'])
-        self._assertExpected(self.node, loaded_node)
-
-    @test.idempotent_id('4ca123c4-160d-4d8d-a3f7-15feda812263')
-    def test_list_nodes(self):
-        _, body = self.client.list_nodes()
-        self.assertIn(self.node['uuid'],
-                      [i['uuid'] for i in body['nodes']])
-
-    @test.idempotent_id('85b1f6e0-57fd-424c-aeff-c3422920556f')
-    def test_list_nodes_association(self):
-        _, body = self.client.list_nodes(associated=True)
-        self.assertNotIn(self.node['uuid'],
-                         [n['uuid'] for n in body['nodes']])
-
-        self._associate_node_with_instance()
-
-        _, body = self.client.list_nodes(associated=True)
-        self.assertIn(self.node['uuid'], [n['uuid'] for n in body['nodes']])
-
-        _, body = self.client.list_nodes(associated=False)
-        self.assertNotIn(self.node['uuid'], [n['uuid'] for n in body['nodes']])
-
-    @test.idempotent_id('18c4ebd8-f83a-4df7-9653-9fb33a329730')
-    def test_node_port_list(self):
-        _, port = self.create_port(self.node['uuid'],
-                                   data_utils.rand_mac_address())
-        _, body = self.client.list_node_ports(self.node['uuid'])
-        self.assertIn(port['uuid'],
-                      [p['uuid'] for p in body['ports']])
-
-    @test.idempotent_id('72591acb-f215-49db-8395-710d14eb86ab')
-    def test_node_port_list_no_ports(self):
-        _, node = self.create_node(self.chassis['uuid'])
-        _, body = self.client.list_node_ports(node['uuid'])
-        self.assertEmpty(body['ports'])
-
-    @test.idempotent_id('4fed270a-677a-4d19-be87-fd38ae490320')
-    def test_update_node(self):
-        props = {'cpu_arch': 'x86_64',
-                 'cpus': '12',
-                 'local_gb': '10',
-                 'memory_mb': '128'}
-
-        _, node = self.create_node(self.chassis['uuid'], **props)
-
-        new_p = {'cpu_arch': 'x86',
-                 'cpus': '1',
-                 'local_gb': '10000',
-                 'memory_mb': '12300'}
-
-        _, body = self.client.update_node(node['uuid'], properties=new_p)
-        _, node = self.client.show_node(node['uuid'])
-        self._assertExpected(new_p, node['properties'])
-
-    @test.idempotent_id('cbf1f515-5f4b-4e49-945c-86bcaccfeb1d')
-    def test_validate_driver_interface(self):
-        _, body = self.client.validate_driver_interface(self.node['uuid'])
-        core_interfaces = ['power', 'deploy']
-        for interface in core_interfaces:
-            self.assertIn(interface, body)
-
-    @test.idempotent_id('5519371c-26a2-46e9-aa1a-f74226e9d71f')
-    def test_set_node_boot_device(self):
-        self.client.set_node_boot_device(self.node['uuid'], 'pxe')
-
-    @test.idempotent_id('9ea73775-f578-40b9-bc34-efc639c4f21f')
-    def test_get_node_boot_device(self):
-        body = self.client.get_node_boot_device(self.node['uuid'])
-        self.assertIn('boot_device', body)
-        self.assertIn('persistent', body)
-        self.assertIsInstance(body['boot_device'], six.string_types)
-        self.assertIsInstance(body['persistent'], bool)
-
-    @test.idempotent_id('3622bc6f-3589-4bc2-89f3-50419c66b133')
-    def test_get_node_supported_boot_devices(self):
-        body = self.client.get_node_supported_boot_devices(self.node['uuid'])
-        self.assertIn('supported_boot_devices', body)
-        self.assertIsInstance(body['supported_boot_devices'], list)
-
-    @test.idempotent_id('f63b6288-1137-4426-8cfe-0d5b7eb87c06')
-    def test_get_console(self):
-        _, body = self.client.get_console(self.node['uuid'])
-        con_info = ['console_enabled', 'console_info']
-        for key in con_info:
-            self.assertIn(key, body)
-
-    @test.idempotent_id('80504575-9b21-4670-92d1-143b948f9437')
-    def test_set_console_mode(self):
-        self.client.set_console_mode(self.node['uuid'], True)
-
-        _, body = self.client.get_console(self.node['uuid'])
-        self.assertEqual(True, body['console_enabled'])
-
-    @test.idempotent_id('b02a4f38-5e8b-44b2-aed2-a69a36ecfd69')
-    def test_get_node_by_instance_uuid(self):
-        instance_uuid = self._associate_node_with_instance()
-        _, body = self.client.show_node_by_instance_uuid(instance_uuid)
-        self.assertEqual(len(body['nodes']), 1)
-        self.assertIn(self.node['uuid'], [n['uuid'] for n in body['nodes']])
diff --git a/tempest/api/baremetal/admin/test_nodestates.py b/tempest/api/baremetal/admin/test_nodestates.py
deleted file mode 100644
index e74dd04..0000000
--- a/tempest/api/baremetal/admin/test_nodestates.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# 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 oslo_utils import timeutils
-
-from tempest.api.baremetal.admin import base
-from tempest.lib import exceptions
-from tempest import test
-
-
-class TestNodeStates(base.BaseBaremetalTest):
-    """Tests for baremetal NodeStates."""
-
-    @classmethod
-    def resource_setup(cls):
-        super(TestNodeStates, cls).resource_setup()
-        _, cls.chassis = cls.create_chassis()
-        _, 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:
-            _, node = self.client.show_node(node_uuid)
-            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.idempotent_id('cd8afa5e-3f57-4e43-8185-beb83d3c9015')
-    def test_list_nodestates(self):
-        _, nodestates = self.client.list_nodestates(self.node['uuid'])
-        for key in nodestates:
-            self.assertEqual(nodestates[key], self.node[key])
-
-    @test.idempotent_id('fc5b9320-0c98-4e5a-8848-877fe5a0322c')
-    def test_set_node_power_state(self):
-        _, node = self.create_node(self.chassis['uuid'])
-        states = ["power on", "rebooting", "power off"]
-        for state in states:
-            # Set power state
-            self.client.set_node_power_state(node['uuid'], state)
-            # Check power state after state is set
-            self._validate_power_state(node['uuid'], state)
diff --git a/tempest/api/baremetal/admin/test_ports.py b/tempest/api/baremetal/admin/test_ports.py
deleted file mode 100644
index ce519c1..0000000
--- a/tempest/api/baremetal/admin/test_ports.py
+++ /dev/null
@@ -1,266 +0,0 @@
-#    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 six
-
-from tempest.api.baremetal.admin import base
-from tempest.common.utils import data_utils
-from tempest.lib import exceptions as lib_exc
-from tempest import test
-
-
-class TestPorts(base.BaseBaremetalTest):
-    """Tests for ports."""
-
-    def setUp(self):
-        super(TestPorts, self).setUp()
-
-        _, 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 six.iteritems(expected):
-            if key not in ('created_at', 'updated_at'):
-                self.assertIn(key, actual)
-                self.assertEqual(value, actual[key])
-
-    @test.idempotent_id('83975898-2e50-42ed-b5f0-e510e36a0b56')
-    def test_create_port(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        _, port = self.create_port(node_id=node_id, address=address)
-
-        _, body = self.client.show_port(port['uuid'])
-
-        self._assertExpected(port, body)
-
-    @test.idempotent_id('d1f6b249-4cf6-4fe6-9ed6-a6e84b1bf67b')
-    def test_create_port_specifying_uuid(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        uuid = data_utils.rand_uuid()
-
-        _, port = self.create_port(node_id=node_id,
-                                   address=address, uuid=uuid)
-
-        _, body = self.client.show_port(uuid)
-        self._assertExpected(port, body)
-
-    @test.idempotent_id('4a02c4b0-6573-42a4-a513-2e36ad485b62')
-    def test_create_port_with_extra(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        extra = {'str': 'value', 'int': 123, 'float': 0.123,
-                 'bool': True, 'list': [1, 2, 3], 'dict': {'foo': 'bar'}}
-
-        _, port = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)
-
-        _, body = self.client.show_port(port['uuid'])
-        self._assertExpected(port, body)
-
-    @test.idempotent_id('1bf257a9-aea3-494e-89c0-63f657ab4fdd')
-    def test_delete_port(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        _, port = self.create_port(node_id=node_id, address=address)
-
-        self.delete_port(port['uuid'])
-
-        self.assertRaises(lib_exc.NotFound, self.client.show_port,
-                          port['uuid'])
-
-    @test.idempotent_id('9fa77ab5-ce59-4f05-baac-148904ba1597')
-    def test_show_port(self):
-        _, port = self.client.show_port(self.port['uuid'])
-        self._assertExpected(self.port, port)
-
-    @test.idempotent_id('7c1114ff-fc3f-47bb-bc2f-68f61620ba8b')
-    def test_show_port_by_address(self):
-        _, port = self.client.show_port_by_address(self.port['address'])
-        self._assertExpected(self.port, port['ports'][0])
-
-    @test.idempotent_id('bd773405-aea5-465d-b576-0ab1780069e5')
-    def test_show_port_with_links(self):
-        _, port = self.client.show_port(self.port['uuid'])
-        self.assertIn('links', port.keys())
-        self.assertEqual(2, len(port['links']))
-        self.assertIn(port['uuid'], port['links'][0]['href'])
-
-    @test.idempotent_id('b5e91854-5cd7-4a8e-bb35-3e0a1314606d')
-    def test_list_ports(self):
-        _, body = self.client.list_ports()
-        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'],
-                                    port['links'][0]['href'])
-
-    @test.idempotent_id('324a910e-2f80-4258-9087-062b5ae06240')
-    def test_list_with_limit(self):
-        _, body = self.client.list_ports(limit=3)
-
-        next_marker = body['ports'][-1]['uuid']
-        self.assertIn(next_marker, body['next'])
-
-    @test.idempotent_id('8a94b50f-9895-4a63-a574-7ecff86e5875')
-    def test_list_ports_details(self):
-        node_id = self.node['uuid']
-
-        uuids = [
-            self.create_port(node_id=node_id,
-                             address=data_utils.rand_mac_address())
-            [1]['uuid'] for i in range(0, 5)]
-
-        _, body = self.client.list_ports_detail()
-
-        ports_dict = dict((port['uuid'], port) for port in body['ports']
-                          if port['uuid'] in uuids)
-
-        for uuid in uuids:
-            self.assertIn(uuid, ports_dict)
-            port = ports_dict[uuid]
-            self.assertIn('extra', port)
-            self.assertIn('node_uuid', port)
-            # never expose the node_id
-            self.assertNotIn('node_id', port)
-            # Verify self link.
-            self.validate_self_link('ports', port['uuid'],
-                                    port['links'][0]['href'])
-
-    @test.idempotent_id('8a03f688-7d75-4ecd-8cbc-e06b8f346738')
-    def test_list_ports_details_with_address(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        self.create_port(node_id=node_id, address=address)
-        for i in range(0, 5):
-            self.create_port(node_id=node_id,
-                             address=data_utils.rand_mac_address())
-
-        _, body = self.client.list_ports_detail(address=address)
-        self.assertEqual(1, len(body['ports']))
-        self.assertEqual(address, body['ports'][0]['address'])
-
-    @test.idempotent_id('9c26298b-1bcb-47b7-9b9e-8bdd6e3c4aba')
-    def test_update_port_replace(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        extra = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
-
-        _, port = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)
-
-        new_address = data_utils.rand_mac_address()
-        new_extra = {'key1': 'new-value1', 'key2': 'new-value2',
-                     'key3': 'new-value3'}
-
-        patch = [{'path': '/address',
-                  'op': 'replace',
-                  'value': new_address},
-                 {'path': '/extra/key1',
-                  'op': 'replace',
-                  'value': new_extra['key1']},
-                 {'path': '/extra/key2',
-                  'op': 'replace',
-                  'value': new_extra['key2']},
-                 {'path': '/extra/key3',
-                  'op': 'replace',
-                  'value': new_extra['key3']}]
-
-        self.client.update_port(port['uuid'], patch)
-
-        _, body = self.client.show_port(port['uuid'])
-        self.assertEqual(new_address, body['address'])
-        self.assertEqual(new_extra, body['extra'])
-
-    @test.idempotent_id('d7e7fece-6ed9-460a-9ebe-9267217e8580')
-    def test_update_port_remove(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        extra = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
-
-        _, port = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)
-
-        # Removing one item from the collection
-        self.client.update_port(port['uuid'],
-                                [{'path': '/extra/key2',
-                                 'op': 'remove'}])
-        extra.pop('key2')
-        _, body = self.client.show_port(port['uuid'])
-        self.assertEqual(extra, body['extra'])
-
-        # Removing the collection
-        self.client.update_port(port['uuid'], [{'path': '/extra',
-                                               'op': 'remove'}])
-        _, body = self.client.show_port(port['uuid'])
-        self.assertEqual({}, body['extra'])
-
-        # Assert nothing else was changed
-        self.assertEqual(node_id, body['node_uuid'])
-        self.assertEqual(address, body['address'])
-
-    @test.idempotent_id('241288b3-e98a-400f-a4d7-d1f716146361')
-    def test_update_port_add(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        _, port = self.create_port(node_id=node_id, address=address)
-
-        extra = {'key1': 'value1', 'key2': 'value2'}
-
-        patch = [{'path': '/extra/key1',
-                  'op': 'add',
-                  'value': extra['key1']},
-                 {'path': '/extra/key2',
-                  'op': 'add',
-                  'value': extra['key2']}]
-
-        self.client.update_port(port['uuid'], patch)
-
-        _, body = self.client.show_port(port['uuid'])
-        self.assertEqual(extra, body['extra'])
-
-    @test.idempotent_id('5309e897-0799-4649-a982-0179b04c3876')
-    def test_update_port_mixed_ops(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        extra = {'key1': 'value1', 'key2': 'value2'}
-
-        _, port = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)
-
-        new_address = data_utils.rand_mac_address()
-        new_extra = {'key1': 0.123, 'key3': {'cat': 'meow'}}
-
-        patch = [{'path': '/address',
-                  'op': 'replace',
-                  'value': new_address},
-                 {'path': '/extra/key1',
-                  'op': 'replace',
-                  'value': new_extra['key1']},
-                 {'path': '/extra/key2',
-                  'op': 'remove'},
-                 {'path': '/extra/key3',
-                  'op': 'add',
-                  'value': new_extra['key3']}]
-
-        self.client.update_port(port['uuid'], patch)
-
-        _, body = self.client.show_port(port['uuid'])
-        self.assertEqual(new_address, body['address'])
-        self.assertEqual(new_extra, body['extra'])
diff --git a/tempest/api/baremetal/admin/test_ports_negative.py b/tempest/api/baremetal/admin/test_ports_negative.py
deleted file mode 100644
index 5e3a33f..0000000
--- a/tempest/api/baremetal/admin/test_ports_negative.py
+++ /dev/null
@@ -1,338 +0,0 @@
-#    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.baremetal.admin import base
-from tempest.common.utils import data_utils
-from tempest.lib import exceptions as lib_exc
-from tempest import test
-
-
-class TestPortsNegative(base.BaseBaremetalTest):
-    """Negative tests for ports."""
-
-    def setUp(self):
-        super(TestPortsNegative, self).setUp()
-
-        _, self.chassis = self.create_chassis()
-        _, self.node = self.create_node(self.chassis['uuid'])
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('0a6ee1f7-d0d9-4069-8778-37f3aa07303a')
-    def test_create_port_malformed_mac(self):
-        node_id = self.node['uuid']
-        address = 'malformed:mac'
-
-        self.assertRaises(lib_exc.BadRequest,
-                          self.create_port, node_id=node_id, address=address)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('30277ee8-0c60-4f1d-b125-0e51c2f43369')
-    def test_create_port_nonexsistent_node_id(self):
-        node_id = data_utils.rand_uuid()
-        address = data_utils.rand_mac_address()
-        self.assertRaises(lib_exc.BadRequest, self.create_port,
-                          node_id=node_id, address=address)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('029190f6-43e1-40a3-b64a-65173ba653a3')
-    def test_show_port_malformed_uuid(self):
-        self.assertRaises(lib_exc.BadRequest, self.client.show_port,
-                          'malformed:uuid')
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('0d00e13d-e2e0-45b1-bcbc-55a6d90ca793')
-    def test_show_port_nonexistent_uuid(self):
-        self.assertRaises(lib_exc.NotFound, self.client.show_port,
-                          data_utils.rand_uuid())
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('4ad85266-31e9-4942-99ac-751897dc9e23')
-    def test_show_port_by_mac_not_allowed(self):
-        self.assertRaises(lib_exc.BadRequest, self.client.show_port,
-                          data_utils.rand_mac_address())
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('89a34380-3c61-4c32-955c-2cd9ce94da21')
-    def test_create_port_duplicated_port_uuid(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        uuid = data_utils.rand_uuid()
-
-        self.create_port(node_id=node_id, address=address, uuid=uuid)
-        self.assertRaises(lib_exc.Conflict, self.create_port, node_id=node_id,
-                          address=address, uuid=uuid)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('65e84917-733c-40ae-ae4b-96a4adff931c')
-    def test_create_port_no_mandatory_field_node_id(self):
-        address = data_utils.rand_mac_address()
-
-        self.assertRaises(lib_exc.BadRequest, self.create_port, node_id=None,
-                          address=address)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('bcea3476-7033-4183-acfe-e56a30809b46')
-    def test_create_port_no_mandatory_field_mac(self):
-        node_id = self.node['uuid']
-
-        self.assertRaises(lib_exc.BadRequest, self.create_port,
-                          node_id=node_id, address=None)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('2b51cd18-fb95-458b-9780-e6257787b649')
-    def test_create_port_malformed_port_uuid(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        uuid = 'malformed:uuid'
-
-        self.assertRaises(lib_exc.BadRequest, self.create_port,
-                          node_id=node_id, address=address, uuid=uuid)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('583a6856-6a30-4ac4-889f-14e2adff8105')
-    def test_create_port_malformed_node_id(self):
-        address = data_utils.rand_mac_address()
-        self.assertRaises(lib_exc.BadRequest, self.create_port,
-                          node_id='malformed:nodeid', address=address)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('e27f8b2e-42c6-4a43-a3cd-accff716bc5c')
-    def test_create_port_duplicated_mac(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        self.create_port(node_id=node_id, address=address)
-        self.assertRaises(lib_exc.Conflict,
-                          self.create_port, node_id=node_id,
-                          address=address)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('8907082d-ac5e-4be3-b05f-d072ede82020')
-    def test_update_port_by_mac_not_allowed(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        extra = {'key': 'value'}
-
-        self.create_port(node_id=node_id, address=address, extra=extra)
-
-        patch = [{'path': '/extra/key',
-                  'op': 'replace',
-                  'value': 'new-value'}]
-
-        self.assertRaises(lib_exc.BadRequest,
-                          self.client.update_port, address,
-                          patch)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('df1ac70c-db9f-41d9-90f1-78cd6b905718')
-    def test_update_port_nonexistent(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        extra = {'key': 'value'}
-
-        _, port = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)
-        port_id = port['uuid']
-
-        _, body = self.client.delete_port(port_id)
-
-        patch = [{'path': '/extra/key',
-                  'op': 'replace',
-                  'value': 'new-value'}]
-        self.assertRaises(lib_exc.NotFound,
-                          self.client.update_port, port_id, patch)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('c701e315-aa52-41ea-817c-65c5ca8ca2a8')
-    def test_update_port_malformed_port_uuid(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        self.create_port(node_id=node_id, address=address)
-
-        new_address = data_utils.rand_mac_address()
-        self.assertRaises(lib_exc.BadRequest, self.client.update_port,
-                          uuid='malformed:uuid',
-                          patch=[{'path': '/address', 'op': 'replace',
-                                  'value': new_address}])
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('f8f15803-34d6-45dc-b06f-e5e04bf1b38b')
-    def test_update_port_add_nonexistent_property(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        _, port = self.create_port(node_id=node_id, address=address)
-        port_id = port['uuid']
-
-        self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
-                          [{'path': '/nonexistent', ' op': 'add',
-                            'value': 'value'}])
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('898ec904-38b1-4fcb-9584-1187d4263a2a')
-    def test_update_port_replace_node_id_with_malformed(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        _, port = self.create_port(node_id=node_id, address=address)
-        port_id = port['uuid']
-
-        patch = [{'path': '/node_uuid',
-                  'op': 'replace',
-                  'value': 'malformed:node_uuid'}]
-        self.assertRaises(lib_exc.BadRequest,
-                          self.client.update_port, port_id, patch)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('2949f30f-5f59-43fa-a6d9-4eac578afab4')
-    def test_update_port_replace_mac_with_duplicated(self):
-        node_id = self.node['uuid']
-        address1 = data_utils.rand_mac_address()
-        address2 = data_utils.rand_mac_address()
-
-        _, port1 = self.create_port(node_id=node_id, address=address1)
-
-        _, port2 = self.create_port(node_id=node_id, address=address2)
-        port_id = port2['uuid']
-
-        patch = [{'path': '/address',
-                  'op': 'replace',
-                  'value': address1}]
-        self.assertRaises(lib_exc.Conflict,
-                          self.client.update_port, port_id, patch)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('97f6e048-6e4f-4eba-a09d-fbbc78b77a77')
-    def test_update_port_replace_node_id_with_nonexistent(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        _, port = self.create_port(node_id=node_id, address=address)
-        port_id = port['uuid']
-
-        patch = [{'path': '/node_uuid',
-                  'op': 'replace',
-                  'value': data_utils.rand_uuid()}]
-        self.assertRaises(lib_exc.BadRequest,
-                          self.client.update_port, port_id, patch)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('375022c5-9e9e-4b11-9ca4-656729c0c9b2')
-    def test_update_port_replace_mac_with_malformed(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        _, port = self.create_port(node_id=node_id, address=address)
-        port_id = port['uuid']
-
-        patch = [{'path': '/address',
-                  'op': 'replace',
-                  'value': 'malformed:mac'}]
-
-        self.assertRaises(lib_exc.BadRequest,
-                          self.client.update_port, port_id, patch)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('5722b853-03fc-4854-8308-2036a1b67d85')
-    def test_update_port_replace_nonexistent_property(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        _, port = self.create_port(node_id=node_id, address=address)
-        port_id = port['uuid']
-
-        patch = [{'path': '/nonexistent', ' op': 'replace', 'value': 'value'}]
-
-        self.assertRaises(lib_exc.BadRequest,
-                          self.client.update_port, port_id, patch)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('ae2696ca-930a-4a7f-918f-30ae97c60f56')
-    def test_update_port_remove_mandatory_field_mac(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        _, port = self.create_port(node_id=node_id, address=address)
-        port_id = port['uuid']
-
-        self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
-                          [{'path': '/address', 'op': 'remove'}])
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('5392c1f0-2071-4697-9064-ec2d63019018')
-    def test_update_port_remove_mandatory_field_port_uuid(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        _, port = self.create_port(node_id=node_id, address=address)
-        port_id = port['uuid']
-
-        self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
-                          [{'path': '/uuid', 'op': 'remove'}])
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('06b50d82-802a-47ef-b079-0a3311cf85a2')
-    def test_update_port_remove_nonexistent_property(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        _, port = self.create_port(node_id=node_id, address=address)
-        port_id = port['uuid']
-
-        self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
-                          [{'path': '/nonexistent', 'op': 'remove'}])
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('03d42391-2145-4a6c-95bf-63fe55eb64fd')
-    def test_delete_port_by_mac_not_allowed(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-
-        self.create_port(node_id=node_id, address=address)
-        self.assertRaises(lib_exc.BadRequest, self.client.delete_port, address)
-
-    @test.attr(type=['negative'])
-    @test.idempotent_id('0629e002-818e-4763-b25b-ae5e07b1cb23')
-    def test_update_port_mixed_ops_integrity(self):
-        node_id = self.node['uuid']
-        address = data_utils.rand_mac_address()
-        extra = {'key1': 'value1', 'key2': 'value2'}
-
-        _, port = self.create_port(node_id=node_id, address=address,
-                                   extra=extra)
-        port_id = port['uuid']
-
-        new_address = data_utils.rand_mac_address()
-        new_extra = {'key1': 'new-value1', 'key3': 'new-value3'}
-
-        patch = [{'path': '/address',
-                  'op': 'replace',
-                  'value': new_address},
-                 {'path': '/extra/key1',
-                  'op': 'replace',
-                  'value': new_extra['key1']},
-                 {'path': '/extra/key2',
-                  'op': 'remove'},
-                 {'path': '/extra/key3',
-                  'op': 'add',
-                  'value': new_extra['key3']},
-                 {'path': '/nonexistent',
-                  'op': 'replace',
-                  'value': 'value'}]
-
-        self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
-                          patch)
-
-        # patch should not be applied
-        _, body = self.client.show_port(port_id)
-        self.assertEqual(address, body['address'])
-        self.assertEqual(extra, body['extra'])
diff --git a/tempest/api/compute/admin/test_agents.py b/tempest/api/compute/admin/test_agents.py
index 40cb523..1c37cad 100644
--- a/tempest/api/compute/admin/test_agents.py
+++ b/tempest/api/compute/admin/test_agents.py
@@ -12,14 +12,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from oslo_log import log
-
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import test
 
-LOG = log.getLogger(__name__)
-
 
 class AgentsAdminTestJSON(base.BaseV2ComputeAdminTest):
     """Tests Agents API"""
diff --git a/tempest/api/compute/admin/test_baremetal_nodes.py b/tempest/api/compute/admin/test_baremetal_nodes.py
index b764483..722d9a6 100644
--- a/tempest/api/compute/admin/test_baremetal_nodes.py
+++ b/tempest/api/compute/admin/test_baremetal_nodes.py
@@ -25,7 +25,7 @@
     @classmethod
     def resource_setup(cls):
         super(BaremetalNodesAdminTestJSON, cls).resource_setup()
-        if not CONF.service_available.ironic:
+        if not getattr(CONF.service_available, 'ironic', False):
             skip_msg = ('%s skipped as Ironic is not available' % cls.__name__)
             raise cls.skipException(skip_msg)
         cls.client = cls.os_adm.baremetal_nodes_client
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
index c9ba730..2dd2e89 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -31,7 +31,6 @@
         super(MigrationsAdminTest, cls).setup_clients()
         cls.client = cls.os_adm.migrations_client
         cls.flavors_admin_client = cls.os_adm.flavors_client
-        cls.admin_hosts_client = cls.os_adm.hosts_client
         cls.admin_servers_client = cls.os_adm.servers_client
 
     @test.idempotent_id('75c0b83d-72a0-4cf8-a153-631e83e7d53f')
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index efa55d5..a8a8b83 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -29,7 +29,6 @@
         super(ServersAdminTestJSON, cls).setup_clients()
         cls.client = cls.os_adm.servers_client
         cls.non_admin_client = cls.servers_client
-        cls.flavors_client = cls.os_adm.flavors_client
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 19e2880..0b4a2a8 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from oslo_log import log as logging
-
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest.common import waiters
@@ -23,7 +21,6 @@
 from tempest import test
 
 CONF = config.CONF
-LOG = logging.getLogger(__name__)
 
 
 class ImagesOneServerTestJSON(base.BaseV2ComputeTest):
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 690bef2..2dcacb7 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -294,7 +294,7 @@
             self.validation_resources['keypair']['private_key'],
             server=server_no_eph_disk,
             servers_client=self.client)
-        partition_num = len(linux_client.get_partitions().split('\n'))
+        disks_num = len(linux_client.get_disks().split('\n'))
 
         # Explicit server deletion necessary for Juno compatibility
         self.client.delete_server(server_no_eph_disk['id'])
@@ -314,8 +314,8 @@
             self.validation_resources['keypair']['private_key'],
             server=server_with_eph_disk,
             servers_client=self.client)
-        partition_num_emph = len(linux_client.get_partitions().split('\n'))
-        self.assertEqual(partition_num + 1, partition_num_emph)
+        disks_num_eph = len(linux_client.get_disks().split('\n'))
+        self.assertEqual(disks_num + 1, disks_num_eph)
 
 
 class ServersTestManualDisk(ServersTestJSON):
diff --git a/tempest/api/compute/servers/test_device_tagging.py b/tempest/api/compute/servers/test_device_tagging.py
index 7252e1b..b2d5ae7 100644
--- a/tempest/api/compute/servers/test_device_tagging.py
+++ b/tempest/api/compute/servers/test_device_tagging.py
@@ -52,9 +52,7 @@
         super(DeviceTaggingTest, cls).setup_clients()
         cls.networks_client = cls.os.networks_client
         cls.ports_client = cls.os.ports_client
-        cls.volumes_client = cls.os.volumes_client
         cls.subnets_client = cls.os.subnets_client
-        cls.routers_client = cls.os.routers_client
         cls.interfaces_client = cls.os.interfaces_client
 
     @classmethod
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 5a35b4e..3e408d2 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -40,14 +40,9 @@
             srv = cls.create_test_server(wait_until='ACTIVE')
             cls.existing_fixtures.append(srv)
 
-        srv = cls.create_test_server()
+        srv = cls.create_test_server(wait_until='ACTIVE')
         cls.client.delete_server(srv['id'])
-        # We ignore errors on termination because the server may
-        # be put into ERROR status on a quick spawn, then delete,
-        # as the compute node expects the instance local status
-        # to be spawning, not deleted. See LP Bug#1061167
-        waiters.wait_for_server_termination(cls.client, srv['id'],
-                                            ignore_error=True)
+        waiters.wait_for_server_termination(cls.client, srv['id'])
         cls.deleted_fixtures.append(srv)
 
     @test.attr(type=['negative'])
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 56ec8c6..1edadef 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -111,9 +111,9 @@
                 server=server,
                 servers_client=self.servers_client)
 
-            partitions = linux_client.get_partitions()
-            device_name_to_match = ' ' + self.device + '\n'
-            self.assertIn(device_name_to_match, partitions)
+            disks = linux_client.get_disks()
+            device_name_to_match = '\n' + self.device + ' '
+            self.assertIn(device_name_to_match, disks)
 
         self._detach_volume(server['id'], attachment['volumeId'])
         self.servers_client.stop_server(server['id'])
@@ -133,8 +133,8 @@
                 server=server,
                 servers_client=self.servers_client)
 
-            partitions = linux_client.get_partitions()
-            self.assertNotIn(device_name_to_match, partitions)
+            disks = linux_client.get_disks()
+            self.assertNotIn(device_name_to_match, disks)
 
     @test.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
     def test_list_get_volume_attachments(self):
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index e4e625b..82cc653 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -13,14 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from oslo_log import log as logging
-
 from tempest.api.compute import base
 from tempest import config
 from tempest import test
 
 CONF = config.CONF
-LOG = logging.getLogger(__name__)
 
 
 class VolumesTestJSON(base.BaseV2ComputeTest):
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index fd2683e..3ec4ff1 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -15,11 +15,17 @@
 
 import time
 
+import testtools
+
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
+from tempest import config
 from tempest import test
 
 
+CONF = config.CONF
+
+
 class UsersV3TestJSON(base.BaseIdentityV3AdminTest):
 
     @test.idempotent_id('b537d090-afb9-4519-b95d-270b0708e87e')
@@ -152,3 +158,30 @@
         user = self.setup_test_user()
         fetched_user = self.users_client.show_user(user['id'])['user']
         self.assertEqual(user['id'], fetched_user['id'])
+
+    @testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
+                          'Security compliance not available.')
+    @test.idempotent_id('568cd46c-ee6c-4ab4-a33a-d3791931979e')
+    def test_password_history_not_enforced_in_admin_reset(self):
+        old_password = self.os.credentials.password
+        user_id = self.os.credentials.user_id
+
+        new_password = data_utils.rand_password()
+        self.users_client.update_user(user_id, password=new_password)
+        # To be safe, we add this cleanup to restore the original password in
+        # case something goes wrong before it is restored later.
+        self.addCleanup(
+            self.users_client.update_user, user_id, password=old_password)
+
+        # Check authorization with new password
+        self.token.auth(user_id=user_id, password=new_password)
+
+        if CONF.identity.user_unique_last_password_count > 1:
+            # The password history is not enforced via the admin reset route.
+            # We can set the same password.
+            self.users_client.update_user(user_id, password=new_password)
+
+        # Restore original password
+        self.users_client.update_user(user_id, password=old_password)
+        # Check authorization with old password
+        self.token.auth(user_id=user_id, password=old_password)
diff --git a/tempest/api/identity/v2/test_users.py b/tempest/api/identity/v2/test_users.py
index 33d212c..bafb1f2 100644
--- a/tempest/api/identity/v2/test_users.py
+++ b/tempest/api/identity/v2/test_users.py
@@ -16,11 +16,15 @@
 import time
 
 from tempest.api.identity import base
+from tempest import config
 from tempest.lib.common.utils import data_utils
 from tempest.lib import exceptions
 from tempest import test
 
 
+CONF = config.CONF
+
+
 class IdentityUsersTest(base.BaseIdentityV2Test):
 
     @classmethod
@@ -31,36 +35,10 @@
         cls.password = cls.creds.password
         cls.tenant_name = cls.creds.tenant_name
 
-    @test.idempotent_id('165859c9-277f-4124-9479-a7d1627b0ca7')
-    def test_user_update_own_password(self):
-
-        def _restore_password(client, user_id, old_pass, new_pass):
-            # Reset auth to get a new token with the new password
-            client.auth_provider.clear_auth()
-            client.auth_provider.credentials.password = new_pass
-            client.update_user_own_password(user_id, password=old_pass,
-                                            original_password=new_pass)
-            # Reset auth again to verify the password restore does work.
-            # Clear auth restores the original credentials and deletes
-            # cached auth data
-            client.auth_provider.clear_auth()
-            # NOTE(lbragstad): Fernet tokens are not subsecond aware and
-            # Keystone should only be precise to the second. Sleep to ensure we
-            # are passing the second boundary before attempting to
-            # authenticate.
-            time.sleep(1)
-            client.auth_provider.set_auth()
-
-        old_pass = self.creds.password
-        new_pass = data_utils.rand_password()
-        user_id = self.creds.user_id
-        # to change password back. important for allow_tenant_isolation = false
-        self.addCleanup(_restore_password, self.non_admin_users_client,
-                        user_id, old_pass=old_pass, new_pass=new_pass)
-
-        # user updates own password
+    def _update_password(self, user_id, original_password, password):
         self.non_admin_users_client.update_user_own_password(
-            user_id, password=new_pass, original_password=old_pass)
+            user_id, password=password, original_password=original_password)
+
         # NOTE(morganfainberg): Fernet tokens are not subsecond aware and
         # Keystone should only be precise to the second. Sleep to ensure
         # we are passing the second boundary.
@@ -68,13 +46,55 @@
 
         # check authorization with new password
         self.non_admin_token_client.auth(self.username,
-                                         new_pass,
+                                         password,
                                          self.tenant_name)
 
+        # Reset auth to get a new token with the new password
+        self.non_admin_users_client.auth_provider.clear_auth()
+        self.non_admin_users_client.auth_provider.credentials.password = (
+            password)
+
+    def _restore_password(self, user_id, old_pass, new_pass):
+        if CONF.identity_feature_enabled.security_compliance:
+            # First we need to clear the password history
+            unique_count = CONF.identity.user_unique_last_password_count
+            for i in range(unique_count):
+                random_pass = data_utils.rand_password()
+                self._update_password(
+                    user_id, original_password=new_pass, password=random_pass)
+                new_pass = random_pass
+
+        self._update_password(
+            user_id, original_password=new_pass, password=old_pass)
+        # Reset auth again to verify the password restore does work.
+        # Clear auth restores the original credentials and deletes
+        # cached auth data
+        self.non_admin_users_client.auth_provider.clear_auth()
+        # NOTE(lbragstad): Fernet tokens are not subsecond aware and
+        # Keystone should only be precise to the second. Sleep to ensure we
+        # are passing the second boundary before attempting to
+        # authenticate.
+        time.sleep(1)
+        self.non_admin_users_client.auth_provider.set_auth()
+
+    @test.idempotent_id('165859c9-277f-4124-9479-a7d1627b0ca7')
+    def test_user_update_own_password(self):
+        old_pass = self.creds.password
+        old_token = self.non_admin_users_client.token
+        new_pass = data_utils.rand_password()
+        user_id = self.creds.user_id
+
+        # to change password back. important for allow_tenant_isolation = false
+        self.addCleanup(self._restore_password, user_id, old_pass, new_pass)
+
+        # user updates own password
+        self._update_password(
+            user_id, original_password=old_pass, password=new_pass)
+
         # authorize with old token should lead to Unauthorized
         self.assertRaises(exceptions.Unauthorized,
                           self.non_admin_token_client.auth_token,
-                          self.non_admin_users_client.token)
+                          old_token)
 
         # authorize with old password should lead to Unauthorized
         self.assertRaises(exceptions.Unauthorized,
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
index 1a38f3a..f5b357c 100644
--- a/tempest/api/identity/v3/test_users.py
+++ b/tempest/api/identity/v3/test_users.py
@@ -15,12 +15,18 @@
 
 import time
 
+import testtools
+
 from tempest.api.identity import base
+from tempest import config
 from tempest.lib.common.utils import data_utils
 from tempest.lib import exceptions
 from tempest import test
 
 
+CONF = config.CONF
+
+
 class IdentityV3UsersTest(base.BaseIdentityV3Test):
 
     @classmethod
@@ -31,36 +37,11 @@
         cls.username = cls.creds.username
         cls.password = cls.creds.password
 
-    @test.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
-    def test_user_update_own_password(self):
-
-        def _restore_password(client, user_id, old_pass, new_pass):
-            # Reset auth to get a new token with the new password
-            client.auth_provider.clear_auth()
-            client.auth_provider.credentials.password = new_pass
-            client.update_user_password(user_id, password=old_pass,
-                                        original_password=new_pass)
-            # Reset auth again to verify the password restore does work.
-            # Clear auth restores the original credentials and deletes
-            # cached auth data
-            client.auth_provider.clear_auth()
-            # NOTE(lbragstad): Fernet tokens are not subsecond aware and
-            # Keystone should only be precise to the second. Sleep to ensure we
-            # are passing the second boundary before attempting to
-            # authenticate.
-            time.sleep(1)
-            client.auth_provider.set_auth()
-
-        old_pass = self.creds.password
-        new_pass = data_utils.rand_password()
-        user_id = self.creds.user_id
-        # to change password back. important for allow_tenant_isolation = false
-        self.addCleanup(_restore_password, self.non_admin_users_client,
-                        user_id, old_pass=old_pass, new_pass=new_pass)
-
-        # user updates own password
+    def _update_password(self, original_password, password):
         self.non_admin_users_client.update_user_password(
-            user_id, password=new_pass, original_password=old_pass)
+            self.user_id,
+            password=password,
+            original_password=original_password)
 
         # NOTE(morganfainberg): Fernet tokens are not subsecond aware and
         # Keystone should only be precise to the second. Sleep to ensure
@@ -68,15 +49,112 @@
         time.sleep(1)
 
         # check authorization with new password
-        self.non_admin_token.auth(user_id=self.user_id, password=new_pass)
+        self.non_admin_token.auth(user_id=self.user_id, password=password)
+
+        # Reset auth to get a new token with the new password
+        self.non_admin_users_client.auth_provider.clear_auth()
+        self.non_admin_users_client.auth_provider.credentials.password = (
+            password)
+
+    def _restore_password(self, old_pass, new_pass):
+        if CONF.identity_feature_enabled.security_compliance:
+            # First we need to clear the password history
+            unique_count = CONF.identity.user_unique_last_password_count
+            for i in range(unique_count):
+                random_pass = data_utils.rand_password()
+                self._update_password(
+                    original_password=new_pass, password=random_pass)
+                new_pass = random_pass
+
+        self._update_password(original_password=new_pass, password=old_pass)
+        # Reset auth again to verify the password restore does work.
+        # Clear auth restores the original credentials and deletes
+        # cached auth data
+        self.non_admin_users_client.auth_provider.clear_auth()
+        # NOTE(lbragstad): Fernet tokens are not subsecond aware and
+        # Keystone should only be precise to the second. Sleep to ensure we
+        # are passing the second boundary before attempting to
+        # authenticate.
+        time.sleep(1)
+        self.non_admin_users_client.auth_provider.set_auth()
+
+    @test.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
+    def test_user_update_own_password(self):
+        old_pass = self.creds.password
+        old_token = self.non_admin_client.token
+        new_pass = data_utils.rand_password()
+
+        # to change password back. important for allow_tenant_isolation = false
+        self.addCleanup(self._restore_password, old_pass, new_pass)
+
+        # user updates own password
+        self._update_password(original_password=old_pass, password=new_pass)
 
         # authorize with old token should lead to IdentityError (404 code)
         self.assertRaises(exceptions.IdentityError,
                           self.non_admin_token.auth,
-                          token=self.non_admin_client.token)
+                          token=old_token)
 
         # authorize with old password should lead to Unauthorized
         self.assertRaises(exceptions.Unauthorized,
                           self.non_admin_token.auth,
                           user_id=self.user_id,
                           password=old_pass)
+
+    @testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
+                          'Security compliance not available.')
+    @test.idempotent_id('941784ee-5342-4571-959b-b80dd2cea516')
+    def test_password_history_check_self_service_api(self):
+        old_pass = self.creds.password
+        new_pass1 = data_utils.rand_password()
+        new_pass2 = data_utils.rand_password()
+
+        self.addCleanup(self._restore_password, old_pass, new_pass2)
+
+        # Update password
+        self._update_password(original_password=old_pass, password=new_pass1)
+
+        if CONF.identity.user_unique_last_password_count > 1:
+            # Can not reuse a previously set password
+            self.assertRaises(exceptions.BadRequest,
+                              self.non_admin_users_client.update_user_password,
+                              self.user_id,
+                              password=new_pass1,
+                              original_password=new_pass1)
+
+            self.assertRaises(exceptions.BadRequest,
+                              self.non_admin_users_client.update_user_password,
+                              self.user_id,
+                              password=old_pass,
+                              original_password=new_pass1)
+
+        # A different password can be set
+        self._update_password(original_password=new_pass1, password=new_pass2)
+
+    @testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
+                          'Security compliance not available.')
+    @test.idempotent_id('a7ad8bbf-2cff-4520-8c1d-96332e151658')
+    def test_user_account_lockout(self):
+        password = self.creds.password
+
+        # First, we login using the correct credentials
+        self.non_admin_token.auth(user_id=self.user_id, password=password)
+
+        # Lock user account by using the wrong password to login
+        bad_password = data_utils.rand_password()
+        for i in range(CONF.identity.user_lockout_failure_attempts):
+            self.assertRaises(exceptions.Unauthorized,
+                              self.non_admin_token.auth,
+                              user_id=self.user_id,
+                              password=bad_password)
+
+        # The user account must be locked, so now it is not possible to login
+        # even using the correct password
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_token.auth,
+                          user_id=self.user_id,
+                          password=password)
+
+        # If we wait the required time, the user account will be unlocked
+        time.sleep(CONF.identity.user_lockout_duration + 1)
+        self.token.auth(user_id=self.user_id, password=password)
diff --git a/tempest/api/network/test_service_providers.py b/tempest/api/network/test_service_providers.py
index 09fb5fe..be17b3e 100644
--- a/tempest/api/network/test_service_providers.py
+++ b/tempest/api/network/test_service_providers.py
@@ -10,6 +10,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest.api.network import base
 from tempest import test
 
@@ -17,6 +19,9 @@
 class ServiceProvidersTest(base.BaseNetworkTest):
 
     @test.idempotent_id('2cbbeea9-f010-40f6-8df5-4eaa0c918ea6')
+    @testtools.skipUnless(
+        test.is_extension_enabled('service-type', 'network'),
+        'service-type extension not enabled.')
     def test_service_providers_list(self):
         body = self.service_providers_client.list_service_providers()
         self.assertIn('service_providers', body)
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 261e652..a63cbf0 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -14,27 +14,11 @@
 #    under the License.
 
 from tempest.api.volume import base
-from tempest import config
 from tempest import test
 
-CONF = config.CONF
-
 
 class VolumesActionsV2Test(base.BaseVolumeAdminTest):
 
-    @classmethod
-    def resource_setup(cls):
-        super(VolumesActionsV2Test, cls).resource_setup()
-
-        # Create a test shared volume for tests
-        cls.volume = cls.create_volume()
-
-    def tearDown(self):
-        # Set volume's status to available after test
-        self.admin_volume_client.reset_volume_status(
-            self.volume['id'], status='available')
-        super(VolumesActionsV2Test, self).tearDown()
-
     def _create_reset_and_force_delete_temp_volume(self, status=None):
         # Create volume, reset volume status, and force delete temp volume
         temp_volume = self.create_volume()
@@ -47,11 +31,13 @@
     @test.idempotent_id('d063f96e-a2e0-4f34-8b8a-395c42de1845')
     def test_volume_reset_status(self):
         # test volume reset status : available->error->available
-        self.admin_volume_client.reset_volume_status(
-            self.volume['id'], status='error')
-        volume_get = self.admin_volume_client.show_volume(
-            self.volume['id'])['volume']
-        self.assertEqual('error', volume_get['status'])
+        volume = self.create_volume()
+        for status in ['error', 'available']:
+            self.admin_volume_client.reset_volume_status(
+                volume['id'], status=status)
+            volume_get = self.admin_volume_client.show_volume(
+                volume['id'])['volume']
+            self.assertEqual(status, volume_get['status'])
 
     @test.idempotent_id('21737d5a-92f2-46d7-b009-a0cc0ee7a570')
     def test_volume_force_delete_when_volume_is_creating(self):
diff --git a/tempest/api/volume/admin/v2/test_volume_pools.py b/tempest/api/volume/admin/v2/test_volume_pools.py
index e460278..8544a6a 100644
--- a/tempest/api/volume/admin/v2/test_volume_pools.py
+++ b/tempest/api/volume/admin/v2/test_volume_pools.py
@@ -25,19 +25,18 @@
         # Create a test shared volume for tests
         cls.volume = cls.create_volume()
 
-    @test.idempotent_id('0248a46c-e226-4933-be10-ad6fca8227e7')
-    def test_get_pools_without_details(self):
-        volume_info = self.admin_volume_client. \
-            show_volume(self.volume['id'])['volume']
-        cinder_pools = self.admin_scheduler_stats_client.list_pools()['pools']
+    def _assert_host_volume_in_pools(self, with_detail=False):
+        volume_info = self.admin_volume_client.show_volume(
+            self.volume['id'])['volume']
+        cinder_pools = self.admin_volume_client.show_pools(
+            detail=with_detail)['pools']
         self.assertIn(volume_info['os-vol-host-attr:host'],
                       [pool['name'] for pool in cinder_pools])
 
+    @test.idempotent_id('0248a46c-e226-4933-be10-ad6fca8227e7')
+    def test_get_pools_without_details(self):
+        self._assert_host_volume_in_pools()
+
     @test.idempotent_id('d4bb61f7-762d-4437-b8a4-5785759a0ced')
     def test_get_pools_with_details(self):
-        volume_info = self.admin_volume_client. \
-            show_volume(self.volume['id'])['volume']
-        cinder_pools = self.admin_scheduler_stats_client.\
-            list_pools(detail=True)['pools']
-        self.assertIn(volume_info['os-vol-host-attr:host'],
-                      [pool['name'] for pool in cinder_pools])
+        self._assert_host_volume_in_pools(with_detail=True)
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 7cd72e1..9f522bd 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -181,7 +181,7 @@
         self.addCleanup(waiters.wait_for_volume_status, self.volumes_client,
                         volume_id, 'available')
         self.addCleanup(self.servers_client.detach_volume, server_id,
-                        self.volume_origin['id'])
+                        volume_id)
 
     @classmethod
     def clear_volumes(cls):
diff --git a/tempest/api/volume/test_volumes_backup.py b/tempest/api/volume/test_volumes_backup.py
index 972dd58..70b3c58 100644
--- a/tempest/api/volume/test_volumes_backup.py
+++ b/tempest/api/volume/test_volumes_backup.py
@@ -30,6 +30,22 @@
         if not CONF.volume_feature_enabled.backup:
             raise cls.skipException("Cinder backup feature disabled")
 
+    def restore_backup(self, backup_id):
+        # Restore a backup
+        restored_volume = self.backups_client.restore_backup(
+            backup_id)['restore']
+
+        # Delete backup
+        self.addCleanup(self.volumes_client.delete_volume,
+                        restored_volume['volume_id'])
+        self.assertEqual(backup_id, restored_volume['backup_id'])
+        waiters.wait_for_backup_status(self.backups_client,
+                                       backup_id, 'available')
+        waiters.wait_for_volume_status(self.volumes_client,
+                                       restored_volume['volume_id'],
+                                       'available')
+        return restored_volume
+
     @test.idempotent_id('a66eb488-8ee1-47d4-8e9f-575a095728c6')
     def test_volume_backup_create_get_detailed_list_restore_delete(self):
         # Create backup
@@ -38,8 +54,10 @@
                         volume['id'])
         backup_name = data_utils.rand_name(
             self.__class__.__name__ + '-Backup')
+        description = data_utils.rand_name("volume-backup-description")
         backup = self.create_backup(volume_id=volume['id'],
-                                    name=backup_name)
+                                    name=backup_name,
+                                    description=description)
         self.assertEqual(backup_name, backup['name'])
         waiters.wait_for_volume_status(self.volumes_client,
                                        volume['id'], 'available')
@@ -47,6 +65,7 @@
         # Get a given backup
         backup = self.backups_client.show_backup(backup['id'])['backup']
         self.assertEqual(backup_name, backup['name'])
+        self.assertEqual(description, backup['description'])
 
         # Get all backups with detail
         backups = self.backups_client.list_backups(
@@ -54,18 +73,7 @@
         self.assertIn((backup['name'], backup['id']),
                       [(m['name'], m['id']) for m in backups])
 
-        # Restore backup
-        restore = self.backups_client.restore_backup(
-            backup['id'])['restore']
-
-        # Delete backup
-        self.addCleanup(self.volumes_client.delete_volume,
-                        restore['volume_id'])
-        self.assertEqual(backup['id'], restore['backup_id'])
-        waiters.wait_for_backup_status(self.backups_client,
-                                       backup['id'], 'available')
-        waiters.wait_for_volume_status(self.volumes_client,
-                                       restore['volume_id'], 'available')
+        self.restore_backup(backup['id'])
 
     @test.idempotent_id('07af8f6d-80af-44c9-a5dc-c8427b1b62e6')
     @test.services('compute')
@@ -96,6 +104,28 @@
                                     name=backup_name, force=True)
         self.assertEqual(backup_name, backup['name'])
 
+    @test.idempotent_id('2a8ba340-dff2-4511-9db7-646f07156b15')
+    def test_bootable_volume_backup_and_restore(self):
+        # Create volume from image
+        img_uuid = CONF.compute.image_ref
+        volume = self.create_volume(imageRef=img_uuid)
+
+        volume_details = self.volumes_client.show_volume(
+            volume['id'])['volume']
+        self.assertEqual('true', volume_details['bootable'])
+
+        # Create a backup
+        backup = self.create_backup(volume_id=volume['id'])
+
+        # Restore the backup
+        restored_volume_id = self.restore_backup(backup['id'])['volume_id']
+
+        # Verify the restored backup volume is bootable
+        restored_volume_info = self.volumes_client.show_volume(
+            restored_volume_id)['volume']
+
+        self.assertEqual('true', restored_volume_info['bootable'])
+
 
 class VolumesBackupsV1Test(VolumesBackupsV2Test):
     _api_version = 1
diff --git a/tempest/clients.py b/tempest/clients.py
index 4a30f6f..1ab7cfe 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -21,7 +21,6 @@
 from tempest.lib import auth
 from tempest.lib import exceptions as lib_exc
 from tempest.lib.services import clients
-from tempest.services import baremetal
 from tempest.services import identity
 from tempest.services import object_storage
 from tempest.services import orchestration
@@ -35,14 +34,6 @@
 
     default_params = config.service_client_config()
 
-    # TODO(andreaf) This is only used by baremetal clients,
-    # and should be removed once they are out of Tempest
-    default_params_with_timeout_values = {
-        'build_interval': CONF.compute.build_interval,
-        'build_timeout': CONF.compute.build_timeout
-    }
-    default_params_with_timeout_values.update(default_params)
-
     def __init__(self, credentials, service=None, scope='project'):
         """Initialization of Manager class.
 
@@ -66,12 +57,6 @@
         self._set_image_clients()
         self._set_network_clients()
 
-        self.baremetal_client = baremetal.BaremetalClient(
-            self.auth_provider,
-            CONF.baremetal.catalog_type,
-            CONF.identity.region,
-            endpoint_type=CONF.baremetal.endpoint_type,
-            **self.default_params_with_timeout_values)
         self.orchestration_client = orchestration.OrchestrationClient(
             self.auth_provider,
             CONF.orchestration.catalog_type,
@@ -177,7 +162,6 @@
         self.instance_usages_audit_log_client = (
             self.compute.InstanceUsagesAuditLogClient())
         self.tenant_networks_client = self.compute.TenantNetworksClient()
-        self.baremetal_nodes_client = self.compute.BaremetalNodesClient()
 
         # NOTE: The following client needs special timeout values because
         # the API is a proxy for the other component.
diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py
index 5634958..bf8d30e 100644
--- a/tempest/common/credentials_factory.py
+++ b/tempest/common/credentials_factory.py
@@ -88,7 +88,7 @@
             project_network_mask_bits=CONF.network.project_network_mask_bits,
             public_network_id=CONF.network.public_network_id,
             create_networks=(CONF.auth.create_isolated_networks and not
-                             CONF.baremetal.driver_enabled),
+                             CONF.network.shared_physical_network),
             resource_prefix=CONF.resources_prefix,
             **get_dynamic_provider_params())
     else:
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 9ec217f..d8993bb 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -112,11 +112,22 @@
         output = self.exec_command('grep -c ^processor /proc/cpuinfo')
         return int(output)
 
-    def get_partitions(self):
-        # Return the contents of /proc/partitions
-        command = 'cat /proc/partitions'
+    def get_disks(self):
+        # Select root disk devices as shown by lsblk
+        command = 'lsblk -lb --nodeps'
         output = self.exec_command(command)
-        return output
+        selected = []
+        pos = None
+        for l in output.splitlines():
+            if pos is None and l.find("TYPE") > 0:
+                pos = l.find("TYPE")
+                # Show header line too
+                selected.append(l)
+            # lsblk lists disk type in a column right-aligned with TYPE
+            elif pos > 0 and l[pos:pos + 4] == "disk":
+                selected.append(l)
+
+        return "\n".join(selected)
 
     def get_boot_time(self):
         cmd = 'cut -f1 -d. /proc/uptime'
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 981a922..fe648a0 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -231,35 +231,6 @@
             raise lib_exc.TimeoutException(message)
 
 
-def wait_for_bm_node_status(client, node_id, attr, status):
-    """Waits for a baremetal node attribute to reach given status.
-
-    The client should have a show_node(node_uuid) method to get the node.
-    """
-    _, node = client.show_node(node_id)
-    start = int(time.time())
-
-    while node[attr] != status:
-        time.sleep(client.build_interval)
-        _, node = client.show_node(node_id)
-        status_curr = node[attr]
-        if status_curr == status:
-            return
-
-        if int(time.time()) - start >= client.build_timeout:
-            message = ('Node %(node_id)s failed to reach %(attr)s=%(status)s '
-                       'within the required time (%(timeout)s s).' %
-                       {'node_id': node_id,
-                        'attr': attr,
-                        'status': status,
-                        'timeout': client.build_timeout})
-            message += ' Current state of %s: %s.' % (attr, status_curr)
-            caller = test_utils.find_test_caller()
-            if caller:
-                message = '(%s) %s' % (caller, message)
-            raise lib_exc.TimeoutException(message)
-
-
 def wait_for_qos_operations(client, qos_id, operation, args=None):
     """Waits for a qos operations to be completed.
 
diff --git a/tempest/config.py b/tempest/config.py
index 47eb427..281e283 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -171,7 +171,20 @@
     cfg.BoolOpt('admin_domain_scope',
                 default=False,
                 help="Whether keystone identity v3 policy required "
-                     "a domain scoped token to use admin APIs")
+                     "a domain scoped token to use admin APIs"),
+    # Security Compliance (PCI-DSS)
+    cfg.IntOpt('user_lockout_failure_attempts',
+               default=2,
+               help="The number of unsuccessful login attempts the user is "
+                    "allowed before having the account locked."),
+    cfg.IntOpt('user_lockout_duration',
+               default=5,
+               help="The number of seconds a user account will remain "
+                    "locked."),
+    cfg.IntOpt('user_unique_last_password_count',
+               default=2,
+               help="The number of passwords for a user that must be unique "
+                    "before an old password can be reused."),
 ]
 
 service_clients_group = cfg.OptGroup(name='service-clients',
@@ -208,7 +221,11 @@
     # of life.
     cfg.BoolOpt('reseller',
                 default=False,
-                help='Does the environment support reseller?')
+                help='Does the environment support reseller?'),
+    cfg.BoolOpt('security_compliance',
+                default=False,
+                help='Does the environment have the security compliance '
+                     'settings enabled?')
 ]
 
 compute_group = cfg.OptGroup(name='compute',
@@ -422,10 +439,16 @@
                 default=['all'],
                 help="A list of enabled filters that nova will accept as hints"
                      " to the scheduler when creating a server. A special "
-                     "entry 'all' indicates all filters are enabled. Empty "
-                     "list indicates all filters are disabled. The full "
-                     "available list of filters is in nova.conf: "
-                     "DEFAULT.scheduler_available_filters"),
+                     "entry 'all' indicates all filters that are included "
+                     "with nova are enabled. Empty list indicates all filters "
+                     "are disabled. The full list of available filters is in "
+                     "nova.conf: DEFAULT.scheduler_available_filters. If the "
+                     "default value is overridden in nova.conf by the test "
+                     "environment (which means that a different set of "
+                     "filters is enabled than what is included in Nova by "
+                     "default) then, this option must be configured to "
+                     "contain the same filters that Nova uses in the test "
+                     "environment."),
     cfg.BoolOpt('swap_volume',
                 default=False,
                 help='Does the test environment support in-place swapping of '
@@ -565,6 +588,10 @@
                 default=["1.0.0.0/16", "2.0.0.0/16"],
                 help="List of ip pools"
                      " for subnetpools creation"),
+    cfg.BoolOpt('shared_physical_network',
+                default=False,
+                help="The environment does not support network separation "
+                     "between tenants."),
     # TODO(ylobankov): Delete this option once the Liberty release is EOL.
     cfg.BoolOpt('dvr_extra_resources',
                 default=True,
@@ -969,9 +996,6 @@
     cfg.BoolOpt('sahara',
                 default=False,
                 help="Whether or not Sahara is expected to be available"),
-    cfg.BoolOpt('ironic',
-                default=False,
-                help="Whether or not Ironic is expected to be available"),
 ]
 
 debug_group = cfg.OptGroup(name="debug",
@@ -1026,56 +1050,6 @@
                deprecated_for_removal=True),
 ]
 
-
-baremetal_group = cfg.OptGroup(name='baremetal',
-                               title='Baremetal provisioning service options',
-                               help='When enabling baremetal tests, Nova '
-                                    'must be configured to use the Ironic '
-                                    'driver. The following parameters for the '
-                                    '[compute] section must be disabled: '
-                                    'console_output, interface_attach, '
-                                    'live_migration, pause, rescue, resize '
-                                    'shelve, snapshot, and suspend')
-
-
-# NOTE(deva): Ironic tests have been ported to tempest.lib. New config options
-#             should be added to ironic/ironic_tempest_plugin/config.py.
-#             However, these options need to remain here for testing stable
-#             branches until Liberty release reaches EOL.
-BaremetalGroup = [
-    cfg.StrOpt('catalog_type',
-               default='baremetal',
-               help="Catalog type of the baremetal provisioning service"),
-    cfg.BoolOpt('driver_enabled',
-                default=False,
-                help="Whether the Ironic nova-compute driver is enabled"),
-    cfg.StrOpt('driver',
-               default='fake',
-               help="Driver name which Ironic uses"),
-    cfg.StrOpt('endpoint_type',
-               default='publicURL',
-               choices=['public', 'admin', 'internal',
-                        'publicURL', 'adminURL', 'internalURL'],
-               help="The endpoint type to use for the baremetal provisioning "
-                    "service"),
-    cfg.IntOpt('active_timeout',
-               default=300,
-               help="Timeout for Ironic node to completely provision"),
-    cfg.IntOpt('association_timeout',
-               default=30,
-               help="Timeout for association of Nova instance and Ironic "
-                    "node"),
-    cfg.IntOpt('power_timeout',
-               default=60,
-               help="Timeout for Ironic power transitions."),
-    cfg.IntOpt('unprovision_timeout',
-               default=300,
-               help="Timeout for unprovisioning an Ironic node. "
-                    "Takes longer since Kilo as Ironic performs an extra "
-                    "step in Node cleaning.")
-]
-
-
 DefaultGroup = [
     cfg.StrOpt('resources_prefix',
                default='tempest',
@@ -1105,7 +1079,6 @@
     (scenario_group, ScenarioGroup),
     (service_available_group, ServiceAvailableGroup),
     (debug_group, DebugGroup),
-    (baremetal_group, BaremetalGroup),
     (input_scenario_group, InputScenarioGroup),
     (None, DefaultGroup)
 ]
@@ -1168,7 +1141,6 @@
         self.scenario = _CONF.scenario
         self.service_available = _CONF.service_available
         self.debug = _CONF.debug
-        self.baremetal = _CONF.baremetal
         self.input_scenario = _CONF['input-scenario']
         logging.tempest_set_log_file('tempest.log')
 
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 73544d9..376dd19 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -157,7 +157,7 @@
                 # Convert security group names to security group ids
                 # to pass to create_port
                 if 'security_groups' in kwargs:
-                    security_groups =\
+                    security_groups = \
                         clients.security_groups_client.list_security_groups(
                         ).get('security_groups')
                     sec_dict = dict([(s['name'], s['id'])
@@ -817,7 +817,7 @@
         # servers. Neutron does not bind ports for Ironic instances, as a
         # result the port remains in the DOWN state.
         # TODO(vsaienko) remove once bug: #1599836 is resolved.
-        if CONF.service_available.ironic:
+        if getattr(CONF.service_available, 'ironic', False):
             p_status.append('DOWN')
         port_map = [(p["id"], fxip["ip_address"])
                     for p in ports
@@ -1189,7 +1189,7 @@
         :param dns_nameservers: list of dns servers to send to subnet.
         :returns: network, subnet, router
         """
-        if CONF.baremetal.driver_enabled:
+        if CONF.network.shared_physical_network:
             # NOTE(Shrews): This exception is for environments where tenant
             # credential isolation is available, but network separation is
             # not (the current baremetal case). Likely can be removed when
@@ -1230,151 +1230,6 @@
         return network, subnet, router
 
 
-# power/provision states as of icehouse
-class BaremetalPowerStates(object):
-    """Possible power states of an Ironic node."""
-    POWER_ON = 'power on'
-    POWER_OFF = 'power off'
-    REBOOT = 'rebooting'
-    SUSPEND = 'suspended'
-
-
-class BaremetalProvisionStates(object):
-    """Possible provision states of an Ironic node."""
-    NOSTATE = None
-    INIT = 'initializing'
-    ACTIVE = 'active'
-    BUILDING = 'building'
-    DEPLOYWAIT = 'wait call-back'
-    DEPLOYING = 'deploying'
-    DEPLOYFAIL = 'deploy failed'
-    DEPLOYDONE = 'deploy complete'
-    DELETING = 'deleting'
-    DELETED = 'deleted'
-    ERROR = 'error'
-
-
-class BaremetalScenarioTest(ScenarioTest):
-
-    credentials = ['primary', 'admin']
-
-    @classmethod
-    def skip_checks(cls):
-        super(BaremetalScenarioTest, cls).skip_checks()
-        if (not CONF.service_available.ironic or
-           not CONF.baremetal.driver_enabled):
-            msg = 'Ironic not available or Ironic compute driver not enabled'
-            raise cls.skipException(msg)
-
-    @classmethod
-    def setup_clients(cls):
-        super(BaremetalScenarioTest, cls).setup_clients()
-
-        cls.baremetal_client = cls.admin_manager.baremetal_client
-
-    @classmethod
-    def resource_setup(cls):
-        super(BaremetalScenarioTest, cls).resource_setup()
-        # allow any issues obtaining the node list to raise early
-        cls.baremetal_client.list_nodes()
-
-    def _node_state_timeout(self, node_id, state_attr,
-                            target_states, timeout=10, interval=1):
-        if not isinstance(target_states, list):
-            target_states = [target_states]
-
-        def check_state():
-            node = self.get_node(node_id=node_id)
-            if node.get(state_attr) in target_states:
-                return True
-            return False
-
-        if not test_utils.call_until_true(
-            check_state, timeout, interval):
-            msg = ("Timed out waiting for node %s to reach %s state(s) %s" %
-                   (node_id, state_attr, target_states))
-            raise lib_exc.TimeoutException(msg)
-
-    def wait_provisioning_state(self, node_id, state, timeout):
-        self._node_state_timeout(
-            node_id=node_id, state_attr='provision_state',
-            target_states=state, timeout=timeout)
-
-    def wait_power_state(self, node_id, state):
-        self._node_state_timeout(
-            node_id=node_id, state_attr='power_state',
-            target_states=state, timeout=CONF.baremetal.power_timeout)
-
-    def wait_node(self, instance_id):
-        """Waits for a node to be associated with instance_id."""
-
-        def _get_node():
-            node = test_utils.call_and_ignore_notfound_exc(
-                self.get_node, instance_id=instance_id)
-            return node is not None
-
-        if not test_utils.call_until_true(
-            _get_node, CONF.baremetal.association_timeout, 1):
-            msg = ('Timed out waiting to get Ironic node by instance id %s'
-                   % instance_id)
-            raise lib_exc.TimeoutException(msg)
-
-    def get_node(self, node_id=None, instance_id=None):
-        if node_id:
-            _, body = self.baremetal_client.show_node(node_id)
-            return body
-        elif instance_id:
-            _, body = self.baremetal_client.show_node_by_instance_uuid(
-                instance_id)
-            if body['nodes']:
-                return body['nodes'][0]
-
-    def get_ports(self, node_uuid):
-        ports = []
-        _, body = self.baremetal_client.list_node_ports(node_uuid)
-        for port in body['ports']:
-            _, p = self.baremetal_client.show_port(port['uuid'])
-            ports.append(p)
-        return ports
-
-    def add_keypair(self):
-        self.keypair = self.create_keypair()
-
-    def boot_instance(self):
-        self.instance = self.create_server(
-            key_name=self.keypair['name'])
-
-        self.wait_node(self.instance['id'])
-        self.node = self.get_node(instance_id=self.instance['id'])
-
-        self.wait_power_state(self.node['uuid'], BaremetalPowerStates.POWER_ON)
-
-        self.wait_provisioning_state(
-            self.node['uuid'],
-            [BaremetalProvisionStates.DEPLOYWAIT,
-             BaremetalProvisionStates.ACTIVE],
-            timeout=15)
-
-        self.wait_provisioning_state(self.node['uuid'],
-                                     BaremetalProvisionStates.ACTIVE,
-                                     timeout=CONF.baremetal.active_timeout)
-
-        waiters.wait_for_server_status(self.servers_client,
-                                       self.instance['id'], 'ACTIVE')
-        self.node = self.get_node(instance_id=self.instance['id'])
-        self.instance = (self.servers_client.show_server(self.instance['id'])
-                         ['server'])
-
-    def terminate_instance(self):
-        self.servers_client.delete_server(self.instance['id'])
-        self.wait_power_state(self.node['uuid'],
-                              BaremetalPowerStates.POWER_OFF)
-        self.wait_provisioning_state(
-            self.node['uuid'],
-            BaremetalProvisionStates.NOSTATE,
-            timeout=CONF.baremetal.unprovision_timeout)
-
-
 class EncryptionScenarioTest(ScenarioTest):
     """Base class for encryption scenario tests"""
 
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
deleted file mode 100644
index 45c38f6..0000000
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#
-# Copyright 2014 Hewlett-Packard Development Company, L.P.
-#
-# 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 oslo_log import log as logging
-
-from tempest.scenario import manager
-from tempest import test
-
-LOG = logging.getLogger(__name__)
-
-
-class BaremetalBasicOps(manager.BaremetalScenarioTest):
-    """This test tests the pxe_ssh Ironic driver.
-
-    It follows this basic set of operations:
-        * Creates a keypair
-        * Boots an instance using the keypair
-        * Monitors the associated Ironic node for power and
-          expected state transitions
-        * Validates Ironic node's port data has been properly updated
-        * Verifies SSH connectivity using created keypair via fixed IP
-        * Associates a floating ip
-        * Verifies SSH connectivity using created keypair via floating IP
-        * Deletes instance
-        * Monitors the associated Ironic node for power and
-          expected state transitions
-    """
-    def verify_partition(self, client, label, mount, gib_size):
-        """Verify a labeled partition's mount point and size."""
-        LOG.info("Looking for partition %s mounted on %s" % (label, mount))
-
-        # Validate we have a device with the given partition label
-        cmd = "/sbin/blkid | grep '%s' | cut -d':' -f1" % label
-        device = client.exec_command(cmd).rstrip('\n')
-        LOG.debug("Partition device is %s" % device)
-        self.assertNotEqual('', device)
-
-        # Validate the mount point for the device
-        cmd = "mount | grep '%s' | cut -d' ' -f3" % device
-        actual_mount = client.exec_command(cmd).rstrip('\n')
-        LOG.debug("Partition mount point is %s" % actual_mount)
-        self.assertEqual(actual_mount, mount)
-
-        # Validate the partition size matches what we expect
-        numbers = '0123456789'
-        devnum = device.replace('/dev/', '')
-        cmd = "cat /sys/block/%s/%s/size" % (devnum.rstrip(numbers), devnum)
-        num_bytes = client.exec_command(cmd).rstrip('\n')
-        num_bytes = int(num_bytes) * 512
-        actual_gib_size = num_bytes / (1024 * 1024 * 1024)
-        LOG.debug("Partition size is %d GiB" % actual_gib_size)
-        self.assertEqual(actual_gib_size, gib_size)
-
-    def get_flavor_ephemeral_size(self):
-        """Returns size of the ephemeral partition in GiB."""
-        f_id = self.instance['flavor']['id']
-        flavor = self.flavors_client.show_flavor(f_id)['flavor']
-        ephemeral = flavor.get('OS-FLV-EXT-DATA:ephemeral')
-        if not ephemeral or ephemeral == 'N/A':
-            return None
-        return int(ephemeral)
-
-    def validate_ports(self):
-        for port in self.get_ports(self.node['uuid']):
-            n_port_id = port['extra']['vif_port_id']
-            body = self.ports_client.show_port(n_port_id)
-            n_port = body['port']
-            self.assertEqual(n_port['device_id'], self.instance['id'])
-            self.assertEqual(n_port['mac_address'], port['address'])
-
-    @test.idempotent_id('549173a5-38ec-42bb-b0e2-c8b9f4a08943')
-    @test.services('baremetal', 'compute', 'image', 'network')
-    def test_baremetal_server_ops(self):
-        self.add_keypair()
-        self.boot_instance()
-        self.validate_ports()
-        ip_address = self.get_server_ip(self.instance)
-        self.get_remote_client(ip_address).validate_authentication()
-        vm_client = self.get_remote_client(ip_address)
-
-        # We expect the ephemeral partition to be mounted on /mnt and to have
-        # the same size as our flavor definition.
-        eph_size = self.get_flavor_ephemeral_size()
-        if eph_size:
-            self.verify_partition(vm_client, 'ephemeral0', '/mnt', eph_size)
-            # Create the test file
-            self.create_timestamp(
-                ip_address, private_key=self.keypair['private_key'])
-
-        self.terminate_instance()
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index f2f17d2..c454ae2 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -66,10 +66,10 @@
         waiters.wait_for_server_status(self.servers_client,
                                        server['id'], 'ACTIVE')
 
-    def check_partitions(self):
+    def check_disks(self):
         # NOTE(andreaf) The device name may be different on different guest OS
-        partitions = self.linux_client.get_partitions()
-        self.assertEqual(1, partitions.count(CONF.compute.volume_device_name))
+        disks = self.linux_client.get_disks()
+        self.assertEqual(1, disks.count(CONF.compute.volume_device_name))
 
     def create_and_add_security_group_to_server(self, server):
         secgroup = self._create_security_group()
@@ -145,7 +145,7 @@
         self.linux_client = self.get_remote_client(
             floating_ip['ip'], private_key=keypair['private_key'])
 
-        self.check_partitions()
+        self.check_disks()
 
         # delete the floating IP, this should refresh the server addresses
         self.compute_floating_ips_client.delete_floating_ip(floating_ip['id'])
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 4a076e4..4bbe4eb 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -417,8 +417,9 @@
             should_connect=True, mtu=self.network['mtu'])
 
     @test.idempotent_id('1546850e-fbaa-42f5-8b5f-03d8a6a95f15')
-    @testtools.skipIf(CONF.baremetal.driver_enabled,
-                      'Baremetal relies on a shared physical network.')
+    @testtools.skipIf(CONF.network.shared_physical_network,
+                      'Connectivity can only be tested when in a '
+                      'multitenant network environment')
     @decorators.skip_because(bug="1610994")
     @test.services('compute', 'network')
     def test_connectivity_between_vms_on_different_networks(self):
@@ -492,9 +493,9 @@
         self._check_network_internal_connectivity(network=self.new_net)
 
     @test.idempotent_id('04b9fe4e-85e8-4aea-b937-ea93885ac59f')
-    @testtools.skipIf(CONF.baremetal.driver_enabled,
-                      'Router state cannot be altered on a shared baremetal '
-                      'network')
+    @testtools.skipIf(CONF.network.shared_physical_network,
+                      'Router state can be altered only with multitenant '
+                      'networks capabilities')
     @test.services('compute', 'network')
     def test_update_router_admin_state(self):
         """Test to update admin state up of router
@@ -524,8 +525,8 @@
             "admin_state_up of router to True")
 
     @test.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
-    @testtools.skipIf(CONF.baremetal.driver_enabled,
-                      'network isolation not available for baremetal nodes')
+    @testtools.skipIf(CONF.network.shared_physical_network,
+                      'network isolation not available')
     @testtools.skipUnless(CONF.scenario.dhcp_client,
                           "DHCP client is not available.")
     @test.services('compute', 'network')
@@ -607,9 +608,6 @@
                             "new DNS nameservers")
 
     @test.idempotent_id('f5dfcc22-45fd-409f-954c-5bd500d7890b')
-    @testtools.skipIf(CONF.baremetal.driver_enabled,
-                      'admin_state of instance ports cannot be altered '
-                      'for baremetal nodes')
     @testtools.skipUnless(CONF.network_feature_enabled.port_admin_state_change,
                           "Changing a port's admin state is not supported "
                           "by the test environment")
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 6700236..40b3317 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -50,8 +50,8 @@
             msg = ('Either project_networks_reachable must be "true", or '
                    'public_network_id must be defined.')
             raise cls.skipException(msg)
-        if CONF.baremetal.driver_enabled:
-            msg = ('Baremetal does not currently support network isolation')
+        if CONF.network.shared_physical_network:
+            msg = 'Deployment uses a shared physical network'
             raise cls.skipException(msg)
 
     @classmethod
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 1360b09..f8c5c0a 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -130,9 +130,6 @@
     @classmethod
     def skip_checks(cls):
         super(TestSecurityGroupsBasicOps, cls).skip_checks()
-        if CONF.baremetal.driver_enabled:
-            msg = ('Not currently supported by baremetal.')
-            raise cls.skipException(msg)
         if CONF.network.port_vnic_type in ['direct', 'macvtap']:
             msg = ('Not currently supported when using vnic_type'
                    ' direct or macvtap')
@@ -145,6 +142,10 @@
         if not test.is_extension_enabled('security-group', 'network'):
             msg = "security-group extension not enabled."
             raise cls.skipException(msg)
+        if CONF.network.shared_physical_network:
+            msg = ('Deployment uses a shared physical network, security '
+                   'groups not supported')
+            raise cls.skipException(msg)
 
     @classmethod
     def setup_credentials(cls):
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 0f2c78c..dff00e7 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -85,9 +85,9 @@
         ssh = self.get_remote_client(ip_address, private_key=private_key)
 
         def _func():
-            part = ssh.get_partitions()
-            LOG.debug("Partitions:%s" % part)
-            return CONF.compute.volume_device_name in part
+            disks = ssh.get_disks()
+            LOG.debug("Disks: %s" % disks)
+            return CONF.compute.volume_device_name in disks
 
         if not test_utils.call_until_true(_func,
                                           CONF.compute.build_timeout,
diff --git a/tempest/services/baremetal/__init__.py b/tempest/services/baremetal/__init__.py
deleted file mode 100644
index 390f40a..0000000
--- a/tempest/services/baremetal/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
-#
-# 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.services.baremetal.v1.json.baremetal_client import \
-    BaremetalClient
-
-__all__ = ['BaremetalClient']
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
deleted file mode 100644
index 2bdd092..0000000
--- a/tempest/services/baremetal/base.py
+++ /dev/null
@@ -1,205 +0,0 @@
-#    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 functools
-
-from oslo_serialization import jsonutils as json
-import six
-from six.moves.urllib import parse as urllib
-
-from tempest.lib.common import rest_client
-
-
-def handle_errors(f):
-    """A decorator that allows to ignore certain types of errors."""
-
-    @functools.wraps(f)
-    def wrapper(*args, **kwargs):
-        param_name = 'ignore_errors'
-        ignored_errors = kwargs.get(param_name, tuple())
-
-        if param_name in kwargs:
-            del kwargs[param_name]
-
-        try:
-            return f(*args, **kwargs)
-        except ignored_errors:
-            # Silently ignore errors
-            pass
-
-    return wrapper
-
-
-class BaremetalClient(rest_client.RestClient):
-    """Base Tempest REST client for Ironic API."""
-
-    uri_prefix = ''
-
-    def serialize(self, object_dict):
-        """Serialize an Ironic object."""
-
-        return json.dumps(object_dict)
-
-    def deserialize(self, object_str):
-        """Deserialize an Ironic object."""
-
-        return json.loads(object_str)
-
-    def _get_uri(self, resource_name, uuid=None, permanent=False):
-        """Get URI for a specific resource or object.
-
-        :param resource_name: The name of the REST resource, e.g., 'nodes'.
-        :param uuid: The unique identifier of an object in UUID format.
-        :returns: Relative URI for the resource or object.
-
-        """
-        prefix = self.uri_prefix if not permanent else ''
-
-        return '{pref}/{res}{uuid}'.format(pref=prefix,
-                                           res=resource_name,
-                                           uuid='/%s' % uuid if uuid else '')
-
-    def _make_patch(self, allowed_attributes, **kwargs):
-        """Create a JSON patch according to RFC 6902.
-
-        :param allowed_attributes: An iterable object that contains a set of
-            allowed attributes for an object.
-        :param **kwargs: Attributes and new values for them.
-        :returns: A JSON path that sets values of the specified attributes to
-            the new ones.
-
-        """
-        def get_change(kwargs, path='/'):
-            for name, value in six.iteritems(kwargs):
-                if isinstance(value, dict):
-                    for ch in get_change(value, path + '%s/' % name):
-                        yield ch
-                else:
-                    if value is None:
-                        yield {'path': path + name,
-                               'op': 'remove'}
-                    else:
-                        yield {'path': path + name,
-                               'value': value,
-                               'op': 'replace'}
-
-        patch = [ch for ch in get_change(kwargs)
-                 if ch['path'].lstrip('/') in allowed_attributes]
-
-        return patch
-
-    def _list_request(self, resource, permanent=False, **kwargs):
-        """Get the list of objects of the specified type.
-
-        :param resource: The name of the REST resource, e.g., 'nodes'.
-        :param **kwargs: Parameters for the request.
-        :returns: A tuple with the server response and deserialized JSON list
-                 of objects
-
-        """
-        uri = self._get_uri(resource, permanent=permanent)
-        if kwargs:
-            uri += "?%s" % urllib.urlencode(kwargs)
-
-        resp, body = self.get(uri)
-        self.expected_success(200, resp.status)
-
-        return resp, self.deserialize(body)
-
-    def _show_request(self, resource, uuid, permanent=False, **kwargs):
-        """Gets a specific object of the specified type.
-
-        :param uuid: Unique identifier of the object in UUID format.
-        :returns: Serialized object as a dictionary.
-
-        """
-        if 'uri' in kwargs:
-            uri = kwargs['uri']
-        else:
-            uri = self._get_uri(resource, uuid=uuid, permanent=permanent)
-        resp, body = self.get(uri)
-        self.expected_success(200, resp.status)
-
-        return resp, self.deserialize(body)
-
-    def _create_request(self, resource, object_dict):
-        """Create an object of the specified type.
-
-        :param resource: The name of the REST resource, e.g., 'nodes'.
-        :param object_dict: A Python dict that represents an object of the
-                            specified type.
-        :returns: A tuple with the server response and the deserialized created
-                 object.
-
-        """
-        body = self.serialize(object_dict)
-        uri = self._get_uri(resource)
-
-        resp, body = self.post(uri, body=body)
-        self.expected_success(201, resp.status)
-
-        return resp, self.deserialize(body)
-
-    def _delete_request(self, resource, uuid):
-        """Delete specified object.
-
-        :param resource: The name of the REST resource, e.g., 'nodes'.
-        :param uuid: The unique identifier of an object in UUID format.
-        :returns: A tuple with the server response and the response body.
-
-        """
-        uri = self._get_uri(resource, uuid)
-
-        resp, body = self.delete(uri)
-        self.expected_success(204, resp.status)
-        return resp, body
-
-    def _patch_request(self, resource, uuid, patch_object):
-        """Update specified object with JSON-patch.
-
-        :param resource: The name of the REST resource, e.g., 'nodes'.
-        :param uuid: The unique identifier of an object in UUID format.
-        :returns: A tuple with the server response and the serialized patched
-                 object.
-
-        """
-        uri = self._get_uri(resource, uuid)
-        patch_body = json.dumps(patch_object)
-
-        resp, body = self.patch(uri, body=patch_body)
-        self.expected_success(200, resp.status)
-        return resp, self.deserialize(body)
-
-    @handle_errors
-    def get_api_description(self):
-        """Retrieves all versions of the Ironic API."""
-
-        return self._list_request('', permanent=True)
-
-    @handle_errors
-    def get_version_description(self, version='v1'):
-        """Retrieves the desctription of the API.
-
-        :param version: The version of the API. Default: 'v1'.
-        :returns: Serialized description of API resources.
-
-        """
-        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)
-        self.expected_success([202, 204], resp.status)
-        return resp, body
diff --git a/tempest/services/baremetal/v1/__init__.py b/tempest/services/baremetal/v1/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/baremetal/v1/__init__.py
+++ /dev/null
diff --git a/tempest/services/baremetal/v1/json/__init__.py b/tempest/services/baremetal/v1/json/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/baremetal/v1/json/__init__.py
+++ /dev/null
diff --git a/tempest/services/baremetal/v1/json/baremetal_client.py b/tempest/services/baremetal/v1/json/baremetal_client.py
deleted file mode 100644
index 7405871..0000000
--- a/tempest/services/baremetal/v1/json/baremetal_client.py
+++ /dev/null
@@ -1,362 +0,0 @@
-#    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.services.baremetal import base
-
-
-class BaremetalClient(base.BaremetalClient):
-    """Base Tempest REST client for Ironic API v1."""
-    version = '1'
-    uri_prefix = 'v1'
-
-    @base.handle_errors
-    def list_nodes(self, **kwargs):
-        """List all existing nodes.
-
-        Available params: see http://developer.openstack.org/api-ref/
-                              baremetal/index.html#list-nodes
-        """
-        return self._list_request('nodes', **kwargs)
-
-    @base.handle_errors
-    def list_chassis(self):
-        """List all existing chassis."""
-        return self._list_request('chassis')
-
-    @base.handle_errors
-    def list_chassis_nodes(self, chassis_uuid):
-        """List all nodes associated with a chassis."""
-        return self._list_request('/chassis/%s/nodes' % chassis_uuid)
-
-    @base.handle_errors
-    def list_ports(self, **kwargs):
-        """List all existing ports.
-
-        Available params: see http://developer.openstack.org/api-ref/
-                              baremetal/index.html?expanded=#list-ports
-        """
-        return self._list_request('ports', **kwargs)
-
-    @base.handle_errors
-    def list_node_ports(self, uuid):
-        """List all ports associated with the node."""
-        return self._list_request('/nodes/%s/ports' % uuid)
-
-    @base.handle_errors
-    def list_nodestates(self, uuid):
-        """List all existing states."""
-        return self._list_request('/nodes/%s/states' % uuid)
-
-    @base.handle_errors
-    def list_ports_detail(self, **kwargs):
-        """Details list all existing ports.
-
-        Available params: see http://developer.openstack.org/api-ref/baremetal/
-                              index.html?expanded=#list-detailed-ports
-        """
-        return self._list_request('/ports/detail', **kwargs)
-
-    @base.handle_errors
-    def list_drivers(self):
-        """List all existing drivers."""
-        return self._list_request('drivers')
-
-    @base.handle_errors
-    def show_node(self, uuid):
-        """Gets a specific node.
-
-        :param uuid: Unique identifier of the node in UUID format.
-        :return: Serialized node as a dictionary.
-
-        """
-        return self._show_request('nodes', uuid)
-
-    @base.handle_errors
-    def show_node_by_instance_uuid(self, instance_uuid):
-        """Gets a node associated with given instance uuid.
-
-        :param instance_uuid: Unique identifier of the instance in UUID format.
-        :return: Serialized node as a dictionary.
-
-        """
-        uri = '/nodes/detail?instance_uuid=%s' % instance_uuid
-
-        return self._show_request('nodes',
-                                  uuid=None,
-                                  uri=uri)
-
-    @base.handle_errors
-    def show_chassis(self, uuid):
-        """Gets a specific chassis.
-
-        :param uuid: Unique identifier of the chassis in UUID format.
-        :return: Serialized chassis as a dictionary.
-
-        """
-        return self._show_request('chassis', uuid)
-
-    @base.handle_errors
-    def show_port(self, uuid):
-        """Gets a specific port.
-
-        :param uuid: Unique identifier of the port in UUID format.
-        :return: Serialized port as a dictionary.
-
-        """
-        return self._show_request('ports', uuid)
-
-    @base.handle_errors
-    def show_port_by_address(self, address):
-        """Gets a specific port by address.
-
-        :param address: MAC address of the port.
-        :return: Serialized port as a dictionary.
-
-        """
-        uri = '/ports/detail?address=%s' % address
-
-        return self._show_request('ports', uuid=None, uri=uri)
-
-    def show_driver(self, driver_name):
-        """Gets a specific driver.
-
-        :param driver_name: Name of driver.
-        :return: Serialized driver as a dictionary.
-        """
-        return self._show_request('drivers', driver_name)
-
-    @base.handle_errors
-    def create_node(self, chassis_id=None, **kwargs):
-        """Create a baremetal node with the specified parameters.
-
-        :param chassis_id: The unique identifier of the chassis.
-        :param cpu_arch: CPU architecture of the node. Default: x86_64.
-        :param cpus: Number of CPUs. Default: 8.
-        :param local_gb: Disk size. Default: 1024.
-        :param memory_mb: Available RAM. Default: 4096.
-        :param driver: Driver name. Default: "fake"
-        :return: A tuple with the server response and the created node.
-
-        """
-        node = {'chassis_uuid': chassis_id,
-                'properties': {'cpu_arch': kwargs.get('cpu_arch', 'x86_64'),
-                               'cpus': kwargs.get('cpus', 8),
-                               'local_gb': kwargs.get('local_gb', 1024),
-                               'memory_mb': kwargs.get('memory_mb', 4096)},
-                'driver': kwargs.get('driver', 'fake')}
-
-        return self._create_request('nodes', node)
-
-    @base.handle_errors
-    def create_chassis(self, **kwargs):
-        """Create a chassis with the specified parameters.
-
-        :param description: The description of the chassis.
-            Default: test-chassis
-        :return: A tuple with the server response and the created chassis.
-
-        """
-        chassis = {'description': kwargs.get('description', 'test-chassis')}
-
-        return self._create_request('chassis', chassis)
-
-    @base.handle_errors
-    def create_port(self, node_id, **kwargs):
-        """Create a port with the specified parameters.
-
-        :param node_id: The ID of the node which owns the port.
-        :param address: MAC address of the port.
-        :param extra: Meta data of the port. Default: {'foo': 'bar'}.
-        :param uuid: UUID of the port.
-        :return: A tuple with the server response and the created port.
-
-        """
-        port = {'extra': kwargs.get('extra', {'foo': 'bar'}),
-                'uuid': kwargs['uuid']}
-
-        if node_id is not None:
-            port['node_uuid'] = node_id
-
-        if kwargs['address'] is not None:
-            port['address'] = kwargs['address']
-
-        return self._create_request('ports', port)
-
-    @base.handle_errors
-    def delete_node(self, uuid):
-        """Deletes a node having the specified UUID.
-
-        :param uuid: The unique identifier of the node.
-        :return: A tuple with the server response and the response body.
-
-        """
-        return self._delete_request('nodes', uuid)
-
-    @base.handle_errors
-    def delete_chassis(self, uuid):
-        """Deletes a chassis having the specified UUID.
-
-        :param uuid: The unique identifier of the chassis.
-        :return: A tuple with the server response and the response body.
-
-        """
-        return self._delete_request('chassis', uuid)
-
-    @base.handle_errors
-    def delete_port(self, uuid):
-        """Deletes a port having the specified UUID.
-
-        :param uuid: The unique identifier of the port.
-        :return: A tuple with the server response and the response body.
-
-        """
-        return self._delete_request('ports', uuid)
-
-    @base.handle_errors
-    def update_node(self, uuid, **kwargs):
-        """Update the specified node.
-
-        :param uuid: The unique identifier of the node.
-        :return: A tuple with the server response and the updated node.
-
-        """
-        node_attributes = ('properties/cpu_arch',
-                           'properties/cpus',
-                           'properties/local_gb',
-                           'properties/memory_mb',
-                           'driver',
-                           'instance_uuid')
-
-        patch = self._make_patch(node_attributes, **kwargs)
-
-        return self._patch_request('nodes', uuid, patch)
-
-    @base.handle_errors
-    def update_chassis(self, uuid, **kwargs):
-        """Update the specified chassis.
-
-        :param uuid: The unique identifier of the chassis.
-        :return: A tuple with the server response and the updated chassis.
-
-        """
-        chassis_attributes = ('description',)
-        patch = self._make_patch(chassis_attributes, **kwargs)
-
-        return self._patch_request('chassis', uuid, patch)
-
-    @base.handle_errors
-    def update_port(self, uuid, patch):
-        """Update the specified port.
-
-        :param uuid: The unique identifier of the port.
-        :param patch: List of dicts representing json patches.
-        :return: A tuple with the server response and the updated port.
-
-        """
-
-        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.
-        :param state: desired state to set (on/off/reboot).
-
-        """
-        target = {'target': state}
-        return self._put_request('nodes/%s/states/power' % node_uuid,
-                                 target)
-
-    @base.handle_errors
-    def validate_driver_interface(self, node_uuid):
-        """Get all driver interfaces of a specific node.
-
-        :param node_uuid: Unique identifier of the node in UUID format.
-
-        """
-
-        uri = '{pref}/{res}/{uuid}/{postf}'.format(pref=self.uri_prefix,
-                                                   res='nodes',
-                                                   uuid=node_uuid,
-                                                   postf='validate')
-
-        return self._show_request('nodes', node_uuid, uri=uri)
-
-    @base.handle_errors
-    def set_node_boot_device(self, node_uuid, boot_device, persistent=False):
-        """Set the boot device of the specified node.
-
-        :param node_uuid: The unique identifier of the node.
-        :param boot_device: The boot device name.
-        :param persistent: Boolean value. True if the boot device will
-                           persist to all future boots, False if not.
-                           Default: False.
-
-        """
-        request = {'boot_device': boot_device, 'persistent': persistent}
-        resp, body = self._put_request('nodes/%s/management/boot_device' %
-                                       node_uuid, request)
-        self.expected_success(204, resp.status)
-        return body
-
-    @base.handle_errors
-    def get_node_boot_device(self, node_uuid):
-        """Get the current boot device of the specified node.
-
-        :param node_uuid: The unique identifier of the node.
-
-        """
-        path = 'nodes/%s/management/boot_device' % node_uuid
-        resp, body = self._list_request(path)
-        self.expected_success(200, resp.status)
-        return body
-
-    @base.handle_errors
-    def get_node_supported_boot_devices(self, node_uuid):
-        """Get the supported boot devices of the specified node.
-
-        :param node_uuid: The unique identifier of the node.
-
-        """
-        path = 'nodes/%s/management/boot_device/supported' % node_uuid
-        resp, body = self._list_request(path)
-        self.expected_success(200, resp.status)
-        return body
-
-    @base.handle_errors
-    def get_console(self, node_uuid):
-        """Get connection information about the console.
-
-        :param node_uuid: Unique identifier of the node in UUID format.
-
-        """
-
-        resp, body = self._show_request('nodes/states/console', node_uuid)
-        self.expected_success(200, resp.status)
-        return resp, body
-
-    @base.handle_errors
-    def set_console_mode(self, node_uuid, enabled):
-        """Start and stop the node console.
-
-        :param node_uuid: Unique identifier of the node in UUID format.
-        :param enabled: Boolean value; whether to enable or disable the
-                        console.
-
-        """
-
-        enabled = {'enabled': enabled}
-        resp, body = self._put_request('nodes/%s/states/console' % node_uuid,
-                                       enabled)
-        self.expected_success(202, resp.status)
-        return resp, body
diff --git a/tempest/test.py b/tempest/test.py
index 51f0a6a..4cc2a2b 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -64,7 +64,6 @@
     service_list = {
         'compute': CONF.service_available.nova,
         'image': CONF.service_available.glance,
-        'baremetal': CONF.service_available.ironic,
         'volume': CONF.service_available.cinder,
         'network': True,
         'identity': True,
@@ -164,7 +163,15 @@
 
 
 def is_scheduler_filter_enabled(filter_name):
-    """Check the list of enabled compute scheduler filters from config. """
+    """Check the list of enabled compute scheduler filters from config.
+
+    This function checks whether the given compute scheduler filter is
+    available and configured in the config file. If the
+    scheduler_available_filters option is set to 'all' (Default value. which
+    means default filters are configured in nova) in tempest.conf then, this
+    function returns True with assumption that requested filter 'filter_name'
+    is one of available filter in nova ("nova.scheduler.filters.all_filters").
+    """
 
     filters = CONF.compute_feature_enabled.scheduler_available_filters
     if len(filters) == 0:
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
index e59e08f..e4f4c04 100644
--- a/tempest/tests/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -107,13 +107,20 @@
         self.assertEqual(self.conn.get_number_of_vcpus(), 16)
         self._assert_exec_called_with('grep -c ^processor /proc/cpuinfo')
 
-    def test_get_partitions(self):
-        proc_partitions = """major minor  #blocks  name
+    def test_get_disks(self):
+        output_lsblk = """\
+NAME       MAJ:MIN    RM          SIZE RO TYPE MOUNTPOINT
+sda          8:0       0  128035676160  0 disk
+sdb          8:16      0 1000204886016  0 disk
+sr0         11:0       1    1073741312  0 rom"""
+        result = """\
+NAME       MAJ:MIN    RM          SIZE RO TYPE MOUNTPOINT
+sda          8:0       0  128035676160  0 disk
+sdb          8:16      0 1000204886016  0 disk"""
 
-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')
+        self.ssh_mock.mock.exec_command.return_value = output_lsblk
+        self.assertEqual(self.conn.get_disks(), result)
+        self._assert_exec_called_with('lsblk -lb --nodeps')
 
     def test_get_boot_time(self):
         booted_at = 10000
diff --git a/tempest/tests/lib/fake_identity.py b/tempest/tests/lib/fake_identity.py
index 831f8b5..8bae34f 100644
--- a/tempest/tests/lib/fake_identity.py
+++ b/tempest/tests/lib/fake_identity.py
@@ -55,6 +55,7 @@
         },
         "user": {
             "id": "fake_alt_user_id",
+            "password_expires_at": None,
         },
         "serviceCatalog": CATALOG_V2,
     },
@@ -71,6 +72,7 @@
         },
         "user": {
             "id": "fake_user_id",
+            "password_expires_at": None,
         },
         "serviceCatalog": CATALOG_V2,
     },
@@ -83,18 +85,21 @@
             "id": "first_compute_fake_service",
             "interface": "public",
             "region": "NoMatchRegion",
+            "region_id": "NoMatchRegion",
             "url": "http://fake_url/v3/first_endpoint/api"
         },
         {
             "id": "second_fake_service",
             "interface": "public",
             "region": "FakeRegion",
+            "region_id": "FakeRegion",
             "url": "http://fake_url/v3/second_endpoint/api"
         },
         {
             "id": "third_fake_service",
             "interface": "admin",
             "region": "MiddleEarthRegion",
+            "region_id": "MiddleEarthRegion",
             "url": "http://fake_url/v3/third_endpoint/api"
         }
 
@@ -108,6 +113,7 @@
 
 IDENTITY_V3_RESPONSE = {
     "token": {
+        "audit_ids": ["ny5LA5YXToa_mAVO8Hnupw", "9NPTvsRDSkmsW61abP978Q"],
         "methods": [
             "token",
             "password"
@@ -127,7 +133,8 @@
                 "name": "domain_name"
             },
             "id": "fake_user_id",
-            "name": "username"
+            "name": "username",
+            "password_expires_at": None,
         },
         "issued_at": "2013-05-29T16:55:21.468960Z",
         "catalog": CATALOG_V3
@@ -136,6 +143,7 @@
 
 IDENTITY_V3_RESPONSE_DOMAIN_SCOPE = {
     "token": {
+        "audit_ids": ["ny5LA5YXToa_mAVO8Hnupw", "9NPTvsRDSkmsW61abP978Q"],
         "methods": [
             "token",
             "password"
@@ -151,7 +159,8 @@
                 "name": "domain_name"
             },
             "id": "fake_user_id",
-            "name": "username"
+            "name": "username",
+            "password_expires_at": None,
         },
         "issued_at": "2013-05-29T16:55:21.468960Z",
         "catalog": CATALOG_V3
@@ -160,6 +169,7 @@
 
 IDENTITY_V3_RESPONSE_NO_SCOPE = {
     "token": {
+        "audit_ids": ["ny5LA5YXToa_mAVO8Hnupw", "9NPTvsRDSkmsW61abP978Q"],
         "methods": [
             "token",
             "password"
@@ -171,7 +181,8 @@
                 "name": "domain_name"
             },
             "id": "fake_user_id",
-            "name": "username"
+            "name": "username",
+            "password_expires_at": None,
         },
         "issued_at": "2013-05-29T16:55:21.468960Z",
     }
diff --git a/tempest/tests/lib/services/identity/v3/test_token_client.py b/tempest/tests/lib/services/identity/v3/test_token_client.py
index 9f4b4cc..38e8c4a 100644
--- a/tempest/tests/lib/services/identity/v3/test_token_client.py
+++ b/tempest/tests/lib/services/identity/v3/test_token_client.py
@@ -20,7 +20,7 @@
 from tempest.lib import exceptions
 from tempest.lib.services.identity.v3 import token_client
 from tempest.tests import base
-from tempest.tests.lib import fake_http
+from tempest.tests.lib import fake_identity
 
 
 class TestTokenClientV3(base.TestCase):
@@ -31,10 +31,8 @@
 
     def test_auth(self):
         token_client_v3 = token_client.V3TokenClient('fake_url')
-        response = fake_http.fake_http_response(
-            None, status=201,
-        )
-        body = {'access': {'token': 'fake_token'}}
+        response, body_text = fake_identity._fake_v3_response(None, None)
+        body = json.loads(body_text)
 
         with mock.patch.object(token_client_v3, 'post') as post_mock:
             post_mock.return_value = response, body
@@ -60,10 +58,8 @@
 
     def test_auth_with_project_id_and_domain_id(self):
         token_client_v3 = token_client.V3TokenClient('fake_url')
-        response = fake_http.fake_http_response(
-            None, status=201,
-        )
-        body = {'access': {'token': 'fake_token'}}
+        response, body_text = fake_identity._fake_v3_response(None, None)
+        body = json.loads(body_text)
 
         with mock.patch.object(token_client_v3, 'post') as post_mock:
             post_mock.return_value = response, body
@@ -103,10 +99,8 @@
 
     def test_auth_with_tenant(self):
         token_client_v3 = token_client.V3TokenClient('fake_url')
-        response = fake_http.fake_http_response(
-            None, status=201,
-        )
-        body = {'access': {'token': 'fake_token'}}
+        response, body_text = fake_identity._fake_v3_response(None, None)
+        body = json.loads(body_text)
 
         with mock.patch.object(token_client_v3, 'post') as post_mock:
             post_mock.return_value = response, body
@@ -138,13 +132,10 @@
 
     def test_request_with_str_body(self):
         token_client_v3 = token_client.V3TokenClient('fake_url')
-        response = fake_http.fake_http_response(
-            None, status=200,
-        )
-        body = str('{"access": {"token": "fake_token"}}')
 
         with mock.patch.object(token_client_v3, 'raw_request') as mock_raw_r:
-            mock_raw_r.return_value = response, body
+            mock_raw_r.return_value = (
+                fake_identity._fake_v3_response(None, None))
             resp, body = token_client_v3.request('GET', 'fake_uri')
 
         self.assertIsInstance(body, dict)
@@ -152,10 +143,8 @@
     def test_request_with_bytes_body(self):
         token_client_v3 = token_client.V3TokenClient('fake_url')
 
-        response = fake_http.fake_http_response(
-            None, status=200,
-        )
-        body = b'{"access": {"token": "fake_token"}}'
+        response, body_text = fake_identity._fake_v3_response(None, None)
+        body = body_text.encode('utf-8')
 
         with mock.patch.object(token_client_v3, 'raw_request') as mock_raw_r:
             mock_raw_r.return_value = response, body