Merge "Distinguish between luks and cryptsetup volume types"
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index a7c8fb7..15369de 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -3,6 +3,21 @@
 Tempest Configuration Guide
 ===========================
 
+This guide is a starting point for configuring tempest. It aims to elaborate
+on and explain some of the mandatory and common configuration settings and how
+they are used in conjunction. The source of truth on each option is the sample
+config file which explains the purpose of each individual option.
+
+Lock Path
+---------
+
+There are some tests and operations inside of tempest that need to be
+externally locked when running in parallel to prevent them from running at
+the same time. This is a mandatory step for configuring tempest and is still
+needed even when running serially. All that is needed to do this is:
+
+ #. Set the lock_path option in the oslo_concurrency group
+
 Auth/Credentials
 ----------------
 
diff --git a/requirements.txt b/requirements.txt
index f6e30ce..56796d8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,7 +12,6 @@
 python-ceilometerclient>=1.0.6
 python-glanceclient>=0.15.0
 python-keystoneclient>=1.1.0
-python-neutronclient>=2.3.11,<3
 python-cinderclient>=1.1.0
 python-heatclient>=0.3.0
 python-ironicclient>=0.2.1
diff --git a/tempest/api/compute/admin/test_flavors_negative.py b/tempest/api/compute/admin/test_flavors_negative.py
deleted file mode 100644
index c7eb9ae..0000000
--- a/tempest/api/compute/admin/test_flavors_negative.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# 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.
-
-import uuid
-
-from tempest_lib.common.utils import data_utils
-from tempest_lib import exceptions as lib_exc
-
-from tempest.api.compute import base
-from tempest.api_schema.request.compute.v2 import flavors
-from tempest import config
-from tempest import test
-
-
-CONF = config.CONF
-
-load_tests = test.NegativeAutoTest.load_tests
-
-
-class FlavorsAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
-
-    """
-    Tests Flavors API Create and Delete that require admin privileges
-    """
-
-    @classmethod
-    def skip_checks(cls):
-        super(FlavorsAdminNegativeTestJSON, cls).skip_checks()
-        if not test.is_extension_enabled('OS-FLV-EXT-DATA', 'compute'):
-            msg = "OS-FLV-EXT-DATA extension not enabled."
-            raise cls.skipException(msg)
-
-    @classmethod
-    def setup_clients(cls):
-        super(FlavorsAdminNegativeTestJSON, cls).setup_clients()
-        cls.client = cls.os_adm.flavors_client
-        cls.user_client = cls.os.flavors_client
-
-    @classmethod
-    def resource_setup(cls):
-        super(FlavorsAdminNegativeTestJSON, cls).resource_setup()
-        cls.flavor_name_prefix = 'test_flavor_'
-        cls.ram = 512
-        cls.vcpus = 1
-        cls.disk = 10
-        cls.ephemeral = 10
-        cls.swap = 1024
-        cls.rxtx = 2
-
-    @test.attr(type=['negative', 'gate'])
-    @test.idempotent_id('404451c0-c1ae-4448-8d50-d74f26f93ec8')
-    def test_get_flavor_details_for_deleted_flavor(self):
-        # Delete a flavor and ensure it is not listed
-        # Create a test flavor
-        flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-
-        # no need to specify flavor_id, we can get the flavor_id from a
-        # response of create_flavor() call.
-        flavor = self.client.create_flavor(flavor_name,
-                                           self.ram,
-                                           self.vcpus, self.disk,
-                                           None,
-                                           ephemeral=self.ephemeral,
-                                           swap=self.swap,
-                                           rxtx=self.rxtx)
-        # Delete the flavor
-        new_flavor_id = flavor['id']
-        self.client.delete_flavor(new_flavor_id)
-
-        # Deleted flavors can be seen via detailed GET
-        flavor = self.client.get_flavor_details(new_flavor_id)
-        self.assertEqual(flavor['name'], flavor_name)
-
-        # Deleted flavors should not show up in a list however
-        flavors = self.client.list_flavors_with_detail()
-        flag = True
-        for flavor in flavors:
-            if flavor['name'] == flavor_name:
-                flag = False
-        self.assertTrue(flag)
-
-    @test.attr(type=['negative', 'gate'])
-    @test.idempotent_id('6f56e7b7-7500-4d0c-9913-880ca1efed87')
-    def test_create_flavor_as_user(self):
-        # only admin user can create a flavor
-        flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        new_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(lib_exc.Forbidden,
-                          self.user_client.create_flavor,
-                          flavor_name, self.ram, self.vcpus, self.disk,
-                          new_flavor_id, ephemeral=self.ephemeral,
-                          swap=self.swap, rxtx=self.rxtx)
-
-    @test.attr(type=['negative', 'gate'])
-    @test.idempotent_id('a9a6dc02-8c14-4e05-a1ca-3468d4214882')
-    def test_delete_flavor_as_user(self):
-        # only admin user can delete a flavor
-        self.assertRaises(lib_exc.Forbidden,
-                          self.user_client.delete_flavor,
-                          self.flavor_ref_alt)
-
-
-@test.SimpleNegativeAutoTest
-class FlavorCreateNegativeTestJSON(base.BaseV2ComputeAdminTest,
-                                   test.NegativeAutoTest):
-    _service = CONF.compute.catalog_type
-    _schema = flavors.flavor_create
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 7a64de3..86d90f6 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -95,7 +95,8 @@
         self.assertEqual(quota_usage['volumes']['in_use'] + 1,
                          new_quota_usage['volumes']['in_use'])
 
