Merge "rm pyc files before test runs"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 0f2b2cf..13ee8fe 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -78,7 +78,7 @@
 #
 
 # List of logger=LEVEL pairs. (list value)
-#default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN
+#default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN
 
 # Enables or disables fatal status of deprecations. (boolean value)
 #fatal_deprecations = false
diff --git a/requirements.txt b/requirements.txt
index 1e4c40b..e939c5c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,7 +5,7 @@
 anyjson>=0.3.3
 httplib2>=0.7.5
 jsonschema>=2.0.0,<3.0.0
-testtools>=0.9.36,!=1.2.0,!=1.4.0
+testtools>=0.9.36,!=1.2.0
 lxml>=2.3
 boto>=2.32.1
 paramiko>=1.13.0
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 47f2b52..40cf04f 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -212,6 +212,24 @@
                                                 port_range_max,
                                                 remote_ip_prefix=ip_prefix)
 
+    @test.attr(type='smoke')
+    def test_create_security_group_rule_with_protocol_integer_value(self):
+        # Verify creating security group rule with the
+        # protocol as integer value
+        # arguments : "protocol": 17
+        group_create_body, _ = self._create_security_group()
+        direction = 'ingress'
+        protocol = 17
+        security_group_id = group_create_body['security_group']['id']
+        _, rule_create_body = self.client.create_security_group_rule(
+            security_group_id=security_group_id,
+            direction=direction,
+            protocol=protocol
+        )
+        sec_group_rule = rule_create_body['security_group_rule']
+        self.assertEqual(sec_group_rule['direction'], direction)
+        self.assertEqual(int(sec_group_rule['protocol']), protocol)
+
 
 class SecGroupTestXML(SecGroupTest):
     _interface = 'xml'
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index bf014a8..1357d31 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -23,17 +23,16 @@
 LOG = logging.getLogger(__name__)
 
 
-class VolumesBackupsTest(base.BaseVolumeV1AdminTest):
+class VolumesBackupsV2Test(base.BaseVolumeAdminTest):
     _interface = "json"
 
     @classmethod
     def resource_setup(cls):
-        super(VolumesBackupsTest, cls).resource_setup()
+        super(VolumesBackupsV2Test, cls).resource_setup()
 
         if not CONF.volume_feature_enabled.backup:
             raise cls.skipException("Cinder backup feature disabled")
 
-        cls.backups_adm_client = cls.os_adm.backups_client
         cls.volume = cls.create_volume()
 
     @test.attr(type='smoke')
@@ -71,3 +70,7 @@
                                                        'available')
         self.admin_volume_client.wait_for_volume_status(
             restore['volume_id'], 'available')
+
+
+class VolumesBackupsV1Test(VolumesBackupsV2Test):
+    _api_version = 1
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index f9f03ac..5d99123 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -176,6 +176,7 @@
             cls.admin_volume_client = cls.os_adm.volumes_client
             cls.hosts_client = cls.os_adm.volume_hosts_client
             cls.admin_snapshots_client = cls.os_adm.snapshots_client
+            cls.backups_adm_client = cls.os_adm.backups_client
         elif cls._api_version == 2:
             if not CONF.volume_feature_enabled.api_v2:
                 msg = "Volume API v2 is disabled"
@@ -185,6 +186,7 @@
             cls.admin_volume_client = cls.os_adm.volumes_v2_client
             cls.hosts_client = cls.os_adm.volume_hosts_v2_client
             cls.admin_snapshots_client = cls.os_adm.snapshots_v2_client
+            cls.backups_adm_client = cls.os_adm.backups_v2_client
 
     @classmethod
     def resource_cleanup(cls):
diff --git a/tempest/clients.py b/tempest/clients.py
index 9546502..756614d 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -187,6 +187,7 @@
     VolumeTypesV2ClientJSON
 from tempest.services.volume.v2.json.availability_zone_client import \
     VolumeV2AvailabilityZoneClientJSON
+from tempest.services.volume.v2.json.backups_client import BackupsClientV2JSON
 from tempest.services.volume.v2.json.extensions_client import \
     ExtensionsV2ClientJSON as VolumeV2ExtensionClientJSON
 from tempest.services.volume.v2.json.qos_client import QosSpecsV2ClientJSON
