Merge "Fix for volume quota class test"
diff --git a/HACKING.rst b/HACKING.rst
index c0a857c..cef4f21 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -232,9 +232,9 @@
   and xml version of the same test class there could still be a race between
   methods.
 
-- The rand_name() function from tempest.common.utils.data_utils should be used
-  anywhere a resource is created with a name. Static naming should be avoided
-  to prevent resource conflicts.
+- The rand_name() function from tempest.lib.common.utils.data_utils should be
+  used anywhere a resource is created with a name. Static naming should be
+  avoided to prevent resource conflicts.
 
 - If the execution of a set of tests is required to be serialized then locking
   can be used to perform this. See AggregatesAdminTest in
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 2314222..4accd94 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -52,8 +52,7 @@
  #. ``uri_v3``
 
 The ``auth_version`` option is used to tell Tempest whether it should be using
-keystone's v2 or v3 api for communicating with keystone. (except for the
-identity api tests which will test a specific version) The two uri options are
+keystone's v2 or v3 api for communicating with keystone. The two uri options are
 used to tell Tempest the url of the keystone endpoint. The ``uri`` option is
 used for keystone v2 request and ``uri_v3`` is used for keystone v3. You want to
 ensure that which ever version you set for ``auth_version`` has its uri option
diff --git a/releasenotes/notes/add-floating-ip-config-option-e5774bf77702ce9f.yaml b/releasenotes/notes/add-floating-ip-config-option-e5774bf77702ce9f.yaml
new file mode 100644
index 0000000..8221d78
--- /dev/null
+++ b/releasenotes/notes/add-floating-ip-config-option-e5774bf77702ce9f.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - A new config option in the network-feature-enabled section, floating_ips,
+    to specify whether floating ips are available in the cloud under test. By
+    default this is set to True.
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index 2769245..faa7b5d 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -30,6 +30,12 @@
     floating_ip = None
 
     @classmethod
+    def skip_checks(cls):
+        super(FloatingIPsTestJSON, cls).skip_checks()
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
+
+    @classmethod
     def setup_clients(cls):
         super(FloatingIPsTestJSON, cls).setup_clients()
         cls.client = cls.floating_ips_client
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index 96983b0..483bd95 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -28,6 +28,12 @@
 class FloatingIPsNegativeTestJSON(base.BaseFloatingIPsTest):
 
     @classmethod
+    def skip_checks(cls):
+        super(FloatingIPsNegativeTestJSON, cls).skip_checks()
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
+
+    @classmethod
     def setup_clients(cls):
         super(FloatingIPsNegativeTestJSON, cls).setup_clients()
         cls.client = cls.floating_ips_client
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 71f5f13..74d2dc4 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -24,6 +24,12 @@
 class FloatingIPDetailsTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
+    def skip_checks(cls):
+        super(FloatingIPDetailsTestJSON, cls).skip_checks()
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
+
+    @classmethod
     def setup_clients(cls):
         super(FloatingIPDetailsTestJSON, cls).setup_clients()
         cls.client = cls.floating_ips_client
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
index 9d70bf7..b5bbb8c 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
@@ -26,6 +26,12 @@
 class FloatingIPDetailsNegativeTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
+    def skip_checks(cls):
+        super(FloatingIPDetailsNegativeTestJSON, cls).skip_checks()
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
+
+    @classmethod
     def setup_clients(cls):
         super(FloatingIPDetailsNegativeTestJSON, cls).setup_clients()
         cls.client = cls.floating_ips_client
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 76b9c44..6f072b2 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -531,6 +531,10 @@
         self.client.unshelve_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
 