-        self.assertEqual(quota_usage['gigabytes']['in_use'] + 1,
+        self.assertEqual(quota_usage['gigabytes']['in_use'] +
+                         volume["size"],
                          new_quota_usage['gigabytes']['in_use'])
 
     @test.attr(type='gate')
diff --git a/tempest/api/volume/admin/test_volume_quotas_negative.py b/tempest/api/volume/admin/test_volume_quotas_negative.py
index 98b7143..d7287f0 100644
--- a/tempest/api/volume/admin/test_volume_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_quotas_negative.py
@@ -31,7 +31,9 @@
     @classmethod
     def resource_setup(cls):
         super(BaseVolumeQuotasNegativeV2TestJSON, cls).resource_setup()
-        cls.shared_quota_set = {'gigabytes': 3, 'volumes': 1, 'snapshots': 1}
+        cls.default_volume_size = cls.volumes_client.default_volume_size
+        cls.shared_quota_set = {'gigabytes': 3 * cls.default_volume_size,
+                                'volumes': 1, 'snapshots': 1}
 
         # NOTE(gfidente): no need to restore original quota set
         # after the tests as they only work with tenant isolation.
@@ -67,14 +69,16 @@
                         self.demo_tenant_id,
                         **self.shared_quota_set)
 
-        new_quota_set = {'gigabytes': 2, 'volumes': 2, 'snapshots': 1}
+        new_quota_set = {'gigabytes': 2 * self.default_volume_size,
+                         'volumes': 2, 'snapshots': 1}
         self.quotas_client.update_quota_set(
             self.demo_tenant_id,
             **new_quota_set)
         self.assertRaises(lib_exc.OverLimit,
                           self.volumes_client.create_volume)
 
-        new_quota_set = {'gigabytes': 2, 'volumes': 1, 'snapshots': 2}
+        new_quota_set = {'gigabytes': 2 * self.default_volume_size,
+                         'volumes': 1, 'snapshots': 2}
         self.quotas_client.update_quota_set(
             self.demo_tenant_id,
             **self.shared_quota_set)
diff --git a/tempest/api_schema/response/compute/parameter_types.py b/tempest/api_schema/response/compute/parameter_types.py
index 4a1dfdd..90d4c8f 100644
--- a/tempest/api_schema/response/compute/parameter_types.py
+++ b/tempest/api_schema/response/compute/parameter_types.py
@@ -65,3 +65,17 @@
         }
     }
 }