@@ -436,6 +437,7 @@
 
     def _set_volume_json_clients(self):
         self.backups_client = BackupsClientJSON(self.auth_provider)
+        self.backups_v2_client = BackupsClientV2JSON(self.auth_provider)
         self.snapshots_client = SnapshotsClientJSON(self.auth_provider)
         self.snapshots_v2_client = SnapshotsV2ClientJSON(self.auth_provider)
         self.volumes_client = VolumesClientJSON(self.auth_provider)
diff --git a/tempest/openstack/common/__init__.py b/tempest/openstack/common/__init__.py
index d1223ea..e69de29 100644
--- a/tempest/openstack/common/__init__.py
+++ b/tempest/openstack/common/__init__.py
@@ -1,17 +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
-
-
-six.add_move(six.MovedModule('mox', 'mox', 'mox3.mox'))
diff --git a/tempest/openstack/common/_i18n.py b/tempest/openstack/common/_i18n.py
new file mode 100644
index 0000000..fdc8327
--- /dev/null
+++ b/tempest/openstack/common/_i18n.py
@@ -0,0 +1,45 @@
+#    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.
+
+"""oslo.i18n integration module.
+
+See http://docs.openstack.org/developer/oslo.i18n/usage.html
+
+"""
+
+try:
+    import oslo.i18n
+
+    # NOTE(dhellmann): This reference to o-s-l-o will be replaced by the
+    # application name when this module is synced into the separate
+    # repository. It is OK to have more than one translation function
+    # using the same domain, since there will still only be one message
+    # catalog.
+    _translators = oslo.i18n.TranslatorFactory(domain='tempest')
+
+    # The primary translation function using the well-known name "_"
+    _ = _translators.primary
+
+    # Translators for log levels.
+    #
+    # The abbreviated names are meant to reflect the usual use of a short
+    # name like '_'. The "L" is for "log" and the other letter comes from
+    # the level.
+    _LI = _translators.log_info
+    _LW = _translators.log_warning
+    _LE = _translators.log_error
+    _LC = _translators.log_critical
+except ImportError:
+    # NOTE(dims): Support for cases where a project wants to use
+    # code from tempest-incubator, but is not ready to be internationalized
+    # (like tempest)
+    _ = _LI = _LW = _LE = _LC = lambda x: x
diff --git a/tempest/openstack/common/log.py b/tempest/openstack/common/log.py
index 44102c0..26cd6ad 100644
--- a/tempest/openstack/common/log.py
+++ b/tempest/openstack/common/log.py
@@ -33,20 +33,20 @@
 import logging.config
 import logging.handlers
 import os
+import socket
 import sys
 import traceback
 
 from oslo.config import cfg
+from oslo.serialization import jsonutils
+from oslo.utils import importutils
 import six
 from six import moves
 
-from tempest.openstack.common.gettextutils import _
-from tempest.openstack.common import importutils
-from tempest.openstack.common import jsonutils
+_PY26 = sys.version_info[0:2] == (2, 6)
+
+from tempest.openstack.common._i18n import _
 from tempest.openstack.common import local
-# NOTE(flaper87): Pls, remove when graduating this module
-# from the incubator.
-from tempest.openstack.common.strutils import mask_password  # noqa
 
 
 _DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
@@ -124,7 +124,9 @@
                       'qpid=WARN', 'sqlalchemy=WARN', 'suds=INFO',
                       'oslo.messaging=INFO', 'iso8601=WARN',
                       'requests.packages.urllib3.connectionpool=WARN',