+        images = self.compute_images_client.list_images(**params)['images']
+        msg = ('After unshelve, shelved image is not deleted.')
+        self.assertEmpty(images, msg)
+
     @decorators.idempotent_id('af8eafd4-38a7-4a4b-bdbc-75145a580560')
     def test_stop_start_server(self):
         self.client.stop_server(self.server_id)
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 83151b3..b0ef3bc 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -65,6 +65,8 @@
     @decorators.idempotent_id('4842e0cf-e87d-4d9d-b61f-f4791da3cacc')
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
+    @testtools.skipUnless(CONF.network_feature_enabled.floating_ips,
+                          "Floating ips are not available")
     def test_rescued_vm_associate_dissociate_floating_ip(self):
         # Association of floating IP to a rescued vm
         floating_ip_body = self.floating_ips_client.create_floating_ip(
diff --git a/tempest/api/identity/admin/v3/test_oauth_consumers.py b/tempest/api/identity/admin/v3/test_oauth_consumers.py
index f06fb8f..970ead3 100644
--- a/tempest/api/identity/admin/v3/test_oauth_consumers.py
+++ b/tempest/api/identity/admin/v3/test_oauth_consumers.py
@@ -14,7 +14,7 @@
 #    under the License.
 
 from tempest.api.identity import base
-from tempest.common.utils import data_utils
+from tempest.lib.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as exceptions
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index c83dd7f..4d41e33 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -10,11 +10,16 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest.api.network import base
+from tempest import config
 from tempest.lib.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 
+CONF = config.CONF
+
 
 class ExternalNetworksTestJSON(base.BaseAdminNetworkTest):
 
@@ -91,6 +96,8 @@
         self.assertFalse(show_net['router:external'])
 
     @decorators.idempotent_id('82068503-2cf2-4ed4-b3be-ecb89432e4bb')
+    @testtools.skipUnless(CONF.network_feature_enabled.floating_ips,
+                          'Floating ips are not availabled')
     def test_delete_external_networks_with_floating_ip(self):
         # Verifies external network can be deleted while still holding
         # (unassociated) floating IPs
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index 11f520a..7ee819e 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -34,6 +34,8 @@
         if not CONF.network.public_network_id:
             msg = "The public_network_id option must be specified."
             raise cls.skipException(msg)
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
 
     @classmethod
     def setup_clients(cls):
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index f0f92ac..c799b15 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -49,6 +49,8 @@
         if not CONF.network.public_network_id:
             msg = "The public_network_id option must be specified."
             raise cls.skipException(msg)
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index f5830ab..5ca17fe 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -40,6 +40,8 @@
         if not CONF.network.public_network_id:
             msg = "The public_network_id option must be specified."
             raise cls.skipException(msg)
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/config.py b/tempest/config.py
index a2e0877..989d53a 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -647,6 +647,9 @@
     cfg.BoolOpt('port_security',
                 default=False,
                 help="Does the test environment support port security?"),
+    cfg.BoolOpt('floating_ips',
+                default=True,
+                help='Does the test environment support floating_ips')
 ]
 
 validation_group = cfg.OptGroup(name='validation',
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 5fee801..eae1056 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -103,6 +103,8 @@
     @decorators.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
+    @testtools.skipUnless(CONF.network_feature_enabled.floating_ips,
+                          'Floating ips are not available')
     @test.services('compute', 'volume', 'image', 'network')
     def test_minimum_basic_scenario(self):
         image = self.glance_image_create()
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index c2fc1a7..ec6d362 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -48,6 +48,8 @@
             msg = ('Either project_networks_reachable must be "true", or '
                    'public_network_id must be defined.')
             raise cls.skipException(msg)
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
 
     @classmethod
     def setup_credentials(cls):
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index d2907a0..c76c082 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -90,6 +90,8 @@
             if not test.is_extension_enabled(ext, 'network'):
                 msg = "%s extension not enabled." % ext
                 raise cls.skipException(msg)
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
 
     @classmethod
     def setup_credentials(cls):
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index c581812..3504a44 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -51,6 +51,8 @@
         if CONF.network.shared_physical_network:
             msg = 'Deployment uses a shared physical network'
             raise cls.skipException(msg)
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
 
     @classmethod
     def setup_credentials(cls):
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 413f315..41c60f1 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -148,6 +148,8 @@
             msg = ('Deployment uses a shared physical network, security '
                    'groups not supported')
             raise cls.skipException(msg)
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
 
     @classmethod
     def setup_credentials(cls):
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 2be9e06..77563b3 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -43,6 +43,12 @@
      * Terminate the instance
     """
 
+    @classmethod
+    def skip_checks(cls):
+        super(TestServerBasicOps, cls).skip_checks()
+        if not CONF.network_feature_enabled.floating_ips:
+            raise cls.skipException("Floating ips are not available")
+
     def setUp(self):
         super(TestServerBasicOps, self).setUp()
         self.run_ssh = CONF.validation.run_validation