+
+response_header = {
+    'connection': {'type': 'string'},
+    'content-length': {'type': 'string'},
+    'content-type': {'type': 'string'},
+    'status': {'type': 'string'},
+    'x-compute-request-id': {'type': 'string'},
+    'vary': {'type': 'string'},
+    'x-openstack-nova-api-version': {'type': 'string'},
+    'date': {
+        'type': 'string',
+        'format': 'data-time'
+    }
+}
diff --git a/tempest/api_schema/response/compute/servers.py b/tempest/api_schema/response/compute/servers.py
index f9c957b..3950173 100644
--- a/tempest/api_schema/response/compute/servers.py
+++ b/tempest/api_schema/response/compute/servers.py
@@ -71,6 +71,18 @@
             },
             'required': ['id', 'links']
         },
+        'fault': {
+            'type': 'object',
+            'properties': {
+                'code': {'type': 'integer'},
+                'created': {'type': 'string'},
+                'message': {'type': 'string'},
+                'details': {'type': 'string'},
+            },
+            # NOTE(gmann): 'details' is not necessary to be present
+            #  in the 'fault'. So it is not defined as 'required'.
+            'required': ['code', 'created', 'message']
+        },
         'user_id': {'type': 'string'},
         'tenant_id': {'type': 'string'},
         'created': {'type': 'string'},
@@ -83,7 +95,9 @@
     # NOTE(GMann): 'progress' attribute is present in the response
     # only when server's status is one of the progress statuses
     # ("ACTIVE","BUILD", "REBUILD", "RESIZE","VERIFY_RESIZE")
-    # So it is not defined as 'required'.
+    # 'fault' attribute is present in the response
+    # only when server's status is one of the  "ERROR", "DELETED".
+    # So they are not defined as 'required'.
     'required': ['id', 'name', 'status', 'image', 'flavor',
                  'user_id', 'tenant_id', 'created', 'updated',
                  'metadata', 'links', 'addresses']
@@ -144,8 +158,11 @@
                     },
                     'required': ['id', 'links', 'name']
                 }
-            }
+            },
+            'servers_links': parameter_types.links
         },
+        # NOTE(gmann): servers_links attribute is not necessary to be
+        # present always So it is not 'required'.
         'required': ['servers']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2/images.py b/tempest/api_schema/response/compute/v2/images.py
index 43dae38..3c0b80e 100644
--- a/tempest/api_schema/response/compute/v2/images.py
+++ b/tempest/api_schema/response/compute/v2/images.py
@@ -78,8 +78,11 @@
                     },
                     'required': ['id', 'links', 'name']
                 }
-            }
+            },
+            'images_links': parameter_types.links
         },
+        # NOTE(gmann): images_links attribute is not necessary to be
+        # present always So it is not 'required'.
         'required': ['images']
     }
 }
@@ -88,15 +91,16 @@
     'status_code': [202],
     'response_header': {
         'type': 'object',
-        'properties': {
-            'location': {
-                'type': 'string',
-                'format': 'uri'
-            }
-        },
-        'required': ['location']
+        'properties': parameter_types.response_header
     }
 }
+create_image['response_header']['properties'].update(
+    {'location': {
+        'type': 'string',
+        'format': 'uri'}
+     }
+)
+create_image['response_header']['required'] = ['location']
 
 delete = {
     'status_code': [204]
@@ -132,8 +136,11 @@
             'images': {
                 'type': 'array',
                 'items': common_image_schema
-            }
+            },
+            'images_links': parameter_types.links
         },
+        # NOTE(gmann): images_links attribute is not necessary to be
+        # present always So it is not 'required'.
         'required': ['images']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2/servers.py b/tempest/api_schema/response/compute/v2/servers.py
index c116bf5..ebee697 100644
--- a/tempest/api_schema/response/compute/v2/servers.py
+++ b/tempest/api_schema/response/compute/v2/servers.py
@@ -335,7 +335,11 @@
     'items']['properties'].update({
         'OS-EXT-IPS:type': {'type': 'string'},
         'OS-EXT-IPS-MAC:mac_addr': parameter_types.mac_address})
