Merge "Enable H407,H305,H307,E122 ignore E123"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 4dcf460..9ace4ea 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -397,6 +397,9 @@
 # If false, skip all nova v3 tests. (boolean value)
 #api_v3=false
 
+# If false skip all v2 api tests with xml (boolean value)
+#xml_api_v2=true
+
 # If false, skip disk config tests (boolean value)
 #disk_config=true
 
@@ -416,6 +419,10 @@
 # password? (boolean value)
 #change_password=false
 
+# Does the test environment support obtaining instance serial
+# console output? (boolean value)
+#console_output=true
+
 # Does the test environment support resizing? (boolean value)
 #resize=false
 
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index a3295eb..343a39a 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -37,6 +37,9 @@
     def setUpClass(cls):
         cls.set_network_resources()
         super(BaseComputeTest, cls).setUpClass()
+        if getattr(cls, '_interface', None) == 'xml' and cls._api_version == 2:
+            if not CONF.compute_feature_enabled.xml_api_v2:
+                raise cls.skipException('XML API is not enabled')
 
         # TODO(andreaf) WE should care also for the alt_manager here
         # but only once client lazy load in the manager is done
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 37b1224..005f38a 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -348,6 +348,8 @@
         lines = len(output.split('\n'))
         self.assertEqual(lines, 10)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
+                          'Console output not supported.')
     @test.attr(type='gate')
     def test_get_console_output(self):
         # Positive test:Should be able to GET the console output
@@ -364,6 +366,8 @@
 
         self.wait_for(self._get_output)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
+                          'Console output not supported.')
     @test.attr(type='gate')
     def test_get_console_output_server_id_in_shutoff_status(self):
         # Positive test:Should be able to GET the console output
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index 27ac5b6..d05e158 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -339,6 +339,8 @@
         lines = len(output.split('\n'))
         self.assertEqual(lines, 10)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
+                          'Console output not supported.')
     @test.attr(type='gate')
     def test_get_console_output(self):
         # Positive test:Should be able to GET the console output
@@ -355,6 +357,8 @@
 
         self.wait_for(self._get_output)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
+                          'Console output not supported.')
     @test.attr(type='gate')
     def test_get_console_output_server_id_in_shutoff_status(self):
         # Positive test:Should be able to GET the console output
diff --git a/tempest/api/compute/v3/servers/test_server_rescue_negative.py b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
index 83fe128..6d192a3 100644
--- a/tempest/api/compute/v3/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
@@ -56,7 +56,8 @@
 
     @classmethod
     def tearDownClass(cls):
-        cls.delete_volume(cls.volume['id'])
+        if hasattr(cls, 'volume'):
+            cls.delete_volume(cls.volume['id'])
         super(ServerRescueNegativeV3Test, cls).tearDownClass()
 
     def _detach(self, server_id, volume_id):
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 8eb7d33..3996cc1 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -18,9 +18,12 @@
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest import exceptions
+from tempest.openstack.common import log as logging
 import tempest.test
 
 CONF = config.CONF
+LOG = logging.getLogger(__name__)
 
 
 class BaseIdentityAdminTest(tempest.test.BaseTestCase):
@@ -195,19 +198,36 @@
                 description=self.test_description)
             self.domains.append(self.domain)
 
+        @staticmethod
+        def _try_wrapper(func, item, **kwargs):
+            try:
+                if kwargs:
+                    func(item['id'], kwargs)
+                else:
+                    func(item['id'])
+            except exceptions.NotFound:
+                pass
+            except Exception:
+                LOG.exception("Unexpected exception occurred in %s deletion."
+                              " But ignored here." % item['id'])
+
         def teardown_all(self):
+            # NOTE(masayukig): v3 client doesn't have v2 method.
+            # (e.g. delete_tenant) So we need to check resources existence
+            # before using client methods.
             for user in self.users:
-                self.client.delete_user(user['id'])
+                self._try_wrapper(self.client.delete_user, user)
             for tenant in self.tenants:
-                self.client.delete_tenant(tenant['id'])
+                self._try_wrapper(self.client.delete_tenant, tenant)
             for role in self.roles:
-                self.client.delete_role(role['id'])
+                self._try_wrapper(self.client.delete_role, role)
             for v3_user in self.v3_users:
-                self.client.delete_user(v3_user['id'])
+                self._try_wrapper(self.client.delete_user, v3_user)
             for v3_project in self.projects:
-                self.client.delete_project(v3_project['id'])
+                self._try_wrapper(self.client.delete_project, v3_project)
             for v3_role in self.v3_roles:
-                self.client.delete_role(v3_role['id'])
+                self._try_wrapper(self.client.delete_role, v3_role)
             for domain in self.domains:
-                self.client.update_domain(domain['id'], enabled=False)
-                self.client.delete_domain(domain['id'])
+                self._try_wrapper(self.client.update_domain, domain,
+                                  enabled=False)
+                self._try_wrapper(self.client.delete_domain, domain)
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 86815b3..26e3ac6 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -67,16 +67,17 @@
             cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
             _, resources = cls.client.list_resources(cls.stack_identifier)
         except exceptions.TimeoutException as e:
-            # attempt to log the server console to help with debugging
-            # the cause of the server not signalling the waitcondition
-            # to heat.
-            resp, body = cls.client.get_resource(cls.stack_identifier,
-                                                 'Server')
-            server_id = body['physical_resource_id']
-            LOG.debug('Console output for %s', server_id)
-            resp, output = cls.servers_client.get_console_output(
-                server_id, None)
-            LOG.debug(output)
+            if CONF.compute_feature_enabled.console_output:
+                # attempt to log the server console to help with debugging
+                # the cause of the server not signalling the waitcondition
+                # to heat.
+                resp, body = cls.client.get_resource(cls.stack_identifier,
+                                                     'Server')
+                server_id = body['physical_resource_id']
+                LOG.debug('Console output for %s', server_id)
+                resp, output = cls.servers_client.get_console_output(
+                    server_id, None)
+                LOG.debug(output)
             raise e
 
         cls.test_resources = {}
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index 05d758f..f711f2f 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -373,31 +373,6 @@
             LOG.warn('network with name: %s not found for delete' %
                      network_name)
 
-    def _cleanup_ports(self, network_id):
-        # TODO(mlavalle) This method will be removed once patch
-        # https://review.openstack.org/#/c/46563/ merges in Neutron
-        if not self.ports:
-            if self.tempest_client:
-                resp, resp_body = self.network_admin_client.list_ports()
-            else:
-                resp_body = self.network_admin_client.list_ports()
-            self.ports = resp_body['ports']
-        ports_to_delete = [
-            port
-            for port in self.ports
-            if (port['network_id'] == network_id and
-                port['device_owner'] != 'network:router_interface' and
-                port['device_owner'] != 'network:dhcp')
-        ]
-        for port in ports_to_delete:
-            try:
-                LOG.info('Cleaning up port id %s, name %s' %
-                         (port['id'], port['name']))
-                self.network_admin_client.delete_port(port['id'])
-            except exceptions.NotFound:
-                LOG.warn('Port id: %s, name %s not found for clean-up' %
-                         (port['id'], port['name']))
-
     def _clear_isolated_net_resources(self):
         net_client = self.network_admin_client
         for cred in self.isolated_net_resources:
@@ -419,11 +394,6 @@
                              router['name'])
                 self._clear_isolated_router(router['id'], router['name'])
             if (not self.network_resources or
-                self.network_resources.get('network')):
-                # TODO(mlavalle) This method call will be removed once patch
-                # https://review.openstack.org/#/c/46563/ merges in Neutron
-                self._cleanup_ports(network['id'])
-            if (not self.network_resources or
                 self.network_resources.get('subnet')):
                 self._clear_isolated_subnet(subnet['id'], subnet['name'])
             if (not self.network_resources or
diff --git a/tempest/config.py b/tempest/config.py
index 3b61700..af6dd7a 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -273,6 +273,9 @@
     cfg.BoolOpt('api_v3',
                 default=False,
                 help="If false, skip all nova v3 tests."),
+    cfg.BoolOpt('xml_api_v2',
+                default=True,
+                help="If false skip all v2 api tests with xml"),
     cfg.BoolOpt('disk_config',
                 default=True,
                 help="If false, skip disk config tests"),
@@ -292,6 +295,10 @@
                 default=False,
                 help="Does the test environment support changing the admin "
                      "password?"),
+    cfg.BoolOpt('console_output',
+                default=True,
+                help="Does the test environment support obtaining instance "
+                     "serial console output?"),
     cfg.BoolOpt('resize',
                 default=False,
                 help="Does the test environment support resizing?"),
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index c8859b4..203b653 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -490,6 +490,9 @@
         return linux_client
 
     def _log_console_output(self, servers=None):
+        if not CONF.compute_feature_enabled.console_output:
+            LOG.debug('Console output not supported, cannot log')
+            return
         if not servers:
             servers = self.compute_client.servers.list()
         for server in servers: