Merge "Correct test_get_usage_tenant's AttributeError"
diff --git a/HACKING.rst b/HACKING.rst
index d3ac5c6..ec7ff6a 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -132,16 +132,18 @@
 
 Set-up is split in a series of steps (setup stages), which can be overwritten
 by test classes. Set-up stages are:
- - `skip_checks`
- - `setup_credentials`
- - `setup_clients`
- - `resource_setup`
+
+- `skip_checks`
+- `setup_credentials`
+- `setup_clients`
+- `resource_setup`
 
 Tear-down is also split in a series of steps (teardown stages), which are
 stacked for execution only if the corresponding setup stage had been
 reached during the setup phase. Tear-down stages are:
- - `clear_credentials` (defined in the base test class)
- - `resource_cleanup`
+
+- `clear_credentials` (defined in the base test class)
+- `resource_cleanup`
 
 Skipping Tests
 --------------
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index d610dc5..9a7ce15 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -348,11 +348,14 @@
     service catalog should be in a standard format (which is going to be
     standardized at the keystone level).
     Tempest expects URLs in the Service catalog in the following format:
-     * ``http://example.com:1234/<version-info>``
+
+    * ``http://example.com:1234/<version-info>``
+
     Examples:
-     * Good - ``http://example.com:1234/v2.0``
-     * Wouldn’t work -  ``http://example.com:1234/xyz/v2.0/``
-       (adding prefix/suffix around version etc)
+
+    * Good - ``http://example.com:1234/v2.0``
+    * Wouldn’t work -  ``http://example.com:1234/xyz/v2.0/``
+      (adding prefix/suffix around version etc)
 
 Service Feature Configuration
 -----------------------------
diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst
index fc05b12..3568470 100644
--- a/doc/source/microversion_testing.rst
+++ b/doc/source/microversion_testing.rst
@@ -24,6 +24,7 @@
 
   Those should be defined under respective section of each service.
   For example::
+
       [compute]
       min_microversion = None
       max_microversion = latest
@@ -159,7 +160,8 @@
 
 
 Notes about Compute Microversion Tests
