Merge "[V3 identity] Renaming service_client into services_client"
diff --git a/README.rst b/README.rst
index 45cb4c0..71e185f 100644
--- a/README.rst
+++ b/README.rst
@@ -87,7 +87,7 @@
    be done with testr directly or any `testr`_ based test runner, like
    `ostestr`_. For example, from the working dir running::
 
-     $ ostestr --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty))'
+     $ ostestr --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario))'
 
    will run the same set of tests as the default gate jobs.
 
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 1b2b6d2..a16f3b7 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -9,16 +9,6 @@
 config file which explains the purpose of each individual option. You can see
 the sample config file here: :ref:`tempest-sampleconf`
 
-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/doc/source/field_guide/thirdparty.rst b/doc/source/field_guide/thirdparty.rst
deleted file mode 120000
index 3fd6a51..0000000
--- a/doc/source/field_guide/thirdparty.rst
+++ /dev/null
@@ -1 +0,0 @@
-../../../tempest/thirdparty/README.rst
\ No newline at end of file
diff --git a/doc/source/index.rst b/doc/source/index.rst
index fe6074f..32e6e51 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -26,7 +26,6 @@
    field_guide/api
    field_guide/scenario
    field_guide/stress
-   field_guide/thirdparty
    field_guide/unit_tests
 
 ---------------------------
diff --git a/requirements.txt b/requirements.txt
index d470c30..df04ca8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,7 +7,6 @@
 httplib2>=0.7.5
 jsonschema!=2.5.0,<3.0.0,>=2.0.0
 testtools>=1.4.0
-boto>=2.32.1
 paramiko>=1.13.0
 netaddr!=0.7.16,>=0.7.12
 testrepository>=0.0.18
diff --git a/run_tempest.sh b/run_tempest.sh
index a704684..8c8f25f 100755
--- a/run_tempest.sh
+++ b/run_tempest.sh
@@ -14,8 +14,6 @@
   echo "  -C, --config             Config file location"
   echo "  -h, --help               Print this usage message"
   echo "  -d, --debug              Run tests with testtools instead of testr. This allows you to use PDB"
-  echo "  -l, --logging            Enable logging"
-  echo "  -L, --logging-config     Logging config file location.  Default is etc/logging.conf"
   echo "  -- [TESTROPTIONS]        After the first '--' you can pass arbitrary arguments to testr "
 }
 
@@ -31,10 +29,8 @@
 wrapper=""
 config_file=""
 update=0
-logging=0
-logging_config=etc/logging.conf
 
-if ! options=$(getopt -o VNnfusthdC:lL: -l virtual-env,no-virtual-env,no-site-packages,force,update,smoke,serial,help,debug,config:,logging,logging-config: -- "$@")
+if ! options=$(getopt -o VNnfusthdC:lL: -l virtual-env,no-virtual-env,no-site-packages,force,update,smoke,serial,help,debug,config: -- "$@")
 then
     # parse error
     usage
@@ -55,8 +51,6 @@
     -C|--config) config_file=$2; shift;;
     -s|--smoke) testrargs+="smoke";;
     -t|--serial) serial=1;;
-    -l|--logging) logging=1;;
-    -L|--logging-config) logging_config=$2; shift;;
     --) [ "yes" == "$first_uu" ] || testrargs="$testrargs $1"; first_uu=no  ;;
     *) testrargs="$testrargs $1";;
   esac
@@ -69,16 +63,6 @@
     export TEMPEST_CONFIG=`basename "$config_file"`
 fi
 
-if [ $logging -eq 1 ]; then
-    if [ ! -f "$logging_config" ]; then
-        echo "No such logging config file: $logging_config"
-        exit 1
-    fi
-    logging_config=`readlink -f "$logging_config"`
-    export TEMPEST_LOG_CONFIG_DIR=`dirname "$logging_config"`
-    export TEMPEST_LOG_CONFIG=`basename "$logging_config"`
-fi
-
 cd `dirname "$0"`
 
 if [ $no_site_packages -eq 1 ]; then
diff --git a/tempest/README.rst b/tempest/README.rst
index f93a173..113b191 100644
--- a/tempest/README.rst
+++ b/tempest/README.rst
@@ -16,7 +16,6 @@
 |    api/ - API tests
 |    scenario/ - complex scenario tests
 |    stress/ - stress tests
-|    thirdparty/ - 3rd party api tests
 
 Each of these directories contains different types of tests. What
 belongs in each directory, the rules and examples for good tests, are
@@ -56,14 +55,6 @@
 several test jobs in parallel and can run any existing test in Tempest as a
 stress job.
 
-:ref:`third_party_field_guide`
-------------------------------
-
-Many openstack components include 3rdparty API support. It is
-completely legitimate for Tempest to include tests of 3rdparty APIs,
-but those should be kept separate from the normal OpenStack
-validation.
-
 :ref:`unit_tests_field_guide`
 -----------------------------
 
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 2d9019a..754cc5a 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -32,7 +32,7 @@
 
     @test.idempotent_id('9d9b28e3-1b2e-4483-a2cc-24aa0ea1de54')
     def test_volume_type_list(self):
-        # List Volume types.
+        # List volume types.
         body = self.volume_types_client.list_volume_types()['volume_types']
         self.assertIsInstance(body, list)
 
diff --git a/tempest/clients.py b/tempest/clients.py
index f9fe404..30bbe48 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -70,7 +70,6 @@
 from tempest import manager
 from tempest.services.baremetal.v1.json.baremetal_client import \
     BaremetalClient
-from tempest.services import botoclients
 from tempest.services.compute.json.floating_ips_client import \
     FloatingIPsClient as ComputeFloatingIPsClient
 from tempest.services.compute.json.keypairs_client import KeyPairsClient
@@ -320,15 +319,6 @@
         self.negative_client = negative_rest_client.NegativeRestClient(
             self.auth_provider, service, **self.default_params)
 
-        # Generating EC2 credentials in tempest is only supported
-        # with identity v2
-        if CONF.identity_feature_enabled.api_v2 and \
-                CONF.identity.auth_version == 'v2':
-            # EC2 and S3 clients, if used, will check configured AWS
-            # credentials and generate new ones if needed
-            self.ec2api_client = botoclients.APIClientEC2(self.identity_client)
-            self.s3_client = botoclients.ObjectClientS3(self.identity_client)
-
     def _set_compute_clients(self):
         params = {
             'service': CONF.compute.catalog_type,
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 297a066..b90ee04 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -357,7 +357,7 @@
                 resources['users'].append({
                     'tenant': tenant,
                     'name': user,
-                    'pass': data_utils.rand_name(),
+                    'pass': data_utils.rand_password(),
                     'prefix': user_group['prefix'],
                     'roles': user_group['roles']
                 })
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index 3c32d48..b79bff4 100644
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -176,14 +176,14 @@
             svc.run()
 
     def _init_admin_ids(self):
-        id_cl = self.admin_mgr.identity_client
+        tn_cl = self.admin_mgr.tenants_client
         rl_cl = self.admin_mgr.roles_client
 
-        tenant = identity.get_tenant_by_name(id_cl,
+        tenant = identity.get_tenant_by_name(tn_cl,
                                              CONF.auth.admin_tenant_name)
         self.admin_tenant_id = tenant['id']
 
-        user = identity.get_user_by_username(id_cl, self.admin_tenant_id,
+        user = identity.get_user_by_username(tn_cl, self.admin_tenant_id,
                                              CONF.auth.admin_username)
         self.admin_id = user['id']
 
@@ -249,9 +249,9 @@
                               "exists, exception: %s" % ex)
 
     def _tenant_exists(self, tenant_id):
-        id_cl = self.admin_mgr.identity_client
+        tn_cl = self.admin_mgr.tenants_client
         try:
-            t = id_cl.show_tenant(tenant_id)
+            t = tn_cl.show_tenant(tenant_id)
             LOG.debug("Tenant is: %s" % str(t))
             return True
         except Exception as ex:
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 032b8b4..c2f3885 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -855,7 +855,7 @@
             self.data['users'][user['id']] = user['name']
 
 
-class RoleService(IdentityService):
+class RoleService(BaseService):
 
     def __init__(self, manager, **kwargs):
         super(RoleService, self).__init__(kwargs)
@@ -895,7 +895,7 @@
             self.data['roles'][role['id']] = role['name']
 
 
-class TenantService(IdentityService):
+class TenantService(BaseService):
 
     def __init__(self, manager, **kwargs):
         super(TenantService, self).__init__(kwargs)
diff --git a/tempest/config.py b/tempest/config.py
index a4ae966..8f2ca4b 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -388,9 +388,6 @@
                 default=True,
                 help='Does the test environment support creating snapshot '
                      'images of running instances?'),
-    cfg.BoolOpt('ec2_api',
-                default=True,
-                help='Does the test environment have the ec2 api running?'),
     cfg.BoolOpt('nova_cert',
                 default=True,
                 help='Does the test environment have the nova cert running?'),
@@ -1004,54 +1001,6 @@
                 help="List of enabled data processing plugins")
 ]
 