-                      'urllib3.connectionpool=WARN']
+                      'urllib3.connectionpool=WARN', 'websocket=WARN',
+                      "keystonemiddleware=WARN", "routes.middleware=WARN",
+                      "stevedore=WARN"]
 
 log_opts = [
     cfg.StrOpt('logging_context_format_string',
@@ -227,6 +229,15 @@
     def audit(self, msg, *args, **kwargs):
         self.log(logging.AUDIT, msg, *args, **kwargs)
 
+    def isEnabledFor(self, level):
+        if _PY26:
+            # This method was added in python 2.7 (and it does the exact
+            # same logic, so we need to do the exact same logic so that
+            # python 2.6 has this capability as well).
+            return self.logger.isEnabledFor(level)
+        else:
+            return super(BaseLoggerAdapter, self).isEnabledFor(level)
+
 
 class LazyAdapter(BaseLoggerAdapter):
     def __init__(self, name='unknown', version='unknown'):
@@ -289,11 +300,10 @@
         self.warn(stdmsg, *args, **kwargs)
 
     def process(self, msg, kwargs):
-        # NOTE(mrodden): catch any Message/other object and
-        #                coerce to unicode before they can get
-        #                to the python logging and possibly
-        #                cause string encoding trouble
-        if not isinstance(msg, six.string_types):
+        # NOTE(jecarey): If msg is not unicode, coerce it into unicode
+        #                before it can get to the python logging and
+        #                possibly cause string encoding trouble
+        if not isinstance(msg, six.text_type):
             msg = six.text_type(msg)
 
         if 'extra' not in kwargs:
@@ -410,18 +420,20 @@
     sys.excepthook = _create_logging_excepthook(product_name)
 
 
-def set_defaults(logging_context_format_string,
+def set_defaults(logging_context_format_string=None,
                  default_log_levels=None):
     # Just in case the caller is not setting the
     # default_log_level. This is insurance because
     # we introduced the default_log_level parameter
     # later in a backwards in-compatible change
-    if default_log_levels is None:
-        default_log_levels = DEFAULT_LOG_LEVELS
-    cfg.set_defaults(
+    if default_log_levels is not None:
+        cfg.set_defaults(
             log_opts,
-            logging_context_format_string=logging_context_format_string,
             default_log_levels=default_log_levels)
+    if logging_context_format_string is not None:
+        cfg.set_defaults(
+            log_opts,
+            logging_context_format_string=logging_context_format_string)
 
 
 def _find_facility_from_conf():
@@ -470,18 +482,6 @@
     for handler in log_root.handlers:
         log_root.removeHandler(handler)
 
-    if CONF.use_syslog:
-        facility = _find_facility_from_conf()
-        # TODO(bogdando) use the format provided by RFCSysLogHandler
-        #   after existing syslog format deprecation in J
-        if CONF.use_syslog_rfc_format:
-            syslog = RFCSysLogHandler(address='/dev/log',
-                                      facility=facility)
-        else:
-            syslog = logging.handlers.SysLogHandler(address='/dev/log',
-                                                    facility=facility)
-        log_root.addHandler(syslog)
-
     logpath = _get_log_file_path()
     if logpath:
         filelog = logging.handlers.WatchedFileHandler(logpath)
@@ -540,6 +540,20 @@
         else:
             logger.setLevel(level_name)
 
+    if CONF.use_syslog:
+        try:
+            facility = _find_facility_from_conf()
+            # TODO(bogdando) use the format provided by RFCSysLogHandler
+            #   after existing syslog format deprecation in J
+            if CONF.use_syslog_rfc_format:
+                syslog = RFCSysLogHandler(facility=facility)
+            else:
+                syslog = logging.handlers.SysLogHandler(facility=facility)
+            log_root.addHandler(syslog)
+        except socket.error:
+            log_root.error('Unable to add syslog handler. Verify that syslog '
+                           'is running.')
+
 
 _loggers = {}
 
@@ -609,6 +623,12 @@
     def format(self, record):
         """Uses contextstring if request_id is set, otherwise default."""
 
+        # NOTE(jecarey): If msg is not unicode, coerce it into unicode
+        #                before it can get to the python logging and
+        #                possibly cause string encoding trouble
+        if not isinstance(record.msg, six.text_type):
+            record.msg = six.text_type(record.msg)
+
         # store project info
         record.project = self.project
         record.version = self.version
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index ea4365e..522aa43 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -456,6 +456,68 @@
 
         return tempest.test.call_until_true(ping, timeout, 1)
 
+    def check_vm_connectivity(self, ip_address,
+                              username=None,
+                              private_key=None,
+                              should_connect=True):
+        """
+        :param ip_address: server to test against
+        :param username: server's ssh username
+        :param private_key: server's ssh private key to be used
+        :param should_connect: True/False indicates positive/negative test
+            positive - attempt ping and ssh
+            negative - attempt ping and fail if succeed
+
+        :raises: AssertError if the result of the connectivity check does
+            not match the value of the should_connect param
+        """
+        if should_connect:
+            msg = "Timed out waiting for %s to become reachable" % ip_address
+        else:
+            msg = "ip address %s is reachable" % ip_address
+        self.assertTrue(self.ping_ip_address(ip_address,
+                                             should_succeed=should_connect),
+                        msg=msg)
+        if should_connect:
+            # no need to check ssh for negative connectivity
+            self.get_remote_client(ip_address, username, private_key)
+
+    def check_public_network_connectivity(self, ip_address, username,
+                                          private_key, should_connect=True,
+                                          msg=None, servers=None):
+        # The target login is assumed to have been configured for
+        # key-based authentication by cloud-init.
+        LOG.debug('checking network connections to IP %s with user: %s' %
+                  (ip_address, username))
+        try:
+            self.check_vm_connectivity(ip_address,
+                                       username,
+                                       private_key,
+                                       should_connect=should_connect)
+        except Exception as e:
+            ex_msg = 'Public network connectivity check failed'
+            if msg:
+                ex_msg += ": " + msg
+            LOG.exception(ex_msg)
+            self._log_console_output(servers)
+            # network debug is called as part of ssh init
+            if not isinstance(e, exceptions.SSHTimeout):
+                debug.log_net_debug()
+            raise
+
+    def create_floating_ip(self, thing, pool_name=None):
+        """Creates a floating IP and associates to a server using
+        Nova clients
+        """
+
+        _, floating_ip = self.floating_ips_client.create_floating_ip(pool_name)
+        self.addCleanup(self.delete_wrapper,
+                        self.floating_ips_client.delete_floating_ip,
+                        floating_ip['id'])
+        self.floating_ips_client.associate_floating_ip_to_server(
+            floating_ip['ip'], thing['id'])
+        return floating_ip
+
 
 class NetworkScenarioTest(ScenarioTest):
     """Base class for network scenario tests.
@@ -591,8 +653,13 @@
         net = self._list_networks(name=network_name)
         return net_resources.AttributeDict(net[0])
 
-    def _create_floating_ip(self, thing, external_network_id, port_id=None,
-                            client=None):
+    def create_floating_ip(self, thing, external_network_id=None,
+                           port_id=None, client=None):
+        """Creates a floating IP and associates to a resource/port using
+        Neutron client
+        """
+        if not external_network_id:
+            external_network_id = CONF.network.public_network_id
         if not client:
             client = self.network_client
         if not port_id:
@@ -645,53 +712,6 @@
         LOG.info("FloatingIP: {fp} is at status: {st}"
                  .format(fp=floating_ip, st=status))
 
-    def _check_vm_connectivity(self, ip_address,
-                               username=None,
-                               private_key=None,
-                               should_connect=True):
-        """
-        :param ip_address: server to test against
-        :param username: server's ssh username
-        :param private_key: server's ssh private key to be used
-        :param should_connect: True/False indicates positive/negative test
-            positive - attempt ping and ssh
-            negative - attempt ping and fail if succeed
-
-        :raises: AssertError if the result of the connectivity check does
-            not match the value of the should_connect param
-        """
-        if should_connect:
-            msg = "Timed out waiting for %s to become reachable" % ip_address
-        else:
-            msg = "ip address %s is reachable" % ip_address
-        self.assertTrue(self.ping_ip_address(ip_address,
-                                             should_succeed=should_connect),
-                        msg=msg)
-        if should_connect:
-            # no need to check ssh for negative connectivity
-            self.get_remote_client(ip_address, username, private_key)
-
-    def _check_public_network_connectivity(self, ip_address, username,
-                                           private_key, should_connect=True,
-                                           msg=None, servers=None):
-        # The target login is assumed to have been configured for
-        # key-based authentication by cloud-init.
-        LOG.debug('checking network connections to IP %s with user: %s' %
-                  (ip_address, username))
-        try:
-            self._check_vm_connectivity(ip_address,
-                                        username,
-                                        private_key,
-                                        should_connect=should_connect)
-        except Exception as e:
-            ex_msg = 'Public network connectivity check failed'
-            if msg:
-                ex_msg += ": " + msg
-            LOG.exception(ex_msg)
-            self._log_console_output(servers)
-            self._log_net_info(e)
-            raise
-
     def _check_tenant_network_connectivity(self, server,
                                            username,
                                            private_key,
@@ -706,10 +726,10 @@
         try:
             for net_name, ip_addresses in server['networks'].iteritems():
                 for ip_address in ip_addresses:
-                    self._check_vm_connectivity(ip_address,
-                                                username,
-                                                private_key,
-                                                should_connect=should_connect)
+                    self.check_vm_connectivity(ip_address,
+                                               username,
+                                               private_key,
+                                               should_connect=should_connect)
         except Exception as e:
             LOG.exception('Tenant network connectivity check failed')
             self._log_console_output(servers_for_debug)
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 9e404c8..d061406 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -137,7 +137,7 @@
         if (config.network.public_network_id and not
                 config.network.tenant_networks_reachable):
             public_network_id = config.network.public_network_id
-            floating_ip = self._create_floating_ip(
+            floating_ip = self.create_floating_ip(
                 server, public_network_id)
             self.floating_ips[floating_ip] = server
             self.server_ips[server['id']] = floating_ip.floating_ip_address
@@ -257,8 +257,8 @@
     def _assign_floating_ip_to_vip(self, vip):
         public_network_id = config.network.public_network_id
         port_id = vip.port_id
-        floating_ip = self._create_floating_ip(vip, public_network_id,
-                                               port_id=port_id)
+        floating_ip = self.create_floating_ip(vip, public_network_id,
+                                              port_id=port_id)
         self.floating_ips.setdefault(vip.id, [])
         self.floating_ips[vip.id].append(floating_ip)
 
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index ead021e..59af6b3 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -89,16 +89,6 @@
         self.servers_client.reboot(self.server['id'], 'SOFT')
         self._wait_for_server_status('ACTIVE')
 
-    def nova_floating_ip_create(self):
-        _, self.floating_ip = self.floating_ips_client.create_floating_ip()
-        self.addCleanup(self.delete_wrapper,
-                        self.floating_ips_client.delete_floating_ip,
-                        self.floating_ip['id'])
-
-    def nova_floating_ip_add(self):
-        self.floating_ips_client.associate_floating_ip_to_server(
-            self.floating_ip['ip'], self.server['id'])
-
     def ssh_to_server(self):
         try:
             self.linux_client = self.get_remote_client(self.floating_ip['ip'])
@@ -155,8 +145,7 @@
         self.addCleanup(self.nova_volume_detach)
         self.cinder_show()
 
-        self.nova_floating_ip_create()
-        self.nova_floating_ip_add()
+        self.floating_ip = self.create_floating_ip(self.server)
         self.create_and_add_security_group()
         self.ssh_to_server()
         self.nova_reboot()
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 0c48334..ad7f18c 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -70,8 +70,8 @@
         server_name = data_utils.rand_name('server-smoke')
         self.server = self.create_server(name=server_name,
                                          create_kwargs=create_kwargs)
-        self.floating_ip = self._create_floating_ip(self.server,
-                                                    public_network_id)
+        self.floating_ip = self.create_floating_ip(self.server,
+                                                   public_network_id)
         # Verify that we can indeed connect to the server before we mess with
         # it's state
         self._wait_server_status_and_check_network_connectivity()
@@ -84,9 +84,9 @@
             should_connect=should_connect,
             servers_for_debug=[self.server])
         floating_ip = self.floating_ip.floating_ip_address
-        self._check_public_network_connectivity(floating_ip, username,
-                                                private_key, should_connect,
-                                                servers=[self.server])
+        self.check_public_network_connectivity(floating_ip, username,
+                                               private_key, should_connect,
+                                               servers=[self.server])
         self.check_floating_ip_status(self.floating_ip, 'ACTIVE')
 
     def _wait_server_status_and_check_network_connectivity(self):
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index e3f87e9..bac955d 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -112,7 +112,8 @@
         server = self._create_server(name, self.network)
         self._check_tenant_network_connectivity()
 
-        self._create_and_associate_floating_ips(server)
+        floating_ip = self.create_floating_ip(server)
+        self.floating_ip_tuple = Floating_IP_tuple(floating_ip, server)
 
     def check_networks(self):
         """
@@ -169,13 +170,8 @@
                     server, ssh_login, self._get_server_key(server),
                     servers_for_debug=self.servers)
 
-    def _create_and_associate_floating_ips(self, server):
-        public_network_id = CONF.network.public_network_id
-        floating_ip = self._create_floating_ip(server, public_network_id)
-        self.floating_ip_tuple = Floating_IP_tuple(floating_ip, server)
-
-    def _check_public_network_connectivity(self, should_connect=True,
-                                           msg=None):
+    def check_public_network_connectivity(self, should_connect=True,
+                                          msg=None):
         """Verifies connectivty to a VM via public network and floating IP,
         and verifies floating IP has resource status is correct.
 
@@ -194,7 +190,7 @@
             private_key = self._get_server_key(server)
             floatingip_status = 'ACTIVE'
         # call the common method in the parent class
-        super(TestNetworkBasicOps, self)._check_public_network_connectivity(
+        super(TestNetworkBasicOps, self).check_public_network_connectivity(
             ip_address, ssh_login, private_key, should_connect, msg,
             self.servers)
         self.check_floating_ip_status(floating_ip, floatingip_status)
@@ -367,17 +363,17 @@
 
         """
         self._setup_network_and_servers()
-        self._check_public_network_connectivity(should_connect=True)
+        self.check_public_network_connectivity(should_connect=True)
         self._check_network_internal_connectivity(network=self.network)
         self._check_network_external_connectivity()
         self._disassociate_floating_ips()
-        self._check_public_network_connectivity(should_connect=False,
-                                                msg="after disassociate "
-                                                    "floating ip")
+        self.check_public_network_connectivity(should_connect=False,
+                                               msg="after disassociate "
+                                                   "floating ip")
         self._reassociate_floating_ips()
-        self._check_public_network_connectivity(should_connect=True,
-                                                msg="after re-associate "
-                                                    "floating ip")
+        self.check_public_network_connectivity(should_connect=True,
+                                               msg="after re-associate "
+                                                   "floating ip")
 
     @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
                           'NIC hotplug not available')
@@ -393,7 +389,7 @@
 
         """
         self._setup_network_and_servers()
-        self._check_public_network_connectivity(should_connect=True)
+        self.check_public_network_connectivity(should_connect=True)
         self._create_new_network()
         self._hotplug_server()
         self._check_network_internal_connectivity(network=self.new_net)
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 6ea3253..747850b 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -271,7 +271,7 @@
 
     def _assign_floating_ips(self, tenant, server):
         public_network_id = CONF.network.public_network_id
-        floating_ip = self._create_floating_ip(
+        floating_ip = self.create_floating_ip(
             server, public_network_id,
             client=tenant.manager.network_client)
         self.floating_ips.setdefault(server['id'], floating_ip)
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index dc32edc..9a99da4 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -65,17 +65,6 @@
         got_timestamp = ssh_client.exec_command('cat /tmp/timestamp')
         self.assertEqual(self.timestamp, got_timestamp)
 
-    def _create_floating_ip(self):
-        _, floating_ip = self.floating_ips_client.create_floating_ip()
-        self.addCleanup(self.delete_wrapper,
-                        self.floating_ips_client.delete_floating_ip,
-                        floating_ip['id'])
-        return floating_ip
-
-    def _set_floating_ip_to_server(self, server, floating_ip):
-        self.floating_ips_client.associate_floating_ip_to_server(
-            floating_ip['ip'], server['id'])
-
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.services('compute', 'network', 'image')
@@ -87,8 +76,7 @@
         # boot a instance and create a timestamp file in it
         server = self._boot_image(CONF.compute.image_ref)
         if CONF.compute.use_floatingip_for_ssh:
-            fip_for_server = self._create_floating_ip()
-            self._set_floating_ip_to_server(server, fip_for_server)
+            fip_for_server = self.create_floating_ip(server)
             self._write_timestamp(fip_for_server['ip'])
         else:
             self._write_timestamp(server)
@@ -101,9 +89,7 @@
 
         # check the existence of the timestamp file in the second instance
         if CONF.compute.use_floatingip_for_ssh:
-            fip_for_snapshot = self._create_floating_ip()
-            self._set_floating_ip_to_server(server_from_snapshot,
-                                            fip_for_snapshot)
+            fip_for_snapshot = self.create_floating_ip(server_from_snapshot)
             self._check_timestamp(fip_for_snapshot['ip'])
         else:
             self._check_timestamp(server_from_snapshot)
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index e30c824..ee2c737 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -71,17 +71,6 @@
     def _add_keypair(self):
         self.keypair = self.create_keypair()
 
-    def _create_floating_ip(self):
-        _, floating_ip = self.floating_ips_client.create_floating_ip()
-        self.addCleanup(self.delete_wrapper,
-                        self.floating_ips_client.delete_floating_ip,
-                        floating_ip['id'])
-        return floating_ip
-
-    def _add_floating_ip(self, server, floating_ip):
-        self.floating_ips_client.associate_floating_ip_to_server(
-            floating_ip['ip'], server['id'])
-
     def _ssh_to_server(self, server_or_ip):
         return self.get_remote_client(server_or_ip)
 
@@ -163,8 +152,7 @@
 
         # create and add floating IP to server1
         if CONF.compute.use_floatingip_for_ssh:
-            floating_ip_for_server = self._create_floating_ip()
-            self._add_floating_ip(server, floating_ip_for_server)
+            floating_ip_for_server = self.create_floating_ip(server)
             ip_for_server = floating_ip_for_server['ip']
         else:
             ip_for_server = server
@@ -189,9 +177,8 @@
 
         # create and add floating IP to server_from_snapshot
         if CONF.compute.use_floatingip_for_ssh:
-            floating_ip_for_snapshot = self._create_floating_ip()
-            self._add_floating_ip(server_from_snapshot,
-                                  floating_ip_for_snapshot)
+            floating_ip_for_snapshot = self.create_floating_ip(
+                server_from_snapshot)
             ip_for_snapshot = floating_ip_for_snapshot['ip']
         else:
             ip_for_snapshot = server_from_snapshot
diff --git a/tempest/services/volume/json/backups_client.py b/tempest/services/volume/json/backups_client.py
index 63fc646..da47639 100644
--- a/tempest/services/volume/json/backups_client.py
+++ b/tempest/services/volume/json/backups_client.py
@@ -23,13 +23,13 @@
 CONF = config.CONF
 
 
-class BackupsClientJSON(rest_client.RestClient):
+class BaseBackupsClientJSON(rest_client.RestClient):
     """
     Client class to send CRUD Volume backup API requests to a Cinder endpoint
     """
 
     def __init__(self, auth_provider):
-        super(BackupsClientJSON, self).__init__(auth_provider)
+        super(BaseBackupsClientJSON, self).__init__(auth_provider)
         self.service = CONF.volume.catalog_type
         self.build_interval = CONF.volume.build_interval
         self.build_timeout = CONF.volume.build_timeout
@@ -99,3 +99,7 @@
                            'the required time (%s s).' %
                            (backup_id, status, self.build_timeout))
                 raise exceptions.TimeoutException(message)
+
+
+class BackupsClientJSON(BaseBackupsClientJSON):
+    """Volume V1 Backups client"""
diff --git a/tempest/services/volume/v2/json/backups_client.py b/tempest/services/volume/v2/json/backups_client.py
new file mode 100644
index 0000000..9698075
--- /dev/null
+++ b/tempest/services/volume/v2/json/backups_client.py
@@ -0,0 +1,26 @@
+# Copyright 2014 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.
+
+from tempest.services.volume.json import backups_client
+
+
+class BackupsClientV2JSON(backups_client.BaseBackupsClientJSON):
+    """
+    Client class to send CRUD Volume V2 API requests to a Cinder endpoint
+    """
+
+    def __init__(self, auth_provider):
+        super(BackupsClientV2JSON, self).__init__(auth_provider)
+        self.api_version = "v2"
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index f3f11fd..00b17d9 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -306,8 +306,7 @@
 
         volume.detach()
 
-        self.assertVolumeStatusWait(_volume_state, "available")
-        wait.re_search_wait(_volume_state, "available")
+        self.assertVolumeStatusWait(volume, "available")
 
         wait.state_wait(_part_state, 'DECREASE')