-"""""""""""""""""""""""""""""""""""
+""""""""""""""""""""""""""""""""""""""
+
 Some of the compute Microversion tests have been already implemented
 with the Microversion testing framework. So for further tests only
 step 4 is needed.
diff --git a/requirements.txt b/requirements.txt
index d567082..f41d2a7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,17 +9,17 @@
 netaddr!=0.7.16,>=0.7.12 # BSD
 testrepository>=0.0.18 # Apache-2.0/BSD
 pyOpenSSL>=0.14 # Apache-2.0
-oslo.concurrency>=3.5.0 # Apache-2.0
+oslo.concurrency>=3.8.0 # Apache-2.0
 oslo.config>=3.9.0 # Apache-2.0
 oslo.i18n>=2.1.0 # Apache-2.0
 oslo.log>=1.14.0 # Apache-2.0
 oslo.serialization>=1.10.0 # Apache-2.0
 oslo.utils>=3.5.0 # Apache-2.0
 six>=1.9.0 # MIT
-fixtures<2.0,>=1.3.1 # Apache-2.0/BSD
+fixtures>=3.0.0 # Apache-2.0/BSD
 testscenarios>=0.4 # Apache-2.0/BSD
 PyYAML>=3.1.0 # MIT
 stevedore>=1.10.0 # Apache-2.0
 PrettyTable<0.8,>=0.7 # BSD
-os-testr>=0.4.1 # Apache-2.0
+os-testr>=0.7.0 # Apache-2.0
 urllib3>=1.15.1 # MIT
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index c05045e..07423ff 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -204,10 +204,6 @@
     @test.idempotent_id('1678d144-ed74-43f8-8e57-ab10dbf9b3c2')
     @testtools.skipUnless(CONF.service_available.neutron,
                           'Neutron service must be available.')
-    # The below skipUnless should be removed once Kilo-eol happens.
-    @testtools.skipUnless(CONF.compute_feature_enabled.
-                          allow_duplicate_networks,
-                          'Duplicate networks must be allowed')
     def test_verify_duplicate_network_nics(self):
         # Verify that server creation does not fail when more than one nic
         # is created on the same network.
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index b9765c8..a3b0a82 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -153,6 +153,7 @@
 
         # Create rule for icmp protocol with invalid ports
         states = [(1, 256, 'Invalid value for ICMP code'),
+                  (-1, 25, 'Invalid value'),
                   (None, 6, 'ICMP type (port-range-min) is missing'),
                   (300, 1, 'Invalid value for ICMP type')]
         for pmin, pmax, msg in states:
diff --git a/tempest/api/volume/test_qos.py b/tempest/api/volume/admin/test_qos.py
similarity index 100%
rename from tempest/api/volume/test_qos.py
rename to tempest/api/volume/admin/test_qos.py
diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py
index 82db9cc..286e01f 100644
--- a/tempest/common/credentials_factory.py
+++ b/tempest/common/credentials_factory.py
@@ -73,8 +73,8 @@
     # the test should be skipped else it would fail.
     identity_version = identity_version or CONF.identity.auth_version
     if CONF.auth.use_dynamic_credentials or force_tenant_isolation:
-        admin_creds = get_configured_credentials(
-            'identity_admin', fill_in=True, identity_version=identity_version)
+        admin_creds = get_configured_admin_credentials(
+            fill_in=True, identity_version=identity_version)
         return dynamic_creds.DynamicCredentialProvider(
             name=name,
             network_resources=network_resources,
@@ -111,8 +111,8 @@
             is_admin = False
     else:
         try:
-            get_configured_credentials('identity_admin', fill_in=False,
-                                       identity_version=identity_version)
+            get_configured_admin_credentials(fill_in=False,
+                                             identity_version=identity_version)
         except exceptions.InvalidConfiguration:
             is_admin = False
     return is_admin
@@ -163,39 +163,32 @@
 
 # Read credentials from configuration, builds a Credentials object
 # based on the specified or configured version
-def get_configured_credentials(credential_type, fill_in=True,
-                               identity_version=None):
+def get_configured_admin_credentials(fill_in=True, identity_version=None):
     identity_version = identity_version or CONF.identity.auth_version
 
     if identity_version not in ('v2', 'v3'):
         raise exceptions.InvalidConfiguration(
             'Unsupported auth version: %s' % identity_version)
 
-    if credential_type not in CREDENTIAL_TYPES:
-        raise exceptions.InvalidCredentials()
-    conf_attributes = ['username', 'password', 'project_name']
+    conf_attributes = ['username', 'password',
+                       'project_name']
 
     if identity_version == 'v3':
         conf_attributes.append('domain_name')
     # Read the parts of credentials from config
     params = DEFAULT_PARAMS.copy()
-    section, prefix = CREDENTIAL_TYPES[credential_type]
     for attr in conf_attributes:
-        _section = getattr(CONF, section)
-        if prefix is None:
-            params[attr] = getattr(_section, attr)
-        else:
-            params[attr] = getattr(_section, prefix + "_" + attr)
+        params[attr] = getattr(CONF.auth, 'admin_' + attr)
     # Build and validate credentials. We are reading configured credentials,
     # so validate them even if fill_in is False
     credentials = get_credentials(fill_in=fill_in,
                                   identity_version=identity_version, **params)
     if not fill_in:
         if not credentials.is_valid():
-            msg = ("The %s credentials are incorrectly set in the config file."
-                   " Double check that all required values are assigned" %
-                   credential_type)
-            raise exceptions.InvalidConfiguration(msg)
+            msg = ("The admin credentials are incorrectly set in the config "
+                   "file for identity version %s. Double check that all "
+                   "required values are assigned.")
+            raise exceptions.InvalidConfiguration(msg % identity_version)
     return credentials
 
 
@@ -223,19 +216,10 @@
 # === Credential / client managers
 
 
-class ConfiguredUserManager(clients.Manager):
-    """Manager that uses user credentials for its managed client objects"""
-
-    def __init__(self, service=None):
-        super(ConfiguredUserManager, self).__init__(
-            credentials=get_configured_credentials('user'),
-            service=service)
-
-
 class AdminManager(clients.Manager):
     """Manager that uses admin credentials for its managed client objects"""
 
     def __init__(self, service=None):
         super(AdminManager, self).__init__(
-            credentials=get_configured_credentials('identity_admin'),
+            credentials=get_configured_admin_credentials(),
             service=service)
diff --git a/tempest/common/utils/file_utils.py b/tempest/common/utils/file_utils.py
deleted file mode 100644
index 43083f4..0000000
--- a/tempest/common/utils/file_utils.py
+++ /dev/null
@@ -1,23 +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.
-
-
-def have_effective_read_access(path):
-    try:
-        fh = open(path, "rb")
-    except IOError:
-        return False
-    fh.close()
-    return True
diff --git a/tempest/config.py b/tempest/config.py
index f5125b5..71b25d0 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -370,14 +370,6 @@
                      'encrypted volume to a running server instance? This may '
                      'depend on the combination of compute_driver in nova and '
                      'the volume_driver(s) in cinder.'),
-    # TODO(mriedem): Remove allow_duplicate_networks once kilo-eol happens
-    # since the option was removed from nova in Liberty and is the default
-    # behavior starting in Liberty.
-    cfg.BoolOpt('allow_duplicate_networks',
-                default=False,
-                help='Does the test environment support creating instances '
-                     'with multiple ports on the same network? This is only '
-                     'valid when using Neutron.'),
     cfg.BoolOpt('config_drive',
                 default=True,
                 help='Enable special configuration drive with metadata.'),
diff --git a/tempest/lib/api_schema/response/compute/v2_1/images.py b/tempest/lib/api_schema/response/compute/v2_1/images.py
index daab898..b0f1934 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/images.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/images.py
@@ -77,7 +77,7 @@
                     'properties': {
                         'id': {'type': 'string'},
                         'links': image_links,
-                        'name': {'type': 'string'}
+                        'name': {'type': ['string', 'null']}
                     },
                     'additionalProperties': False,
                     'required': ['id', 'links', 'name']
diff --git a/tempest/lib/cli/base.py b/tempest/lib/cli/base.py
index 9460bf4..a43d002 100644
--- a/tempest/lib/cli/base.py
+++ b/tempest/lib/cli/base.py
@@ -119,7 +119,7 @@
         :param merge_stderr: if True the stderr buffer is merged into stdout
         :type merge_stderr: boolean
         """
