Merge "Use isinstance instead of type"
diff --git a/.gitignore b/.gitignore
index d58b162..5b87cec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,6 @@
 !.coveragerc
 cover/
 doc/source/_static/tempest.conf.sample
+
+# Files created by releasenotes build
+releasenotes/build
diff --git a/README.rst b/README.rst
index 71e185f..c859ddd 100644
--- a/README.rst
+++ b/README.rst
@@ -94,6 +94,45 @@
 .. _testr: https://testrepository.readthedocs.org/en/latest/MANUAL.html
 .. _ostestr: http://docs.openstack.org/developer/os-testr/
 
+Library
+-------
+Tempest exposes a library interface. This interface is a stable interface and
+should be backwards compatible (including backwards compatibility with the
+old tempest-lib package, with the exception of the import). If you plan to
+directly consume tempest in your project you should only import code from the
+tempest library interface, other pieces of tempest do not have the same
+stable interface and there are no guarantees on the Python API unless otherwise
+stated.
+
+For more details refer to the library documentation here: :ref:`library`
+
+Release Versioning
+------------------
+Tempest's released versions are broken into 2 sets of information. Depending on
+how you intend to consume tempest you might need
+
+The version is a set of 3 numbers:
+
+X.Y.Z
+
+While this is almost `semver`_ like, the way versioning is handled is slightly
+different:
+
+X is used to represent the supported OpenStack releases for tempest tests
+in-tree, and to signify major feature changes to tempest. It's a monotonically
+increasing integer where each version either indicates a new supported OpenStack
+release, the drop of support for an OpenStack release (which will coincide with
+the upstream stable branch going EOL), or a major feature lands (or is removed)
+from tempest.
+
+Y.Z is used to represent library interface changes. This is treated the same
+way as minor and patch versions from `semver`_ but only for the library
+interface. When Y is incremented we've added functionality to the library
+interface and when Z is incremented it's a bug fix release for the library.
+Also note that both Y and Z are reset to 0 at each increment of X.
+
+.. _semver: http://semver.org/
+
 Configuration
 -------------
 
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index e428592..524c0fa 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -139,6 +139,11 @@
  #. ``alt_password``
  #. ``alt_tenant_name``
 
+If using Identity API v3, use the ``domain_name`` option to specify a
+domain other than the default domain.  The ``auth_version`` setting is
+used to switch between v2 (``v2``) or v3 (``v3``) versions of the Identity
+API.
+
 And in the ``auth`` section:
 
  #. ``use_dynamic_credentials = False``
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 32e6e51..17def1c 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -11,6 +11,7 @@
    HACKING
    REVIEWING
    plugin
+   library
 
 ------------
 Field Guides