-
-boto_group = cfg.OptGroup(name='boto',
-                          title='EC2/S3 options')
-BotoGroup = [
-    cfg.StrOpt('ec2_url',
-               default="http://localhost:8773/services/Cloud",
-               help="EC2 URL"),
-    cfg.StrOpt('s3_url',
-               default="http://localhost:8080",
-               help="S3 URL"),
-    cfg.StrOpt('aws_secret',
-               help="AWS Secret Key",
-               secret=True),
-    cfg.StrOpt('aws_access',
-               help="AWS Access Key"),
-    cfg.StrOpt('aws_zone',
-               default="nova",
-               help="AWS Zone for EC2 tests"),
-    cfg.StrOpt('s3_materials_path',
-               default="/opt/stack/devstack/files/images/"
-                       "s3-materials/cirros-0.3.0",
-               help="S3 Materials Path"),
-    cfg.StrOpt('ari_manifest',
-               default="cirros-0.3.0-x86_64-initrd.manifest.xml",
-               help="ARI Ramdisk Image manifest"),
-    cfg.StrOpt('ami_manifest',
-               default="cirros-0.3.0-x86_64-blank.img.manifest.xml",
-               help="AMI Machine Image manifest"),
-    cfg.StrOpt('aki_manifest',
-               default="cirros-0.3.0-x86_64-vmlinuz.manifest.xml",
-               help="AKI Kernel Image manifest"),
-    cfg.StrOpt('instance_type',
-               default="m1.tiny",
-               help="Instance type"),
-    cfg.IntOpt('http_socket_timeout',
-               default=3,
-               help="boto Http socket timeout"),
-    cfg.IntOpt('num_retries',
-               default=1,
-               help="boto num_retries on error"),
-    cfg.IntOpt('build_timeout',
-               default=60,
-               help="Status Change Timeout"),
-    cfg.IntOpt('build_interval',
-               default=1,
-               help="Status Change Test Interval"),
-]
-
 stress_group = cfg.OptGroup(name='stress', title='Stress Test Options')
 
 StressGroup = [
@@ -1310,7 +1259,6 @@
     (dashboard_group, DashboardGroup),
     (data_processing_group, DataProcessingGroup),
     (data_processing_feature_group, DataProcessingFeaturesGroup),
-    (boto_group, BotoGroup),
     (stress_group, StressGroup),
     (scenario_group, ScenarioGroup),
     (service_available_group, ServiceAvailableGroup),
@@ -1380,7 +1328,6 @@
         self.data_processing = _CONF['data-processing']
         self.data_processing_feature_enabled = _CONF[
             'data-processing-feature-enabled']
-        self.boto = _CONF.boto
         self.stress = _CONF.stress
         self.scenario = _CONF.scenario
         self.service_available = _CONF.service_available
@@ -1425,6 +1372,13 @@
             _CONF([], project='tempest', default_config_files=config_files)
         else:
             _CONF([], project='tempest')
+
+        logging_cfg_path = "%s/logging.conf" % os.path.dirname(path)
+        if (not hasattr(_CONF, 'log_config_append') and
+            os.path.isfile(logging_cfg_path)):
+            # if logging conf is in place we need to set log_config_append
+            _CONF.log_config_append = logging_cfg_path
+
         logging.setup(_CONF, 'tempest')
         LOG = logging.getLogger('tempest')
         LOG.info("Using tempest config file %s" % path)
diff --git a/tempest/services/botoclients.py b/tempest/services/botoclients.py
deleted file mode 100644
index 9d452ff..0000000
--- a/tempest/services/botoclients.py
+++ /dev/null
@@ -1,217 +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 contextlib
-import types
-
-import boto
-import boto.ec2
-import boto.s3.connection
-from six.moves import configparser as ConfigParser
-from six.moves.urllib import parse as urlparse
-from tempest_lib import exceptions as lib_exc
-
-from tempest import config
-
-CONF = config.CONF
-
-
-class BotoClientBase(object):
-
-    ALLOWED_METHODS = set()
-
-    def __init__(self, identity_client):
-        self.identity_client = identity_client
-
-        self.ca_cert = CONF.identity.ca_certificates_file
-        self.connection_timeout = str(CONF.boto.http_socket_timeout)
-        self.num_retries = str(CONF.boto.num_retries)
-        self.build_timeout = CONF.boto.build_timeout
-
-        self.connection_data = {}
-
-    def _config_boto_timeout(self, timeout, retries):
-        try:
-            boto.config.add_section("Boto")
-        except ConfigParser.DuplicateSectionError:
-            pass
-        boto.config.set("Boto", "http_socket_timeout", timeout)
-        boto.config.set("Boto", "num_retries", retries)
-
-    def _config_boto_ca_certificates_file(self, ca_cert):
-        if ca_cert is None:
-            return
-
-        try:
-            boto.config.add_section("Boto")
-        except ConfigParser.DuplicateSectionError:
-            pass
-        boto.config.set("Boto", "ca_certificates_file", ca_cert)
-
-    def __getattr__(self, name):
-        """Automatically creates methods for the allowed methods set."""
-        if name in self.ALLOWED_METHODS:
-            def func(self, *args, **kwargs):
-                with contextlib.closing(self.get_connection()) as conn:
-                    return getattr(conn, name)(*args, **kwargs)
-
-            func.__name__ = name
-            setattr(self, name, types.MethodType(func, self, self.__class__))
-            setattr(self.__class__, name,
-                    types.MethodType(func, None, self.__class__))
-            return getattr(self, name)
-        else:
-            raise AttributeError(name)
-
-    def get_connection(self):
-        self._config_boto_timeout(self.connection_timeout, self.num_retries)
-        self._config_boto_ca_certificates_file(self.ca_cert)
-
-        ec2_client_args = {'aws_access_key_id': CONF.boto.aws_access,
-                           'aws_secret_access_key': CONF.boto.aws_secret}
-        if not all(ec2_client_args.values()):
-            ec2_client_args = self.get_aws_credentials(self.identity_client)
-
-        self.connection_data.update(ec2_client_args)
-        return self.connect_method(**self.connection_data)
-
-    def get_aws_credentials(self, identity_client):
-        """Obtain existing, or create new AWS credentials
-
-        :param identity_client: identity client with embedded credentials
-        :return: EC2 credentials
-        """
-        ec2_cred_list = identity_client.list_user_ec2_credentials(
-            identity_client.user_id)['credentials']
-        for cred in ec2_cred_list:
-            if cred['tenant_id'] == identity_client.tenant_id:
-                ec2_cred = cred
-                break
-        else:
-            ec2_cred = (identity_client.create_user_ec2_credentials(
-                identity_client.user_id,
-                tenant_id=identity_client.tenant_id)['credential'])
-        if not all((ec2_cred, ec2_cred['access'], ec2_cred['secret'])):
-            raise lib_exc.NotFound("Unable to get access and secret keys")
-        else:
-            ec2_cred_aws = {}
-            ec2_cred_aws['aws_access_key_id'] = ec2_cred['access']
-            ec2_cred_aws['aws_secret_access_key'] = ec2_cred['secret']
-        return ec2_cred_aws
-
-
-class APIClientEC2(BotoClientBase):
-
-    def connect_method(self, *args, **kwargs):
-        return boto.connect_ec2(*args, **kwargs)
-
-    def __init__(self, identity_client):
-        super(APIClientEC2, self).__init__(identity_client)
-        insecure_ssl = CONF.identity.disable_ssl_certificate_validation
-        purl = urlparse.urlparse(CONF.boto.ec2_url)
-
-        region_name = CONF.compute.region
-        if not region_name:
-            region_name = CONF.identity.region
-        region = boto.ec2.regioninfo.RegionInfo(name=region_name,
-                                                endpoint=purl.hostname)
-        port = purl.port
-        if port is None:
-            if purl.scheme is not "https":
-                port = 80
-            else:
-                port = 443
-        else:
-            port = int(port)
-        self.connection_data.update({"is_secure": purl.scheme == "https",
-                                     "validate_certs": not insecure_ssl,
-                                     "region": region,
-                                     "host": purl.hostname,
-                                     "port": port,
-                                     "path": purl.path})
-
-    ALLOWED_METHODS = set(('create_key_pair', 'get_key_pair',
-                           'delete_key_pair', 'import_key_pair',
-                           'get_all_key_pairs',
-                           'get_all_tags',
-                           'create_image', 'get_image',
-                           'register_image', 'deregister_image',
-                           'get_all_images', 'get_image_attribute',
-                           'modify_image_attribute', 'reset_image_attribute',
-                           'get_all_kernels',
-                           'create_volume', 'delete_volume',
-                           'get_all_volume_status', 'get_all_volumes',
-                           'get_volume_attribute', 'modify_volume_attribute'
-                           'bundle_instance', 'cancel_spot_instance_requests',
-                           'confirm_product_instanc',
-                           'get_all_instance_status', 'get_all_instances',
-                           'get_all_reserved_instances',
-                           'get_all_spot_instance_requests',
-                           'get_instance_attribute', 'monitor_instance',
-                           'monitor_instances', 'unmonitor_instance',
-                           'unmonitor_instances',
-                           'purchase_reserved_instance_offering',
-                           'reboot_instances', 'request_spot_instances',
-                           'reset_instance_attribute', 'run_instances',
-                           'start_instances', 'stop_instances',
-                           'terminate_instances',
-                           'attach_network_interface', 'attach_volume',
-                           'detach_network_interface', 'detach_volume',
-                           'get_console_output',
-                           'delete_network_interface', 'create_subnet',
-                           'create_network_interface', 'delete_subnet',
-                           'get_all_network_interfaces',
-                           'allocate_address', 'associate_address',
-                           'disassociate_address', 'get_all_addresses',
-                           'release_address',
-                           'create_snapshot', 'delete_snapshot',
-                           'get_all_snapshots', 'get_snapshot_attribute',
-                           'modify_snapshot_attribute',
-                           'reset_snapshot_attribute', 'trim_snapshots',
-                           'get_all_regions', 'get_all_zones',
-                           'get_all_security_groups', 'create_security_group',
-                           'delete_security_group', 'authorize_security_group',
-                           'authorize_security_group_egress',
-                           'revoke_security_group',
-                           'revoke_security_group_egress'))
-
-
-class ObjectClientS3(BotoClientBase):
-
-    def connect_method(self, *args, **kwargs):
-        return boto.connect_s3(*args, **kwargs)
-
-    def __init__(self, identity_client):
-        super(ObjectClientS3, self).__init__(identity_client)
-        insecure_ssl = CONF.identity.disable_ssl_certificate_validation
-        purl = urlparse.urlparse(CONF.boto.s3_url)
-        port = purl.port
-        if port is None:
-            if purl.scheme is not "https":
-                port = 80
-            else:
-                port = 443
-        else:
-            port = int(port)
-        self.connection_data.update({"is_secure": purl.scheme == "https",
-                                     "validate_certs": not insecure_ssl,
-                                     "host": purl.hostname,
-                                     "port": port,
-                                     "calling_format": boto.s3.connection.
-                                     OrdinaryCallingFormat()})
-
-    ALLOWED_METHODS = set(('create_bucket', 'delete_bucket', 'generate_url',
-                           'get_all_buckets', 'get_bucket', 'delete_key',
-                           'lookup'))
diff --git a/tempest/test_discover/test_discover.py b/tempest/test_discover/test_discover.py
index dac7d91..330f370 100644
--- a/tempest/test_discover/test_discover.py
+++ b/tempest/test_discover/test_discover.py
@@ -30,8 +30,7 @@
     base_path = os.path.split(os.path.dirname(os.path.abspath(__file__)))[0]
     base_path = os.path.split(base_path)[0]
     # Load local tempest tests
-    for test_dir in ['tempest/api', 'tempest/scenario',
-                     'tempest/thirdparty']:
+    for test_dir in ['tempest/api', 'tempest/scenario']:
         full_test_dir = os.path.join(base_path, test_dir)
         if not pattern:
             suite.addTests(loader.discover(full_test_dir,
diff --git a/tempest/thirdparty/README.rst b/tempest/thirdparty/README.rst
deleted file mode 100644
index b0bfdf7..0000000
--- a/tempest/thirdparty/README.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-.. _third_party_field_guide:
-
-Tempest Field Guide to Third Party API tests
-============================================
-
-
-What are these tests?
----------------------
-
-Third party tests are tests for non native OpenStack APIs that are
-part of OpenStack projects. If we ship an API, we're really required
-to ensure that it's working.
-
-An example is that Nova Compute currently has EC2 API support in tree,
-which should be tested as part of normal process.
-
-
-Why are these tests in tempest?
--------------------------------
-
-If we ship an API in an OpenStack component, there should be tests in
-tempest to exercise it in some way.
-
-
-Scope of these tests
---------------------
-
-Third party API testing should be limited to the functional testing of
-third party API compliance. Complex scenarios should be avoided, and
-instead exercised with the OpenStack API, unless the third party API
-can't be tested without those scenarios.
-
-Whenever possible third party API testing should use a client as close
-to the third party API as possible. The point of these tests is API
-validation.
diff --git a/tempest/thirdparty/__init__.py b/tempest/thirdparty/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/thirdparty/__init__.py
+++ /dev/null
diff --git a/tempest/thirdparty/boto/__init__.py b/tempest/thirdparty/boto/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/thirdparty/boto/__init__.py
+++ /dev/null
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
deleted file mode 100644
index cfd3747..0000000
--- a/tempest/thirdparty/boto/test.py
+++ /dev/null
@@ -1,694 +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 contextlib
-import logging as orig_logging
-import os
-import re
-
-import boto
-from boto import ec2
-from boto import exception
-from boto import s3
-from oslo_log import log as logging
-import six
-from six.moves.urllib import parse as urlparse
-from tempest_lib import exceptions as lib_exc
-
-from tempest.common import credentials_factory as credentials
-from tempest.common.utils import file_utils
-from tempest import config
-from tempest import exceptions
-import tempest.test
-from tempest.thirdparty.boto.utils import wait
-
-CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
-
-def decision_maker():
-    A_I_IMAGES_READY = True  # ari,ami,aki
-    S3_CAN_CONNECT_ERROR = None
-    EC2_CAN_CONNECT_ERROR = None
-    secret_matcher = re.compile("[A-Za-z0-9+/]{32,}")  # 40 in other system
-    id_matcher = re.compile("[A-Za-z0-9]{20,}")
-
-    def all_read(*args):
-        return all(map(file_utils.have_effective_read_access, args))
-
-    materials_path = CONF.boto.s3_materials_path
-    ami_path = materials_path + os.sep + CONF.boto.ami_manifest
-    aki_path = materials_path + os.sep + CONF.boto.aki_manifest
-    ari_path = materials_path + os.sep + CONF.boto.ari_manifest
-
-    A_I_IMAGES_READY = all_read(ami_path, aki_path, ari_path)
-    boto_logger = logging.getLogger('boto')
-    level = boto_logger.logger.level
-    # suppress logging for boto
-    boto_logger.logger.setLevel(orig_logging.CRITICAL)
-
-    def _cred_sub_check(connection_data):
-        if not id_matcher.match(connection_data["aws_access_key_id"]):
-            raise Exception("Invalid AWS access Key")
-        if not secret_matcher.match(connection_data["aws_secret_access_key"]):
-            raise Exception("Invalid AWS secret Key")
-        raise Exception("Unknown (Authentication?) Error")
-    # NOTE(andreaf) Setting up an extra manager here is redundant,
-    # and should be removed.
-    openstack = credentials.ConfiguredUserManager()
-    try:
-        if urlparse.urlparse(CONF.boto.ec2_url).hostname is None:
-            raise Exception("Failed to get hostname from the ec2_url")
-        ec2client = openstack.ec2api_client
-        try:
-            ec2client.get_all_regions()
-        except exception.BotoServerError as exc:
-                if exc.error_code is None:
-                    raise Exception("EC2 target does not looks EC2 service")
-                _cred_sub_check(ec2client.connection_data)
-
-    except lib_exc.Unauthorized:
-        EC2_CAN_CONNECT_ERROR = "AWS credentials not set," +\
-                                " also failed to get it from keystone"
-    except Exception as exc:
-        EC2_CAN_CONNECT_ERROR = str(exc)
-
-    try:
-        if urlparse.urlparse(CONF.boto.s3_url).hostname is None:
-            raise Exception("Failed to get hostname from the s3_url")
-        s3client = openstack.s3_client
-        try:
-            s3client.get_bucket("^INVALID*#()@INVALID.")
-        except exception.BotoServerError as exc:
-            if exc.status == 403:
-                _cred_sub_check(s3client.connection_data)
-    except Exception as exc:
-        S3_CAN_CONNECT_ERROR = str(exc)
-    except lib_exc.Unauthorized:
-        S3_CAN_CONNECT_ERROR = "AWS credentials not set," +\
-                               " failed to get them even by keystoneclient"
-    boto_logger.logger.setLevel(level)
-    return {'A_I_IMAGES_READY': A_I_IMAGES_READY,
-            'S3_CAN_CONNECT_ERROR': S3_CAN_CONNECT_ERROR,
-            'EC2_CAN_CONNECT_ERROR': EC2_CAN_CONNECT_ERROR}
-
-
-class BotoExceptionMatcher(object):
-    STATUS_RE = r'[45]\d\d'
-    CODE_RE = '.*'  # regexp makes sense in group match
-
-    def match(self, exc):
-        """Check boto exception
-
-        :returns: Returns with an error string if it does not match,
-                  returns with None when it matches.
-        """
-        if not isinstance(exc, exception.BotoServerError):
-            return "%r not an BotoServerError instance" % exc
-        LOG.info("Status: %s , error_code: %s", exc.status, exc.error_code)
-        if re.match(self.STATUS_RE, str(exc.status)) is None:
-            return ("Status code (%s) does not match"
-                    "the expected re pattern \"%s\""
-                    % (exc.status, self.STATUS_RE))
-        if re.match(self.CODE_RE, str(exc.error_code)) is None:
-            return ("Error code (%s) does not match" +
-                    "the expected re pattern \"%s\"") %\
-                   (exc.error_code, self.CODE_RE)
-        return None
-
-
-class ClientError(BotoExceptionMatcher):
-    STATUS_RE = r'4\d\d'
-
-
-class ServerError(BotoExceptionMatcher):
-    STATUS_RE = r'5\d\d'
-
-
-def _add_matcher_class(error_cls, error_data, base=BotoExceptionMatcher):
-    """Usable for adding an ExceptionMatcher(s) into the exception tree.
-
-       The not leaf elements does wildcard match
-    """
-    # in error_code just literal and '.' characters expected
-    if not isinstance(error_data, six.string_types):
-        (error_code, status_code) = map(str, error_data)
-    else:
-        status_code = None
-        error_code = error_data
-    parts = error_code.split('.')
-    basematch = ""
-    num_parts = len(parts)
-    max_index = num_parts - 1
-    add_cls = error_cls
-    for i_part in six.moves.xrange(num_parts):
-        part = parts[i_part]
-        leaf = i_part == max_index
-        if not leaf:
-            match = basematch + part + "[.].*"
-        else:
-            match = basematch + part
-
-        basematch += part + "[.]"
-        if not hasattr(add_cls, part):
-            cls_dict = {"CODE_RE": match}
-            if leaf and status_code is not None:
-                cls_dict["STATUS_RE"] = status_code
-            cls = type(part, (base, ), cls_dict)
-            setattr(add_cls, part, cls())
-            add_cls = cls
-        elif leaf:
-            raise LookupError("Tries to redefine an error code \"%s\"" % part)
-        else:
-            add_cls = getattr(add_cls, part)
-
-
-# TODO(afazekas): classmethod handling
-def friendly_function_name_simple(call_able):
-    name = ""
-    if hasattr(call_able, "im_class"):
-        name += call_able.im_class.__name__ + "."
-    name += call_able.__name__
-    return name
-
-
-def friendly_function_call_str(call_able, *args, **kwargs):
-    string = friendly_function_name_simple(call_able)
-    string += "(" + ", ".join(map(str, args))
-    if len(kwargs):
-        if len(args):
-            string += ", "
-    string += ", ".join("=".join(map(str, (key, value)))
-                        for (key, value) in kwargs.items())
-    return string + ")"
-
-
-class BotoTestCase(tempest.test.BaseTestCase):
-    """Recommended to use as base class for boto related test."""
-
-    credentials = ['primary']
-
-    @classmethod
-    def skip_checks(cls):
-        super(BotoTestCase, cls).skip_checks()
-        if not CONF.compute_feature_enabled.ec2_api:
-            raise cls.skipException("The EC2 API is not available")
-        if not CONF.identity_feature_enabled.api_v2 or \
-                not CONF.identity.auth_version == 'v2':
-            raise cls.skipException("Identity v2 is not available")
-
-    @classmethod
-    def resource_setup(cls):
-        super(BotoTestCase, cls).resource_setup()
-        cls.conclusion = decision_maker()
-        # The trash contains cleanup functions and parameters in tuples
-        # (function, *args, **kwargs)
-        cls._resource_trash_bin = {}
-        cls._sequence = -1
-        if (hasattr(cls, "EC2") and
-            cls.conclusion['EC2_CAN_CONNECT_ERROR'] is not None):
-            raise cls.skipException("EC2 " + cls.__name__ + ": " +
-                                    cls.conclusion['EC2_CAN_CONNECT_ERROR'])
-        if (hasattr(cls, "S3") and
-            cls.conclusion['S3_CAN_CONNECT_ERROR'] is not None):
-            raise cls.skipException("S3 " + cls.__name__ + ": " +
-                                    cls.conclusion['S3_CAN_CONNECT_ERROR'])
-
-    @classmethod
-    def addResourceCleanUp(cls, function, *args, **kwargs):
-        """Adds CleanUp callable, used by tearDownClass.
-
-        Recommended to a use (deep)copy on the mutable args.
-        """
-        cls._sequence = cls._sequence + 1
-        cls._resource_trash_bin[cls._sequence] = (function, args, kwargs)
-        return cls._sequence
-
-    @classmethod
-    def cancelResourceCleanUp(cls, key):
-        """Cancel Clean up request."""
-        del cls._resource_trash_bin[key]
-
-    # TODO(afazekas): Add "with" context handling
-    def assertBotoError(self, excMatcher, callableObj,
-                        *args, **kwargs):
-        """Example usage:
-
-            self.assertBotoError(self.ec2_error_code.client.
-                                 InvalidKeyPair.Duplicate,
-                                 self.client.create_keypair,
-                                 key_name)
-        """
-        try:
-            callableObj(*args, **kwargs)
-        except exception.BotoServerError as exc:
-            error_msg = excMatcher.match(exc)
-            if error_msg is not None:
-                raise self.failureException(error_msg)
-        else:
-            raise self.failureException("BotoServerError not raised")
-
-    @classmethod
-    def resource_cleanup(cls):
-        """Calls the callables added by addResourceCleanUp
-
-        when you overwrite this function don't forget to call this too.
-        """
-        fail_count = 0
-        trash_keys = sorted(cls._resource_trash_bin, reverse=True)
-        for key in trash_keys:
-            (function, pos_args, kw_args) = cls._resource_trash_bin[key]
-            try:
-                func_name = friendly_function_call_str(function, *pos_args,
-                                                       **kw_args)
-                LOG.debug("Cleaning up: %s" % func_name)
-                function(*pos_args, **kw_args)
-            except BaseException:
-                fail_count += 1
-                LOG.exception("Cleanup failed %s" % func_name)
-            finally:
-                del cls._resource_trash_bin[key]
-        super(BotoTestCase, cls).resource_cleanup()
-        # NOTE(afazekas): let the super called even on exceptions
-        # The real exceptions already logged, if the super throws another,
-        # does not causes hidden issues
-        if fail_count:
-            raise exceptions.TearDownException(num=fail_count)
-
-    ec2_error_code = BotoExceptionMatcher()
-    # InsufficientInstanceCapacity can be both server and client error
-    ec2_error_code.server = ServerError()
-    ec2_error_code.client = ClientError()
-    s3_error_code = BotoExceptionMatcher()
-    s3_error_code.server = ServerError()
-    s3_error_code.client = ClientError()
-    valid_image_state = set(('available', 'pending', 'failed'))
-    # NOTE(afazekas): 'paused' is not valid status in EC2, but it does not have
-    # a good mapping, because it uses memory, but not really a running machine
-    valid_instance_state = set(('pending', 'running', 'shutting-down',
-                                'terminated', 'stopping', 'stopped', 'paused'))
-    valid_volume_status = set(('creating', 'available', 'in-use',
-                               'deleting', 'deleted', 'error'))
-    valid_snapshot_status = set(('pending', 'completed', 'error'))
-
-    gone_set = set(('_GONE',))
-
-    @classmethod
-    def get_lfunction_gone(cls, obj):
-        # NOTE: If the object is instance of a well know type returns back with
-        # with the corresponding function otherwise it assumes the obj itself
-        # is the function.
-        ec = cls.ec2_error_code
-        if isinstance(obj, ec2.instance.Instance):
-            colusure_matcher = ec.client.InvalidInstanceID.NotFound
-            status_attr = "state"
-        elif isinstance(obj, ec2.image.Image):
-            colusure_matcher = ec.client.InvalidAMIID.NotFound
-            status_attr = "state"
-        elif isinstance(obj, ec2.snapshot.Snapshot):
-            colusure_matcher = ec.client.InvalidSnapshot.NotFound
-            status_attr = "status"
-        elif isinstance(obj, ec2.volume.Volume):
-            colusure_matcher = ec.client.InvalidVolume.NotFound
-            status_attr = "status"
-        else:
-            return obj
-
-        def _status():
-            try:
-                obj.update(validate=True)
-            except ValueError:
-                return "_GONE"
-            except exception.EC2ResponseError as exc:
-                if colusure_matcher.match(exc) is None:
-                    return "_GONE"
-                else:
-                    raise
-            return getattr(obj, status_attr)
-
-        return _status
-
-    def state_wait_gone(self, lfunction, final_set, valid_set):
-        if not isinstance(final_set, set):
-            final_set = set((final_set,))
-        final_set |= self.gone_set
-        lfunction = self.get_lfunction_gone(lfunction)
-        state = wait.state_wait(lfunction, final_set, valid_set)
-        self.assertIn(state, valid_set | self.gone_set)
-        return state
-
-    def waitImageState(self, lfunction, wait_for):
-        return self.state_wait_gone(lfunction, wait_for,
-                                    self.valid_image_state)
-
-    def waitInstanceState(self, lfunction, wait_for):
-        return self.state_wait_gone(lfunction, wait_for,
-                                    self.valid_instance_state)
-
-    def waitSnapshotStatus(self, lfunction, wait_for):
-        return self.state_wait_gone(lfunction, wait_for,
-                                    self.valid_snapshot_status)
-
-    def waitVolumeStatus(self, lfunction, wait_for):
-        return self.state_wait_gone(lfunction, wait_for,
-                                    self.valid_volume_status)
-
-    def assertImageStateWait(self, lfunction, wait_for):
-        state = self.waitImageState(lfunction, wait_for)
-        self.assertIn(state, wait_for)
-
-    def assertInstanceStateWait(self, lfunction, wait_for):
-        state = self.waitInstanceState(lfunction, wait_for)
-        self.assertIn(state, wait_for)
-
-    def assertVolumeStatusWait(self, lfunction, wait_for):
-        state = self.waitVolumeStatus(lfunction, wait_for)
-        self.assertIn(state, wait_for)
-
-    def assertSnapshotStatusWait(self, lfunction, wait_for):
-        state = self.waitSnapshotStatus(lfunction, wait_for)
-        self.assertIn(state, wait_for)
-
-    def assertAddressDisassociatedWait(self, address):
-
-        def _disassociate():
-            cli = self.ec2_client
-            addresses = cli.get_all_addresses(addresses=(address.public_ip,))
-            if len(addresses) != 1:
-                return "INVALID"
-            if addresses[0].instance_id:
-                LOG.info("%s associated to %s",
-                         address.public_ip,
-                         addresses[0].instance_id)
-                return "ASSOCIATED"
-            return "DISASSOCIATED"
-
-        state = wait.state_wait(_disassociate, "DISASSOCIATED",
-                                set(("ASSOCIATED", "DISASSOCIATED")))
-        self.assertEqual(state, "DISASSOCIATED")
-
-    def assertAddressReleasedWait(self, address):
-
-        def _address_delete():
-            # NOTE(afazekas): the filter gives back IP
-            # even if it is not associated to my tenant
-            if (address.public_ip not in map(lambda a: a.public_ip,
-                self.ec2_client.get_all_addresses())):
-                    return "DELETED"
-            return "NOTDELETED"
-
-        state = wait.state_wait(_address_delete, "DELETED")
-        self.assertEqual(state, "DELETED")
-
-    def assertReSearch(self, regexp, string):
-        if re.search(regexp, string) is None:
-            raise self.failureException("regexp: '%s' not found in '%s'" %
-                                        (regexp, string))
-
-    def assertNotReSearch(self, regexp, string):
-        if re.search(regexp, string) is not None:
-            raise self.failureException("regexp: '%s' found in '%s'" %
-                                        (regexp, string))
-
-    def assertReMatch(self, regexp, string):
-        if re.match(regexp, string) is None:
-            raise self.failureException("regexp: '%s' not matches on '%s'" %
-                                        (regexp, string))
-
-    def assertNotReMatch(self, regexp, string):
-        if re.match(regexp, string) is not None:
-            raise self.failureException("regexp: '%s' matches on '%s'" %
-                                        (regexp, string))
-
-    @classmethod
-    def destroy_bucket(cls, connection_data, bucket):
-        """Destroys the bucket and its content, just for teardown."""
-        exc_num = 0
-        try:
-            with contextlib.closing(
-                    boto.connect_s3(**connection_data)) as conn:
-                if isinstance(bucket, basestring):
-                    bucket = conn.lookup(bucket)
-                    assert isinstance(bucket, s3.bucket.Bucket)
-                for obj in bucket.list():
-                    try:
-                        bucket.delete_key(obj.key)
-                        obj.close()
-                    except BaseException:
-                        LOG.exception("Failed to delete key %s " % obj.key)
-                        exc_num += 1
-            conn.delete_bucket(bucket)
-        except BaseException:
-            LOG.exception("Failed to destroy bucket %s " % bucket)
-            exc_num += 1
-        if exc_num:
-            raise exceptions.TearDownException(num=exc_num)
-
-    @classmethod
-    def destroy_reservation(cls, reservation):
-        """Terminate instances in a reservation, just for teardown."""
-        exc_num = 0
-
-        def _instance_state():
-            try:
-                instance.update(validate=True)
-            except ValueError:
-                return "_GONE"
-            except exception.EC2ResponseError as exc:
-                if cls.ec2_error_code.\
-                        client.InvalidInstanceID.NotFound.match(exc) is None:
-                    return "_GONE"
-                # NOTE(afazekas): incorrect code,
-                # but the resource must be destroyed
-                if exc.error_code == "InstanceNotFound":
-                    return "_GONE"
-
-            return instance.state
-
-        for instance in reservation.instances:
-            try:
-                instance.terminate()
-                wait.re_search_wait(_instance_state, "_GONE")
-            except BaseException:
-                LOG.exception("Failed to terminate instance %s " % instance)
-                exc_num += 1
-        if exc_num:
-            raise exceptions.TearDownException(num=exc_num)
-
-    # NOTE(afazekas): The incorrect ErrorCodes makes very, very difficult
-    # to write better teardown
-
-    @classmethod
-    def destroy_security_group_wait(cls, group):
-        """Delete group.
-
-           Use just for teardown!
-        """
-        # NOTE(afazekas): should wait/try until all related instance terminates
-        group.delete()
-
-    @classmethod
-    def destroy_volume_wait(cls, volume):
-        """Delete volume, tries to detach first.
-
-           Use just for teardown!
-        """
-        exc_num = 0
-        snaps = volume.snapshots()
-        if len(snaps):
-            LOG.critical("%s Volume has %s snapshot(s)", volume.id,
-                         map(snaps.id, snaps))
-
-        # NOTE(afazekas): detaching/attaching not valid EC2 status
-        def _volume_state():
-            volume.update(validate=True)
-            try:
-                # NOTE(gmann): Make sure volume is attached.
-                # Checking status as 'not "available"' is not enough to make
-                # sure volume is attached as it can be in "error" state
-                if volume.status == "in-use":
-                    volume.detach(force=True)
-            except BaseException:
-                LOG.exception("Failed to detach volume %s" % volume)
-                # exc_num += 1 "nonlocal" not in python2
-            return volume.status
-
-        try:
-            wait.re_search_wait(_volume_state, "available")
-            # not validates status
-            LOG.info(_volume_state())
-            volume.delete()
-        except BaseException:
-            LOG.exception("Failed to delete volume %s" % volume)
-            exc_num += 1
-        if exc_num:
-            raise exceptions.TearDownException(num=exc_num)
-
-    @classmethod
-    def destroy_snapshot_wait(cls, snapshot):
-        """delete snapshot, wait until it ceases to exist."""
-        snapshot.delete()
-
-        def _update():
-            snapshot.update(validate=True)
-
-        wait.wait_exception(_update)
-
-
-# you can specify tuples if you want to specify the status pattern
-for code in ('AddressLimitExceeded', 'AttachmentLimitExceeded', 'AuthFailure',
-             'Blocked', 'CustomerGatewayLimitExceeded', 'DependencyViolation',
-             'DiskImageSizeTooLarge', 'FilterLimitExceeded',
-             'Gateway.NotAttached', 'IdempotentParameterMismatch',
-             'IncorrectInstanceState', 'IncorrectState',
-             'InstanceLimitExceeded', 'InsufficientInstanceCapacity',
-             'InsufficientReservedInstancesCapacity',
-             'InternetGatewayLimitExceeded', 'InvalidAMIAttributeItemValue',
-             'InvalidAMIID.Malformed', 'InvalidAMIID.NotFound',
-             'InvalidAMIID.Unavailable', 'InvalidAssociationID.NotFound',
-             'InvalidAttachment.NotFound', 'InvalidConversionTaskId',
-             'InvalidCustomerGateway.DuplicateIpAddress',
-             'InvalidCustomerGatewayID.NotFound', 'InvalidDevice.InUse',
-             'InvalidDhcpOptionsID.NotFound', 'InvalidFormat',
-             'InvalidFilter', 'InvalidGatewayID.NotFound',
-             'InvalidGroup.Duplicate', 'InvalidGroupId.Malformed',
-             'InvalidGroup.InUse', 'InvalidGroup.NotFound',
-             'InvalidGroup.Reserved', 'InvalidInstanceID.Malformed',
-             'InvalidInstanceID.NotFound',
-             'InvalidInternetGatewayID.NotFound', 'InvalidIPAddress.InUse',
-             'InvalidKeyPair.Duplicate', 'InvalidKeyPair.Format',
-             'InvalidKeyPair.NotFound', 'InvalidManifest',
-             'InvalidNetworkAclEntry.NotFound',
-             'InvalidNetworkAclID.NotFound', 'InvalidParameterCombination',
-             'InvalidParameterValue', 'InvalidPermission.Duplicate',
-             'InvalidPermission.Malformed', 'InvalidReservationID.Malformed',
-             'InvalidReservationID.NotFound', 'InvalidRoute.NotFound',
-             'InvalidRouteTableID.NotFound',
-             'InvalidSecurity.RequestHasExpired',
-             'InvalidSnapshotID.Malformed', 'InvalidSnapshot.NotFound',
-             'InvalidUserID.Malformed', 'InvalidReservedInstancesId',
-             'InvalidReservedInstancesOfferingId',
-             'InvalidSubnetID.NotFound', 'InvalidVolumeID.Duplicate',
-             'InvalidVolumeID.Malformed', 'InvalidVolumeID.ZoneMismatch',
-             'InvalidVolume.NotFound', 'InvalidVpcID.NotFound',
-             'InvalidVpnConnectionID.NotFound',
-             'InvalidVpnGatewayID.NotFound',
-             'InvalidZone.NotFound', 'LegacySecurityGroup',
-             'MissingParameter', 'NetworkAclEntryAlreadyExists',
-             'NetworkAclEntryLimitExceeded', 'NetworkAclLimitExceeded',
-             'NonEBSInstance', 'PendingSnapshotLimitExceeded',
-             'PendingVerification', 'OptInRequired', 'RequestLimitExceeded',
-             'ReservedInstancesLimitExceeded', 'Resource.AlreadyAssociated',
-             'ResourceLimitExceeded', 'RouteAlreadyExists',
-             'RouteLimitExceeded', 'RouteTableLimitExceeded',
-             'RulesPerSecurityGroupLimitExceeded',
-             'SecurityGroupLimitExceeded',
-             'SecurityGroupsPerInstanceLimitExceeded',
-             'SnapshotLimitExceeded', 'SubnetLimitExceeded',
-             'UnknownParameter', 'UnsupportedOperation',
-             'VolumeLimitExceeded', 'VpcLimitExceeded',
-             'VpnConnectionLimitExceeded',
-             'VpnGatewayAttachmentLimitExceeded', 'VpnGatewayLimitExceeded'):
-    _add_matcher_class(BotoTestCase.ec2_error_code.client,
-                       code, base=ClientError)
-
-for code in ('InsufficientAddressCapacity', 'InsufficientInstanceCapacity',
-             'InsufficientReservedInstanceCapacity', 'InternalError',
-             'Unavailable'):
-    _add_matcher_class(BotoTestCase.ec2_error_code.server,
-                       code, base=ServerError)
-
-
-for code in (('AccessDenied', 403),
-             ('AccountProblem', 403),
-             ('AmbiguousGrantByEmailAddress', 400),
-             ('BadDigest', 400),
-             ('BucketAlreadyExists', 409),
-             ('BucketAlreadyOwnedByYou', 409),
-             ('BucketNotEmpty', 409),
-             ('CredentialsNotSupported', 400),
-             ('CrossLocationLoggingProhibited', 403),
-             ('EntityTooSmall', 400),
-             ('EntityTooLarge', 400),
-             ('ExpiredToken', 400),
-             ('IllegalVersioningConfigurationException', 400),
-             ('IncompleteBody', 400),
-             ('IncorrectNumberOfFilesInPostRequest', 400),
-             ('InlineDataTooLarge', 400),
-             ('InvalidAccessKeyId', 403),
-             'InvalidAddressingHeader',
-             ('InvalidArgument', 400),
-             ('InvalidBucketName', 400),
-             ('InvalidBucketState', 409),
-             ('InvalidDigest', 400),
-             ('InvalidLocationConstraint', 400),
-             ('InvalidPart', 400),
-             ('InvalidPartOrder', 400),
-             ('InvalidPayer', 403),
-             ('InvalidPolicyDocument', 400),
-             ('InvalidRange', 416),
-             ('InvalidRequest', 400),
-             ('InvalidSecurity', 403),
-             ('InvalidSOAPRequest', 400),
-             ('InvalidStorageClass', 400),
-             ('InvalidTargetBucketForLogging', 400),
-             ('InvalidToken', 400),
-             ('InvalidURI', 400),
-             ('KeyTooLong', 400),
-             ('MalformedACLError', 400),
-             ('MalformedPOSTRequest', 400),
-             ('MalformedXML', 400),
-             ('MaxMessageLengthExceeded', 400),
-             ('MaxPostPreDataLengthExceededError', 400),
-             ('MetadataTooLarge', 400),
-             ('MethodNotAllowed', 405),
-             ('MissingAttachment'),
-             ('MissingContentLength', 411),
-             ('MissingRequestBodyError', 400),
-             ('MissingSecurityElement', 400),
-             ('MissingSecurityHeader', 400),
-             ('NoLoggingStatusForKey', 400),
-             ('NoSuchBucket', 404),
-             ('NoSuchKey', 404),
-             ('NoSuchLifecycleConfiguration', 404),
-             ('NoSuchUpload', 404),
-             ('NoSuchVersion', 404),
-             ('NotSignedUp', 403),
-             ('NotSuchBucketPolicy', 404),
-             ('OperationAborted', 409),
-             ('PermanentRedirect', 301),
-             ('PreconditionFailed', 412),
-             ('Redirect', 307),
-             ('RequestIsNotMultiPartContent', 400),
-             ('RequestTimeout', 400),
-             ('RequestTimeTooSkewed', 403),
-             ('RequestTorrentOfBucketError', 400),
-             ('SignatureDoesNotMatch', 403),
-             ('TemporaryRedirect', 307),
-             ('TokenRefreshRequired', 400),
-             ('TooManyBuckets', 400),
-             ('UnexpectedContent', 400),
-             ('UnresolvableGrantByEmailAddress', 400),
-             ('UserKeyMustBeSpecified', 400)):
-    _add_matcher_class(BotoTestCase.s3_error_code.client,
-                       code, base=ClientError)
-
-
-for code in (('InternalError', 500),
-             ('NotImplemented', 501),
-             ('ServiceUnavailable', 503),
-             ('SlowDown', 503)):
-    _add_matcher_class(BotoTestCase.s3_error_code.server,
-                       code, base=ServerError)
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
deleted file mode 100644
index 8fe9406..0000000
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ /dev/null
@@ -1,363 +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.
-
-from oslo_log import log as logging
-
-from tempest.common.utils import data_utils
-from tempest.common.utils.linux import remote_client
-from tempest import config
-from tempest import exceptions
-from tempest import test
-from tempest.thirdparty.boto import test as boto_test
-from tempest.thirdparty.boto.utils import s3
-from tempest.thirdparty.boto.utils import wait
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class InstanceRunTest(boto_test.BotoTestCase):
-
-    @classmethod
-    def setup_clients(cls):
-        super(InstanceRunTest, cls).setup_clients()
-        cls.s3_client = cls.os.s3_client
-        cls.ec2_client = cls.os.ec2api_client
-
-    @classmethod
-    def resource_setup(cls):
-        super(InstanceRunTest, cls).resource_setup()
-        if not cls.conclusion['A_I_IMAGES_READY']:
-            raise cls.skipException("".join(("EC2 ", cls.__name__,
-                                    ": requires ami/aki/ari manifest")))
-        cls.zone = CONF.boto.aws_zone
-        cls.materials_path = CONF.boto.s3_materials_path
-        ami_manifest = CONF.boto.ami_manifest
-        aki_manifest = CONF.boto.aki_manifest
-        ari_manifest = CONF.boto.ari_manifest
-        cls.instance_type = CONF.boto.instance_type
-        cls.bucket_name = data_utils.rand_name("s3bucket")
-        cls.keypair_name = data_utils.rand_name("keypair")
-        cls.keypair = cls.ec2_client.create_key_pair(cls.keypair_name)
-        cls.addResourceCleanUp(cls.ec2_client.delete_key_pair,
-                               cls.keypair_name)
-        bucket = cls.s3_client.create_bucket(cls.bucket_name)
-        cls.addResourceCleanUp(cls.destroy_bucket,
-                               cls.s3_client.connection_data,
-                               cls.bucket_name)
-        s3.s3_upload_dir(bucket, cls.materials_path)
-        cls.images = {"ami":
-                      {"name": data_utils.rand_name("ami-name"),
-                       "location": cls.bucket_name + "/" + ami_manifest},
-                      "aki":
-                      {"name": data_utils.rand_name("aki-name"),
-                       "location": cls.bucket_name + "/" + aki_manifest},
-                      "ari":
-                      {"name": data_utils.rand_name("ari-name"),
-                       "location": cls.bucket_name + "/" + ari_manifest}}
-        for image_type in ("aki", "ari"):
-            image = cls.images[image_type]
-            image["image_id"] = cls.ec2_client.register_image(
-                name=image["name"],
-                image_location=image["location"])
-            cls.addResourceCleanUp(cls.ec2_client.deregister_image,
-                                   image["image_id"])
-        image = cls.images["ami"]
-        image["image_id"] = cls.ec2_client.register_image(
-            name=image["name"],
-            image_location=image["location"],
-            kernel_id=cls.images["aki"]["image_id"],
-            ramdisk_id=cls.images["ari"]["image_id"])
-        cls.addResourceCleanUp(cls.ec2_client.deregister_image,
-                               image["image_id"])
-
-        for image in cls.images.itervalues():
-            def _state():
-                retr = cls.ec2_client.get_image(image["image_id"])
-                return retr.state
-            state = wait.state_wait(_state, "available")
-            if state != "available":
-                for _image in cls.images.itervalues():
-                    cls.ec2_client.deregister_image(_image["image_id"])
-                raise exceptions.EC2RegisterImageException(
-                    image_id=image["image_id"])
-
-    def _terminate_reservation(self, reservation, rcuk):
-        for instance in reservation.instances:
-            instance.terminate()
-        for instance in reservation.instances:
-            self.assertInstanceStateWait(instance, '_GONE')
-        self.cancelResourceCleanUp(rcuk)
-
-    @test.idempotent_id('c881fbb7-d56e-4054-9d76-1c3a60a207b0')
-    def test_run_idempotent_instances(self):
-        # EC2 run instances idempotently
-
-        def _run_instance(client_token):
-            reservation = self.ec2_client.run_instances(
-                image_id=self.images["ami"]["image_id"],
-                kernel_id=self.images["aki"]["image_id"],
-                ramdisk_id=self.images["ari"]["image_id"],
-                instance_type=self.instance_type,
-                client_token=client_token)
-            rcuk = self.addResourceCleanUp(self.destroy_reservation,
-                                           reservation)
-            return (reservation, rcuk)
-
-        reservation_1, rcuk_1 = _run_instance('token_1')
-        reservation_2, rcuk_2 = _run_instance('token_2')
-        reservation_1a, rcuk_1a = _run_instance('token_1')
-
-        self.assertIsNotNone(reservation_1)
-        self.assertIsNotNone(reservation_2)
-        self.assertIsNotNone(reservation_1a)
-
-        # same reservation for token_1
-        self.assertEqual(reservation_1.id, reservation_1a.id)
-
-        # Cancel cleanup -- since it's a duplicate, it's
-        # handled by rcuk1
-        self.cancelResourceCleanUp(rcuk_1a)
-
-        self._terminate_reservation(reservation_1, rcuk_1)
-        self._terminate_reservation(reservation_2, rcuk_2)
-
-    @test.idempotent_id('2ea26a39-f96c-48fc-8374-5c10ec184c67')
-    def test_run_stop_terminate_instance(self):
-        # EC2 run, stop and terminate instance
-        image_ami = self.ec2_client.get_image(self.images["ami"]
-                                              ["image_id"])
-        reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
-                                    ramdisk_id=self.images["ari"]["image_id"],
-                                    instance_type=self.instance_type)
-        rcuk = self.addResourceCleanUp(self.destroy_reservation, reservation)
-
-        for instance in reservation.instances:
-            LOG.info("state: %s", instance.state)
-            if instance.state != "running":
-                self.assertInstanceStateWait(instance, "running")
-
-        for instance in reservation.instances:
-            instance.stop()
-            LOG.info("state: %s", instance.state)
-            if instance.state != "stopped":
-                self.assertInstanceStateWait(instance, "stopped")
-
-        self._terminate_reservation(reservation, rcuk)
-
-    @test.idempotent_id('3d77225a-5cec-4e54-a017-9ebf11a266e6')
-    def test_run_stop_terminate_instance_with_tags(self):
-        # EC2 run, stop and terminate instance with tags
-        image_ami = self.ec2_client.get_image(self.images["ami"]
-                                              ["image_id"])
-        reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
-                                    ramdisk_id=self.images["ari"]["image_id"],
-                                    instance_type=self.instance_type)
-        rcuk = self.addResourceCleanUp(self.destroy_reservation, reservation)
-
-        for instance in reservation.instances:
-            LOG.info("state: %s", instance.state)
-            if instance.state != "running":
-                self.assertInstanceStateWait(instance, "running")
-            instance.add_tag('key1', value='value1')
-
-        tags = self.ec2_client.get_all_tags()
-        td = dict((item.name, item.value) for item in tags)
-
-        self.assertIn('key1', td)
-        self.assertEqual('value1', td['key1'])
-
-        tags = self.ec2_client.get_all_tags(filters={'key': 'key1'})
-        td = dict((item.name, item.value) for item in tags)
-        self.assertIn('key1', td)
-        self.assertEqual('value1', td['key1'])
-
-        tags = self.ec2_client.get_all_tags(filters={'value': 'value1'})
-        td = dict((item.name, item.value) for item in tags)
-        self.assertIn('key1', td)
-        self.assertEqual('value1', td['key1'])
-
-        tags = self.ec2_client.get_all_tags(filters={'key': 'value2'})
-        td = dict((item.name, item.value) for item in tags)
-        self.assertNotIn('key1', td)
-
-        for instance in reservation.instances:
-            instance.remove_tag('key1', value='value1')
-
-        tags = self.ec2_client.get_all_tags()
-
-        # NOTE: Volume-attach and detach causes metadata (tags) to be created
-        # for the volume. So exclude them while asserting.
-        self.assertNotIn('key1', tags)
-
-        for instance in reservation.instances:
-            instance.stop()
-            LOG.info("state: %s", instance.state)
-            if instance.state != "stopped":
-                self.assertInstanceStateWait(instance, "stopped")
-
-        self._terminate_reservation(reservation, rcuk)
-
-    @test.idempotent_id('252945b5-3294-4fda-ae21-928a42f63f76')
-    def test_run_terminate_instance(self):
-        # EC2 run, terminate immediately
-        image_ami = self.ec2_client.get_image(self.images["ami"]
-                                              ["image_id"])
-        reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
-                                    ramdisk_id=self.images["ari"]["image_id"],
-                                    instance_type=self.instance_type)
-
-        for instance in reservation.instances:
-            instance.terminate()
-        self.assertInstanceStateWait(instance, '_GONE')
-
-    @test.idempotent_id('ab836c29-737b-4101-9fb9-87045eaf89e9')
-    def test_compute_with_volumes(self):
-        # EC2 1. integration test (not strict)
-        image_ami = self.ec2_client.get_image(self.images["ami"]["image_id"])
-        sec_group_name = data_utils.rand_name("securitygroup")
-        group_desc = sec_group_name + " security group description "
-        security_group = self.ec2_client.create_security_group(sec_group_name,
-                                                               group_desc)
-        self.addResourceCleanUp(self.destroy_security_group_wait,
-                                security_group)
-        self.assertTrue(
-            self.ec2_client.authorize_security_group(
-                sec_group_name,
-                ip_protocol="icmp",
-                cidr_ip="0.0.0.0/0",
-                from_port=-1,
-                to_port=-1))
-        self.assertTrue(
-            self.ec2_client.authorize_security_group(
-                sec_group_name,
-                ip_protocol="tcp",
-                cidr_ip="0.0.0.0/0",
-                from_port=22,
-                to_port=22))
-        reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
-                                    ramdisk_id=self.images["ari"]["image_id"],
-                                    instance_type=self.instance_type,
-                                    key_name=self.keypair_name,
-                                    security_groups=(sec_group_name,))
-
-        LOG.debug("Instance booted - state: %s",
-                  reservation.instances[0].state)
-
-        self.addResourceCleanUp(self.destroy_reservation,
-                                reservation)
-        volume = self.ec2_client.create_volume(CONF.volume.volume_size,
-                                               self.zone)
-        LOG.debug("Volume created - status: %s", volume.status)
-
-        self.addResourceCleanUp(self.destroy_volume_wait, volume)
-        instance = reservation.instances[0]
-        if instance.state != "running":
-            self.assertInstanceStateWait(instance, "running")
-        LOG.debug("Instance now running - state: %s", instance.state)
-
-        address = self.ec2_client.allocate_address()
-        rcuk_a = self.addResourceCleanUp(address.delete)
-        self.assertTrue(address.associate(instance.id))
-
-        rcuk_da = self.addResourceCleanUp(address.disassociate)
-        # TODO(afazekas): ping test. dependecy/permission ?
-
-        self.assertVolumeStatusWait(volume, "available")
-        # NOTE(afazekas): it may be reports available before it is available
-
-        ssh = remote_client.RemoteClient(address.public_ip,
-                                         CONF.validation.image_ssh_user,
-                                         pkey=self.keypair.material)
-        text = data_utils.rand_name("Pattern text for console output")
-        try:
-            resp = ssh.write_to_console(text)
-        except Exception:
-            if not CONF.compute_feature_enabled.console_output:
-                LOG.debug('Console output not supported, cannot log')
-            else:
-                console_output = instance.get_console_output().output
-                LOG.debug('Console output for %s\nbody=\n%s',
-                          instance.id, console_output)
-            raise
-
-        self.assertFalse(resp)
-
-        def _output():
-            output = instance.get_console_output()
-            return output.output
-
-        wait.re_search_wait(_output, text)
-        part_lines = ssh.get_partitions().split('\n')
-        volume.attach(instance.id, "/dev/vdh")
-
-        def _volume_state():
-            """Return volume state realizing that 'in-use' is overloaded."""
-            volume.update(validate=True)
-            status = volume.status
-            attached = volume.attach_data.status
-            LOG.debug("Volume %s is in status: %s, attach_status: %s",
-                      volume.id, status, attached)
-            # Nova reports 'in-use' on 'attaching' volumes because we
-            # have a single volume status, and EC2 has 2. Ensure that
-            # if we aren't attached yet we return something other than
-            # 'in-use'
-            if status == 'in-use' and attached != 'attached':
-                return 'attaching'
-            else:
-                return status
-
-        wait.re_search_wait(_volume_state, "in-use")
-
-        # NOTE(afazekas):  Different Hypervisor backends names
-        # differently the devices,
-        # now we just test is the partition number increased/decrised
-
-        def _part_state():
-            current = ssh.get_partitions().split('\n')
-            LOG.debug("Partition map for instance: %s", current)
-            if current > part_lines:
-                return 'INCREASE'
-            if current < part_lines:
-                return 'DECREASE'
-            return 'EQUAL'
-
-        wait.state_wait(_part_state, 'INCREASE')
-        part_lines = ssh.get_partitions().split('\n')
-
-        # TODO(afazekas): Resource compare to the flavor settings
-
-        volume.detach()
-
-        self.assertVolumeStatusWait(volume, "available")
-
-        wait.state_wait(_part_state, 'DECREASE')
-
-        instance.stop()
-        address.disassociate()
-        self.assertAddressDisassociatedWait(address)
-        self.cancelResourceCleanUp(rcuk_da)
-        address.release()
-        self.assertAddressReleasedWait(address)
-        self.cancelResourceCleanUp(rcuk_a)
-
-        LOG.debug("Instance %s state: %s", instance.id, instance.state)
-        if instance.state != "stopped":
-            self.assertInstanceStateWait(instance, "stopped")
-        # TODO(afazekas): move steps from teardown to the test case
-
-
-# TODO(afazekas): Snapshot/volume read/write test case
diff --git a/tempest/thirdparty/boto/test_ec2_keys.py b/tempest/thirdparty/boto/test_ec2_keys.py
deleted file mode 100644
index 1b58cb4..0000000
--- a/tempest/thirdparty/boto/test_ec2_keys.py
+++ /dev/null
@@ -1,75 +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.
-
-from tempest.common.utils import data_utils
-from tempest import test
-from tempest.thirdparty.boto import test as boto_test
-
-
-def compare_key_pairs(a, b):
-    return (a.name == b.name and
-            a.fingerprint == b.fingerprint)
-
-
-class EC2KeysTest(boto_test.BotoTestCase):
-
-    @classmethod
-    def setup_clients(cls):
-        super(EC2KeysTest, cls).setup_clients()
-        cls.client = cls.os.ec2api_client
-
-    @classmethod
-    def resource_setup(cls):
-        super(EC2KeysTest, cls).resource_setup()
-        cls.ec = cls.ec2_error_code
-
-# TODO(afazekas): merge create, delete, get test cases
-    @test.idempotent_id('54236804-01b7-4cfe-a6f9-bce1340feec8')
-    def test_create_ec2_keypair(self):
-        # EC2 create KeyPair
-        key_name = data_utils.rand_name("keypair")
-        self.addResourceCleanUp(self.client.delete_key_pair, key_name)
-        keypair = self.client.create_key_pair(key_name)
-        self.assertTrue(compare_key_pairs(keypair,
-                        self.client.get_key_pair(key_name)))
-
-    @test.idempotent_id('3283b898-f90c-4952-b238-3e42b8c3f34f')
-    def test_delete_ec2_keypair(self):
-        # EC2 delete KeyPair
-        key_name = data_utils.rand_name("keypair")
-        self.client.create_key_pair(key_name)
-        self.client.delete_key_pair(key_name)
-        self.assertIsNone(self.client.get_key_pair(key_name))
-
-    @test.idempotent_id('fd89bd26-4d4d-4cf3-a303-65dd9158fcdc')
-    def test_get_ec2_keypair(self):
-        # EC2 get KeyPair
-        key_name = data_utils.rand_name("keypair")
-        self.addResourceCleanUp(self.client.delete_key_pair, key_name)
-        keypair = self.client.create_key_pair(key_name)
-        self.assertTrue(compare_key_pairs(keypair,
-                        self.client.get_key_pair(key_name)))
-
-    @test.idempotent_id('daa73da1-e11c-4558-8d76-a716be79a401')
-    def test_duplicate_ec2_keypair(self):
-        # EC2 duplicate KeyPair
-        key_name = data_utils.rand_name("keypair")
-        self.addResourceCleanUp(self.client.delete_key_pair, key_name)
-        keypair = self.client.create_key_pair(key_name)
-        self.assertBotoError(self.ec.client.InvalidKeyPair.Duplicate,
-                             self.client.create_key_pair,
-                             key_name)
-        self.assertTrue(compare_key_pairs(keypair,
-                        self.client.get_key_pair(key_name)))
diff --git a/tempest/thirdparty/boto/test_ec2_security_groups.py b/tempest/thirdparty/boto/test_ec2_security_groups.py
deleted file mode 100644
index 594dc8b..0000000
--- a/tempest/thirdparty/boto/test_ec2_security_groups.py
+++ /dev/null
@@ -1,72 +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.
-
-from tempest.common.utils import data_utils
-from tempest import test
-from tempest.thirdparty.boto import test as boto_test
-
-
-class EC2SecurityGroupTest(boto_test.BotoTestCase):
-
-    @classmethod
-    def setup_clients(cls):
-        super(EC2SecurityGroupTest, cls).setup_clients()
-        cls.client = cls.os.ec2api_client
-
-    @test.idempotent_id('519b566e-0c38-4629-905e-7d6b6355f524')
-    def test_create_authorize_security_group(self):
-        # EC2 Create, authorize/revoke security group
-        group_name = data_utils.rand_name("securty_group")
-        group_description = group_name + " security group description "
-        group = self.client.create_security_group(group_name,
-                                                  group_description)
-        self.addResourceCleanUp(self.client.delete_security_group, group_name)
-        groups_get = self.client.get_all_security_groups(
-            groupnames=(group_name,))
-        self.assertEqual(len(groups_get), 1)
-        group_get = groups_get[0]
-        self.assertEqual(group.name, group_get.name)
-        self.assertEqual(group.name, group_get.name)
-        # ping (icmp_echo) and other icmp allowed from everywhere
-        # from_port and to_port act as icmp type
-        success = self.client.authorize_security_group(group_name,
-                                                       ip_protocol="icmp",
-                                                       cidr_ip="0.0.0.0/0",
-                                                       from_port=-1,
-                                                       to_port=-1)
-        self.assertTrue(success)
-        # allow standard ssh port from anywhere
-        success = self.client.authorize_security_group(group_name,
-                                                       ip_protocol="tcp",
-                                                       cidr_ip="0.0.0.0/0",
-                                                       from_port=22,
-                                                       to_port=22)
-        self.assertTrue(success)
-        # TODO(afazekas): Duplicate tests
-        group_get = self.client.get_all_security_groups(
-            groupnames=(group_name,))[0]
-        # remove listed rules
-        for ip_permission in group_get.rules:
-            for cidr in ip_permission.grants:
-                self.assertTrue(self.client.revoke_security_group(group_name,
-                                ip_protocol=ip_permission.ip_protocol,
-                                cidr_ip=cidr,
-                                from_port=ip_permission.from_port,
-                                to_port=ip_permission.to_port))
-
-        group_get = self.client.get_all_security_groups(
-            groupnames=(group_name,))[0]
-        # all rules should be removed now
-        self.assertEqual(0, len(group_get.rules))
diff --git a/tempest/thirdparty/boto/test_ec2_volumes.py b/tempest/thirdparty/boto/test_ec2_volumes.py
deleted file mode 100644
index 483d4c3..0000000
--- a/tempest/thirdparty/boto/test_ec2_volumes.py
+++ /dev/null
@@ -1,78 +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.
-
-from oslo_log import log as logging
-
-from tempest import config
-from tempest import test
-from tempest.thirdparty.boto import test as boto_test
-
-CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
-
-def compare_volumes(a, b):
-    return (a.id == b.id and
-            a.size == b.size)
-
-
-class EC2VolumesTest(boto_test.BotoTestCase):
-
-    @classmethod
-    def skip_checks(cls):
-        super(EC2VolumesTest, cls).skip_checks()
-        if not CONF.service_available.cinder:
-            skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
-            raise cls.skipException(skip_msg)
-
-    @classmethod
-    def setup_clients(cls):
-        super(EC2VolumesTest, cls).setup_clients()
-        cls.client = cls.os.ec2api_client
-
-    @classmethod
-    def resource_setup(cls):
-        super(EC2VolumesTest, cls).resource_setup()
-        cls.zone = CONF.boto.aws_zone
-
-    @test.idempotent_id('663f0077-c743-48ad-8ae0-46821cbc0918')
-    def test_create_get_delete(self):
-        # EC2 Create, get, delete Volume
-        volume = self.client.create_volume(CONF.volume.volume_size, self.zone)
-        cuk = self.addResourceCleanUp(self.client.delete_volume, volume.id)
-        self.assertIn(volume.status, self.valid_volume_status)
-        retrieved = self.client.get_all_volumes((volume.id,))
-        self.assertEqual(1, len(retrieved))
-        self.assertTrue(compare_volumes(volume, retrieved[0]))
-        self.assertVolumeStatusWait(volume, "available")
-        self.client.delete_volume(volume.id)
-        self.cancelResourceCleanUp(cuk)
-
-    @test.idempotent_id('c6b60d7a-1af7-4f8e-af21-d539d9496149')
-    def test_create_volume_from_snapshot(self):
-        # EC2 Create volume from snapshot
-        volume = self.client.create_volume(CONF.volume.volume_size, self.zone)
-        self.addResourceCleanUp(self.client.delete_volume, volume.id)
-        self.assertVolumeStatusWait(volume, "available")
-        snap = self.client.create_snapshot(volume.id)
-        self.addResourceCleanUp(self.destroy_snapshot_wait, snap)
-        self.assertSnapshotStatusWait(snap, "completed")
-
-        svol = self.client.create_volume(CONF.volume.volume_size, self.zone,
-                                         snapshot=snap)
-        cuk = self.addResourceCleanUp(svol.delete)
-        self.assertVolumeStatusWait(svol, "available")
-        svol.delete()
-        self.cancelResourceCleanUp(cuk)
diff --git a/tempest/thirdparty/boto/test_s3_buckets.py b/tempest/thirdparty/boto/test_s3_buckets.py
deleted file mode 100644
index f008973..0000000
--- a/tempest/thirdparty/boto/test_s3_buckets.py
+++ /dev/null
@@ -1,41 +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.
-
-from tempest.common.utils import data_utils
-from tempest import test
-from tempest.thirdparty.boto import test as boto_test
-
-
-class S3BucketsTest(boto_test.BotoTestCase):
-
-    @classmethod
-    def setup_clients(cls):
-        super(S3BucketsTest, cls).setup_clients()
-        cls.client = cls.os.s3_client
-
-    @test.idempotent_id('4678525d-8da0-4518-81c1-f1f67d595b00')
-    def test_create_and_get_delete_bucket(self):
-        # S3 Create, get and delete bucket
-        bucket_name = data_utils.rand_name("s3bucket")
-        cleanup_key = self.addResourceCleanUp(self.client.delete_bucket,
-                                              bucket_name)
-        bucket = self.client.create_bucket(bucket_name)
-        self.assertTrue(bucket.name == bucket_name)
-        bucket = self.client.get_bucket(bucket_name)
-        self.assertTrue(bucket.name == bucket_name)
-        self.client.delete_bucket(bucket_name)
-        self.assertBotoError(self.s3_error_code.client.NoSuchBucket,
-                             self.client.get_bucket, bucket_name)
-        self.cancelResourceCleanUp(cleanup_key)
diff --git a/tempest/thirdparty/boto/test_s3_ec2_images.py b/tempest/thirdparty/boto/test_s3_ec2_images.py
deleted file mode 100644
index c41c7ac..0000000
--- a/tempest/thirdparty/boto/test_s3_ec2_images.py
+++ /dev/null
@@ -1,126 +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 os
-
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import test
-from tempest.thirdparty.boto import test as boto_test
-from tempest.thirdparty.boto.utils import s3
-
-CONF = config.CONF
-
-
-class S3ImagesTest(boto_test.BotoTestCase):
-
-    @classmethod
-    def setup_clients(cls):
-        super(S3ImagesTest, cls).setup_clients()
-        cls.s3_client = cls.os.s3_client
-        cls.images_client = cls.os.ec2api_client
-
-    @classmethod
-    def resource_setup(cls):
-        super(S3ImagesTest, cls).resource_setup()
-        if not cls.conclusion['A_I_IMAGES_READY']:
-            raise cls.skipException("".join(("EC2 ", cls.__name__,
-                                    ": requires ami/aki/ari manifest")))
-        cls.materials_path = CONF.boto.s3_materials_path
-        cls.ami_manifest = CONF.boto.ami_manifest
-        cls.aki_manifest = CONF.boto.aki_manifest
-        cls.ari_manifest = CONF.boto.ari_manifest
-        cls.ami_path = cls.materials_path + os.sep + cls.ami_manifest
-        cls.aki_path = cls.materials_path + os.sep + cls.aki_manifest
-        cls.ari_path = cls.materials_path + os.sep + cls.ari_manifest
-        cls.bucket_name = data_utils.rand_name("bucket")
-        bucket = cls.s3_client.create_bucket(cls.bucket_name)
-        cls.addResourceCleanUp(cls.destroy_bucket,
-                               cls.s3_client.connection_data,
-                               cls.bucket_name)
-        s3.s3_upload_dir(bucket, cls.materials_path)
-
-    @test.idempotent_id('f9d360a5-0188-4c77-9db2-4c34c28d12a5')
-    def test_register_get_deregister_ami_image(self):
-        # Register and deregister ami image
-        image = {"name": data_utils.rand_name("ami-name"),
-                 "location": self.bucket_name + "/" + self.ami_manifest,
-                 "type": "ami"}
-        image["image_id"] = self.images_client.register_image(
-            name=image["name"],
-            image_location=image["location"])
-        # NOTE(afazekas): delete_snapshot=True might trigger boto lib? bug
-        image["cleanUp"] = self.addResourceCleanUp(
-            self.images_client.deregister_image,
-            image["image_id"])
-        self.assertEqual(image["image_id"][0:3], image["type"])
-        retrieved_image = self.images_client.get_image(image["image_id"])
-        self.assertTrue(retrieved_image.name == image["name"])
-        self.assertTrue(retrieved_image.id == image["image_id"])
-        if retrieved_image.state != "available":
-            self.assertImageStateWait(retrieved_image, "available")
-        self.images_client.deregister_image(image["image_id"])
-        self.assertNotIn(image["image_id"], str(
-            self.images_client.get_all_images()))
-        self.cancelResourceCleanUp(image["cleanUp"])
-
-    @test.idempotent_id('42cca5b0-453b-4618-b99f-dbc039db426f')
-    def test_register_get_deregister_aki_image(self):
-        # Register and deregister aki image
-        image = {"name": data_utils.rand_name("aki-name"),
-                 "location": self.bucket_name + "/" + self.aki_manifest,
-                 "type": "aki"}
-        image["image_id"] = self.images_client.register_image(
-            name=image["name"],
-            image_location=image["location"])
-        image["cleanUp"] = self.addResourceCleanUp(
-            self.images_client.deregister_image,
-            image["image_id"])
-        self.assertEqual(image["image_id"][0:3], image["type"])
-        retrieved_image = self.images_client.get_image(image["image_id"])
-        self.assertTrue(retrieved_image.name == image["name"])
-        self.assertTrue(retrieved_image.id == image["image_id"])
-        self.assertIn(retrieved_image.state, self.valid_image_state)
-        if retrieved_image.state != "available":
-            self.assertImageStateWait(retrieved_image, "available")
-        self.images_client.deregister_image(image["image_id"])
-        self.assertNotIn(image["image_id"], str(
-            self.images_client.get_all_images()))
-        self.cancelResourceCleanUp(image["cleanUp"])
-
-    @test.idempotent_id('1359e860-841c-43bb-80f3-bb389cbfd81d')
-    def test_register_get_deregister_ari_image(self):
-        # Register and deregister ari image
-        image = {"name": data_utils.rand_name("ari-name"),
-                 "location": "/" + self.bucket_name + "/" + self.ari_manifest,
-                 "type": "ari"}
-        image["image_id"] = self.images_client.register_image(
-            name=image["name"],
-            image_location=image["location"])
-        image["cleanUp"] = self.addResourceCleanUp(
-            self.images_client.deregister_image,
-            image["image_id"])
-        self.assertEqual(image["image_id"][0:3], image["type"])
-        retrieved_image = self.images_client.get_image(image["image_id"])
-        self.assertIn(retrieved_image.state, self.valid_image_state)
-        if retrieved_image.state != "available":
-            self.assertImageStateWait(retrieved_image, "available")
-        self.assertIn(retrieved_image.state, self.valid_image_state)
-        self.assertTrue(retrieved_image.name == image["name"])
-        self.assertTrue(retrieved_image.id == image["image_id"])
-        self.images_client.deregister_image(image["image_id"])
-        self.cancelResourceCleanUp(image["cleanUp"])
-
-# TODO(afazekas): less copy-paste style
diff --git a/tempest/thirdparty/boto/test_s3_objects.py b/tempest/thirdparty/boto/test_s3_objects.py
deleted file mode 100644
index c42d85c..0000000
--- a/tempest/thirdparty/boto/test_s3_objects.py
+++ /dev/null
@@ -1,51 +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 contextlib
-
-import boto.s3.key
-
-from tempest.common.utils import data_utils
-from tempest import test
-from tempest.thirdparty.boto import test as boto_test
-
-
-class S3BucketsTest(boto_test.BotoTestCase):
-
-    @classmethod
-    def setup_clients(cls):
-        super(S3BucketsTest, cls).setup_clients()
-        cls.client = cls.os.s3_client
-
-    @test.idempotent_id('4eea567a-b46a-405b-a475-6097e1faebde')
-    def test_create_get_delete_object(self):
-        # S3 Create, get and delete object
-        bucket_name = data_utils.rand_name("s3bucket")
-        object_name = data_utils.rand_name("s3object")
-        content = 'x' * 42
-        bucket = self.client.create_bucket(bucket_name)
-        self.addResourceCleanUp(self.destroy_bucket,
-                                self.client.connection_data,
-                                bucket_name)
-
-        self.assertTrue(bucket.name == bucket_name)
-        with contextlib.closing(boto.s3.key.Key(bucket)) as key:
-            key.key = object_name
-            key.set_contents_from_string(content)
-            readback = key.get_contents_as_string()
-            self.assertTrue(readback == content)
-            bucket.delete_key(key)
-            self.assertBotoError(self.s3_error_code.client.NoSuchKey,
-                                 key.get_contents_as_string)
diff --git a/tempest/thirdparty/boto/utils/__init__.py b/tempest/thirdparty/boto/utils/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/thirdparty/boto/utils/__init__.py
+++ /dev/null
diff --git a/tempest/thirdparty/boto/utils/s3.py b/tempest/thirdparty/boto/utils/s3.py
deleted file mode 100644
index 55c1b0a..0000000
--- a/tempest/thirdparty/boto/utils/s3.py
+++ /dev/null
@@ -1,41 +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 contextlib
-import os
-import re
-
-import boto
-import boto.s3.key
-
-from oslo_log import log as logging
-
-LOG = logging.getLogger(__name__)
-
-
-def s3_upload_dir(bucket, path, prefix="", connection_data=None):
-    if isinstance(bucket, basestring):
-        with contextlib.closing(boto.connect_s3(**connection_data)) as conn:
-            bucket = conn.lookup(bucket)
-    for root, dirs, files in os.walk(path):
-        for fil in files:
-            with contextlib.closing(boto.s3.key.Key(bucket)) as key:
-                source = root + os.sep + fil
-                target = re.sub("^" + re.escape(path) + "?/", prefix, source)
-                if os.sep != '/':
-                    target = re.sub(re.escape(os.sep), '/', target)
-                key.key = target
-                LOG.info("Uploading %s to %s/%s", source, bucket.name, target)
-                key.set_contents_from_filename(source)
diff --git a/tempest/thirdparty/boto/utils/wait.py b/tempest/thirdparty/boto/utils/wait.py
deleted file mode 100644
index 8771ed7..0000000
--- a/tempest/thirdparty/boto/utils/wait.py
+++ /dev/null
@@ -1,125 +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 re
-import time
-
-import boto.exception
-from oslo_log import log as logging
-import testtools
-
-from tempest import config
-
-CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
-
-def state_wait(lfunction, final_set=set(), valid_set=None):
-    # TODO(afazekas): evaluate using ABC here
-    if not isinstance(final_set, set):
-        final_set = set((final_set,))
-    if not isinstance(valid_set, set) and valid_set is not None:
-        valid_set = set((valid_set,))
-    start_time = time.time()
-    old_status = status = lfunction()
-    while True:
-        if status != old_status:
-            LOG.info('State transition "%s" ==> "%s" %d second', old_status,
-                     status, time.time() - start_time)
-        if status in final_set:
-            return status
-        if valid_set is not None and status not in valid_set:
-            return status
-        dtime = time.time() - start_time
-        if dtime > CONF.boto.build_timeout:
-            raise testtools.TestCase\
-                .failureException("State change timeout exceeded!"
-                                  '(%ds) While waiting'
-                                  'for %s at "%s"' %
-                                  (dtime, final_set, status))
-        time.sleep(CONF.boto.build_interval)
-        old_status = status
-        status = lfunction()
-
-
-def re_search_wait(lfunction, regexp):
-    """Stops waiting on success."""
-    start_time = time.time()
-    while True:
-        text = lfunction()
-        result = re.search(regexp, text)
-        if result is not None:
-            LOG.info('Pattern "%s" found in %d second in "%s"',
-                     regexp,
-                     time.time() - start_time,
-                     text)
-            return result
-        dtime = time.time() - start_time
-        if dtime > CONF.boto.build_timeout:
-            raise testtools.TestCase\
-                .failureException('Pattern find timeout exceeded!'
-                                  '(%ds) While waiting for'
-                                  '"%s" pattern in "%s"' %
-                                  (dtime, regexp, text))
-        time.sleep(CONF.boto.build_interval)
-
-
-def wait_no_exception(lfunction, exc_class=None, exc_matcher=None):
-    """Stops waiting on success."""
-    start_time = time.time()
-    if exc_matcher is not None:
-        exc_class = boto.exception.BotoServerError
-
-    if exc_class is None:
-        exc_class = BaseException
-    while True:
-        result = None
-        try:
-            result = lfunction()
-            LOG.info('No Exception in %d second',
-                     time.time() - start_time)
-            return result
-        except exc_class as exc:
-            if exc_matcher is not None:
-                res = exc_matcher.match(exc)
-                if res is not None:
-                    LOG.info(res)
-                    raise exc
-        # Let the other exceptions propagate
-        dtime = time.time() - start_time
-        if dtime > CONF.boto.build_timeout:
-            raise testtools.TestCase\
-                .failureException("Wait timeout exceeded! (%ds)" % dtime)
-        time.sleep(CONF.boto.build_interval)
-
-
-# NOTE(afazekas): EC2/boto normally raise exception instead of empty list
-def wait_exception(lfunction):
-    """Returns with the exception or raises one."""
-    start_time = time.time()
-    while True:
-        try:
-            lfunction()
-        except BaseException as exc:
-            LOG.info('Exception in %d second',
-                     time.time() - start_time)
-            return exc
-        dtime = time.time() - start_time
-        if dtime > CONF.boto.build_timeout:
-            raise testtools.TestCase\
-                .failureException("Wait timeout exceeded! (%ds)" % dtime)
-        time.sleep(CONF.boto.build_interval)
-
-# TODO(afazekas): consider strategy design pattern..