-
+# Defining 'servers_links' attributes for V2 server schema
+list_servers_detail['response_body'][
+    'properties'].update({'servers_links': parameter_types.links})
+# NOTE(gmann): servers_links attribute is not necessary to be
+# present always So it is not 'required'.
 
 rebuild_server = copy.deepcopy(update_server)
 rebuild_server['status_code'] = [202]
diff --git a/tempest/cli/simple_read_only/network/__init__.py b/tempest/cli/simple_read_only/network/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/network/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/network/test_neutron.py b/tempest/cli/simple_read_only/network/test_neutron.py
deleted file mode 100644
index e8b3554..0000000
--- a/tempest/cli/simple_read_only/network/test_neutron.py
+++ /dev/null
@@ -1,285 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# 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.
-
-import re
-
-from oslo_log import log as logging
-from tempest_lib import exceptions
-
-from tempest import cli
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class SimpleReadOnlyNeutronClientTest(cli.ClientTestBase):
-    """Basic, read-only tests for Neutron CLI client.
-
-    Checks return values and output of read-only commands.
-    These tests do not presume any content, nor do they create
-    their own. They only verify the structure of output if present.
-    """
-
-    @classmethod
-    def resource_setup(cls):
-        if (not CONF.service_available.neutron):
-            msg = "Skipping all Neutron cli tests because it is not available"
-            raise cls.skipException(msg)
-        super(SimpleReadOnlyNeutronClientTest, cls).resource_setup()
-
-    def neutron(self, *args, **kwargs):
-        return self.clients.neutron(*args,
-                                    endpoint_type=CONF.network.endpoint_type,
-                                    **kwargs)
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('84dd7190-2b98-4709-8e2c-3c1d25b9e7d2')
-    def test_neutron_fake_action(self):
-        self.assertRaises(exceptions.CommandFailed,
-                          self.neutron,
-                          'this-does-not-exist')
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('c598c337-313a-45ac-bf27-d6b4124a9e5b')
-    def test_neutron_net_list(self):
-        net_list = self.parser.listing(self.neutron('net-list'))
-        self.assertTableStruct(net_list, ['id', 'name', 'subnets'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('3e172b04-2e3b-4fcf-922d-99d5c803779f')
-    def test_neutron_ext_list(self):
-        ext = self.parser.listing(self.neutron('ext-list'))
-        self.assertTableStruct(ext, ['alias', 'name'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('2e0de814-52d6-4f81-be17-fe327072fc23')
-    @test.requires_ext(extension='dhcp_agent_scheduler', service='network')
-    def test_neutron_dhcp_agent_list_hosting_net(self):
-        self.neutron('dhcp-agent-list-hosting-net',
-                     params=CONF.compute.fixed_network_name)
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('8524a24a-3895-40a5-8c9d-49d4459cdda4')
-    @test.requires_ext(extension='agent', service='network')
-    def test_neutron_agent_list(self):
-        agents = self.parser.listing(self.neutron('agent-list'))
-        field_names = ['id', 'agent_type', 'host', 'alive', 'admin_state_up']
-        self.assertTableStruct(agents, field_names)
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('97c3ef92-7303-45f1-80db-b6622f176782')
-    @test.requires_ext(extension='router', service='network')
-    def test_neutron_floatingip_list(self):
-        self.neutron('floatingip-list')
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('823e0fee-404c-49a7-8bf3-d2f0383cc649')
-    @test.requires_ext(extension='metering', service='network')
-    def test_neutron_meter_label_list(self):
-        self.neutron('meter-label-list')
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('7fb76098-01f6-417f-b9c7-e630ba3f394b')
-    @test.requires_ext(extension='metering', service='network')
-    def test_neutron_meter_label_rule_list(self):
-        self.neutron('meter-label-rule-list')
-
-    @test.requires_ext(extension='lbaas_agent_scheduler', service='network')
-    def _test_neutron_lbaas_command(self, command):
-        try:
-            self.neutron(command)
-        except exceptions.CommandFailed as e:
-            if '404 Not Found' not in e.stderr:
-                self.fail('%s: Unexpected failure.' % command)
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('396d1d87-fd0c-4716-9ff0-f1baa54c6c61')
-    def test_neutron_lb_healthmonitor_list(self):
-        self._test_neutron_lbaas_command('lb-healthmonitor-list')
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('f41fa54d-5cd8-4f2c-bb4e-13abc72dccb6')
-    def test_neutron_lb_member_list(self):
-        self._test_neutron_lbaas_command('lb-member-list')
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('3ec04885-7573-4cce-b086-5722c0b00d85')
-    def test_neutron_lb_pool_list(self):
-        self._test_neutron_lbaas_command('lb-pool-list')
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('1ab530e0-ec87-498f-baf2-85f6635a2ad9')
-    def test_neutron_lb_vip_list(self):
-        self._test_neutron_lbaas_command('lb-vip-list')
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('e92f7362-4009-4b37-afee-f469105b24e7')
-    @test.requires_ext(extension='external-net', service='network')
-    def test_neutron_net_external_list(self):
-        net_ext_list = self.parser.listing(self.neutron('net-external-list'))
-        self.assertTableStruct(net_ext_list, ['id', 'name', 'subnets'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('ed840980-7c84-4b6e-b280-f13c5848a0e9')
-    def test_neutron_port_list(self):
-        port_list = self.parser.listing(self.neutron('port-list'))
-        self.assertTableStruct(port_list, ['id', 'name', 'mac_address',
-                                           'fixed_ips'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('dded0dfa-f2ac-4c1f-bc90-69fd06dd7132')
-    @test.requires_ext(extension='quotas', service='network')
-    def test_neutron_quota_list(self):
-        self.neutron('quota-list')
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('927fca1e-4397-42a2-ba47-d738299466de')
-    @test.requires_ext(extension='router', service='network')
-    def test_neutron_router_list(self):
-        router_list = self.parser.listing(self.neutron('router-list'))
-        self.assertTableStruct(router_list, ['id', 'name',
-                                             'external_gateway_info'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('e2e3d2d5-1aee-499d-84d9-37382dcf26ff')
-    @test.requires_ext(extension='security-group', service='network')
-    def test_neutron_security_group_list(self):
-        security_grp = self.parser.listing(self.neutron('security-group-list'))
-        self.assertTableStruct(security_grp, ['id', 'name', 'description'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('288602c2-8b59-44cd-8c5d-1ec916a114d3')
-    @test.requires_ext(extension='security-group', service='network')
-    def test_neutron_security_group_rule_list(self):
-        security_grp = self.parser.listing(self.neutron
-                                           ('security-group-rule-list'))
-        self.assertTableStruct(security_grp, ['id', 'security_group',
-                                              'direction', 'protocol',
-                                              'remote_ip_prefix',
-                                              'remote_group'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('2a874a08-b9c9-4f0f-82ef-8cadb15bbd5d')
-    def test_neutron_subnet_list(self):
-        subnet_list = self.parser.listing(self.neutron('subnet-list'))
-        self.assertTableStruct(subnet_list, ['id', 'name', 'cidr',
-                                             'allocation_pools'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('048e1ec3-cf6c-4066-b262-2028e03ce825')
-    @test.requires_ext(extension='vpnaas', service='network')
-    def test_neutron_vpn_ikepolicy_list(self):
-        ikepolicy = self.parser.listing(self.neutron('vpn-ikepolicy-list'))
-        self.assertTableStruct(ikepolicy, ['id', 'name',
-                                           'auth_algorithm',
-                                           'encryption_algorithm',
-                                           'ike_version', 'pfs'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('bb8902b7-b2e6-49fd-b9bd-a26dd99732df')
-    @test.requires_ext(extension='vpnaas', service='network')
-    def test_neutron_vpn_ipsecpolicy_list(self):
-        ipsecpolicy = self.parser.listing(self.neutron('vpn-ipsecpolicy-list'))
-        self.assertTableStruct(ipsecpolicy, ['id', 'name',
-                                             'auth_algorithm',
-                                             'encryption_algorithm',
-                                             'pfs'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('c0f33f9a-0ba9-4177-bcd5-dce34b81d523')
-    @test.requires_ext(extension='vpnaas', service='network')
-    def test_neutron_vpn_service_list(self):
-        vpn_list = self.parser.listing(self.neutron('vpn-service-list'))
-        self.assertTableStruct(vpn_list, ['id', 'name',
-                                          'router_id', 'status'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('bb142f8a-e568-405f-b1b7-4cb458de7971')
-    @test.requires_ext(extension='vpnaas', service='network')
-    def test_neutron_ipsec_site_connection_list(self):
-        ipsec_site = self.parser.listing(self.neutron
-                                         ('ipsec-site-connection-list'))
-        self.assertTableStruct(ipsec_site, ['id', 'name',
-                                            'peer_address',
-                                            'peer_cidrs',
-                                            'route_mode',
-                                            'auth_mode', 'status'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('89baff14-8cb7-4ad8-9c24-b0278711170b')
-    @test.requires_ext(extension='fwaas', service='network')
-    def test_neutron_firewall_list(self):
-        firewall_list = self.parser.listing(self.neutron
-                                            ('firewall-list'))
-        self.assertTableStruct(firewall_list, ['id', 'name',
-                                               'firewall_policy_id'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('996e418a-2a51-4018-9602-478ca8053e61')
-    @test.requires_ext(extension='fwaas', service='network')
-    def test_neutron_firewall_policy_list(self):
-        firewall_policy = self.parser.listing(self.neutron
-                                              ('firewall-policy-list'))
-        self.assertTableStruct(firewall_policy, ['id', 'name',
-                                                 'firewall_rules'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('d4638dd6-98d4-4400-a920-26572de1a6fc')
-    @test.requires_ext(extension='fwaas', service='network')
-    def test_neutron_firewall_rule_list(self):
-        firewall_rule = self.parser.listing(self.neutron
-                                            ('firewall-rule-list'))
-        self.assertTableStruct(firewall_rule, ['id', 'name',
-                                               'firewall_policy_id',
-                                               'summary', 'enabled'])
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('1c4551e1-e3f3-4af2-8a40-c3f551e4a536')
-    def test_neutron_help(self):
-        help_text = self.neutron('help')
-        lines = help_text.split('\n')
-        self.assertFirstLineStartsWith(lines, 'usage: neutron')
-
-        commands = []
-        cmds_start = lines.index('Commands for API v2.0:')
-        command_pattern = re.compile('^ {2}([a-z0-9\-\_]+)')
-        for line in lines[cmds_start:]:
-            match = command_pattern.match(line)
-            if match:
-                commands.append(match.group(1))
-        commands = set(commands)
-        wanted_commands = set(('net-create', 'subnet-list', 'port-delete',
-                               'router-show', 'agent-update', 'help'))
-        self.assertFalse(wanted_commands - commands)
-
-    # Optional arguments:
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('381e6fe3-cddc-47c9-a773-70ddb2f79a91')
-    def test_neutron_version(self):
-        self.neutron('', flags='--version')
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('bcad0e07-da8c-4c7c-8ab6-499e5d7ab8cb')
-    def test_neutron_debug_net_list(self):
-        self.neutron('net-list', flags='--debug')
-
-    @test.attr(type='smoke')
-    @test.idempotent_id('3e42d78e-65e5-4e8f-8c29-ca7be8feebb4')
-    def test_neutron_quiet_net_list(self):
-        self.neutron('net-list', flags='--quiet')
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 0735eeb..ab23dea 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -118,6 +118,7 @@
 import tempest.auth
 from tempest import config
 from tempest.services.compute.json import flavors_client
+from tempest.services.compute.json import floating_ips_client
 from tempest.services.compute.json import security_groups_client
 from tempest.services.compute.json import servers_client
 from tempest.services.identity.v2.json import identity_client
@@ -194,6 +195,8 @@
                                                         **compute_params)
         self.flavors = flavors_client.FlavorsClientJSON(_auth,
                                                         **compute_params)
+        self.floating_ips = floating_ips_client.FloatingIPsClientJSON(
+            _auth, **compute_params)
         self.secgroups = security_groups_client.SecurityGroupsClientJSON(
             _auth, **compute_params)
         self.objects = object_client.ObjectClient(_auth,
@@ -451,15 +454,31 @@
             # validate neutron is enabled and ironic disabled:
             if (CONF.service_available.neutron and
                     not CONF.baremetal.driver_enabled):
+                _floating_is_alive = False
                 for network_name, body in found['addresses'].items():
                     for addr in body:
                         ip = addr['addr']
-                        if addr.get('OS-EXT-IPS:type', 'fixed') == 'fixed':
+                        # If floatingip_for_ssh is at True, it's assumed
+                        # you want to use the floating IP to reach the server,
+                        # fallback to fixed IP, then other type.
+                        # This is useful in multi-node environment.
+                        if CONF.compute.use_floatingip_for_ssh:
+                            if addr.get('OS-EXT-IPS:type',
+                                        'floating') == 'floating':
+                                self._ping_ip(ip, 60)
+                                _floating_is_alive = True
+                        elif addr.get('OS-EXT-IPS:type', 'fixed') == 'fixed':
                             namespace = _get_router_namespace(client,
                                                               network_name)
                             self._ping_ip(ip, 60, namespace)
                         else:
                             self._ping_ip(ip, 60)
+                # if floatingip_for_ssh is at True, validate found a
+                # floating IP and ping worked.
+                if CONF.compute.use_floatingip_for_ssh:
+                    self.assertTrue(_floating_is_alive,
+                                    "Server %s has no floating IP." %
+                                    server['name'])
             else:
                 addr = found['addresses']['private'][0]['addr']
                 self._ping_ip(addr, 60)
@@ -838,6 +857,10 @@
         # create to security group(s) after server spawning
         for secgroup in server['secgroups']:
             client.servers.add_security_group(server_id, secgroup)
+        if CONF.compute.use_floatingip_for_ssh:
+            floating_ip = client.floating_ips.create_floating_ip()
+            client.floating_ips.associate_floating_ip_to_server(
+                floating_ip['ip'], server_id)
 
 
 def destroy_servers(servers):
@@ -847,13 +870,32 @@
     for server in servers:
         client = client_for_user(server['owner'])
 
-        response = _get_server_by_name(client, server['name'])
-        if not response:
+        res = _get_server_by_name(client, server['name'])
+        if not res:
             LOG.info("Server '%s' does not exist" % server['name'])
             continue
+        res = client.servers.get_server(res['id'])
 
-        client.servers.delete_server(response['id'])
-        client.servers.wait_for_server_termination(response['id'],
+        # we iterate all interfaces until we find a floating IP
+        # and stop looping after dropping it.
+        def _find_first_floating():
+            if (CONF.service_available.neutron and
+                    not CONF.baremetal.driver_enabled and
+                    CONF.compute.use_floatingip_for_ssh):
+                for network_name, body in res['addresses'].items():
+                    for addr in body:
+                        ip = addr['addr']
+                        if addr.get('OS-EXT-IPS:type',
+                                    'floating') == 'floating':
+                            (client.floating_ips.
+                             disassociate_floating_ip_from_server(
+                                 ip, res['id']))
+                            client.floating_ips.delete_floating_ip(ip)
+                            return
+
+        _find_first_floating()
+        client.servers.delete_server(res['id'])
+        client.servers.wait_for_server_termination(res['id'],
                                                    ignore_error=True)
 
 
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index 4d66ffc..bff9a0a 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -53,7 +53,7 @@
     if identity_version == 'v3':
         conf_attributes.append('domain_name')
     # Read the parts of credentials from config
-    params = DEFAULT_PARAMS
+    params = DEFAULT_PARAMS.copy()
     section, prefix = CREDENTIAL_TYPES[credential_type]
     for attr in conf_attributes:
         _section = getattr(CONF, section)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 7a60403..af7b683 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -393,6 +393,8 @@
                                                    "floating ip")
 
     @test.idempotent_id('1546850e-fbaa-42f5-8b5f-03d8a6a95f15')
+    @testtools.skipIf(CONF.baremetal.driver_enabled,
+                      'Baremetal relies on a shared physical network.')
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_connectivity_between_vms_on_different_networks(self):