diff --git a/doc/source/library.rst b/doc/source/library.rst
new file mode 100644
index 0000000..24ead08
--- /dev/null
+++ b/doc/source/library.rst
@@ -0,0 +1,68 @@
+.. _library:
+
+Tempest Library Doucmentation
+=============================
+
+Tempest provides a stable library interface that provides external tools or
+test suites an interface for reusing pieces of tempest code. Any public
+interface that lives in tempest/lib in the tempest repo is treated as a stable
+public interface and it should be safe to external consume that. Every effort
+goes into maintaining backwards compatibility with any change. Just as with
+tempest-lib the library is self contained and doesn't have any dependency on
+other tempest internals outside of lib. (including no usage of tempest
+configuration)
+
+Stability
+---------
+Just as tempest-lib before it any code that lives in tempest/lib will be treated
+as a stable interface, nothing has changed in regards to interface stability.
+This means that any public interface under the tempest/lib directory is
+expected to be a stable interface suitable for public consumption. However, for
+any interfaces outside of tempest/lib in the tempest tree (unless otherwise
+noted) or any private interfaces the same stability guarantees don't apply.
+
+Adding Interfaces
+'''''''''''''''''
+When adding an interface to tempest/lib we have to make sure there are no
+dependencies on any pieces of tempest outside of tempest/lib. This means if
+for example there is a dependency on the configuration file we need remove that.
+The other aspect when adding an interface is to make sure it's really an
+interface ready for external consumption and something we want to commit to
+supporting.
+
+Making changes
+''''''''''''''
+When making changes to tempest/lib you have to be conscious of the effect of
+any changes on external consumers. If your proposed changeset will change the
+default behaviour of any interface, or make something which previously worked
+not after your change, then it is not acceptable. Every effort needs to go into
+preserving backwards compatibility in changes.
+
+Reviewing
+'''''''''
+When reviewing a proposed change to tempest/lib code we need to be careful to
+ensure that we don't break backwards compatibility. For patches that change
+existing interfaces we have to be careful to make sure we don't break any
+external consumers. Some common red flags are:
+
+ * a change to an existing API requires a change outside the library directory
+   where the interface is being consumed
+ * a unit test has to be significantly changed to make the proposed change pass
+
+Testing
+'''''''
+When adding a new interface to the library we need to at a minimum have unit
+test coverage. A proposed change to add an interface to tempest/lib that
+doesn't have unit tests shouldn't be accepted. Ideally these unit tests will
+provide sufficient coverage to ensure a stable interface moving forward.
+
+Current Library APIs
+--------------------
+
+.. toctree::
+   :maxdepth: 2
+
+   library/cli
+   library/decorators
+   library/rest_client
+   library/utils
diff --git a/doc/source/library/cli.rst b/doc/source/library/cli.rst
new file mode 100644
index 0000000..6bd7881
--- /dev/null
+++ b/doc/source/library/cli.rst
@@ -0,0 +1,18 @@
+.. _cli:
+
+CLI Testing Framework Usage
+===========================
+
+-------------------
+The cli.base module
+-------------------
+
+.. automodule:: tempest.lib.cli.base
+   :members:
+
+----------------------------
+The cli.output_parser module
+----------------------------
+
+.. automodule:: tempest.lib.cli.output_parser
+   :members:
diff --git a/doc/source/library/decorators.rst b/doc/source/library/decorators.rst
new file mode 100644
index 0000000..a173967
--- /dev/null
+++ b/doc/source/library/decorators.rst
@@ -0,0 +1,13 @@
+.. _decorators:
+
+Decorators Usage Guide
+======================
+
+---------------------
+The decorators module
+---------------------
+
+.. automodule:: tempest.lib.decorators
+   :members:
+
+
diff --git a/doc/source/library/rest_client.rst b/doc/source/library/rest_client.rst
new file mode 100644
index 0000000..3045694
--- /dev/null
+++ b/doc/source/library/rest_client.rst
@@ -0,0 +1,11 @@
+.. _rest_client:
+
+Rest Client Usage
+=================
+
+----------------------
+The rest_client module
+----------------------
+
+.. automodule:: tempest.lib.common.rest_client
+   :members:
diff --git a/doc/source/library/utils.rst b/doc/source/library/utils.rst
new file mode 100644
index 0000000..bc2f79b
--- /dev/null
+++ b/doc/source/library/utils.rst
@@ -0,0 +1,11 @@
+.. _utils:
+
+Utils Usage
+===========
+
+---------------
+The misc module
+---------------
+
+.. automodule:: tempest.lib.common.utils.misc
+   :members:
diff --git a/releasenotes/notes/.placeholder b/releasenotes/notes/.placeholder
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/releasenotes/notes/.placeholder
diff --git a/releasenotes/notes/10.0-supported-openstack-releases-b88db468695348f6.yaml b/releasenotes/notes/10.0-supported-openstack-releases-b88db468695348f6.yaml
new file mode 100644
index 0000000..217c2f6
--- /dev/null
+++ b/releasenotes/notes/10.0-supported-openstack-releases-b88db468695348f6.yaml
@@ -0,0 +1,13 @@
+---
+other:
+    - OpenStack Releases Supported at this time are the same as in the
+      previous release 9,
+        **Kilo** and
+        **Liberty**.
+
+
+      The release under current development as of this tag is Mitaka,
+      meaning that every Tempest commit is also tested against master during
+      the Mitaka cycle. However, this does not necessarily mean that using
+      Tempest as of this tag will work against a Mitaka (or future releases)
+      cloud.
diff --git a/releasenotes/notes/Tempest-library-interface-0eb680b810139a50.yaml b/releasenotes/notes/Tempest-library-interface-0eb680b810139a50.yaml
new file mode 100644
index 0000000..0ed3130
--- /dev/null
+++ b/releasenotes/notes/Tempest-library-interface-0eb680b810139a50.yaml
@@ -0,0 +1,11 @@
+---
+prelude: |
+    This release includes the addition of the stable library interface for
+    tempest. This behaves just as tempest-lib did prior to this, but instead
+    it lives directly in the tempest project. For more information refer to
+    the `library docs`_.
+
+    .. _library docs: http://docs.openstack.org/developer/tempest/library.html#library
+
+features:
+  - Tempest library interface
diff --git a/releasenotes/notes/start-using-reno-ed9518126fd0e1a3.yaml b/releasenotes/notes/start-using-reno-ed9518126fd0e1a3.yaml
new file mode 100644
index 0000000..0bc9af5
--- /dev/null
+++ b/releasenotes/notes/start-using-reno-ed9518126fd0e1a3.yaml
@@ -0,0 +1,3 @@
+---
+other:
+  - Start using reno for managing release notes.
diff --git a/releasenotes/source/_static/.placeholder b/releasenotes/source/_static/.placeholder
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/releasenotes/source/_static/.placeholder
diff --git a/releasenotes/source/_templates/.placeholder b/releasenotes/source/_templates/.placeholder
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/releasenotes/source/_templates/.placeholder
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
new file mode 100644
index 0000000..4522a17
--- /dev/null
+++ b/releasenotes/source/conf.py
@@ -0,0 +1,277 @@
+# -*- coding: utf-8 -*-
+# 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.
+
+# tempest Release Notes documentation build configuration file, created by
+# sphinx-quickstart on Tue Nov  3 17:40:50 2015.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+# sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'oslosphinx',
+    'reno.sphinxext',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+# source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'tempest Release Notes'
+copyright = u'2016, tempest Developers'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+from tempest.version import version_info as tempest_version
+# The full version, including alpha/beta/rc tags.
+release = tempest_version.version_string_with_vcs()
+# The short X.Y version.
+version = tempest_version.canonical_version_string()
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+# language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+# today = ''
+# Else, today_fmt is used as the format for a strftime call.
+# today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+# default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+# add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+# add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+# show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+# modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+# keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+# html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+# html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+# html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+# html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+# html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+# html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+# html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+# html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+# html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+# html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+# html_additional_pages = {}
+
+# If false, no module index is generated.
+# html_domain_indices = True
+
+# If false, no index is generated.
+# html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+# html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+# html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+# html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+# html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+# html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+# html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'tempestReleaseNotesdoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+    # The paper size ('letterpaper' or 'a4paper').
+    # 'papersize': 'letterpaper',
+
+    # The font size ('10pt', '11pt' or '12pt').
+    # 'pointsize': '10pt',
+
+    # Additional stuff for the LaTeX preamble.
+    # 'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+    ('index', 'olso.configReleaseNotes.tex',
+     u'olso.config Release Notes Documentation',
+     u'tempest Developers', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page
+# latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+# latex_use_parts = False
+
+# If true, show page references after internal links.
+# latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+# latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+# latex_appendices = []
+
+# If false, no module index is generated.
+# latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'olso.configreleasenotes',
+     u'tempest Release Notes Documentation',
+     [u'tempest Developers'], 1)
+]
+
+# If true, show URL addresses after external links.
+# man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+    ('index', 'tempestReleaseNotes',
+     u'tempest Release Notes Documentation',
+     u'tempest Developers', 'olso.configReleaseNotes',
+     'An OpenStack library for parsing configuration options from the command'
+     ' line and configuration files.',
+     'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+# texinfo_appendices = []
+
+# If false, no module index is generated.
+# texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+# texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+# texinfo_no_detailmenu = False
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
new file mode 100644
index 0000000..584540b
--- /dev/null
+++ b/releasenotes/source/index.rst
@@ -0,0 +1,14 @@
+===========================
+ tempest Release Notes
+===========================
+
+ .. toctree::
+    :maxdepth: 1
+
+    unreleased
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
diff --git a/releasenotes/source/unreleased.rst b/releasenotes/source/unreleased.rst
new file mode 100644
index 0000000..5860a46
--- /dev/null
+++ b/releasenotes/source/unreleased.rst
@@ -0,0 +1,5 @@
+==========================
+ Unreleased Release Notes
+==========================
+
+.. release-notes::
diff --git a/requirements.txt b/requirements.txt
index 46ebbc5..23357fd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,12 +11,12 @@
 netaddr!=0.7.16,>=0.7.12 # BSD
 testrepository>=0.0.18 # Apache-2.0/BSD
 pyOpenSSL>=0.14 # Apache-2.0
-oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=3.4.0 # Apache-2.0
+oslo.concurrency>=3.5.0 # Apache-2.0
+oslo.config>=3.7.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.4.0 # Apache-2.0
+oslo.utils>=3.5.0 # Apache-2.0
 six>=1.9.0 # MIT
 iso8601>=0.1.9 # MIT
 fixtures>=1.3.1 # Apache-2.0/BSD
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 3ad9305..b1c42a6 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -19,6 +19,7 @@
 from tempest.api.compute import base
 from tempest.common import waiters
 from tempest import config
+from tempest.lib import decorators
 from tempest import test
 
 CONF = config.CONF
@@ -129,6 +130,8 @@
     def test_live_block_migration_paused(self):
         self._test_live_migration(state='PAUSED')
 
+    @decorators.skip_because(bug="1549511",
+                             condition=CONF.service_available.neutron)
     @test.idempotent_id('5071cf17-3004-4257-ae61-73a84e28badd')
     @test.services('volume')
     def test_volume_backed_live_migration(self):
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 99effd7..07a7a30 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -68,7 +68,11 @@
         flavor_id = self._get_unused_flavor_id()
         quota_set = (self.quotas_client.show_default_quota_set(self.tenant_id)
                      ['quota_set'])