-        flags += ' --endpoint-type %s' % endpoint_type
+        flags += ' --os-endpoint-type %s' % endpoint_type
         return self.cmd_with_auth(
             'nova', action, flags, params, fail_ok, merge_stderr)
 
@@ -247,7 +247,7 @@
         :param merge_stderr: if True the stderr buffer is merged into stdout
         :type merge_stderr: boolean
         """
-        flags += ' --os-endpoint-type %s' % endpoint_type
+        flags += ' --endpoint-type %s' % endpoint_type
         return self.cmd_with_auth(
             'cinder', action, flags, params, fail_ok, merge_stderr)
 
diff --git a/tempest/lib/services/compute/base_compute_client.py b/tempest/lib/services/compute/base_compute_client.py
index a387b85..433c94c 100644
--- a/tempest/lib/services/compute/base_compute_client.py
+++ b/tempest/lib/services/compute/base_compute_client.py
@@ -67,11 +67,13 @@
 
         :param schema_versions_info: List of dict which provides schema
                                      information with range of valid versions.
-        Example -
-        schema_versions_info = [
-            {'min': None, 'max': '2.1', 'schema': schemav21},
-            {'min': '2.2', 'max': '2.9', 'schema': schemav22},
-            {'min': '2.10', 'max': None, 'schema': schemav210}]
+
+        Example::
+
+         schema_versions_info = [
+             {'min': None, 'max': '2.1', 'schema': schemav21},
+             {'min': '2.2', 'max': '2.9', 'schema': schemav22},
+             {'min': '2.10', 'max': None, 'schema': schemav210}]
         """
         schema = None
         version = api_version_request.APIVersionRequest(COMPUTE_MICROVERSION)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 65677a0..7389722 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -1069,10 +1069,11 @@
                                         security_groups_client=None):
         """Create loginable security group rule
 
-        These rules are intended to permit inbound ssh and icmp
-        traffic from all sources, so no group_id is provided.
-        Setting a group_id would only permit traffic from ports
-        belonging to the same security group.
+        This function will create:
+        1. egress and ingress tcp port 22 allow rule in order to allow ssh
+        access for ipv4.
+        2. egress and ingress ipv6 icmp allow rule, in order to allow icmpv6.
+        3. egress and ingress ipv4 icmp allow rule, in order to allow icmpv4.
         """
 
         if security_group_rules_client is None:
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index 6e24801..2bdd092 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -111,7 +111,7 @@
             uri += "?%s" % urllib.urlencode(kwargs)
 
         resp, body = self.get(uri)