-        ram = int(quota_set['ram']) + 1
+        ram = int(quota_set['ram'])
+        if ram == -1:
+            raise self.skipException("default ram quota set is -1,"
+                                     " cannot test overlimit")
+        ram += 1
         vcpus = 8
         disk = 10
         flavor_ref = self.flavors_client.create_flavor(name=flavor_name,
@@ -93,7 +97,11 @@
         ram = 512
         quota_set = (self.quotas_client.show_default_quota_set(self.tenant_id)
                      ['quota_set'])
-        vcpus = int(quota_set['cores']) + 1
+        vcpus = int(quota_set['cores'])
+        if vcpus == -1:
+            raise self.skipException("default cores quota set is -1,"
+                                     " cannot test overlimit")
+        vcpus += 1
         disk = 10
         flavor_ref = self.flavors_client.create_flavor(name=flavor_name,
                                                        ram=ram, vcpus=vcpus,
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 63ba650..e91944f 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -67,7 +67,7 @@
         resp = {}
         resp['status'] = None
         self.assertRaises(lib_exc.NotFound, self.create_image_from_server,
-                          '!@$%^&*()', name=name, meta=meta)
+                          '!@$^&*()', name=name, meta=meta)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('ec176029-73dc-4037-8d72-2e4ff60cf538')
diff --git a/tempest/api/identity/admin/v3/test_default_project_id.py b/tempest/api/identity/admin/v3/test_default_project_id.py
index ff53187..18a50d0 100644
--- a/tempest/api/identity/admin/v3/test_default_project_id.py
+++ b/tempest/api/identity/admin/v3/test_default_project_id.py
@@ -71,8 +71,8 @@
         admin_role_id = admin_role['id']
 
         # grant the admin role to the user on his project
-        self.client.assign_user_role_on_project(proj_id, user_id,
-                                                admin_role_id)
+        self.roles_client.assign_user_role_on_project(proj_id, user_id,
+                                                      admin_role_id)
 
         # create a new client with user's credentials (NOTE: unscoped token!)
         creds = auth.KeystoneV3Credentials(username=user_name,
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index a0a842c..12ef369 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -25,7 +25,7 @@
         super(RolesV3TestJSON, cls).resource_setup()
         for _ in range(3):
             role_name = data_utils.rand_name(name='role')
-            role = cls.client.create_role(name=role_name)['role']
+            role = cls.roles_client.create_role(name=role_name)['role']
             cls.data.roles.append(role)
         cls.fetched_role_ids = list()
         u_name = data_utils.rand_name('user')
@@ -46,12 +46,12 @@
             u_name, description=u_desc, password=cls.u_password,
             email=u_email, project_id=cls.project['id'],
             domain_id=cls.domain['id'])['user']
-        cls.role = cls.client.create_role(
+        cls.role = cls.roles_client.create_role(
             name=data_utils.rand_name('Role'))['role']
 
     @classmethod
     def resource_cleanup(cls):
-        cls.client.delete_role(cls.role['id'])
+        cls.roles_client.delete_role(cls.role['id'])
         cls.groups_client.delete_group(cls.group_body['id'])
         cls.users_client.delete_user(cls.user_body['id'])
         cls.projects_client.delete_project(cls.project['id'])
@@ -67,34 +67,35 @@
 
     @test.attr(type='smoke')
     @test.idempotent_id('18afc6c0-46cf-4911-824e-9989cc056c3a')
-    def test_role_create_update_get_list(self):
+    def test_role_create_update_show_list(self):
         r_name = data_utils.rand_name('Role')
-        role = self.client.create_role(name=r_name)['role']
-        self.addCleanup(self.client.delete_role, role['id'])
+        role = self.roles_client.create_role(name=r_name)['role']
+        self.addCleanup(self.roles_client.delete_role, role['id'])
         self.assertIn('name', role)
         self.assertEqual(role['name'], r_name)
 
         new_name = data_utils.rand_name('NewRole')
-        updated_role = self.client.update_role(role['id'],
-                                               name=new_name)['role']
+        updated_role = self.roles_client.update_role(role['id'],
+                                                     name=new_name)['role']
         self.assertIn('name', updated_role)
         self.assertIn('id', updated_role)
         self.assertIn('links', updated_role)
         self.assertNotEqual(r_name, updated_role['name'])
 
-        new_role = self.client.show_role(role['id'])['role']
+        new_role = self.roles_client.show_role(role['id'])['role']
         self.assertEqual(new_name, new_role['name'])
         self.assertEqual(updated_role['id'], new_role['id'])
 
-        roles = self.client.list_roles()['roles']
+        roles = self.roles_client.list_roles()['roles']
         self.assertIn(role['id'], [r['id'] for r in roles])
 
     @test.idempotent_id('c6b80012-fe4a-498b-9ce8-eb391c05169f')
     def test_grant_list_revoke_role_to_user_on_project(self):
-        self.client.assign_user_role_on_project(
-            self.project['id'], self.user_body['id'], self.role['id'])
+        self.roles_client.assign_user_role_on_project(self.project['id'],
+                                                      self.user_body['id'],
+                                                      self.role['id'])
 
-        roles = self.client.list_user_roles_on_project(
+        roles = self.roles_client.list_user_roles_on_project(
             self.project['id'], self.user_body['id'])['roles']
 
         for i in roles:
@@ -103,18 +104,18 @@
         self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
 
-        self.client.check_user_role_existence_on_project(
+        self.roles_client.check_user_role_existence_on_project(
             self.project['id'], self.user_body['id'], self.role['id'])
 
-        self.client.delete_role_from_user_on_project(
+        self.roles_client.delete_role_from_user_on_project(
             self.project['id'], self.user_body['id'], self.role['id'])
 
     @test.idempotent_id('6c9a2940-3625-43a3-ac02-5dcec62ef3bd')
     def test_grant_list_revoke_role_to_user_on_domain(self):
-        self.client.assign_user_role_on_domain(
+        self.roles_client.assign_user_role_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
 
-        roles = self.client.list_user_roles_on_domain(
+        roles = self.roles_client.list_user_roles_on_domain(
             self.domain['id'], self.user_body['id'])['roles']
 
         for i in roles:
@@ -123,19 +124,19 @@
         self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
 
-        self.client.check_user_role_existence_on_domain(
+        self.roles_client.check_user_role_existence_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
 
-        self.client.delete_role_from_user_on_domain(
+        self.roles_client.delete_role_from_user_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
 
     @test.idempotent_id('cbf11737-1904-4690-9613-97bcbb3df1c4')
     def test_grant_list_revoke_role_to_group_on_project(self):
         # Grant role to group on project
-        self.client.assign_group_role_on_project(
+        self.roles_client.assign_group_role_on_project(
             self.project['id'], self.group_body['id'], self.role['id'])
         # List group roles on project
-        roles = self.client.list_group_roles_on_project(
+        roles = self.roles_client.list_group_roles_on_project(
             self.project['id'], self.group_body['id'])['roles']
 
         for i in roles:
@@ -157,19 +158,19 @@
         self.assertEqual(len(roles), 1)
         self.assertEqual(roles[0]['id'], self.role['id'])
 
-        self.client.check_role_from_group_on_project_existence(
+        self.roles_client.check_role_from_group_on_project_existence(
             self.project['id'], self.group_body['id'], self.role['id'])
 
         # Revoke role to group on project
-        self.client.delete_role_from_group_on_project(
+        self.roles_client.delete_role_from_group_on_project(
             self.project['id'], self.group_body['id'], self.role['id'])
 
     @test.idempotent_id('4bf8a70b-e785-413a-ad53-9f91ce02faa7')
     def test_grant_list_revoke_role_to_group_on_domain(self):
-        self.client.assign_group_role_on_domain(
+        self.roles_client.assign_group_role_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
 
-        roles = self.client.list_group_roles_on_domain(
+        roles = self.roles_client.list_group_roles_on_domain(
             self.domain['id'], self.group_body['id'])['roles']
 
         for i in roles:
@@ -178,15 +179,15 @@
         self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
 
-        self.client.check_role_from_group_on_domain_existence(
+        self.roles_client.check_role_from_group_on_domain_existence(
             self.domain['id'], self.group_body['id'], self.role['id'])
 
-        self.client.delete_role_from_group_on_domain(
+        self.roles_client.delete_role_from_group_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
 
     @test.idempotent_id('f5654bcc-08c4-4f71-88fe-05d64e06de94')
     def test_list_roles(self):
         # Return a list of all roles
-        body = self.client.list_roles()['roles']
+        body = self.roles_client.list_roles()['roles']
         found = [role for role in body if role in self.data.roles]
         self.assertEqual(len(found), len(self.data.roles))
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 63ba158..6f12939 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -77,15 +77,17 @@
 
         # Create a role
         role_name = data_utils.rand_name(name='role')
-        role = self.client.create_role(name=role_name)['role']
-        self.addCleanup(self.client.delete_role, role['id'])
+        role = self.roles_client.create_role(name=role_name)['role']
+        self.addCleanup(self.roles_client.delete_role, role['id'])
 
         # Grant the user the role on both projects.
-        self.client.assign_user_role_on_project(project1['id'], user['id'],
-                                                role['id'])
+        self.roles_client.assign_user_role_on_project(project1['id'],
+                                                      user['id'],
+                                                      role['id'])
 
-        self.client.assign_user_role_on_project(project2['id'], user['id'],
-                                                role['id'])
+        self.roles_client.assign_user_role_on_project(project2['id'],
+                                                      user['id'],
+                                                      role['id'])
 
         # Get an unscoped token.
         token_auth = self.token.auth(user_id=user['id'],
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index d31514c..09ae468 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -69,19 +69,22 @@
         self.delegated_role = data_utils.rand_name('DelegatedRole')
         self.not_delegated_role = data_utils.rand_name('NotDelegatedRole')
 
-        role = self.client.create_role(name=self.delegated_role)['role']
+        role = self.roles_client.create_role(name=self.delegated_role)['role']
         self.delegated_role_id = role['id']
 
-        role = self.client.create_role(name=self.not_delegated_role)['role']
+        role = self.roles_client.create_role(
+            name=self.not_delegated_role)['role']
         self.not_delegated_role_id = role['id']
 
         # Assign roles to trustor
-        self.client.assign_user_role_on_project(self.trustor_project_id,
-                                                self.trustor_user_id,
-                                                self.delegated_role_id)
-        self.client.assign_user_role_on_project(self.trustor_project_id,
-                                                self.trustor_user_id,
-                                                self.not_delegated_role_id)
+        self.roles_client.assign_user_role_on_project(
+            self.trustor_project_id,
+            self.trustor_user_id,
+            self.delegated_role_id)
+        self.roles_client.assign_user_role_on_project(
+            self.trustor_project_id,
+            self.trustor_user_id,
+            self.not_delegated_role_id)
 
         # Get trustee user ID, use the demo user
         trustee_username = self.non_admin_client.user
@@ -105,9 +108,9 @@
         if self.trustor_project_id:
             self.projects_client.delete_project(self.trustor_project_id)
         if self.delegated_role_id:
-            self.client.delete_role(self.delegated_role_id)
+            self.roles_client.delete_role(self.delegated_role_id)
         if self.not_delegated_role_id:
-            self.client.delete_role(self.not_delegated_role_id)
+            self.roles_client.delete_role(self.not_delegated_role_id)
 
     def create_trust(self, impersonate=True, expires=None):
 
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index de659d8..e26624a 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -117,13 +117,13 @@
         # Delete the User at the end of this method
         self.addCleanup(self.users_client.delete_user, user_body['id'])
         # Creating Role
-        role_body = self.client.create_role(
+        role_body = self.roles_client.create_role(
             name=data_utils.rand_name('role'))['role']
         # Delete the Role at the end of this method
-        self.addCleanup(self.client.delete_role, role_body['id'])
+        self.addCleanup(self.roles_client.delete_role, role_body['id'])
 
         user = self.users_client.show_user(user_body['id'])['user']
-        role = self.client.show_role(role_body['id'])['role']
+        role = self.roles_client.show_role(role_body['id'])['role']
         for i in range(2):
             # Creating project so as to assign role
             project_body = self.projects_client.create_project(
@@ -135,9 +135,9 @@
             self.addCleanup(
                 self.projects_client.delete_project, project_body['id'])
             # Assigning roles to user on project
-            self.client.assign_user_role_on_project(project['id'],
-                                                    user['id'],
-                                                    role['id'])
+            self.roles_client.assign_user_role_on_project(project['id'],
+                                                          user['id'],
+                                                          role['id'])
             assigned_project_ids.append(project['id'])
         body = self.users_client.list_user_projects(user['id'])['projects']
         for i in body:
diff --git a/tempest/api/identity/admin/v3/test_users_negative.py b/tempest/api/identity/admin/v3/test_users_negative.py
index f41ec3d..1375db1 100644
--- a/tempest/api/identity/admin/v3/test_users_negative.py
+++ b/tempest/api/identity/admin/v3/test_users_negative.py
@@ -38,7 +38,7 @@
     def test_authentication_for_disabled_user(self):
         # Attempt to authenticate for disabled user should fail
         self.data.setup_test_user()
-        self.disable_user(self.data.user['name'])
+        self.disable_user(self.data.user['name'], self.data.user['domain_id'])
         self.assertRaises(lib_exc.Unauthorized, self.token.auth,
                           username=self.data.user['name'],
                           password=self.data.user_password,
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index c44ffb9..91b3105 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -37,8 +37,12 @@
         cls.tenants_client.update_tenant(tenant['id'], enabled=False)
 
     @classmethod
-    def get_user_by_name(cls, name):
-        users = cls.users_client.list_users()['users']
+    def get_user_by_name(cls, name, domain_id=None):
+        if domain_id:
+            params = {'domain_id': domain_id}
+            users = cls.users_client.list_users(params)['users']
+        else:
+            users = cls.users_client.list_users()['users']
         user = [u for u in users if u['name'] == name]
         if len(user) > 0:
             return user[0]
@@ -108,8 +112,8 @@
     @classmethod
     def resource_setup(cls):
         super(BaseIdentityV2AdminTest, cls).resource_setup()
-        cls.data = DataGeneratorV2(cls.client, cls.tenants_client,
-                                   cls.users_client, cls.roles_client)
+        cls.data = DataGeneratorV2(cls.tenants_client, cls.users_client,
+                                   cls.roles_client)
 
     @classmethod
     def resource_cleanup(cls):
@@ -149,6 +153,7 @@
         cls.domains_client = cls.os_adm.domains_client
         cls.users_client = cls.os_adm.users_v3_client
         cls.trusts_client = cls.os_adm.trusts_client
+        cls.roles_client = cls.os_adm.roles_v3_client
         cls.token = cls.os_adm.token_v3_client
         cls.endpoints_client = cls.os_adm.endpoints_client
         cls.regions_client = cls.os_adm.regions_client
@@ -161,8 +166,8 @@
     @classmethod
     def resource_setup(cls):
         super(BaseIdentityV3AdminTest, cls).resource_setup()
-        cls.data = DataGeneratorV3(cls.client, cls.projects_client,
-                                   cls.users_client, None, cls.domains_client)
+        cls.data = DataGeneratorV3(cls.projects_client, cls.users_client,
+                                   cls.roles_client, cls.domains_client)
 
     @classmethod
     def resource_cleanup(cls):
@@ -170,15 +175,8 @@
         super(BaseIdentityV3AdminTest, cls).resource_cleanup()
 
     @classmethod
-    def get_role_by_name(cls, name):
-        roles = cls.client.list_roles()['roles']
-        role = [r for r in roles if r['name'] == name]
-        if len(role) > 0:
-            return role[0]
-
-    @classmethod
-    def disable_user(cls, user_name):
-        user = cls.get_user_by_name(user_name)
+    def disable_user(cls, user_name, domain_id=None):
+        user = cls.get_user_by_name(user_name, domain_id)
         cls.users_client.update_user(user['id'], user_name, enabled=False)
 
     def delete_domain(self, domain_id):
@@ -190,12 +188,11 @@
 
 class BaseDataGenerator(object):
 
-    def __init__(self, client, projects_client,
-                 users_client, roles_client=None, domains_client=None):
-        self.client = client
+    def __init__(self, projects_client, users_client, roles_client,
+                 domains_client=None):
         self.projects_client = projects_client
         self.users_client = users_client
-        self.roles_client = roles_client or client
+        self.roles_client = roles_client
         self.domains_client = domains_client
 
         self.user_password = None
diff --git a/tempest/clients.py b/tempest/clients.py
index e85a683..60baca6 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -128,6 +128,8 @@
 from tempest.services.identity.v3.json.projects_client import ProjectsClient
 from tempest.services.identity.v3.json.regions_client import \
     RegionsClient as RegionsV3Client
+from tempest.services.identity.v3.json.roles_client import \
+    RolesClient as RolesV3Client
 from tempest.services.identity.v3.json.services_client import \
     ServicesClient as IdentityServicesV3Client
 from tempest.services.identity.v3.json.trusts_client import TrustsClient
@@ -519,6 +521,7 @@
         self.users_v3_client = UsersV3Client(self.auth_provider, **params_v3)
         self.endpoints_client = EndPointV3Client(self.auth_provider,
                                                  **params_v3)
+        self.roles_v3_client = RolesV3Client(self.auth_provider, **params_v3)
         self.identity_services_client = IdentityServicesV3Client(
             self.auth_provider, **params_v3)
         self.policies_client = PoliciesV3Client(self.auth_provider,
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index df2d4b5..b95111a 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -480,8 +480,8 @@
 def main(opts=None):
     setup_logging()
     if not opts:
-        LOG.warn("Use of: 'tempest-account-generator' is deprecated, "
-                 "please use: 'tempest account-generator'")
+        LOG.warning("Use of: 'tempest-account-generator' is deprecated, "
+                    "please use: 'tempest account-generator'")
         opts = get_options()
     if opts.config_file:
         config.CONF.set_config_path(opts.config_file)
diff --git a/tempest/cmd/run_stress.py b/tempest/cmd/run_stress.py
index 943fe5b..6fe3928 100644
--- a/tempest/cmd/run_stress.py
+++ b/tempest/cmd/run_stress.py
@@ -146,8 +146,6 @@
 
 
 def main():
-    LOG.warning("Deprecated: Use 'tempest run-stress' instead. "
-                "The old entrypoint will be removed in a future release.")
     parser = argparse.ArgumentParser(description='Run stress tests')
     pa = add_arguments(parser)
     ns = pa.parse_args()
diff --git a/tempest/common/cred_client.py b/tempest/common/cred_client.py
index edc51ca..37c9727 100644
--- a/tempest/common/cred_client.py
+++ b/tempest/common/cred_client.py
@@ -32,14 +32,12 @@
     """
 
     def __init__(self, identity_client, projects_client, users_client,
-                 roles_client=None):
+                 roles_client):
         # The client implies version and credentials
         self.identity_client = identity_client
         self.users_client = users_client
         self.projects_client = projects_client
-        # this is temporary until the v3 clients are
-        # separated, then using *only* each client will become mandatory
-        self.roles_client = roles_client or identity_client
+        self.roles_client = roles_client
 
     def create_user(self, username, password, project, email):
         user = self.users_client.create_user(
@@ -130,9 +128,9 @@
 class V3CredsClient(CredsClient):
 
     def __init__(self, identity_client, projects_client, users_client,
-                 domains_client, domain_name):
+                 roles_client, domains_client, domain_name):
         super(V3CredsClient, self).__init__(identity_client, projects_client,
-                                            users_client)
+                                            users_client, roles_client)
         self.domains_client = domains_client
 
         try:
@@ -167,10 +165,6 @@
             project_domain_id=self.creds_domain['id'],
             project_domain_name=self.creds_domain['name'])
 
-    def _list_roles(self):
-        roles = self.identity_client.list_roles()['roles']
-        return roles
-
     def _assign_user_role(self, project, user, role):
         self.roles_client.assign_user_role_on_project(project['id'],
                                                       user['id'],
@@ -180,7 +174,7 @@
 def get_creds_client(identity_client,
                      projects_client,
                      users_client,
-                     roles_client=None,
+                     roles_client,
                      domains_client=None,
                      project_domain_name=None):
     if isinstance(identity_client, v2_identity.IdentityClient):
@@ -188,4 +182,4 @@
                              roles_client)
     else:
         return V3CredsClient(identity_client, projects_client, users_client,
-                             domains_client, project_domain_name)
+                             roles_client, domains_client, project_domain_name)
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index a254211..0a01bd4 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -97,7 +97,7 @@
                     os.security_groups_client)
         else:
             return (os.identity_v3_client, os.projects_client,
-                    os.users_v3_client, None, os.domains_client,
+                    os.users_v3_client, os.roles_v3_client, os.domains_client,
                     os.network_client, os.networks_client, os.subnets_client,
                     os.ports_client, os.security_groups_client)
 
@@ -184,12 +184,19 @@
                 router = self._create_router(router_name, tenant_id)
                 self._add_router_interface(router['id'], subnet['id'])
         except Exception:
-            if router:
-                self._clear_isolated_router(router['id'], router['name'])
-            if subnet:
-                self._clear_isolated_subnet(subnet['id'], subnet['name'])
-            if network:
-                self._clear_isolated_network(network['id'], network['name'])
+            try:
+                if router:
+                    self._clear_isolated_router(router['id'], router['name'])
+                if subnet:
+                    self._clear_isolated_subnet(subnet['id'], subnet['name'])
+                if network:
+                    self._clear_isolated_network(network['id'],
+                                                 network['name'])
+            except Exception as cleanup_exception:
+                msg = "There was an exception trying to setup network " \
+                      "resources for tenant %s, and this error happened " \
+                      "trying to clean them up: %s"
+                LOG.warning(msg % (tenant_id, cleanup_exception))
             raise
         return network, subnet, router
 
diff --git a/tempest/config.py b/tempest/config.py
index b062201..0e1b273 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1027,11 +1027,6 @@
                default='cirros-0.3.1-x86_64-vmlinuz',
                help='AKI image file name',
                deprecated_for_removal=True),
-    cfg.IntOpt(
-        'large_ops_number',
-        default=0,
-        help="specifies how many resources to request at once. Used "
-        "for large operations testing."),
     # TODO(yfried): add support for dhcpcd
     cfg.StrOpt('dhcp_client',
                default='udhcpc',
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
deleted file mode 100644
index 9ed831c..0000000
--- a/tempest/scenario/test_large_ops.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# Copyright 2013 NEC Corporation
-# 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 import fixed_network
-from tempest.common.utils import data_utils
-from tempest.common import waiters
-from tempest import config
-from tempest.lib import exceptions as lib_exc
-from tempest.scenario import manager
-from tempest import test
-
-CONF = config.CONF
-
-
-class TestLargeOpsScenario(manager.ScenarioTest):
-
-    """Test large operations.
-
-    This test below:
-    * Spin up multiple instances in one nova call, and repeat three times
-    * as a regular user
-    * TODO: same thing for cinder
-
-    """
-
-    @classmethod
-    def skip_checks(cls):
-        super(TestLargeOpsScenario, cls).skip_checks()
-        if CONF.scenario.large_ops_number < 1:
-            raise cls.skipException("large_ops_number not set to multiple "
-                                    "instances")
-
-    @classmethod
-    def setup_credentials(cls):
-        cls.set_network_resources()
-        super(TestLargeOpsScenario, cls).setup_credentials()
-
-    @classmethod
-    def resource_setup(cls):
-        super(TestLargeOpsScenario, cls).resource_setup()
-        # list of cleanup calls to be executed in reverse order
-        cls._cleanup_resources = []
-
-    @classmethod
-    def resource_cleanup(cls):
-        while cls._cleanup_resources:
-            function, args, kwargs = cls._cleanup_resources.pop(-1)
-            try:
-                function(*args, **kwargs)
-            except lib_exc.NotFound:
-                pass
-        super(TestLargeOpsScenario, cls).resource_cleanup()
-
-    @classmethod
-    def addCleanupClass(cls, function, *arguments, **keywordArguments):
-        cls._cleanup_resources.append((function, arguments, keywordArguments))
-
-    def _wait_for_server_status(self, status):
-        for server in self.servers:
-            # Make sure nova list keeps working throughout the build process
-            self.servers_client.list_servers()
-            waiters.wait_for_server_status(self.servers_client,
-                                           server['id'], status)
-
-    def nova_boot(self, image):
-        name = data_utils.rand_name('scenario-server')
-        flavor_id = CONF.compute.flavor_ref
-        # Explicitly create secgroup to avoid cleanup at the end of testcases.
-        # Since no traffic is tested, we don't need to actually add rules to
-        # secgroup
-        secgroup = self.compute_security_groups_client.create_security_group(
-            name='secgroup-%s' % name,
-            description='secgroup-desc-%s' % name)['security_group']
-        self.addCleanupClass(
-            self.compute_security_groups_client.delete_security_group,
-            secgroup['id'])
-        create_kwargs = {
-            'min_count': CONF.scenario.large_ops_number,
-            'security_groups': [{'name': secgroup['name']}]
-            }
-        network = self.get_tenant_network()
-        create_kwargs = fixed_network.set_networks_kwarg(network,
-                                                         create_kwargs)
-        self.servers_client.create_server(
-            name=name,
-            imageRef=image,
-            flavorRef=flavor_id,
-            **create_kwargs)
-        # needed because of bug 1199788
-        params = {'name': name}
-        server_list = self.servers_client.list_servers(**params)
-        self.servers = server_list['servers']
-        for server in self.servers:
-            # after deleting all servers - wait for all servers to clear
-            # before cleanup continues
-            self.addCleanupClass(waiters.wait_for_server_termination,
-                                 self.servers_client,
-                                 server['id'])
-        for server in self.servers:
-            self.addCleanupClass(self.servers_client.delete_server,
-                                 server['id'])
-        self._wait_for_server_status('ACTIVE')
-
-    def _large_ops_scenario(self):
-        image = self.glance_image_create()
-        self.nova_boot(image)
-
-    @test.idempotent_id('14ba0e78-2ed9-4d17-9659-a48f4756ecb3')
-    @test.services('compute', 'image')
-    def test_large_ops_scenario_1(self):
-        self._large_ops_scenario()
-
-    @test.idempotent_id('b9b79b88-32aa-42db-8f8f-dcc8f4b4ccfe')
-    @test.services('compute', 'image')
-    def test_large_ops_scenario_2(self):
-        self._large_ops_scenario()
-
-    @test.idempotent_id('3aab7e82-2de3-419a-9da1-9f3a070668fb')
-    @test.services('compute', 'image')
-    def test_large_ops_scenario_3(self):
-        self._large_ops_scenario()
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index d8cb99d..6e24801 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -16,7 +16,7 @@
 import six
 from six.moves.urllib import parse as urllib
 
-from tempest.common import service_client
+from tempest.lib.common import rest_client
 
 
 def handle_errors(f):
@@ -39,7 +39,7 @@
     return wrapper
 
 
-class BaremetalClient(service_client.ServiceClient):
+class BaremetalClient(rest_client.RestClient):
     """Base Tempest REST client for Ironic API."""
 
     uri_prefix = ''
diff --git a/tempest/services/data_processing/v1_1/data_processing_client.py b/tempest/services/data_processing/v1_1/data_processing_client.py
index 5aa2622..c74672f 100644
--- a/tempest/services/data_processing/v1_1/data_processing_client.py
+++ b/tempest/services/data_processing/v1_1/data_processing_client.py
@@ -14,10 +14,10 @@
 
 from oslo_serialization import jsonutils as json
 
-from tempest.common import service_client
+from tempest.lib.common import rest_client
 
 
-class DataProcessingClient(service_client.ServiceClient):
+class DataProcessingClient(rest_client.RestClient):
 
     def _request_and_check_resp(self, request_func, uri, resp_status):
         """Make a request and check response status code.
@@ -26,7 +26,7 @@
         """
         resp, body = request_func(uri)
         self.expected_success(resp_status, resp.status)
-        return service_client.ResponseBody(resp, body)
+        return rest_client.ResponseBody(resp, body)
 
     def _request_and_check_resp_data(self, request_func, uri, resp_status):
         """Make a request and check response status code.
@@ -47,7 +47,7 @@
         resp, body = request_func(uri, headers=headers, *args, **kwargs)
         self.expected_success(resp_status, resp.status)
         body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
+        return rest_client.ResponseBody(resp, body)
 
     def list_node_group_templates(self):
         """List all node group templates for a user."""
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index e4daf7a..fed33c5 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -29,50 +29,6 @@
         body = json.loads(body)
         return service_client.ResponseBody(resp, body)
 
-    def create_role(self, **kwargs):
-        """Create a Role.
-
-        Available params: see http://developer.openstack.org/
-                              api-ref-identity-v3.html#createRole
-        """
-        post_body = json.dumps({'role': kwargs})
-        resp, body = self.post('roles', post_body)
-        self.expected_success(201, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def show_role(self, role_id):
-        """GET a Role."""
-        resp, body = self.get('roles/%s' % str(role_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def list_roles(self):
-        """Get the list of Roles."""
-        resp, body = self.get("roles")
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def update_role(self, role_id, **kwargs):
-        """Update a Role.
-
-        Available params: see http://developer.openstack.org/
-                          api-ref-identity-v3.html#updateRole
-        """
-        post_body = json.dumps({'role': kwargs})
-        resp, body = self.patch('roles/%s' % str(role_id), post_body)
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_role(self, role_id):
-        """Delete a role."""
-        resp, body = self.delete('roles/%s' % str(role_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
     def show_token(self, resp_token):
         """Get token details."""
         headers = {'X-Subject-Token': resp_token}
@@ -87,123 +43,3 @@
         resp, body = self.delete("auth/tokens", headers=headers)
         self.expected_success(204, resp.status)
         return service_client.ResponseBody(resp, body)
-
-    def assign_user_role_on_project(self, project_id, user_id, role_id):
-        """Add roles to a user on a project."""
-        resp, body = self.put('projects/%s/users/%s/roles/%s' %
-                              (project_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def assign_user_role_on_domain(self, domain_id, user_id, role_id):
-        """Add roles to a user on a domain."""
-        resp, body = self.put('domains/%s/users/%s/roles/%s' %
-                              (domain_id, user_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def list_user_roles_on_project(self, project_id, user_id):
-        """list roles of a user on a project."""
-        resp, body = self.get('projects/%s/users/%s/roles' %
-                              (project_id, user_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def list_user_roles_on_domain(self, domain_id, user_id):
-        """list roles of a user on a domain."""
-        resp, body = self.get('domains/%s/users/%s/roles' %
-                              (domain_id, user_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_role_from_user_on_project(self, project_id, user_id, role_id):
-        """Delete role of a user on a project."""
-        resp, body = self.delete('projects/%s/users/%s/roles/%s' %
-                                 (project_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_role_from_user_on_domain(self, domain_id, user_id, role_id):
-        """Delete role of a user on a domain."""
-        resp, body = self.delete('domains/%s/users/%s/roles/%s' %
-                                 (domain_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def check_user_role_existence_on_project(self, project_id,
-                                             user_id, role_id):
-        """Check role of a user on a project."""
-        resp, body = self.head('projects/%s/users/%s/roles/%s' %
-                               (project_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp)
-
-    def check_user_role_existence_on_domain(self, domain_id,
-                                            user_id, role_id):
-        """Check role of a user on a domain."""
-        resp, body = self.head('domains/%s/users/%s/roles/%s' %
-                               (domain_id, user_id, role_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp)
-
-    def assign_group_role_on_project(self, project_id, group_id, role_id):
-        """Add roles to a user on a project."""
-        resp, body = self.put('projects/%s/groups/%s/roles/%s' %
-                              (project_id, group_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def assign_group_role_on_domain(self, domain_id, group_id, role_id):
-        """Add roles to a user on a domain."""
-        resp, body = self.put('domains/%s/groups/%s/roles/%s' %
-                              (domain_id, group_id, role_id), None)
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def list_group_roles_on_project(self, project_id, group_id):
-        """list roles of a user on a project."""
-        resp, body = self.get('projects/%s/groups/%s/roles' %
-                              (project_id, group_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def list_group_roles_on_domain(self, domain_id, group_id):
-        """list roles of a user on a domain."""
-        resp, body = self.get('domains/%s/groups/%s/roles' %
-                              (domain_id, group_id))
-        self.expected_success(200, resp.status)
-        body = json.loads(body)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_role_from_group_on_project(self, project_id, group_id, role_id):
-        """Delete role of a user on a project."""
-        resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
-                                 (project_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def delete_role_from_group_on_domain(self, domain_id, group_id, role_id):
-        """Delete role of a user on a domain."""
-        resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
-                                 (domain_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp, body)
-
-    def check_role_from_group_on_project_existence(self, project_id,
-                                                   group_id, role_id):
-        """Check role of a user on a project."""
-        resp, body = self.head('projects/%s/groups/%s/roles/%s' %
-                               (project_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp)
-
-    def check_role_from_group_on_domain_existence(self, domain_id,
-                                                  group_id, role_id):
-        """Check role of a user on a domain."""
-        resp, body = self.head('domains/%s/groups/%s/roles/%s' %
-                               (domain_id, group_id, role_id))
-        self.expected_success(204, resp.status)
-        return service_client.ResponseBody(resp)
diff --git a/tempest/services/identity/v3/json/roles_client.py b/tempest/services/identity/v3/json/roles_client.py
new file mode 100644
index 0000000..b10c02e
--- /dev/null
+++ b/tempest/services/identity/v3/json/roles_client.py
@@ -0,0 +1,185 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# 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_serialization import jsonutils as json
+
+from tempest.common import service_client
+
+
+class RolesClient(service_client.ServiceClient):
+    api_version = "v3"
+
+    def create_role(self, **kwargs):
+        """Create a Role.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-identity-v3.html#createRole
+        """
+        post_body = json.dumps({'role': kwargs})
+        resp, body = self.post('roles', post_body)
+        self.expected_success(201, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def show_role(self, role_id):
+        """GET a Role."""
+        resp, body = self.get('roles/%s' % str(role_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def list_roles(self):
+        """Get the list of Roles."""
+        resp, body = self.get("roles")
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def update_role(self, role_id, **kwargs):
+        """Update a Role.
+
+        Available params: see http://developer.openstack.org/
+                          api-ref-identity-v3.html#updateRole
+        """
+        post_body = json.dumps({'role': kwargs})
+        resp, body = self.patch('roles/%s' % str(role_id), post_body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_role(self, role_id):
+        """Delete a role."""
+        resp, body = self.delete('roles/%s' % str(role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def assign_user_role_on_project(self, project_id, user_id, role_id):
+        """Add roles to a user on a project."""
+        resp, body = self.put('projects/%s/users/%s/roles/%s' %
+                              (project_id, user_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def assign_user_role_on_domain(self, domain_id, user_id, role_id):
+        """Add roles to a user on a domain."""
+        resp, body = self.put('domains/%s/users/%s/roles/%s' %
+                              (domain_id, user_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def list_user_roles_on_project(self, project_id, user_id):
+        """list roles of a user on a project."""
+        resp, body = self.get('projects/%s/users/%s/roles' %
+                              (project_id, user_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def list_user_roles_on_domain(self, domain_id, user_id):
+        """list roles of a user on a domain."""
+        resp, body = self.get('domains/%s/users/%s/roles' %
+                              (domain_id, user_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_role_from_user_on_project(self, project_id, user_id, role_id):
+        """Delete role of a user on a project."""
+        resp, body = self.delete('projects/%s/users/%s/roles/%s' %
+                                 (project_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_role_from_user_on_domain(self, domain_id, user_id, role_id):
+        """Delete role of a user on a domain."""
+        resp, body = self.delete('domains/%s/users/%s/roles/%s' %
+                                 (domain_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def check_user_role_existence_on_project(self, project_id,
+                                             user_id, role_id):
+        """Check role of a user on a project."""
+        resp, body = self.head('projects/%s/users/%s/roles/%s' %
+                               (project_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp)
+
+    def check_user_role_existence_on_domain(self, domain_id,
+                                            user_id, role_id):
+        """Check role of a user on a domain."""
+        resp, body = self.head('domains/%s/users/%s/roles/%s' %
+                               (domain_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp)
+
+    def assign_group_role_on_project(self, project_id, group_id, role_id):
+        """Add roles to a user on a project."""
+        resp, body = self.put('projects/%s/groups/%s/roles/%s' %
+                              (project_id, group_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def assign_group_role_on_domain(self, domain_id, group_id, role_id):
+        """Add roles to a user on a domain."""
+        resp, body = self.put('domains/%s/groups/%s/roles/%s' %
+                              (domain_id, group_id, role_id), None)
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def list_group_roles_on_project(self, project_id, group_id):
+        """list roles of a user on a project."""
+        resp, body = self.get('projects/%s/groups/%s/roles' %
+                              (project_id, group_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def list_group_roles_on_domain(self, domain_id, group_id):
+        """list roles of a user on a domain."""
+        resp, body = self.get('domains/%s/groups/%s/roles' %
+                              (domain_id, group_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_role_from_group_on_project(self, project_id, group_id, role_id):
+        """Delete role of a user on a project."""
+        resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
+                                 (project_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def delete_role_from_group_on_domain(self, domain_id, group_id, role_id):
+        """Delete role of a user on a domain."""
+        resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
+                                 (domain_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp, body)
+
+    def check_role_from_group_on_project_existence(self, project_id,
+                                                   group_id, role_id):
+        """Check role of a user on a project."""
+        resp, body = self.head('projects/%s/groups/%s/roles/%s' %
+                               (project_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp)
+
+    def check_role_from_group_on_domain_existence(self, domain_id,
+                                                  group_id, role_id):
+        """Check role of a user on a domain."""
+        resp, body = self.head('domains/%s/groups/%s/roles/%s' %
+                               (domain_id, group_id, role_id))
+        self.expected_success(204, resp.status)
+        return service_client.ResponseBody(resp)
diff --git a/tempest/stress/__init__.py b/tempest/stress/__init__.py
index e69de29..987a023 100644
--- a/tempest/stress/__init__.py
+++ b/tempest/stress/__init__.py
@@ -0,0 +1,22 @@
+# Copyright 2016 NEC Corporation.  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 warnings
+
+warnings.simplefilter('once', category=DeprecationWarning)
+warnings.warn(
+    'Stress tests are deprecated and will be removed from Tempest '
+    'in the Newton release.',
+    DeprecationWarning)
+warnings.resetwarnings()
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 468578d..382b851 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -153,7 +153,7 @@
                 else:
                     identity_client = admin_manager.identity_v3_client
                     projects_client = admin_manager.projects_client
-                    roles_client = None
+                    roles_client = admin_manager.roles_v3_client
                     users_client = admin_manager.users_v3_client
                     domains_client = admin_manager.domains_client
                 domain = (identity_client.auth_provider.credentials.
diff --git a/tempest/stress/stressaction.py b/tempest/stress/stressaction.py
index c8bd652..cf0a08a 100644
--- a/tempest/stress/stressaction.py
+++ b/tempest/stress/stressaction.py
@@ -85,8 +85,8 @@
             finally:
                 shared_statistic['runs'] += 1
                 if self.stop_on_error and (shared_statistic['fails'] > 1):
-                    self.logger.warn("Stop process due to"
-                                     "\"stop-on-error\" argument")
+                    self.logger.warning("Stop process due to"
+                                        "\"stop-on-error\" argument")
                     self.tearDown()
                     sys.exit(1)
 
diff --git a/tempest/test.py b/tempest/test.py
index 45b818f..cee4e7e 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -445,9 +445,9 @@
             domains_client = None
         else:
             client = self.os_admin.identity_v3_client
-            project_client = self.os_adm.projects_client
             users_client = self.os_admin.users_v3_client
-            roles_client = None
+            project_client = self.os_admin.projects_client
+            roles_client = self.os_admin.roles_v3_client
             domains_client = self.os_admin.domains_client
 
         try:
diff --git a/tempest/tests/common/test_service_clients.py b/tempest/tests/common/test_service_clients.py
index 7e9ff9d..cdc3743 100644
--- a/tempest/tests/common/test_service_clients.py
+++ b/tempest/tests/common/test_service_clients.py
@@ -16,8 +16,6 @@
 import random
 import six
 
-from tempest.services.baremetal.v1.json import baremetal_client
-from tempest.services.data_processing.v1_1 import data_processing_client
 from tempest.services.database.json import flavors_client as db_flavor_client
 from tempest.services.database.json import versions_client as db_version_client
 from tempest.services.identity.v2.json import identity_client as \
@@ -81,8 +79,6 @@
     @mock.patch('tempest.lib.common.rest_client.RestClient.__init__')
     def test_service_client_creations_with_specified_args(self, mock_init):
         test_clients = [
-            baremetal_client.BaremetalClient,
-            data_processing_client.DataProcessingClient,
             db_flavor_client.DatabaseFlavorsClient,
             db_version_client.DatabaseVersionsClient,
             network_client.NetworkClient,
diff --git a/tempest/version.py b/tempest/version.py
new file mode 100644
index 0000000..bc9f651
--- /dev/null
+++ b/tempest/version.py
@@ -0,0 +1,18 @@
+# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
+#
+# 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 pbr.version
+
+version_info = pbr.version.VersionInfo('tempest')
diff --git a/test-requirements.txt b/test-requirements.txt
index eb43f31..be3a4f1 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -6,6 +6,7 @@
 sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
 python-subunit>=0.0.18 # Apache-2.0/BSD
 oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
+reno>=0.1.1 # Apache2
 mox>=0.5.3 # Apache-2.0
 mock>=1.2 # BSD
 coverage>=3.6 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index 95f2cf1..28dfe8b 100644
--- a/tox.ini
+++ b/tox.ini
@@ -70,14 +70,6 @@
   find . -type f -name "*.pyc" -delete
   bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty)) {posargs}'
 
-[testenv:large-ops]
-sitepackages = {[tempestenv]sitepackages}
-setenv = {[tempestenv]setenv}
-deps = {[tempestenv]deps}
-commands =
-  find . -type f -name "*.pyc" -delete
-  python setup.py testr --slowest --testr-args='tempest.scenario.test_large_ops {posargs}'
-
 [testenv:smoke]
 sitepackages = {[tempestenv]sitepackages}
 setenv = {[tempestenv]setenv}
@@ -132,3 +124,6 @@
 ignore = E125,E123,E129
 show-source = True
 exclude = .git,.venv,.tox,dist,doc,openstack,*egg
+
+[testenv:releasenotes]
+commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html