-        self.expected_success(200, resp['status'])
+        self.expected_success(200, resp.status)
 
         return resp, self.deserialize(body)
 
@@ -127,7 +127,7 @@
         else:
             uri = self._get_uri(resource, uuid=uuid, permanent=permanent)
         resp, body = self.get(uri)
-        self.expected_success(200, resp['status'])
+        self.expected_success(200, resp.status)
 
         return resp, self.deserialize(body)
 
@@ -145,7 +145,7 @@
         uri = self._get_uri(resource)
 
         resp, body = self.post(uri, body=body)
-        self.expected_success(201, resp['status'])
+        self.expected_success(201, resp.status)
 
         return resp, self.deserialize(body)
 
@@ -160,7 +160,7 @@
         uri = self._get_uri(resource, uuid)
 
         resp, body = self.delete(uri)
-        self.expected_success(204, resp['status'])
+        self.expected_success(204, resp.status)
         return resp, body
 
     def _patch_request(self, resource, uuid, patch_object):
@@ -176,7 +176,7 @@
         patch_body = json.dumps(patch_object)
 
         resp, body = self.patch(uri, body=patch_body)
-        self.expected_success(200, resp['status'])
+        self.expected_success(200, resp.status)
         return resp, self.deserialize(body)
 
     @handle_errors
@@ -201,5 +201,5 @@
         put_body = json.dumps(put_object)
 
         resp, body = self.put(uri, body=put_body)
-        self.expected_success(202, resp['status'])
+        self.expected_success([202, 204], resp.status)
         return resp, body
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 382b851..2beaaa9 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -135,10 +135,13 @@
                 break
         if skip:
             break
+        # TODO(andreaf) This has to be reworked to use the credential
+        # provider interface. For now only tests marked as 'use_admin' will
+        # work.
         if test.get('use_admin', False):
             manager = admin_manager
         else:
-            manager = credentials.ConfiguredUserManager()
+            raise NotImplemented('Non admin tests are not supported')
         for p_number in moves.xrange(test.get('threads', default_thread_num)):
             if test.get('use_isolated_tenants', False):
                 username = data_utils.rand_name("stress_user")
diff --git a/tempest/tests/common/test_preprov_creds.py b/tempest/tests/common/test_preprov_creds.py
index 22bbdd3..873c4c4 100644
--- a/tempest/tests/common/test_preprov_creds.py
+++ b/tempest/tests/common/test_preprov_creds.py
@@ -352,7 +352,7 @@
     fixed_params = {'name': 'test class',
                     'identity_version': 'v3',
                     'test_accounts_file': 'fake_accounts_file',
-                    'accounts_lock_dir': 'fake_locks_dir',
+                    'accounts_lock_dir': 'fake_locks_dir_v3',
                     'admin_role': 'admin',
                     'object_storage_operator_role': 'operator',
                     'object_storage_reseller_admin_role': 'reseller'}
diff --git a/tempest/tests/common/utils/test_file_utils.py b/tempest/tests/common/utils/test_file_utils.py
deleted file mode 100644
index 937aefa..0000000
--- a/tempest/tests/common/utils/test_file_utils.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2014 IBM Corp.
-# 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 mock
-
-from tempest.common.utils import file_utils
-from tempest.tests import base
-
-
-class TestFileUtils(base.TestCase):
-
-    def test_have_effective_read_path(self):
-        with mock.patch('six.moves.builtins.open', mock.mock_open(),
-                        create=True):
-            result = file_utils.have_effective_read_access('fake_path')
-        self.assertTrue(result)
-
-    def test_not_effective_read_path(self):
-        result = file_utils.have_effective_read_access('fake_path')
-        self.assertFalse(result)
diff --git a/test-requirements.txt b/test-requirements.txt
index 9ef956a..763f0ba 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -7,6 +7,6 @@
 python-subunit>=0.0.18 # Apache-2.0/BSD
 oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
 reno>=1.6.2 # Apache2
-mock>=1.2 # BSD
+mock>=2.0 # BSD
 coverage>=3.6 # Apache-2.0
 oslotest>=1.10.0 # Apache-2.0