diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 4ab3f00..0000000 --- a/.coveragerc +++ /dev/null @@ -1,7 +0,0 @@ -[run] -branch = True -source = tempest_lib -omit = tempest_lib/tests/*,tempest_lib/openstack/* - -[report] -ignore_errors = True diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 4d66ba3..0000000 --- a/.gitignore +++ /dev/null @@ -1,57 +0,0 @@ -*.py[cod] - -# C extensions -*.so - -# Packages -*.egg* -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -cover/ -.coverage* -!.coveragerc -.tox -nosetests.xml -.testrepository - -# Translations -*.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - -# Complexity -output/*.html -output/*/index.html - -# Sphinx -doc/build -releasenotes/build - -# pbr generates these -AUTHORS -ChangeLog - -# Editors -*~ -.*.swp - -#Broken migrations -tempest diff --git a/.mailmap b/.mailmap deleted file mode 100644 index cc92f17..0000000 --- a/.mailmap +++ /dev/null @@ -1,3 +0,0 @@ -# Format is: -# -# \ No newline at end of file diff --git a/.testr.conf b/.testr.conf deleted file mode 100644 index fb62267..0000000 --- a/.testr.conf +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ - OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ - OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \ - ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION -test_id_option=--load-list $IDFILE -test_list_option=--list \ No newline at end of file diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index 57ae440..0000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,16 +0,0 @@ -If you would like to contribute to the development of OpenStack, -you must follow the steps in this page: - - http://docs.openstack.org/infra/manual/developers.html - -Once those steps have been completed, changes to OpenStack -should be submitted for review via the Gerrit tool, following -the workflow documented at: - - http://docs.openstack.org/infra/manual/developers.html#development-workflow - -Pull requests submitted through GitHub will be ignored. - -Bugs should be filed on Launchpad, not GitHub: - - https://bugs.launchpad.net/tempest diff --git a/HACKING.rst b/HACKING.rst deleted file mode 100644 index a9b7e60..0000000 --- a/HACKING.rst +++ /dev/null @@ -1,4 +0,0 @@ -tempest-lib Style Commandments -=============================================== - -Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/ \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 67db858..0000000 --- a/LICENSE +++ /dev/null @@ -1,175 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/README.rst b/README.rst index 9aa8abf..8eb8e46 100644 --- a/README.rst +++ b/README.rst @@ -1,33 +1,17 @@ -=========== -tempest-lib -=========== +This project is no longer maintained. -OpenStack Functional Testing Library +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". -* Free software: Apache license -* Documentation: http://docs.openstack.org/developer/tempest-lib -* Source: http://git.openstack.org/cgit/openstack/tempest-lib -* Bugs: http://bugs.launchpad.net/tempest +As of the 1.0.0 release tempest-lib as a separate repository and project +is deprecated. The library now exists as part of the tempest project, all +future development will occur there. To use the library for future releases +update your imports from tempest_lib to tempest.lib, and add tempest>=10 +to your project requirements. -tempest-lib is a library of common functionality that was originally in tempest -(or similar in scope to tempest) -**As of the 1.0.0 release tempest-lib as a separate repository and project is -deprecated. The library now exists as part of the tempest project, all future -development will occur there. To use the library for future releases update -your imports from tempest_lib to tempest.lib, and add tempest>=10 to your -project requirements** - -Features --------- - -Some of the current functionality exposed from the library includes: - -* OpenStack python-* client CLI testing framework -* subunit-trace: A output filter for subunit streams. Useful in conjunction - with calling a test runner that emits subunit -* A unified REST Client -* Utility functions: - * skip_because: Skip a test because of a bug - * find_test_caller: Perform stack introspection to find the test caller. - common methods +For any further questions, please email +openstack-discuss@lists.openstack.org or join #openstack-dev on +OFTC. diff --git a/babel.cfg b/babel.cfg deleted file mode 100644 index efceab8..0000000 --- a/babel.cfg +++ /dev/null @@ -1 +0,0 @@ -[python: **.py] diff --git a/doc/source/cli.rst b/doc/source/cli.rst deleted file mode 100644 index 301510e..0000000 --- a/doc/source/cli.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. _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/conf.py b/doc/source/conf.py deleted file mode 100755 index 4aff3f2..0000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- 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. - -import os -import sys - -sys.path.insert(0, os.path.abspath('../..')) -# -- General configuration ---------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - 'sphinx.ext.autodoc', - #'sphinx.ext.intersphinx', - 'oslosphinx' -] - -# autodoc generation is a bit aggressive and a nuisance when doing heavy -# text edit cycles. -# execute "export SPHINX_DEBUG=1" in your terminal to disable - -# The suffix of source filenames. -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'tempest-lib' -copyright = u'2013, OpenStack Foundation' - -# 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 - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# -- Options for HTML output -------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -# html_theme_path = ["."] -# html_theme = '_theme' -# html_static_path = ['static'] - -# Output file base name for HTML help builder. -htmlhelp_basename = '%sdoc' % project - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass -# [howto/manual]). -latex_documents = [ - ('index', - '%s.tex' % project, - u'%s Documentation' % project, - u'OpenStack Foundation', 'manual'), -] - -# Example configuration for intersphinx: refer to the Python standard library. -#intersphinx_mapping = {'http://docs.python.org/': None} \ No newline at end of file diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst deleted file mode 100644 index ed77c12..0000000 --- a/doc/source/contributing.rst +++ /dev/null @@ -1,4 +0,0 @@ -============ -Contributing -============ -.. include:: ../../CONTRIBUTING.rst \ No newline at end of file diff --git a/doc/source/decorators.rst b/doc/source/decorators.rst deleted file mode 100644 index a0b7c78..0000000 --- a/doc/source/decorators.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. _decorators: - -Decorators Usage Guide -====================== - ---------------------- -The decorators module ---------------------- - -.. automodule:: tempest_lib.decorators - :members: - - diff --git a/doc/source/history.rst b/doc/source/history.rst deleted file mode 100644 index 69ed4fe..0000000 --- a/doc/source/history.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../ChangeLog diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index 61f8c13..0000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,28 +0,0 @@ -.. tempest-lib documentation master file, created by - sphinx-quickstart on Tue Jul 9 22:26:36 2013. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to tempest-lib's documentation! -======================================================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - readme - installation - usage - contributing - cli - decorators - history - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/doc/source/installation.rst b/doc/source/installation.rst deleted file mode 100644 index a0e6237..0000000 --- a/doc/source/installation.rst +++ /dev/null @@ -1,12 +0,0 @@ -============ -Installation -============ - -At the command line:: - - $ pip install tempest-lib - -Or, if you have virtualenvwrapper installed:: - - $ mkvirtualenv tempest-lib - $ pip install tempest-lib \ No newline at end of file diff --git a/doc/source/readme.rst b/doc/source/readme.rst deleted file mode 100644 index 38ba804..0000000 --- a/doc/source/readme.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../README.rst \ No newline at end of file diff --git a/doc/source/rest_client.rst b/doc/source/rest_client.rst deleted file mode 100644 index 513d8e4..0000000 --- a/doc/source/rest_client.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. _rest_client: - -Rest Client Usage -================= - ----------------------- -The rest_client module ----------------------- - -.. automodule:: tempest_lib.common.rest_client - :members: diff --git a/doc/source/usage.rst b/doc/source/usage.rst deleted file mode 100644 index e305244..0000000 --- a/doc/source/usage.rst +++ /dev/null @@ -1,24 +0,0 @@ -======== -Usage -======== - -To use tempest-lib in a project:: - - import tempest_lib - -:ref:`cli` ----------- -The CLI testing framework allows you to test the command line interface for -an OpenStack project's python-*client - - -:ref:`decorators` ------------------ -These decorators enable common utility functions inside of your test suite - - -:ref:`rest_client` ------------------- -The base building block for making a project specific client - - diff --git a/doc/source/utils.rst b/doc/source/utils.rst deleted file mode 100644 index 0e481b2..0000000 --- a/doc/source/utils.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. _utils: - -Utils Usage -=========== - ---------------- -The misc module ---------------- - -.. automodule:: tempest_lib.common.utils.misc - :members: diff --git a/releasenotes/notes/tempest-lib-deprecation-3ec1ece17a8db9c5.yaml b/releasenotes/notes/tempest-lib-deprecation-3ec1ece17a8db9c5.yaml deleted file mode 100644 index a52389d..0000000 --- a/releasenotes/notes/tempest-lib-deprecation-3ec1ece17a8db9c5.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -prelude: > - Starting with tempest-lib 1.0.0 the tempest-lib development has moved - back into the tempest repository. After this release to get future - code updates to tempest-lib code you need change your requirements - to require tempest instead of tempest-lib and update your tepmest_lib - imports to use tempest.lib instead. -deprecations: - - Tempest-lib itself is deprecated. Development of the tempest library - interface will occur in tempest in the future. -critical: - - The 1.0.0 release is the last planned release for tempes-lib. All future - development for the library interface will occur in tempest in the future. diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py deleted file mode 100644 index 8fc5815..0000000 --- a/releasenotes/source/conf.py +++ /dev/null @@ -1,261 +0,0 @@ -# -*- coding: utf-8 -*- -# -# tempest-lib Release Notes documentation build configuration file, created by -# sphinx-quickstart on Thu Nov 5 11:50:32 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-lib Release Notes' -copyright = u'2016, tempest-lib 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. -# -from pbr import version - -# The full version, including alpha/beta/rc tags. -release = version.VersionInfo('tempest_lib').version_string_with_vcs() -# The short X.Y version. -version = version.VersionInfo('tempest_lib').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 -# " v 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 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 = 'tempest-libReleaseNotesdoc' - - -# -- 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', 'tempest-libReleaseNotes.tex', u'tempest-lib Release Notes ' - 'Documentation', u'tempest-lib 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', 'novareleasenotes', u'tempest-lib Release Notes Documentation', - [u'tempest-lib 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', 'tempest-libReleaseNotes', u'tempest-lib Release Notes Documentation', - u'tempest-lib developers', 'tempest-libReleaseNotes', 'One line description of project.', - '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 deleted file mode 100644 index 8ba9a19..0000000 --- a/releasenotes/source/index.rst +++ /dev/null @@ -1,17 +0,0 @@ -Welcome to tempest-lib Release Notes documentation! -=================================================== - -Contents -======== - -.. toctree:: - :maxdepth: 2 - - unreleased - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`search` diff --git a/releasenotes/source/unreleased.rst b/releasenotes/source/unreleased.rst deleted file mode 100644 index 875030f..0000000 --- a/releasenotes/source/unreleased.rst +++ /dev/null @@ -1,5 +0,0 @@ -============================ -Current Series Release Notes -============================ - -.. release-notes:: diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index e430831..0000000 --- a/requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. -pbr>=1.6 # Apache-2.0 -Babel>=1.3 # BSD -fixtures<2.0,>=1.3.1 # Apache-2.0/BSD -iso8601>=0.1.9 # MIT -jsonschema!=2.5.0,<3.0.0,>=2.0.0 # MIT -httplib2>=0.7.5 # MIT -paramiko>=1.16.0 # LGPL -six>=1.9.0 # MIT -oslo.log>=1.14.0 # Apache-2.0 -os-testr>=0.4.1 # Apache-2.0 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index ab8a786..0000000 --- a/setup.cfg +++ /dev/null @@ -1,51 +0,0 @@ -[metadata] -name = tempest-lib -summary = OpenStack Functional Testing Library -description-file = - README.rst -author = OpenStack -author-email = openstack-dev@lists.openstack.org -home-page = http://www.openstack.org/ -license = Apache License, Version 2.0 -classifier = - Environment :: OpenStack - Intended Audience :: Information Technology - Intended Audience :: System Administrators - License :: OSI Approved :: Apache Software License - Operating System :: POSIX :: Linux - Programming Language :: Python - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.4 - -[files] -packages = - tempest_lib - -[entry_points] -console_scripts = - skip-tracker = tempest_lib.cmd.skip_tracker:main - check-uuid = tempest_lib.cmd.check_uuid:run - -[build_sphinx] -source-dir = doc/source -build-dir = doc/build -all_files = 1 - -[upload_sphinx] -upload-dir = doc/build/html - -[compile_catalog] -directory = tempest_lib/locale -domain = tempest-lib - -[update_catalog] -domain = tempest-lib -output_dir = tempest_lib/locale -input_file = tempest_lib/locale/tempest-lib.pot - -[extract_messages] -keywords = _ gettext ngettext l_ lazy_gettext -mapping_file = babel.cfg -output_file = tempest_lib/locale/tempest-lib.pot diff --git a/setup.py b/setup.py deleted file mode 100644 index 782bb21..0000000 --- a/setup.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2013 Hewlett-Packard 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. - -# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT -import setuptools - -# In python < 2.7.4, a lazy loading of package `pbr` will break -# setuptools if some other modules registered functions in `atexit`. -# solution from: http://bugs.python.org/issue15881#msg170215 -try: - import multiprocessing # noqa -except ImportError: - pass - -setuptools.setup( - setup_requires=['pbr>=1.8'], - pbr=True) diff --git a/tempest_lib/__init__.py b/tempest_lib/__init__.py deleted file mode 100644 index 47f8fcf..0000000 --- a/tempest_lib/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- 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. - -import warnings - -import pbr.version - -__version__ = pbr.version.VersionInfo( - 'tempest_lib').version_string() - -# Emit a warning for tempest-lib deprecation. We want the warning to -# be displayed only once. -warnings.simplefilter('once', category=DeprecationWarning) -warnings.warn( - 'tempest-lib is deprecated for future bug-fixes and code changes in favor ' - 'of tempest. Please change your imports from tempest_lib to tempest.lib', - DeprecationWarning) -# And back to normal! -warnings.resetwarnings() diff --git a/tempest_lib/api_schema/__init__.py b/tempest_lib/api_schema/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/api_schema/response/__init__.py b/tempest_lib/api_schema/response/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/api_schema/response/compute/__init__.py b/tempest_lib/api_schema/response/compute/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/api_schema/response/compute/v2_1/__init__.py b/tempest_lib/api_schema/response/compute/v2_1/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/api_schema/response/compute/v2_1/agents.py b/tempest_lib/api_schema/response/compute/v2_1/agents.py deleted file mode 100644 index 6f712b4..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/agents.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright 2014 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. - -common_agent_info = { - 'type': 'object', - 'properties': { - 'agent_id': {'type': ['integer', 'string']}, - 'hypervisor': {'type': 'string'}, - 'os': {'type': 'string'}, - 'architecture': {'type': 'string'}, - 'version': {'type': 'string'}, - 'url': {'type': 'string', 'format': 'uri'}, - 'md5hash': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['agent_id', 'hypervisor', 'os', 'architecture', - 'version', 'url', 'md5hash'] -} - -list_agents = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'agents': { - 'type': 'array', - 'items': common_agent_info - } - }, - 'additionalProperties': False, - 'required': ['agents'] - } -} - -create_agent = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'agent': common_agent_info - }, - 'additionalProperties': False, - 'required': ['agent'] - } -} - -update_agent = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'agent': { - 'type': 'object', - 'properties': { - 'agent_id': {'type': ['integer', 'string']}, - 'version': {'type': 'string'}, - 'url': {'type': 'string', 'format': 'uri'}, - 'md5hash': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['agent_id', 'version', 'url', 'md5hash'] - } - }, - 'additionalProperties': False, - 'required': ['agent'] - } -} - -delete_agent = { - 'status_code': [200] -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/aggregates.py b/tempest_lib/api_schema/response/compute/v2_1/aggregates.py deleted file mode 100644 index 1a9fe41..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/aggregates.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright 2014 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 copy - -# create-aggregate api doesn't have 'hosts' and 'metadata' attributes. -aggregate_for_create = { - 'type': 'object', - 'properties': { - 'availability_zone': {'type': ['string', 'null']}, - 'created_at': {'type': 'string'}, - 'deleted': {'type': 'boolean'}, - 'deleted_at': {'type': ['string', 'null']}, - 'id': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'updated_at': {'type': ['string', 'null']} - }, - 'additionalProperties': False, - 'required': ['availability_zone', 'created_at', 'deleted', - 'deleted_at', 'id', 'name', 'updated_at'], -} - -common_aggregate_info = copy.deepcopy(aggregate_for_create) -common_aggregate_info['properties'].update({ - 'hosts': {'type': 'array'}, - 'metadata': {'type': 'object'} -}) -common_aggregate_info['required'].extend(['hosts', 'metadata']) - -list_aggregates = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'aggregates': { - 'type': 'array', - 'items': common_aggregate_info - } - }, - 'additionalProperties': False, - 'required': ['aggregates'], - } -} - -get_aggregate = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'aggregate': common_aggregate_info - }, - 'additionalProperties': False, - 'required': ['aggregate'], - } -} - -aggregate_set_metadata = get_aggregate -# The 'updated_at' attribute of 'update_aggregate' can't be null. -update_aggregate = copy.deepcopy(get_aggregate) -update_aggregate['response_body']['properties']['aggregate']['properties'][ - 'updated_at'] = { - 'type': 'string' - } - -delete_aggregate = { - 'status_code': [200] -} - -create_aggregate = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'aggregate': aggregate_for_create - }, - 'additionalProperties': False, - 'required': ['aggregate'], - } -} - -aggregate_add_remove_host = get_aggregate diff --git a/tempest_lib/api_schema/response/compute/v2_1/availability_zone.py b/tempest_lib/api_schema/response/compute/v2_1/availability_zone.py deleted file mode 100644 index d9aebce..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/availability_zone.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2014 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 copy - - -base = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'availabilityZoneInfo': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'zoneName': {'type': 'string'}, - 'zoneState': { - 'type': 'object', - 'properties': { - 'available': {'type': 'boolean'} - }, - 'additionalProperties': False, - 'required': ['available'] - }, - # NOTE: Here is the difference between detail and - # non-detail. - 'hosts': {'type': 'null'} - }, - 'additionalProperties': False, - 'required': ['zoneName', 'zoneState', 'hosts'] - } - } - }, - 'additionalProperties': False, - 'required': ['availabilityZoneInfo'] - } -} - -detail = { - 'type': 'object', - 'patternProperties': { - # NOTE: Here is for a hostname - '^[a-zA-Z0-9-_.]+$': { - 'type': 'object', - 'patternProperties': { - # NOTE: Here is for a service name - '^.*$': { - 'type': 'object', - 'properties': { - 'available': {'type': 'boolean'}, - 'active': {'type': 'boolean'}, - 'updated_at': {'type': ['string', 'null']} - }, - 'additionalProperties': False, - 'required': ['available', 'active', 'updated_at'] - } - } - } - } -} - -list_availability_zone_list = copy.deepcopy(base) - -list_availability_zone_list_detail = copy.deepcopy(base) -list_availability_zone_list_detail['response_body']['properties'][ - 'availabilityZoneInfo']['items']['properties']['hosts'] = detail diff --git a/tempest_lib/api_schema/response/compute/v2_1/baremetal_nodes.py b/tempest_lib/api_schema/response/compute/v2_1/baremetal_nodes.py deleted file mode 100644 index d1ee877..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/baremetal_nodes.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright 2015 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 copy - -node = { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'interfaces': {'type': 'array'}, - 'host': {'type': 'string'}, - 'task_state': {'type': ['string', 'null']}, - 'cpus': {'type': ['integer', 'string']}, - 'memory_mb': {'type': ['integer', 'string']}, - 'disk_gb': {'type': ['integer', 'string']}, - }, - 'additionalProperties': False, - 'required': ['id', 'interfaces', 'host', 'task_state', 'cpus', 'memory_mb', - 'disk_gb'] -} - -list_baremetal_nodes = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'nodes': { - 'type': 'array', - 'items': node - } - }, - 'additionalProperties': False, - 'required': ['nodes'] - } -} - -baremetal_node = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'node': node - }, - 'additionalProperties': False, - 'required': ['node'] - } -} -get_baremetal_node = copy.deepcopy(baremetal_node) -get_baremetal_node['response_body']['properties']['node'][ - 'properties'].update({'instance_uuid': {'type': ['string', 'null']}}) -get_baremetal_node['response_body']['properties']['node'][ - 'required'].append('instance_uuid') diff --git a/tempest_lib/api_schema/response/compute/v2_1/certificates.py b/tempest_lib/api_schema/response/compute/v2_1/certificates.py deleted file mode 100644 index 4e7cbe4..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/certificates.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2014 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 copy - -_common_schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'certificate': { - 'type': 'object', - 'properties': { - 'data': {'type': 'string'}, - 'private_key': {'type': 'string'}, - }, - 'additionalProperties': False, - 'required': ['data', 'private_key'] - } - }, - 'additionalProperties': False, - 'required': ['certificate'] - } -} - -get_certificate = copy.deepcopy(_common_schema) -get_certificate['response_body']['properties']['certificate'][ - 'properties']['private_key'].update({'type': 'null'}) - -create_certificate = copy.deepcopy(_common_schema) diff --git a/tempest_lib/api_schema/response/compute/v2_1/extensions.py b/tempest_lib/api_schema/response/compute/v2_1/extensions.py deleted file mode 100644 index a6a455c..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/extensions.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2014 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. - -list_extensions = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'extensions': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'updated': { - 'type': 'string', - 'format': 'data-time' - }, - 'name': {'type': 'string'}, - 'links': {'type': 'array'}, - 'namespace': { - 'type': 'string', - 'format': 'uri' - }, - 'alias': {'type': 'string'}, - 'description': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['updated', 'name', 'links', 'namespace', - 'alias', 'description'] - } - } - }, - 'additionalProperties': False, - 'required': ['extensions'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/fixed_ips.py b/tempest_lib/api_schema/response/compute/v2_1/fixed_ips.py deleted file mode 100644 index 8119b49..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/fixed_ips.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2014 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_lib.api_schema.response.compute.v2_1 import parameter_types - -get_fixed_ip = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'fixed_ip': { - 'type': 'object', - 'properties': { - 'address': parameter_types.ip_address, - 'cidr': {'type': 'string'}, - 'host': {'type': 'string'}, - 'hostname': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['address', 'cidr', 'host', 'hostname'] - } - }, - 'additionalProperties': False, - 'required': ['fixed_ip'] - } -} - -reserve_unreserve_fixed_ip = { - 'status_code': [202] -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/flavors.py b/tempest_lib/api_schema/response/compute/v2_1/flavors.py deleted file mode 100644 index 1d679d1..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/flavors.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright 2014 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_lib.api_schema.response.compute.v2_1 import parameter_types - -list_flavors = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'flavors': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'name': {'type': 'string'}, - 'links': parameter_types.links, - 'id': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['name', 'links', 'id'] - } - }, - 'flavors_links': parameter_types.links - }, - 'additionalProperties': False, - # NOTE(gmann): flavors_links attribute is not necessary - # to be present always So it is not 'required'. - 'required': ['flavors'] - } -} - -common_flavor_info = { - 'type': 'object', - 'properties': { - 'name': {'type': 'string'}, - 'links': parameter_types.links, - 'ram': {'type': 'integer'}, - 'vcpus': {'type': 'integer'}, - # 'swap' attributes comes as integer value but if it is empty - # it comes as "". So defining type of as string and integer. - 'swap': {'type': ['integer', 'string']}, - 'disk': {'type': 'integer'}, - 'id': {'type': 'string'}, - 'OS-FLV-DISABLED:disabled': {'type': 'boolean'}, - 'os-flavor-access:is_public': {'type': 'boolean'}, - 'rxtx_factor': {'type': 'number'}, - 'OS-FLV-EXT-DATA:ephemeral': {'type': 'integer'} - }, - 'additionalProperties': False, - # 'OS-FLV-DISABLED', 'os-flavor-access', 'rxtx_factor' and - # 'OS-FLV-EXT-DATA' are API extensions. So they are not 'required'. - 'required': ['name', 'links', 'ram', 'vcpus', 'swap', 'disk', 'id'] -} - -list_flavors_details = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'flavors': { - 'type': 'array', - 'items': common_flavor_info - }, - # NOTE(gmann): flavors_links attribute is not necessary - # to be present always So it is not 'required'. - 'flavors_links': parameter_types.links - }, - 'additionalProperties': False, - 'required': ['flavors'] - } -} - -unset_flavor_extra_specs = { - 'status_code': [200] -} - -create_get_flavor_details = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'flavor': common_flavor_info - }, - 'additionalProperties': False, - 'required': ['flavor'] - } -} - -delete_flavor = { - 'status_code': [202] -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/flavors_access.py b/tempest_lib/api_schema/response/compute/v2_1/flavors_access.py deleted file mode 100644 index a4d6af0..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/flavors_access.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2014 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. - -add_remove_list_flavor_access = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'flavor_access': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'flavor_id': {'type': 'string'}, - 'tenant_id': {'type': 'string'}, - }, - 'additionalProperties': False, - 'required': ['flavor_id', 'tenant_id'], - } - } - }, - 'additionalProperties': False, - 'required': ['flavor_access'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/flavors_extra_specs.py b/tempest_lib/api_schema/response/compute/v2_1/flavors_extra_specs.py deleted file mode 100644 index a438d48..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/flavors_extra_specs.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2014 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. - -set_get_flavor_extra_specs = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'extra_specs': { - 'type': 'object', - 'patternProperties': { - '^[a-zA-Z0-9_\-\. :]+$': {'type': 'string'} - } - } - }, - 'additionalProperties': False, - 'required': ['extra_specs'] - } -} - -set_get_flavor_extra_specs_key = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'patternProperties': { - '^[a-zA-Z0-9_\-\. :]+$': {'type': 'string'} - } - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/floating_ips.py b/tempest_lib/api_schema/response/compute/v2_1/floating_ips.py deleted file mode 100644 index f24fb50..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/floating_ips.py +++ /dev/null @@ -1,148 +0,0 @@ -# Copyright 2014 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_lib.api_schema.response.compute.v2_1 import parameter_types - -common_floating_ip_info = { - 'type': 'object', - 'properties': { - # NOTE: Now the type of 'id' is integer, but - # here allows 'string' also because we will be - # able to change it to 'uuid' in the future. - 'id': {'type': ['integer', 'string']}, - 'pool': {'type': ['string', 'null']}, - 'instance_id': {'type': ['string', 'null']}, - 'ip': parameter_types.ip_address, - 'fixed_ip': parameter_types.ip_address - }, - 'additionalProperties': False, - 'required': ['id', 'pool', 'instance_id', - 'ip', 'fixed_ip'], - -} -list_floating_ips = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'floating_ips': { - 'type': 'array', - 'items': common_floating_ip_info - }, - }, - 'additionalProperties': False, - 'required': ['floating_ips'], - } -} - -create_get_floating_ip = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'floating_ip': common_floating_ip_info - }, - 'additionalProperties': False, - 'required': ['floating_ip'], - } -} - -list_floating_ip_pools = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'floating_ip_pools': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'name': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['name'], - } - } - }, - 'additionalProperties': False, - 'required': ['floating_ip_pools'], - } -} - -add_remove_floating_ip = { - 'status_code': [202] -} - -create_floating_ips_bulk = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'floating_ips_bulk_create': { - 'type': 'object', - 'properties': { - 'interface': {'type': ['string', 'null']}, - 'ip_range': {'type': 'string'}, - 'pool': {'type': ['string', 'null']}, - }, - 'additionalProperties': False, - 'required': ['interface', 'ip_range', 'pool'], - } - }, - 'additionalProperties': False, - 'required': ['floating_ips_bulk_create'], - } -} - -delete_floating_ips_bulk = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'floating_ips_bulk_delete': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['floating_ips_bulk_delete'], - } -} - -list_floating_ips_bulk = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'floating_ip_info': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'address': parameter_types.ip_address, - 'instance_uuid': {'type': ['string', 'null']}, - 'interface': {'type': ['string', 'null']}, - 'pool': {'type': ['string', 'null']}, - 'project_id': {'type': ['string', 'null']}, - 'fixed_ip': parameter_types.ip_address - }, - 'additionalProperties': False, - # NOTE: fixed_ip is introduced after JUNO release, - # So it is not defined as 'required'. - 'required': ['address', 'instance_uuid', 'interface', - 'pool', 'project_id'], - } - } - }, - 'additionalProperties': False, - 'required': ['floating_ip_info'], - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/hosts.py b/tempest_lib/api_schema/response/compute/v2_1/hosts.py deleted file mode 100644 index ae70ff1..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/hosts.py +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright 2014 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 copy - - -list_hosts = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'hosts': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'host_name': {'type': 'string'}, - 'service': {'type': 'string'}, - 'zone': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['host_name', 'service', 'zone'] - } - } - }, - 'additionalProperties': False, - 'required': ['hosts'] - } -} - -get_host_detail = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'host': { - 'type': 'array', - 'item': { - 'type': 'object', - 'properties': { - 'resource': { - 'type': 'object', - 'properties': { - 'cpu': {'type': 'integer'}, - 'disk_gb': {'type': 'integer'}, - 'host': {'type': 'string'}, - 'memory_mb': {'type': 'integer'}, - 'project': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['cpu', 'disk_gb', 'host', - 'memory_mb', 'project'] - } - }, - 'additionalProperties': False, - 'required': ['resource'] - } - } - }, - 'additionalProperties': False, - 'required': ['host'] - } -} - -startup_host = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'host': {'type': 'string'}, - 'power_action': {'enum': ['startup']} - }, - 'additionalProperties': False, - 'required': ['host', 'power_action'] - } -} - -# The 'power_action' attribute of 'shutdown_host' API is 'shutdown' -shutdown_host = copy.deepcopy(startup_host) - -shutdown_host['response_body']['properties']['power_action'] = { - 'enum': ['shutdown'] -} - -# The 'power_action' attribute of 'reboot_host' API is 'reboot' -reboot_host = copy.deepcopy(startup_host) - -reboot_host['response_body']['properties']['power_action'] = { - 'enum': ['reboot'] -} - -update_host = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'host': {'type': 'string'}, - 'maintenance_mode': {'enum': ['on_maintenance', - 'off_maintenance']}, - 'status': {'enum': ['enabled', 'disabled']} - }, - 'additionalProperties': False, - 'required': ['host', 'maintenance_mode', 'status'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/hypervisors.py b/tempest_lib/api_schema/response/compute/v2_1/hypervisors.py deleted file mode 100644 index 32697db..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/hypervisors.py +++ /dev/null @@ -1,195 +0,0 @@ -# Copyright 2014 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 copy - -from tempest_lib.api_schema.response.compute.v2_1 import parameter_types - -get_hypervisor_statistics = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'hypervisor_statistics': { - 'type': 'object', - 'properties': { - 'count': {'type': 'integer'}, - 'current_workload': {'type': 'integer'}, - 'disk_available_least': {'type': ['integer', 'null']}, - 'free_disk_gb': {'type': 'integer'}, - 'free_ram_mb': {'type': 'integer'}, - 'local_gb': {'type': 'integer'}, - 'local_gb_used': {'type': 'integer'}, - 'memory_mb': {'type': 'integer'}, - 'memory_mb_used': {'type': 'integer'}, - 'running_vms': {'type': 'integer'}, - 'vcpus': {'type': 'integer'}, - 'vcpus_used': {'type': 'integer'} - }, - 'additionalProperties': False, - 'required': ['count', 'current_workload', - 'disk_available_least', 'free_disk_gb', - 'free_ram_mb', 'local_gb', 'local_gb_used', - 'memory_mb', 'memory_mb_used', 'running_vms', - 'vcpus', 'vcpus_used'] - } - }, - 'additionalProperties': False, - 'required': ['hypervisor_statistics'] - } -} - - -hypervisor_detail = { - 'type': 'object', - 'properties': { - 'status': {'type': 'string'}, - 'state': {'type': 'string'}, - 'cpu_info': {'type': 'string'}, - 'current_workload': {'type': 'integer'}, - 'disk_available_least': {'type': ['integer', 'null']}, - 'host_ip': parameter_types.ip_address, - 'free_disk_gb': {'type': 'integer'}, - 'free_ram_mb': {'type': 'integer'}, - 'hypervisor_hostname': {'type': 'string'}, - 'hypervisor_type': {'type': 'string'}, - 'hypervisor_version': {'type': 'integer'}, - 'id': {'type': ['integer', 'string']}, - 'local_gb': {'type': 'integer'}, - 'local_gb_used': {'type': 'integer'}, - 'memory_mb': {'type': 'integer'}, - 'memory_mb_used': {'type': 'integer'}, - 'running_vms': {'type': 'integer'}, - 'service': { - 'type': 'object', - 'properties': { - 'host': {'type': 'string'}, - 'id': {'type': ['integer', 'string']}, - 'disabled_reason': {'type': ['string', 'null']} - }, - 'additionalProperties': False, - 'required': ['host', 'id'] - }, - 'vcpus': {'type': 'integer'}, - 'vcpus_used': {'type': 'integer'} - }, - 'additionalProperties': False, - # NOTE: When loading os-hypervisor-status extension, - # a response contains status and state. So these params - # should not be required. - 'required': ['cpu_info', 'current_workload', - 'disk_available_least', 'host_ip', - 'free_disk_gb', 'free_ram_mb', - 'hypervisor_hostname', 'hypervisor_type', - 'hypervisor_version', 'id', 'local_gb', - 'local_gb_used', 'memory_mb', 'memory_mb_used', - 'running_vms', 'service', 'vcpus', 'vcpus_used'] -} - -list_hypervisors_detail = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'hypervisors': { - 'type': 'array', - 'items': hypervisor_detail - } - }, - 'additionalProperties': False, - 'required': ['hypervisors'] - } -} - -get_hypervisor = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'hypervisor': hypervisor_detail - }, - 'additionalProperties': False, - 'required': ['hypervisor'] - } -} - -list_search_hypervisors = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'hypervisors': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'status': {'type': 'string'}, - 'state': {'type': 'string'}, - 'id': {'type': ['integer', 'string']}, - 'hypervisor_hostname': {'type': 'string'} - }, - 'additionalProperties': False, - # NOTE: When loading os-hypervisor-status extension, - # a response contains status and state. So these params - # should not be required. - 'required': ['id', 'hypervisor_hostname'] - } - } - }, - 'additionalProperties': False, - 'required': ['hypervisors'] - } -} - -get_hypervisor_uptime = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'hypervisor': { - 'type': 'object', - 'properties': { - 'status': {'type': 'string'}, - 'state': {'type': 'string'}, - 'id': {'type': ['integer', 'string']}, - 'hypervisor_hostname': {'type': 'string'}, - 'uptime': {'type': 'string'} - }, - 'additionalProperties': False, - # NOTE: When loading os-hypervisor-status extension, - # a response contains status and state. So these params - # should not be required. - 'required': ['id', 'hypervisor_hostname', 'uptime'] - } - }, - 'additionalProperties': False, - 'required': ['hypervisor'] - } -} - -get_hypervisors_servers = copy.deepcopy(list_search_hypervisors) -get_hypervisors_servers['response_body']['properties']['hypervisors']['items'][ - 'properties']['servers'] = { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'uuid': {'type': 'string'}, - 'name': {'type': 'string'} - }, - 'additionalProperties': False, - } - } -# In V2 API, if there is no servers (VM) on the Hypervisor host then 'servers' -# attribute will not be present in response body So it is not 'required'. diff --git a/tempest_lib/api_schema/response/compute/v2_1/images.py b/tempest_lib/api_schema/response/compute/v2_1/images.py deleted file mode 100644 index 41aceaf..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/images.py +++ /dev/null @@ -1,154 +0,0 @@ -# Copyright 2014 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 copy - -from tempest_lib.api_schema.response.compute.v2_1 import parameter_types - -image_links = copy.deepcopy(parameter_types.links) -image_links['items']['properties'].update({'type': {'type': 'string'}}) - -common_image_schema = { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'status': {'type': 'string'}, - 'updated': {'type': 'string'}, - 'links': image_links, - 'name': {'type': ['string', 'null']}, - 'created': {'type': 'string'}, - 'minDisk': {'type': 'integer'}, - 'minRam': {'type': 'integer'}, - 'progress': {'type': 'integer'}, - 'metadata': {'type': 'object'}, - 'server': { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'links': parameter_types.links - }, - 'additionalProperties': False, - 'required': ['id', 'links'] - }, - 'OS-EXT-IMG-SIZE:size': {'type': ['integer', 'null']}, - 'OS-DCF:diskConfig': {'type': 'string'} - }, - 'additionalProperties': False, - # 'server' attributes only comes in response body if image is - # associated with any server. 'OS-EXT-IMG-SIZE:size' & 'OS-DCF:diskConfig' - # are API extension, So those are not defined as 'required'. - 'required': ['id', 'status', 'updated', 'links', 'name', - 'created', 'minDisk', 'minRam', 'progress', - 'metadata'] -} - -get_image = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'image': common_image_schema - }, - 'additionalProperties': False, - 'required': ['image'] - } -} - -list_images = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'images': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'links': image_links, - 'name': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['id', 'links', 'name'] - } - }, - 'images_links': parameter_types.links - }, - 'additionalProperties': False, - # NOTE(gmann): images_links attribute is not necessary to be - # present always So it is not 'required'. - 'required': ['images'] - } -} - -create_image = { - 'status_code': [202], - 'response_header': { - 'type': 'object', - 'properties': parameter_types.response_header - } -} -create_image['response_header']['properties'].update( - {'location': { - 'type': 'string', - 'format': 'uri'} - } -) -create_image['response_header']['required'] = ['location'] - -delete = { - 'status_code': [204] -} - -image_metadata = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'metadata': {'type': 'object'} - }, - 'additionalProperties': False, - 'required': ['metadata'] - } -} - -image_meta_item = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'meta': {'type': 'object'} - }, - 'additionalProperties': False, - 'required': ['meta'] - } -} - -list_images_details = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'images': { - 'type': 'array', - 'items': common_image_schema - }, - 'images_links': parameter_types.links - }, - 'additionalProperties': False, - # NOTE(gmann): images_links attribute is not necessary to be - # present always So it is not 'required'. - 'required': ['images'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/instance_usage_audit_logs.py b/tempest_lib/api_schema/response/compute/v2_1/instance_usage_audit_logs.py deleted file mode 100644 index c6c4deb..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/instance_usage_audit_logs.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2014 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. - -common_instance_usage_audit_log = { - 'type': 'object', - 'properties': { - 'hosts_not_run': { - 'type': 'array', - 'items': {'type': 'string'} - }, - 'log': {'type': 'object'}, - 'num_hosts': {'type': 'integer'}, - 'num_hosts_done': {'type': 'integer'}, - 'num_hosts_not_run': {'type': 'integer'}, - 'num_hosts_running': {'type': 'integer'}, - 'overall_status': {'type': 'string'}, - 'period_beginning': {'type': 'string'}, - 'period_ending': {'type': 'string'}, - 'total_errors': {'type': 'integer'}, - 'total_instances': {'type': 'integer'} - }, - 'additionalProperties': False, - 'required': ['hosts_not_run', 'log', 'num_hosts', 'num_hosts_done', - 'num_hosts_not_run', 'num_hosts_running', 'overall_status', - 'period_beginning', 'period_ending', 'total_errors', - 'total_instances'] -} - -get_instance_usage_audit_log = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'instance_usage_audit_log': common_instance_usage_audit_log - }, - 'additionalProperties': False, - 'required': ['instance_usage_audit_log'] - } -} - -list_instance_usage_audit_log = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'instance_usage_audit_logs': common_instance_usage_audit_log - }, - 'additionalProperties': False, - 'required': ['instance_usage_audit_logs'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/interfaces.py b/tempest_lib/api_schema/response/compute/v2_1/interfaces.py deleted file mode 100644 index 7d3750f..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/interfaces.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2014 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_lib.api_schema.response.compute.v2_1 import parameter_types - -interface_common_info = { - 'type': 'object', - 'properties': { - 'port_state': {'type': 'string'}, - 'fixed_ips': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'subnet_id': { - 'type': 'string', - 'format': 'uuid' - }, - 'ip_address': parameter_types.ip_address - }, - 'additionalProperties': False, - 'required': ['subnet_id', 'ip_address'] - } - }, - 'port_id': {'type': 'string', 'format': 'uuid'}, - 'net_id': {'type': 'string', 'format': 'uuid'}, - 'mac_addr': parameter_types.mac_address - }, - 'additionalProperties': False, - 'required': ['port_state', 'fixed_ips', 'port_id', 'net_id', 'mac_addr'] -} - -get_create_interfaces = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'interfaceAttachment': interface_common_info - }, - 'additionalProperties': False, - 'required': ['interfaceAttachment'] - } -} - -list_interfaces = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'interfaceAttachments': { - 'type': 'array', - 'items': interface_common_info - } - }, - 'additionalProperties': False, - 'required': ['interfaceAttachments'] - } -} - -delete_interface = { - 'status_code': [202] -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/keypairs.py b/tempest_lib/api_schema/response/compute/v2_1/keypairs.py deleted file mode 100644 index 9c04c79..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/keypairs.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright 2014 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. - -get_keypair = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'keypair': { - 'type': 'object', - 'properties': { - 'public_key': {'type': 'string'}, - 'name': {'type': 'string'}, - 'fingerprint': {'type': 'string'}, - 'user_id': {'type': 'string'}, - 'deleted': {'type': 'boolean'}, - 'created_at': {'type': 'string'}, - 'updated_at': {'type': ['string', 'null']}, - 'deleted_at': {'type': ['string', 'null']}, - 'id': {'type': 'integer'} - - }, - 'additionalProperties': False, - # When we run the get keypair API, response body includes - # all the above mentioned attributes. - # But in Nova API sample file, response body includes only - # 'public_key', 'name' & 'fingerprint'. So only 'public_key', - # 'name' & 'fingerprint' are defined as 'required'. - 'required': ['public_key', 'name', 'fingerprint'] - } - }, - 'additionalProperties': False, - 'required': ['keypair'] - } -} - -create_keypair = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'keypair': { - 'type': 'object', - 'properties': { - 'fingerprint': {'type': 'string'}, - 'name': {'type': 'string'}, - 'public_key': {'type': 'string'}, - 'user_id': {'type': 'string'}, - 'private_key': {'type': 'string'} - }, - 'additionalProperties': False, - # When create keypair API is being called with 'Public key' - # (Importing keypair) then, response body does not contain - # 'private_key' So it is not defined as 'required' - 'required': ['fingerprint', 'name', 'public_key', 'user_id'] - } - }, - 'additionalProperties': False, - 'required': ['keypair'] - } -} - -delete_keypair = { - 'status_code': [202], -} - -list_keypairs = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'keypairs': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'keypair': { - 'type': 'object', - 'properties': { - 'public_key': {'type': 'string'}, - 'name': {'type': 'string'}, - 'fingerprint': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['public_key', 'name', 'fingerprint'] - } - }, - 'additionalProperties': False, - 'required': ['keypair'] - } - } - }, - 'additionalProperties': False, - 'required': ['keypairs'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/limits.py b/tempest_lib/api_schema/response/compute/v2_1/limits.py deleted file mode 100644 index 81f175f..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/limits.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2014 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. - -get_limit = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'limits': { - 'type': 'object', - 'properties': { - 'absolute': { - 'type': 'object', - 'properties': { - 'maxTotalRAMSize': {'type': 'integer'}, - 'totalCoresUsed': {'type': 'integer'}, - 'maxTotalInstances': {'type': 'integer'}, - 'maxTotalFloatingIps': {'type': 'integer'}, - 'totalSecurityGroupsUsed': {'type': 'integer'}, - 'maxTotalCores': {'type': 'integer'}, - 'totalFloatingIpsUsed': {'type': 'integer'}, - 'maxSecurityGroups': {'type': 'integer'}, - 'maxServerMeta': {'type': 'integer'}, - 'maxPersonality': {'type': 'integer'}, - 'maxImageMeta': {'type': 'integer'}, - 'maxPersonalitySize': {'type': 'integer'}, - 'maxSecurityGroupRules': {'type': 'integer'}, - 'maxTotalKeypairs': {'type': 'integer'}, - 'totalRAMUsed': {'type': 'integer'}, - 'totalInstancesUsed': {'type': 'integer'}, - 'maxServerGroupMembers': {'type': 'integer'}, - 'maxServerGroups': {'type': 'integer'}, - 'totalServerGroupsUsed': {'type': 'integer'} - }, - 'additionalProperties': False, - # NOTE(gmann): maxServerGroupMembers, maxServerGroups - # and totalServerGroupsUsed are API extension, - # and some environments return a response without these - # attributes.So they are not 'required'. - 'required': ['maxImageMeta', - 'maxPersonality', - 'maxPersonalitySize', - 'maxSecurityGroupRules', - 'maxSecurityGroups', - 'maxServerMeta', - 'maxTotalCores', - 'maxTotalFloatingIps', - 'maxTotalInstances', - 'maxTotalKeypairs', - 'maxTotalRAMSize', - 'totalCoresUsed', - 'totalFloatingIpsUsed', - 'totalInstancesUsed', - 'totalRAMUsed', - 'totalSecurityGroupsUsed'] - }, - 'rate': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'limit': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'next-available': - {'type': 'string'}, - 'remaining': - {'type': 'integer'}, - 'unit': - {'type': 'string'}, - 'value': - {'type': 'integer'}, - 'verb': - {'type': 'string'} - }, - 'additionalProperties': False, - } - }, - 'regex': {'type': 'string'}, - 'uri': {'type': 'string'} - }, - 'additionalProperties': False, - } - } - }, - 'additionalProperties': False, - 'required': ['absolute', 'rate'] - } - }, - 'additionalProperties': False, - 'required': ['limits'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/migrations.py b/tempest_lib/api_schema/response/compute/v2_1/migrations.py deleted file mode 100644 index b7d66ea..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/migrations.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2014 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. - -list_migrations = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'migrations': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': {'type': 'integer'}, - 'status': {'type': ['string', 'null']}, - 'instance_uuid': {'type': ['string', 'null']}, - 'source_node': {'type': ['string', 'null']}, - 'source_compute': {'type': ['string', 'null']}, - 'dest_node': {'type': ['string', 'null']}, - 'dest_compute': {'type': ['string', 'null']}, - 'dest_host': {'type': ['string', 'null']}, - 'old_instance_type_id': {'type': ['integer', 'null']}, - 'new_instance_type_id': {'type': ['integer', 'null']}, - 'created_at': {'type': 'string'}, - 'updated_at': {'type': ['string', 'null']} - }, - 'additionalProperties': False, - 'required': [ - 'id', 'status', 'instance_uuid', 'source_node', - 'source_compute', 'dest_node', 'dest_compute', - 'dest_host', 'old_instance_type_id', - 'new_instance_type_id', 'created_at', 'updated_at' - ] - } - } - }, - 'additionalProperties': False, - 'required': ['migrations'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/parameter_types.py b/tempest_lib/api_schema/response/compute/v2_1/parameter_types.py deleted file mode 100644 index 07cc890..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/parameter_types.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright 2014 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. - -links = { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'href': { - 'type': 'string', - 'format': 'uri' - }, - 'rel': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['href', 'rel'] - } -} - -mac_address = { - 'type': 'string', - 'pattern': '(?:[a-f0-9]{2}:){5}[a-f0-9]{2}' -} - -ip_address = { - 'oneOf': [ - { - 'type': 'string', - 'oneOf': [ - {'format': 'ipv4'}, - {'format': 'ipv6'} - ] - }, - {'type': 'null'} - ] -} - -access_ip_v4 = { - 'type': 'string', - 'oneOf': [{'format': 'ipv4'}, {'enum': ['']}] -} - -access_ip_v6 = { - 'type': 'string', - 'oneOf': [{'format': 'ipv6'}, {'enum': ['']}] -} - -addresses = { - 'type': 'object', - 'patternProperties': { - # NOTE: Here is for 'private' or something. - '^[a-zA-Z0-9-_.]+$': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'version': {'type': 'integer'}, - 'addr': { - 'type': 'string', - 'oneOf': [ - {'format': 'ipv4'}, - {'format': 'ipv6'} - ] - } - }, - 'additionalProperties': False, - 'required': ['version', 'addr'] - } - } - } -} - -response_header = { - 'connection': {'type': 'string'}, - 'content-length': {'type': 'string'}, - 'content-type': {'type': 'string'}, - 'status': {'type': 'string'}, - 'x-compute-request-id': {'type': 'string'}, - 'vary': {'type': 'string'}, - 'x-openstack-nova-api-version': {'type': 'string'}, - 'date': { - 'type': 'string', - 'format': 'data-time' - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/quota_classes.py b/tempest_lib/api_schema/response/compute/v2_1/quota_classes.py deleted file mode 100644 index 5667c11..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/quota_classes.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2014 IBM 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 copy - -from tempest_lib.api_schema.response.compute.v2_1 import quotas - -# NOTE(mriedem): os-quota-class-sets responses are the same as os-quota-sets -# except for the key in the response body is quota_class_set instead of -# quota_set, so update this copy of the schema from os-quota-sets. -get_quota_class_set = copy.deepcopy(quotas.get_quota_set) -get_quota_class_set['response_body']['properties']['quota_class_set'] = ( - get_quota_class_set['response_body']['properties'].pop('quota_set')) -get_quota_class_set['response_body']['required'] = ['quota_class_set'] - -update_quota_class_set = copy.deepcopy(quotas.update_quota_set) -update_quota_class_set['response_body']['properties']['quota_class_set'] = ( - update_quota_class_set['response_body']['properties'].pop('quota_set')) -update_quota_class_set['response_body']['required'] = ['quota_class_set'] diff --git a/tempest_lib/api_schema/response/compute/v2_1/quotas.py b/tempest_lib/api_schema/response/compute/v2_1/quotas.py deleted file mode 100644 index 7953983..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/quotas.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2014 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 copy - -update_quota_set = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'quota_set': { - 'type': 'object', - 'properties': { - 'instances': {'type': 'integer'}, - 'cores': {'type': 'integer'}, - 'ram': {'type': 'integer'}, - 'floating_ips': {'type': 'integer'}, - 'fixed_ips': {'type': 'integer'}, - 'metadata_items': {'type': 'integer'}, - 'key_pairs': {'type': 'integer'}, - 'security_groups': {'type': 'integer'}, - 'security_group_rules': {'type': 'integer'}, - 'server_group_members': {'type': 'integer'}, - 'server_groups': {'type': 'integer'}, - 'injected_files': {'type': 'integer'}, - 'injected_file_content_bytes': {'type': 'integer'}, - 'injected_file_path_bytes': {'type': 'integer'} - }, - 'additionalProperties': False, - # NOTE: server_group_members and server_groups are represented - # when enabling quota_server_group extension. So they should - # not be required. - 'required': ['instances', 'cores', 'ram', - 'floating_ips', 'fixed_ips', - 'metadata_items', 'key_pairs', - 'security_groups', 'security_group_rules', - 'injected_files', 'injected_file_content_bytes', - 'injected_file_path_bytes'] - } - }, - 'additionalProperties': False, - 'required': ['quota_set'] - } -} - -get_quota_set = copy.deepcopy(update_quota_set) -get_quota_set['response_body']['properties']['quota_set']['properties'][ - 'id'] = {'type': 'string'} -get_quota_set['response_body']['properties']['quota_set']['required'].extend([ - 'id']) - -delete_quota = { - 'status_code': [202] -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/security_group_default_rule.py b/tempest_lib/api_schema/response/compute/v2_1/security_group_default_rule.py deleted file mode 100644 index 2ec2826..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/security_group_default_rule.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2014 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. - -common_security_group_default_rule_info = { - 'type': 'object', - 'properties': { - 'from_port': {'type': 'integer'}, - 'id': {'type': 'integer'}, - 'ip_protocol': {'type': 'string'}, - 'ip_range': { - 'type': 'object', - 'properties': { - 'cidr': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['cidr'], - }, - 'to_port': {'type': 'integer'}, - }, - 'additionalProperties': False, - 'required': ['from_port', 'id', 'ip_protocol', 'ip_range', 'to_port'], -} - -create_get_security_group_default_rule = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'security_group_default_rule': - common_security_group_default_rule_info - }, - 'additionalProperties': False, - 'required': ['security_group_default_rule'] - } -} - -delete_security_group_default_rule = { - 'status_code': [204] -} - -list_security_group_default_rules = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'security_group_default_rules': { - 'type': 'array', - 'items': common_security_group_default_rule_info - } - }, - 'additionalProperties': False, - 'required': ['security_group_default_rules'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/security_groups.py b/tempest_lib/api_schema/response/compute/v2_1/security_groups.py deleted file mode 100644 index 5ed5a5c..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/security_groups.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright 2014 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. - -common_security_group_rule = { - 'from_port': {'type': ['integer', 'null']}, - 'to_port': {'type': ['integer', 'null']}, - 'group': { - 'type': 'object', - 'properties': { - 'tenant_id': {'type': 'string'}, - 'name': {'type': 'string'} - }, - 'additionalProperties': False, - }, - 'ip_protocol': {'type': ['string', 'null']}, - # 'parent_group_id' can be UUID so defining it as 'string' also. - 'parent_group_id': {'type': ['string', 'integer', 'null']}, - 'ip_range': { - 'type': 'object', - 'properties': { - 'cidr': {'type': 'string'} - }, - 'additionalProperties': False, - # When optional argument is provided in request body - # like 'group_id' then, attribute 'cidr' does not - # comes in response body. So it is not 'required'. - }, - 'id': {'type': ['string', 'integer']} -} - -common_security_group = { - 'type': 'object', - 'properties': { - 'id': {'type': ['integer', 'string']}, - 'name': {'type': 'string'}, - 'tenant_id': {'type': 'string'}, - 'rules': { - 'type': 'array', - 'items': { - 'type': ['object', 'null'], - 'properties': common_security_group_rule, - 'additionalProperties': False, - } - }, - 'description': {'type': 'string'}, - }, - 'additionalProperties': False, - 'required': ['id', 'name', 'tenant_id', 'rules', 'description'], -} - -list_security_groups = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'security_groups': { - 'type': 'array', - 'items': common_security_group - } - }, - 'additionalProperties': False, - 'required': ['security_groups'] - } -} - -get_security_group = create_security_group = update_security_group = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'security_group': common_security_group - }, - 'additionalProperties': False, - 'required': ['security_group'] - } -} - -delete_security_group = { - 'status_code': [202] -} - -create_security_group_rule = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'security_group_rule': { - 'type': 'object', - 'properties': common_security_group_rule, - 'additionalProperties': False, - 'required': ['from_port', 'to_port', 'group', 'ip_protocol', - 'parent_group_id', 'id', 'ip_range'] - } - }, - 'additionalProperties': False, - 'required': ['security_group_rule'] - } -} - -delete_security_group_rule = { - 'status_code': [202] -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/servers.py b/tempest_lib/api_schema/response/compute/v2_1/servers.py deleted file mode 100644 index 7db05fb..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/servers.py +++ /dev/null @@ -1,553 +0,0 @@ -# Copyright 2014 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 copy - -from tempest_lib.api_schema.response.compute.v2_1 import parameter_types - -create_server = { - 'status_code': [202], - 'response_body': { - 'type': 'object', - 'properties': { - 'server': { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'security_groups': {'type': 'array'}, - 'links': parameter_types.links, - 'OS-DCF:diskConfig': {'type': 'string'} - }, - 'additionalProperties': False, - # NOTE: OS-DCF:diskConfig & security_groups are API extension, - # and some environments return a response without these - # attributes.So they are not 'required'. - 'required': ['id', 'links'] - } - }, - 'additionalProperties': False, - 'required': ['server'] - } -} - -create_server_with_admin_pass = copy.deepcopy(create_server) -create_server_with_admin_pass['response_body']['properties']['server'][ - 'properties'].update({'adminPass': {'type': 'string'}}) -create_server_with_admin_pass['response_body']['properties']['server'][ - 'required'].append('adminPass') - -list_servers = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'servers': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'links': parameter_types.links, - 'name': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['id', 'links', 'name'] - } - }, - 'servers_links': parameter_types.links - }, - 'additionalProperties': False, - # NOTE(gmann): servers_links attribute is not necessary to be - # present always So it is not 'required'. - 'required': ['servers'] - } -} - -delete_server = { - 'status_code': [204], -} - -common_show_server = { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'name': {'type': 'string'}, - 'status': {'type': 'string'}, - 'image': {'oneOf': [ - {'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'links': parameter_types.links - }, - 'additionalProperties': False, - 'required': ['id', 'links']}, - {'type': ['string', 'null']} - ]}, - 'flavor': { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'links': parameter_types.links - }, - 'additionalProperties': False, - 'required': ['id', 'links'] - }, - 'fault': { - 'type': 'object', - 'properties': { - 'code': {'type': 'integer'}, - 'created': {'type': 'string'}, - 'message': {'type': 'string'}, - 'details': {'type': 'string'}, - }, - 'additionalProperties': False, - # NOTE(gmann): 'details' is not necessary to be present - # in the 'fault'. So it is not defined as 'required'. - 'required': ['code', 'created', 'message'] - }, - 'user_id': {'type': 'string'}, - 'tenant_id': {'type': 'string'}, - 'created': {'type': 'string'}, - 'updated': {'type': 'string'}, - 'progress': {'type': 'integer'}, - 'metadata': {'type': 'object'}, - 'links': parameter_types.links, - 'addresses': parameter_types.addresses, - 'hostId': {'type': 'string'}, - 'OS-DCF:diskConfig': {'type': 'string'}, - 'accessIPv4': parameter_types.access_ip_v4, - 'accessIPv6': parameter_types.access_ip_v6 - }, - 'additionalProperties': False, - # NOTE(GMann): 'progress' attribute is present in the response - # only when server's status is one of the progress statuses - # ("ACTIVE","BUILD", "REBUILD", "RESIZE","VERIFY_RESIZE") - # 'fault' attribute is present in the response - # only when server's status is one of the "ERROR", "DELETED". - # OS-DCF:diskConfig and accessIPv4/v6 are API - # extensions, and some environments return a response - # without these attributes.So these are not defined as 'required'. - 'required': ['id', 'name', 'status', 'image', 'flavor', - 'user_id', 'tenant_id', 'created', 'updated', - 'metadata', 'links', 'addresses', 'hostId'] -} - -update_server = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'server': common_show_server - }, - 'additionalProperties': False, - 'required': ['server'] - } -} - -server_detail = copy.deepcopy(common_show_server) -server_detail['properties'].update({ - 'key_name': {'type': ['string', 'null']}, - 'security_groups': {'type': 'array'}, - - # NOTE: Non-admin users also can see "OS-SRV-USG" and "OS-EXT-AZ" - # attributes. - 'OS-SRV-USG:launched_at': {'type': ['string', 'null']}, - 'OS-SRV-USG:terminated_at': {'type': ['string', 'null']}, - 'OS-EXT-AZ:availability_zone': {'type': 'string'}, - - # NOTE: Admin users only can see "OS-EXT-STS" and "OS-EXT-SRV-ATTR" - # attributes. - 'OS-EXT-STS:task_state': {'type': ['string', 'null']}, - 'OS-EXT-STS:vm_state': {'type': 'string'}, - 'OS-EXT-STS:power_state': {'type': 'integer'}, - 'OS-EXT-SRV-ATTR:host': {'type': ['string', 'null']}, - 'OS-EXT-SRV-ATTR:instance_name': {'type': 'string'}, - 'OS-EXT-SRV-ATTR:hypervisor_hostname': {'type': ['string', 'null']}, - 'os-extended-volumes:volumes_attached': {'type': 'array'}, - 'config_drive': {'type': 'string'} -}) -server_detail['properties']['addresses']['patternProperties'][ - '^[a-zA-Z0-9-_.]+$']['items']['properties'].update({ - 'OS-EXT-IPS:type': {'type': 'string'}, - 'OS-EXT-IPS-MAC:mac_addr': parameter_types.mac_address}) -# NOTE(gmann): Update OS-EXT-IPS:type and OS-EXT-IPS-MAC:mac_addr -# attributes in server address. Those are API extension, -# and some environments return a response without -# these attributes. So they are not 'required'. - -get_server = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'server': server_detail - }, - 'additionalProperties': False, - 'required': ['server'] - } -} - -list_servers_detail = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'servers': { - 'type': 'array', - 'items': server_detail - }, - 'servers_links': parameter_types.links - }, - 'additionalProperties': False, - # NOTE(gmann): servers_links attribute is not necessary to be - # present always So it is not 'required'. - 'required': ['servers'] - } -} - -rebuild_server = copy.deepcopy(update_server) -rebuild_server['status_code'] = [202] - -rebuild_server_with_admin_pass = copy.deepcopy(rebuild_server) -rebuild_server_with_admin_pass['response_body']['properties']['server'][ - 'properties'].update({'adminPass': {'type': 'string'}}) -rebuild_server_with_admin_pass['response_body']['properties']['server'][ - 'required'].append('adminPass') - -rescue_server = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'adminPass': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['adminPass'] - } -} - -list_virtual_interfaces = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'virtual_interfaces': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'mac_address': parameter_types.mac_address, - 'OS-EXT-VIF-NET:net_id': {'type': 'string'} - }, - 'additionalProperties': False, - # 'OS-EXT-VIF-NET:net_id' is API extension So it is - # not defined as 'required' - 'required': ['id', 'mac_address'] - } - } - }, - 'additionalProperties': False, - 'required': ['virtual_interfaces'] - } -} - -common_attach_volume_info = { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'device': {'type': 'string'}, - 'volumeId': {'type': 'string'}, - 'serverId': {'type': ['integer', 'string']} - }, - 'additionalProperties': False, - 'required': ['id', 'device', 'volumeId', 'serverId'] -} - -attach_volume = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'volumeAttachment': common_attach_volume_info - }, - 'additionalProperties': False, - 'required': ['volumeAttachment'] - } -} - -detach_volume = { - 'status_code': [202] -} - -show_volume_attachment = copy.deepcopy(attach_volume) -show_volume_attachment['response_body']['properties'][ - 'volumeAttachment']['properties'].update({'serverId': {'type': 'string'}}) - -list_volume_attachments = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'volumeAttachments': { - 'type': 'array', - 'items': common_attach_volume_info - } - }, - 'additionalProperties': False, - 'required': ['volumeAttachments'] - } -} -list_volume_attachments['response_body']['properties'][ - 'volumeAttachments']['items']['properties'].update( - {'serverId': {'type': 'string'}}) - -list_addresses_by_network = { - 'status_code': [200], - 'response_body': parameter_types.addresses -} - -list_addresses = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'addresses': parameter_types.addresses - }, - 'additionalProperties': False, - 'required': ['addresses'] - } -} - -common_server_group = { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'name': {'type': 'string'}, - 'policies': { - 'type': 'array', - 'items': {'type': 'string'} - }, - # 'members' attribute contains the array of instance's UUID of - # instances present in server group - 'members': { - 'type': 'array', - 'items': {'type': 'string'} - }, - 'metadata': {'type': 'object'} - }, - 'additionalProperties': False, - 'required': ['id', 'name', 'policies', 'members', 'metadata'] -} - -create_show_server_group = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'server_group': common_server_group - }, - 'additionalProperties': False, - 'required': ['server_group'] - } -} - -delete_server_group = { - 'status_code': [204] -} - -list_server_groups = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'server_groups': { - 'type': 'array', - 'items': common_server_group - } - }, - 'additionalProperties': False, - 'required': ['server_groups'] - } -} - -instance_actions = { - 'type': 'object', - 'properties': { - 'action': {'type': 'string'}, - 'request_id': {'type': 'string'}, - 'user_id': {'type': 'string'}, - 'project_id': {'type': 'string'}, - 'start_time': {'type': 'string'}, - 'message': {'type': ['string', 'null']}, - 'instance_uuid': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['action', 'request_id', 'user_id', 'project_id', - 'start_time', 'message', 'instance_uuid'] -} - -instance_action_events = { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'event': {'type': 'string'}, - 'start_time': {'type': 'string'}, - 'finish_time': {'type': 'string'}, - 'result': {'type': 'string'}, - 'traceback': {'type': ['string', 'null']} - }, - 'additionalProperties': False, - 'required': ['event', 'start_time', 'finish_time', 'result', - 'traceback'] - } -} - -list_instance_actions = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'instanceActions': { - 'type': 'array', - 'items': instance_actions - } - }, - 'additionalProperties': False, - 'required': ['instanceActions'] - } -} - -instance_actions_with_events = copy.deepcopy(instance_actions) -instance_actions_with_events['properties'].update({ - 'events': instance_action_events}) -# 'events' does not come in response body always so it is not -# defined as 'required' - -show_instance_action = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'instanceAction': instance_actions_with_events - }, - 'additionalProperties': False, - 'required': ['instanceAction'] - } -} - -show_password = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'password': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['password'] - } -} - -get_vnc_console = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'console': { - 'type': 'object', - 'properties': { - 'type': {'type': 'string'}, - 'url': { - 'type': 'string', - 'format': 'uri' - } - }, - 'additionalProperties': False, - 'required': ['type', 'url'] - } - }, - 'additionalProperties': False, - 'required': ['console'] - } -} - -get_console_output = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'output': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['output'] - } -} - -set_server_metadata = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'metadata': { - 'type': 'object', - 'patternProperties': { - '^.+$': {'type': 'string'} - } - } - }, - 'additionalProperties': False, - 'required': ['metadata'] - } -} - -list_server_metadata = copy.deepcopy(set_server_metadata) - -update_server_metadata = copy.deepcopy(set_server_metadata) - -delete_server_metadata_item = { - 'status_code': [204] -} - -set_show_server_metadata_item = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'meta': { - 'type': 'object', - 'patternProperties': { - '^.+$': {'type': 'string'} - } - } - }, - 'additionalProperties': False, - 'required': ['meta'] - } -} - -server_actions_common_schema = { - 'status_code': [202] -} - -server_actions_delete_password = { - 'status_code': [204] -} - -server_actions_confirm_resize = copy.deepcopy( - server_actions_delete_password) - -update_attached_volume = { - 'status_code': [202] -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/services.py b/tempest_lib/api_schema/response/compute/v2_1/services.py deleted file mode 100644 index ddef7b2..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/services.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2014 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. - -list_services = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'services': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': {'type': ['integer', 'string'], - 'pattern': '^[a-zA-Z!]*@[0-9]+$'}, - 'zone': {'type': 'string'}, - 'host': {'type': 'string'}, - 'state': {'type': 'string'}, - 'binary': {'type': 'string'}, - 'status': {'type': 'string'}, - 'updated_at': {'type': ['string', 'null']}, - 'disabled_reason': {'type': ['string', 'null']} - }, - 'additionalProperties': False, - 'required': ['id', 'zone', 'host', 'state', 'binary', - 'status', 'updated_at', 'disabled_reason'] - } - } - }, - 'additionalProperties': False, - 'required': ['services'] - } -} - -enable_disable_service = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'service': { - 'type': 'object', - 'properties': { - 'status': {'type': 'string'}, - 'binary': {'type': 'string'}, - 'host': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['status', 'binary', 'host'] - } - }, - 'additionalProperties': False, - 'required': ['service'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/snapshots.py b/tempest_lib/api_schema/response/compute/v2_1/snapshots.py deleted file mode 100644 index 01a524b..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/snapshots.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright 2015 Fujitsu(fnst) 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. - -common_snapshot_info = { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'volumeId': {'type': 'string'}, - 'status': {'type': 'string'}, - 'size': {'type': 'integer'}, - 'createdAt': {'type': 'string'}, - 'displayName': {'type': ['string', 'null']}, - 'displayDescription': {'type': ['string', 'null']} - }, - 'additionalProperties': False, - 'required': ['id', 'volumeId', 'status', 'size', - 'createdAt', 'displayName', 'displayDescription'] -} - -create_get_snapshot = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'snapshot': common_snapshot_info - }, - 'additionalProperties': False, - 'required': ['snapshot'] - } -} - -list_snapshots = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'snapshots': { - 'type': 'array', - 'items': common_snapshot_info - } - }, - 'additionalProperties': False, - 'required': ['snapshots'] - } -} - -delete_snapshot = { - 'status_code': [202] -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/tenant_networks.py b/tempest_lib/api_schema/response/compute/v2_1/tenant_networks.py deleted file mode 100644 index ddfab96..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/tenant_networks.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2015 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. - -param_network = { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'cidr': {'type': ['string', 'null']}, - 'label': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['id', 'cidr', 'label'] -} - - -list_tenant_networks = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'networks': { - 'type': 'array', - 'items': param_network - } - }, - 'additionalProperties': False, - 'required': ['networks'] - } -} - - -get_tenant_network = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'network': param_network - }, - 'additionalProperties': False, - 'required': ['network'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/tenant_usages.py b/tempest_lib/api_schema/response/compute/v2_1/tenant_usages.py deleted file mode 100644 index d51ef12..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/tenant_usages.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright 2014 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 copy - -_server_usages = { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'ended_at': { - 'oneOf': [ - {'type': 'string'}, - {'type': 'null'} - ] - }, - 'flavor': {'type': 'string'}, - 'hours': {'type': 'number'}, - 'instance_id': {'type': 'string'}, - 'local_gb': {'type': 'integer'}, - 'memory_mb': {'type': 'integer'}, - 'name': {'type': 'string'}, - 'started_at': {'type': 'string'}, - 'state': {'type': 'string'}, - 'tenant_id': {'type': 'string'}, - 'uptime': {'type': 'integer'}, - 'vcpus': {'type': 'integer'}, - }, - 'required': ['ended_at', 'flavor', 'hours', 'instance_id', 'local_gb', - 'memory_mb', 'name', 'started_at', 'state', 'tenant_id', - 'uptime', 'vcpus'] - } -} - -_tenant_usage_list = { - 'type': 'object', - 'properties': { - 'server_usages': _server_usages, - 'start': {'type': 'string'}, - 'stop': {'type': 'string'}, - 'tenant_id': {'type': 'string'}, - 'total_hours': {'type': 'number'}, - 'total_local_gb_usage': {'type': 'number'}, - 'total_memory_mb_usage': {'type': 'number'}, - 'total_vcpus_usage': {'type': 'number'}, - }, - 'required': ['start', 'stop', 'tenant_id', - 'total_hours', 'total_local_gb_usage', - 'total_memory_mb_usage', 'total_vcpus_usage'] -} - -# 'required' of get_tenant is different from list_tenant's. -_tenant_usage_get = copy.deepcopy(_tenant_usage_list) -_tenant_usage_get['required'] = ['server_usages', 'start', 'stop', 'tenant_id', - 'total_hours', 'total_local_gb_usage', - 'total_memory_mb_usage', 'total_vcpus_usage'] - -list_tenant_usage = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'tenant_usages': { - 'type': 'array', - 'items': _tenant_usage_list - } - }, - 'required': ['tenant_usages'] - } -} - -get_tenant_usage = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'tenant_usage': _tenant_usage_get - }, - 'required': ['tenant_usage'] - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/versions.py b/tempest_lib/api_schema/response/compute/v2_1/versions.py deleted file mode 100644 index 08a9fab..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/versions.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright 2015 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 copy - - -_version = { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'links': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'href': {'type': 'string', 'format': 'uri'}, - 'rel': {'type': 'string'}, - 'type': {'type': 'string'}, - }, - 'required': ['href', 'rel'], - 'additionalProperties': False - } - }, - 'status': {'type': 'string'}, - 'updated': {'type': 'string', 'format': 'date-time'}, - 'version': {'type': 'string'}, - 'min_version': {'type': 'string'}, - 'media-types': { - 'type': 'array', - 'properties': { - 'base': {'type': 'string'}, - 'type': {'type': 'string'}, - } - }, - }, - # NOTE: version and min_version have been added since Kilo, - # so they should not be required. - # NOTE(sdague): media-types only shows up in single version requests. - 'required': ['id', 'links', 'status', 'updated'], - 'additionalProperties': False -} - -list_versions = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'versions': { - 'type': 'array', - 'items': _version - } - }, - 'required': ['versions'], - 'additionalProperties': False - } -} - - -_detail_get_version = copy.deepcopy(_version) -_detail_get_version['properties'].pop('min_version') -_detail_get_version['properties'].pop('version') -_detail_get_version['properties'].pop('updated') -_detail_get_version['properties']['media-types'] = { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'base': {'type': 'string'}, - 'type': {'type': 'string'} - } - } -} -_detail_get_version['required'] = ['id', 'links', 'status', 'media-types'] - -get_version = { - 'status_code': [300], - 'response_body': { - 'type': 'object', - 'properties': { - 'choices': { - 'type': 'array', - 'items': _detail_get_version - } - }, - 'required': ['choices'], - 'additionalProperties': False - } -} - -get_one_version = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'version': _version - }, - 'additionalProperties': False - } -} diff --git a/tempest_lib/api_schema/response/compute/v2_1/volumes.py b/tempest_lib/api_schema/response/compute/v2_1/volumes.py deleted file mode 100644 index bb34acb..0000000 --- a/tempest_lib/api_schema/response/compute/v2_1/volumes.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2014 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. - -create_get_volume = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'volume': { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'status': {'type': 'string'}, - 'displayName': {'type': ['string', 'null']}, - 'availabilityZone': {'type': 'string'}, - 'createdAt': {'type': 'string'}, - 'displayDescription': {'type': ['string', 'null']}, - 'volumeType': {'type': ['string', 'null']}, - 'snapshotId': {'type': ['string', 'null']}, - 'metadata': {'type': 'object'}, - 'size': {'type': 'integer'}, - 'attachments': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'device': {'type': 'string'}, - 'volumeId': {'type': 'string'}, - 'serverId': {'type': 'string'} - }, - 'additionalProperties': False, - # NOTE- If volume is not attached to any server - # then, 'attachments' attributes comes as array - # with empty objects "[{}]" due to that elements - # of 'attachments' cannot defined as 'required'. - # If it would come as empty array "[]" then, - # those elements can be defined as 'required'. - } - } - }, - 'additionalProperties': False, - 'required': ['id', 'status', 'displayName', 'availabilityZone', - 'createdAt', 'displayDescription', 'volumeType', - 'snapshotId', 'metadata', 'size', 'attachments'] - } - }, - 'additionalProperties': False, - 'required': ['volume'] - } -} - -list_volumes = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'volumes': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'status': {'type': 'string'}, - 'displayName': {'type': ['string', 'null']}, - 'availabilityZone': {'type': 'string'}, - 'createdAt': {'type': 'string'}, - 'displayDescription': {'type': ['string', 'null']}, - 'volumeType': {'type': ['string', 'null']}, - 'snapshotId': {'type': ['string', 'null']}, - 'metadata': {'type': 'object'}, - 'size': {'type': 'integer'}, - 'attachments': { - 'type': 'array', - 'items': { - 'type': 'object', - 'properties': { - 'id': {'type': 'string'}, - 'device': {'type': 'string'}, - 'volumeId': {'type': 'string'}, - 'serverId': {'type': 'string'} - }, - 'additionalProperties': False, - # NOTE- If volume is not attached to any server - # then, 'attachments' attributes comes as array - # with empty object "[{}]" due to that elements - # of 'attachments' cannot defined as 'required' - # If it would come as empty array "[]" then, - # those elements can be defined as 'required'. - } - } - }, - 'additionalProperties': False, - 'required': ['id', 'status', 'displayName', - 'availabilityZone', 'createdAt', - 'displayDescription', 'volumeType', - 'snapshotId', 'metadata', 'size', - 'attachments'] - } - } - }, - 'additionalProperties': False, - 'required': ['volumes'] - } -} - -delete_volume = { - 'status_code': [202] -} diff --git a/tempest_lib/auth.py b/tempest_lib/auth.py deleted file mode 100644 index c16d6dd..0000000 --- a/tempest_lib/auth.py +++ /dev/null @@ -1,676 +0,0 @@ -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# 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 abc -import copy -import datetime -import re - -from oslo_log import log as logging -import six -from six.moves.urllib import parse as urlparse - -from tempest_lib import exceptions -from tempest_lib.services.identity.v2 import token_client as json_v2id -from tempest_lib.services.identity.v3 import token_client as json_v3id - -ISO8601_FLOAT_SECONDS = '%Y-%m-%dT%H:%M:%S.%fZ' -ISO8601_INT_SECONDS = '%Y-%m-%dT%H:%M:%SZ' -LOG = logging.getLogger(__name__) - - -@six.add_metaclass(abc.ABCMeta) -class AuthProvider(object): - """Provide authentication""" - - def __init__(self, credentials): - """Auth provider __init__ - - :param credentials: credentials for authentication - """ - if self.check_credentials(credentials): - self.credentials = credentials - else: - if isinstance(credentials, Credentials): - password = credentials.get('password') - message = "Credentials are: " + str(credentials) - if password is None: - message += " Password is not defined." - else: - message += " Password is defined." - raise exceptions.InvalidCredentials(message) - else: - raise TypeError("credentials object is of type %s, which is" - " not a valid Credentials object type." % - credentials.__class__.__name__) - self.cache = None - self.alt_auth_data = None - self.alt_part = None - - def __str__(self): - return "Creds :{creds}, cached auth data: {cache}".format( - creds=self.credentials, cache=self.cache) - - @abc.abstractmethod - def _decorate_request(self, filters, method, url, headers=None, body=None, - auth_data=None): - """Decorate request with authentication data""" - return - - @abc.abstractmethod - def _get_auth(self): - return - - @abc.abstractmethod - def _fill_credentials(self, auth_data_body): - return - - def fill_credentials(self): - """Fill credentials object with data from auth""" - auth_data = self.get_auth() - self._fill_credentials(auth_data[1]) - return self.credentials - - @classmethod - def check_credentials(cls, credentials): - """Verify credentials are valid.""" - return isinstance(credentials, Credentials) and credentials.is_valid() - - @property - def auth_data(self): - return self.get_auth() - - @auth_data.deleter - def auth_data(self): - self.clear_auth() - - def get_auth(self): - """Returns auth from cache if available, else auth first""" - if self.cache is None or self.is_expired(self.cache): - self.set_auth() - return self.cache - - def set_auth(self): - """Forces setting auth. - - Forces setting auth, ignores cache if it exists. - Refills credentials - """ - self.cache = self._get_auth() - self._fill_credentials(self.cache[1]) - - def clear_auth(self): - """Clear access cache - - Can be called to clear the access cache so that next request - will fetch a new token and base_url. - """ - self.cache = None - self.credentials.reset() - - @abc.abstractmethod - def is_expired(self, auth_data): - return - - def auth_request(self, method, url, headers=None, body=None, filters=None): - """Obtains auth data and decorates a request with that. - - :param method: HTTP method of the request - :param url: relative URL of the request (path) - :param headers: HTTP headers of the request - :param body: HTTP body in case of POST / PUT - :param filters: select a base URL out of the catalog - :returns a Tuple (url, headers, body) - """ - orig_req = dict(url=url, headers=headers, body=body) - - auth_url, auth_headers, auth_body = self._decorate_request( - filters, method, url, headers, body) - auth_req = dict(url=auth_url, headers=auth_headers, body=auth_body) - - # Overwrite part if the request if it has been requested - if self.alt_part is not None: - if self.alt_auth_data is not None: - alt_url, alt_headers, alt_body = self._decorate_request( - filters, method, url, headers, body, - auth_data=self.alt_auth_data) - alt_auth_req = dict(url=alt_url, headers=alt_headers, - body=alt_body) - if auth_req[self.alt_part] == alt_auth_req[self.alt_part]: - raise exceptions.BadAltAuth(part=self.alt_part) - auth_req[self.alt_part] = alt_auth_req[self.alt_part] - - else: - # If the requested part is not affected by auth, we are - # not altering auth as expected, raise an exception - if auth_req[self.alt_part] == orig_req[self.alt_part]: - raise exceptions.BadAltAuth(part=self.alt_part) - # If alt auth data is None, skip auth in the requested part - auth_req[self.alt_part] = orig_req[self.alt_part] - - # Next auth request will be normal, unless otherwise requested - self.reset_alt_auth_data() - - return auth_req['url'], auth_req['headers'], auth_req['body'] - - def reset_alt_auth_data(self): - """Configure auth provider to provide valid authentication data""" - self.alt_part = None - self.alt_auth_data = None - - def set_alt_auth_data(self, request_part, auth_data): - """Alternate auth data on next request - - Configure auth provider to provide alt authentication data - on a part of the *next* auth_request. If credentials are None, - set invalid data. - :param request_part: request part to contain invalid auth: url, - headers, body - :param auth_data: alternative auth_data from which to get the - invalid data to be injected - """ - self.alt_part = request_part - self.alt_auth_data = auth_data - - @abc.abstractmethod - def base_url(self, filters, auth_data=None): - """Extracts the base_url based on provided filters""" - return - - -class KeystoneAuthProvider(AuthProvider): - - EXPIRY_DATE_FORMATS = (ISO8601_FLOAT_SECONDS, ISO8601_INT_SECONDS) - - token_expiry_threshold = datetime.timedelta(seconds=60) - - def __init__(self, credentials, auth_url, - disable_ssl_certificate_validation=None, - ca_certs=None, trace_requests=None): - super(KeystoneAuthProvider, self).__init__(credentials) - self.dsvm = disable_ssl_certificate_validation - self.ca_certs = ca_certs - self.trace_requests = trace_requests - self.auth_client = self._auth_client(auth_url) - - def _decorate_request(self, filters, method, url, headers=None, body=None, - auth_data=None): - if auth_data is None: - auth_data = self.auth_data - token, _ = auth_data - base_url = self.base_url(filters=filters, auth_data=auth_data) - # build authenticated request - # returns new request, it does not touch the original values - _headers = copy.deepcopy(headers) if headers is not None else {} - _headers['X-Auth-Token'] = str(token) - if url is None or url == "": - _url = base_url - else: - # Join base URL and url, and remove multiple contiguous slashes - _url = "/".join([base_url, url]) - parts = [x for x in urlparse.urlparse(_url)] - parts[2] = re.sub("/{2,}", "/", parts[2]) - _url = urlparse.urlunparse(parts) - # no change to method or body - return str(_url), _headers, body - - @abc.abstractmethod - def _auth_client(self): - return - - @abc.abstractmethod - def _auth_params(self): - return - - def _get_auth(self): - # Bypasses the cache - auth_func = getattr(self.auth_client, 'get_token') - auth_params = self._auth_params() - - # returns token, auth_data - token, auth_data = auth_func(**auth_params) - return token, auth_data - - def _parse_expiry_time(self, expiry_string): - expiry = None - for date_format in self.EXPIRY_DATE_FORMATS: - try: - expiry = datetime.datetime.strptime( - expiry_string, date_format) - except ValueError: - pass - if expiry is None: - raise ValueError( - "time data '{data}' does not match any of the" - "expected formats: {formats}".format( - data=expiry_string, formats=self.EXPIRY_DATE_FORMATS)) - return expiry - - def get_token(self): - return self.auth_data[0] - - -class KeystoneV2AuthProvider(KeystoneAuthProvider): - - def _auth_client(self, auth_url): - return json_v2id.TokenClient( - auth_url, disable_ssl_certificate_validation=self.dsvm, - ca_certs=self.ca_certs, trace_requests=self.trace_requests) - - def _auth_params(self): - return dict( - user=self.credentials.username, - password=self.credentials.password, - tenant=self.credentials.tenant_name, - auth_data=True) - - def _fill_credentials(self, auth_data_body): - tenant = auth_data_body['token']['tenant'] - user = auth_data_body['user'] - if self.credentials.tenant_name is None: - self.credentials.tenant_name = tenant['name'] - if self.credentials.tenant_id is None: - self.credentials.tenant_id = tenant['id'] - if self.credentials.username is None: - self.credentials.username = user['name'] - if self.credentials.user_id is None: - self.credentials.user_id = user['id'] - - def base_url(self, filters, auth_data=None): - """Base URL from catalog - - Filters can be: - - service: compute, image, etc - - region: the service region - - endpoint_type: adminURL, publicURL, internalURL - - api_version: replace catalog version with this - - skip_path: take just the base URL - """ - if auth_data is None: - auth_data = self.auth_data - token, _auth_data = auth_data - service = filters.get('service') - region = filters.get('region') - endpoint_type = filters.get('endpoint_type', 'publicURL') - - if service is None: - raise exceptions.EndpointNotFound("No service provided") - - _base_url = None - for ep in _auth_data['serviceCatalog']: - if ep["type"] == service: - for _ep in ep['endpoints']: - if region is not None and _ep['region'] == region: - _base_url = _ep.get(endpoint_type) - if not _base_url: - # No region matching, use the first - _base_url = ep['endpoints'][0].get(endpoint_type) - break - if _base_url is None: - raise exceptions.EndpointNotFound(service) - - parts = urlparse.urlparse(_base_url) - if filters.get('api_version', None) is not None: - path = "/" + filters['api_version'] - noversion_path = "/".join(parts.path.split("/")[2:]) - if noversion_path != "": - path += "/" + noversion_path - _base_url = _base_url.replace(parts.path, path) - if filters.get('skip_path', None) is not None and parts.path != '': - _base_url = _base_url.replace(parts.path, "/") - - return _base_url - - def is_expired(self, auth_data): - _, access = auth_data - expiry = self._parse_expiry_time(access['token']['expires']) - return (expiry - self.token_expiry_threshold <= - datetime.datetime.utcnow()) - - -class KeystoneV3AuthProvider(KeystoneAuthProvider): - - def _auth_client(self, auth_url): - return json_v3id.V3TokenClient( - auth_url, disable_ssl_certificate_validation=self.dsvm, - ca_certs=self.ca_certs, trace_requests=self.trace_requests) - - def _auth_params(self): - return dict( - user_id=self.credentials.user_id, - username=self.credentials.username, - password=self.credentials.password, - project_id=self.credentials.project_id, - project_name=self.credentials.project_name, - user_domain_id=self.credentials.user_domain_id, - user_domain_name=self.credentials.user_domain_name, - project_domain_id=self.credentials.project_domain_id, - project_domain_name=self.credentials.project_domain_name, - domain_id=self.credentials.domain_id, - domain_name=self.credentials.domain_name, - auth_data=True) - - def _fill_credentials(self, auth_data_body): - # project or domain, depending on the scope - project = auth_data_body.get('project', None) - domain = auth_data_body.get('domain', None) - # user is always there - user = auth_data_body['user'] - # Set project fields - if project is not None: - if self.credentials.project_name is None: - self.credentials.project_name = project['name'] - if self.credentials.project_id is None: - self.credentials.project_id = project['id'] - if self.credentials.project_domain_id is None: - self.credentials.project_domain_id = project['domain']['id'] - if self.credentials.project_domain_name is None: - self.credentials.project_domain_name = ( - project['domain']['name']) - # Set domain fields - if domain is not None: - if self.credentials.domain_id is None: - self.credentials.domain_id = domain['id'] - if self.credentials.domain_name is None: - self.credentials.domain_name = domain['name'] - # Set user fields - if self.credentials.username is None: - self.credentials.username = user['name'] - if self.credentials.user_id is None: - self.credentials.user_id = user['id'] - if self.credentials.user_domain_id is None: - self.credentials.user_domain_id = user['domain']['id'] - if self.credentials.user_domain_name is None: - self.credentials.user_domain_name = user['domain']['name'] - - def base_url(self, filters, auth_data=None): - """Base URL from catalog - - Filters can be: - - service: compute, image, etc - - region: the service region - - endpoint_type: adminURL, publicURL, internalURL - - api_version: replace catalog version with this - - skip_path: take just the base URL - """ - if auth_data is None: - auth_data = self.auth_data - token, _auth_data = auth_data - service = filters.get('service') - region = filters.get('region') - endpoint_type = filters.get('endpoint_type', 'public') - - if service is None: - raise exceptions.EndpointNotFound("No service provided") - - if 'URL' in endpoint_type: - endpoint_type = endpoint_type.replace('URL', '') - _base_url = None - catalog = _auth_data['catalog'] - # Select entries with matching service type - service_catalog = [ep for ep in catalog if ep['type'] == service] - if len(service_catalog) > 0: - service_catalog = service_catalog[0]['endpoints'] - else: - # No matching service - raise exceptions.EndpointNotFound(service) - # Filter by endpoint type (interface) - filtered_catalog = [ep for ep in service_catalog if - ep['interface'] == endpoint_type] - if len(filtered_catalog) == 0: - # No matching type, keep all and try matching by region at least - filtered_catalog = service_catalog - # Filter by region - filtered_catalog = [ep for ep in filtered_catalog if - ep['region'] == region] - if len(filtered_catalog) == 0: - # No matching region, take the first endpoint - filtered_catalog = [service_catalog[0]] - # There should be only one match. If not take the first. - _base_url = filtered_catalog[0].get('url', None) - if _base_url is None: - raise exceptions.EndpointNotFound(service) - - parts = urlparse.urlparse(_base_url) - if filters.get('api_version', None) is not None: - path = "/" + filters['api_version'] - noversion_path = "/".join(parts.path.split("/")[2:]) - if noversion_path != "": - path += "/" + noversion_path - _base_url = _base_url.replace(parts.path, path) - if filters.get('skip_path', None) is not None: - _base_url = _base_url.replace(parts.path, "/") - - return _base_url - - def is_expired(self, auth_data): - _, access = auth_data - expiry = self._parse_expiry_time(access['expires_at']) - return (expiry - self.token_expiry_threshold <= - datetime.datetime.utcnow()) - - -def is_identity_version_supported(identity_version): - return identity_version in IDENTITY_VERSION - - -def get_credentials(auth_url, fill_in=True, identity_version='v2', - disable_ssl_certificate_validation=None, ca_certs=None, - trace_requests=None, **kwargs): - """Builds a credentials object based on the configured auth_version - - :param auth_url (string): Full URI of the OpenStack Identity API(Keystone) - which is used to fetch the token from Identity service. - :param fill_in (boolean): obtain a token and fill in all credential - details provided by the identity service. When fill_in is not - specified, credentials are not validated. Validation can be invoked - by invoking ``is_valid()`` - :param identity_version (string): identity API version is used to - select the matching auth provider and credentials class - :param disable_ssl_certificate_validation: whether to enforce SSL - certificate validation in SSL API requests to the auth system - :param ca_certs: CA certificate bundle for validation of certificates - in SSL API requests to the auth system - :param trace_requests: trace in log API requests to the auth system - :param kwargs (dict): Dict of credential key/value pairs - - Examples: - - Returns credentials from the provided parameters: - >>> get_credentials(username='foo', password='bar') - - Returns credentials including IDs: - >>> get_credentials(username='foo', password='bar', fill_in=True) - """ - if not is_identity_version_supported(identity_version): - raise exceptions.InvalidIdentityVersion( - identity_version=identity_version) - - credential_class, auth_provider_class = IDENTITY_VERSION.get( - identity_version) - - creds = credential_class(**kwargs) - # Fill in the credentials fields that were not specified - if fill_in: - dsvm = disable_ssl_certificate_validation - auth_provider = auth_provider_class( - creds, auth_url, disable_ssl_certificate_validation=dsvm, - ca_certs=ca_certs, trace_requests=trace_requests) - creds = auth_provider.fill_credentials() - return creds - - -class Credentials(object): - """Set of credentials for accessing OpenStack services - - ATTRIBUTES: list of valid class attributes representing credentials. - """ - - ATTRIBUTES = [] - - def __init__(self, **kwargs): - """Enforce the available attributes at init time (only). - - Additional attributes can still be set afterwards if tests need - to do so. - """ - self._initial = kwargs - self._apply_credentials(kwargs) - - def _apply_credentials(self, attr): - for key in attr.keys(): - if key in self.ATTRIBUTES: - setattr(self, key, attr[key]) - else: - msg = '%s is not a valid attr for %s' % (key, self.__class__) - raise exceptions.InvalidCredentials(msg) - - def __str__(self): - """Represent only attributes included in self.ATTRIBUTES""" - attrs = [attr for attr in self.ATTRIBUTES if attr is not 'password'] - _repr = dict((k, getattr(self, k)) for k in attrs) - return str(_repr) - - def __eq__(self, other): - """Credentials are equal if attributes in self.ATTRIBUTES are equal""" - return str(self) == str(other) - - def __getattr__(self, key): - # If an attribute is set, __getattr__ is not invoked - # If an attribute is not set, and it is a known one, return None - if key in self.ATTRIBUTES: - return None - else: - raise AttributeError - - def __delitem__(self, key): - # For backwards compatibility, support dict behaviour - if key in self.ATTRIBUTES: - delattr(self, key) - else: - raise AttributeError - - def get(self, item, default=None): - # In this patch act as dict for backward compatibility - try: - return getattr(self, item) - except AttributeError: - return default - - def get_init_attributes(self): - return self._initial.keys() - - def is_valid(self): - raise NotImplementedError - - def reset(self): - # First delete all known attributes - for key in self.ATTRIBUTES: - if getattr(self, key) is not None: - delattr(self, key) - # Then re-apply initial setup - self._apply_credentials(self._initial) - - -class KeystoneV2Credentials(Credentials): - - ATTRIBUTES = ['username', 'password', 'tenant_name', 'user_id', - 'tenant_id'] - - def is_valid(self): - """Check of credentials (no API call) - - Minimum set of valid credentials, are username and password. - Tenant is optional. - """ - return None not in (self.username, self.password) - - -class KeystoneV3Credentials(Credentials): - """Credentials suitable for the Keystone Identity V3 API""" - - ATTRIBUTES = ['domain_id', 'domain_name', 'password', 'username', - 'project_domain_id', 'project_domain_name', 'project_id', - 'project_name', 'tenant_id', 'tenant_name', 'user_domain_id', - 'user_domain_name', 'user_id'] - - def __setattr__(self, key, value): - parent = super(KeystoneV3Credentials, self) - # for tenant_* set both project and tenant - if key == 'tenant_id': - parent.__setattr__('project_id', value) - elif key == 'tenant_name': - parent.__setattr__('project_name', value) - # for project_* set both project and tenant - if key == 'project_id': - parent.__setattr__('tenant_id', value) - elif key == 'project_name': - parent.__setattr__('tenant_name', value) - # for *_domain_* set both user and project if not set yet - if key == 'user_domain_id': - if self.project_domain_id is None: - parent.__setattr__('project_domain_id', value) - if key == 'project_domain_id': - if self.user_domain_id is None: - parent.__setattr__('user_domain_id', value) - if key == 'user_domain_name': - if self.project_domain_name is None: - parent.__setattr__('project_domain_name', value) - if key == 'project_domain_name': - if self.user_domain_name is None: - parent.__setattr__('user_domain_name', value) - # support domain_name coming from config - if key == 'domain_name': - parent.__setattr__('user_domain_name', value) - parent.__setattr__('project_domain_name', value) - # finally trigger default behaviour for all attributes - parent.__setattr__(key, value) - - def is_valid(self): - """Check of credentials (no API call) - - Valid combinations of v3 credentials (excluding token, scope) - - User id, password (optional domain) - - User name, password and its domain id/name - For the scope, valid combinations are: - - None - - Project id (optional domain) - - Project name and its domain id/name - - Domain id - - Domain name - """ - valid_user_domain = any( - [self.user_domain_id is not None, - self.user_domain_name is not None]) - valid_project_domain = any( - [self.project_domain_id is not None, - self.project_domain_name is not None]) - valid_user = any( - [self.user_id is not None, - self.username is not None and valid_user_domain]) - valid_project_scope = any( - [self.project_name is None and self.project_id is None, - self.project_id is not None, - self.project_name is not None and valid_project_domain]) - valid_domain_scope = any( - [self.domain_id is None and self.domain_name is None, - self.domain_id or self.domain_name]) - return all([self.password is not None, - valid_user, - valid_project_scope and valid_domain_scope]) - - -IDENTITY_VERSION = {'v2': (KeystoneV2Credentials, KeystoneV2AuthProvider), - 'v3': (KeystoneV3Credentials, KeystoneV3AuthProvider)} diff --git a/tempest_lib/base.py b/tempest_lib/base.py deleted file mode 100644 index 227ac37..0000000 --- a/tempest_lib/base.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import logging -import os - -import fixtures -import testtools - -LOG = logging.getLogger(__name__) - - -class BaseTestCase(testtools.testcase.WithAttributes, testtools.TestCase): - setUpClassCalled = False - - # NOTE(sdague): log_format is defined inline here instead of using the oslo - # default because going through the config path recouples config to the - # stress tests too early, and depending on testr order will fail unit tests - log_format = ('%(asctime)s %(process)d %(levelname)-8s ' - '[%(name)s] %(message)s') - - @classmethod - def setUpClass(cls): - if hasattr(super(BaseTestCase, cls), 'setUpClass'): - super(BaseTestCase, cls).setUpClass() - cls.setUpClassCalled = True - - @classmethod - def tearDownClass(cls): - if hasattr(super(BaseTestCase, cls), 'tearDownClass'): - super(BaseTestCase, cls).tearDownClass() - - def setUp(self): - super(BaseTestCase, self).setUp() - if not self.setUpClassCalled: - raise RuntimeError("setUpClass does not calls the super's" - "setUpClass in the " - + self.__class__.__name__) - test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0) - try: - test_timeout = int(test_timeout) - except ValueError: - test_timeout = 0 - if test_timeout > 0: - self.useFixture(fixtures.Timeout(test_timeout, gentle=True)) - - if (os.environ.get('OS_STDOUT_CAPTURE') == 'True' or - os.environ.get('OS_STDOUT_CAPTURE') == '1'): - stdout = self.useFixture(fixtures.StringStream('stdout')).stream - self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout)) - if (os.environ.get('OS_STDERR_CAPTURE') == 'True' or - os.environ.get('OS_STDERR_CAPTURE') == '1'): - stderr = self.useFixture(fixtures.StringStream('stderr')).stream - self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) - if (os.environ.get('OS_LOG_CAPTURE') != 'False' and - os.environ.get('OS_LOG_CAPTURE') != '0'): - self.useFixture(fixtures.LoggerFixture(nuke_handlers=False, - format=self.log_format, - level=None)) diff --git a/tempest_lib/cli/__init__.py b/tempest_lib/cli/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/cli/base.py b/tempest_lib/cli/base.py deleted file mode 100644 index d408869..0000000 --- a/tempest_lib/cli/base.py +++ /dev/null @@ -1,410 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import logging -import os -import shlex -import subprocess - -import six - -from tempest_lib import base -import tempest_lib.cli.output_parser -from tempest_lib import exceptions - - -LOG = logging.getLogger(__name__) - - -def execute(cmd, action, flags='', params='', fail_ok=False, - merge_stderr=False, cli_dir='/usr/bin'): - """Executes specified command for the given action. - - :param cmd: command to be executed - :type cmd: string - :param action: string of the cli command to run - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: string of any optional positional args to use - :type params: string - :param fail_ok: boolean if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param merge_stderr: boolean if True the stderr buffer is merged into - stdout - :type merge_stderr: boolean - :param cli_dir: The path where the cmd can be executed - :type cli_dir: string - """ - cmd = ' '.join([os.path.join(cli_dir, cmd), - flags, action, params]) - LOG.info("running: '%s'" % cmd) - if six.PY2: - cmd = cmd.encode('utf-8') - cmd = shlex.split(cmd) - result = '' - result_err = '' - stdout = subprocess.PIPE - stderr = subprocess.STDOUT if merge_stderr else subprocess.PIPE - proc = subprocess.Popen(cmd, stdout=stdout, stderr=stderr) - result, result_err = proc.communicate() - if not fail_ok and proc.returncode != 0: - raise exceptions.CommandFailed(proc.returncode, - cmd, - result, - result_err) - if six.PY2: - return result - else: - return os.fsdecode(result) - - -class CLIClient(object): - """Class to use OpenStack official python client CLI's with auth - - :param username: The username to authenticate with - :type username: string - :param password: The password to authenticate with - :type password: string - :param tenant_name: The name of the tenant to use with the client calls - :type tenant_name: string - :param uri: The auth uri for the OpenStack Deployment - :type uri: string - :param cli_dir: The path where the python client binaries are installed. - defaults to /usr/bin - :type cli_dir: string - :param insecure: if True, --insecure is passed to python client binaries. - :type insecure: boolean - """ - - def __init__(self, username='', password='', tenant_name='', uri='', - cli_dir='', insecure=False, *args, **kwargs): - """Initialize a new CLIClient object.""" - super(CLIClient, self).__init__() - self.cli_dir = cli_dir if cli_dir else '/usr/bin' - self.username = username - self.tenant_name = tenant_name - self.password = password - self.uri = uri - self.insecure = insecure - - def nova(self, action, flags='', params='', fail_ok=False, - endpoint_type='publicURL', merge_stderr=False): - """Executes nova command for the given action. - - :param action: the cli command to run using nova - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param endpoint_type: the type of endpoint for the service - :type endpoint_type: string - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - flags += ' --endpoint-type %s' % endpoint_type - return self.cmd_with_auth( - 'nova', action, flags, params, fail_ok, merge_stderr) - - def nova_manage(self, action, flags='', params='', fail_ok=False, - merge_stderr=False): - """Executes nova-manage command for the given action. - - :param action: the cli command to run using nova-manage - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - return execute( - 'nova-manage', action, flags, params, fail_ok, merge_stderr, - self.cli_dir) - - def keystone(self, action, flags='', params='', fail_ok=False, - merge_stderr=False): - """Executes keystone command for the given action. - - :param action: the cli command to run using keystone - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - return self.cmd_with_auth( - 'keystone', action, flags, params, fail_ok, merge_stderr) - - def glance(self, action, flags='', params='', fail_ok=False, - endpoint_type='publicURL', merge_stderr=False): - """Executes glance command for the given action. - - :param action: the cli command to run using glance - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param endpoint_type: the type of endpoint for the service - :type endpoint_type: string - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - flags += ' --os-endpoint-type %s' % endpoint_type - return self.cmd_with_auth( - 'glance', action, flags, params, fail_ok, merge_stderr) - - def ceilometer(self, action, flags='', params='', - fail_ok=False, endpoint_type='publicURL', - merge_stderr=False): - """Executes ceilometer command for the given action. - - :param action: the cli command to run using ceilometer - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param endpoint_type: the type of endpoint for the service - :type endpoint_type: string - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - flags += ' --os-endpoint-type %s' % endpoint_type - return self.cmd_with_auth( - 'ceilometer', action, flags, params, fail_ok, merge_stderr) - - def heat(self, action, flags='', params='', - fail_ok=False, endpoint_type='publicURL', merge_stderr=False): - """Executes heat command for the given action. - - :param action: the cli command to run using heat - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param endpoint_type: the type of endpoint for the service - :type endpoint_type: string - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - flags += ' --os-endpoint-type %s' % endpoint_type - return self.cmd_with_auth( - 'heat', action, flags, params, fail_ok, merge_stderr) - - def cinder(self, action, flags='', params='', fail_ok=False, - endpoint_type='publicURL', merge_stderr=False): - """Executes cinder command for the given action. - - :param action: the cli command to run using cinder - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param endpoint_type: the type of endpoint for the service - :type endpoint_type: string - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - flags += ' --endpoint-type %s' % endpoint_type - return self.cmd_with_auth( - 'cinder', action, flags, params, fail_ok, merge_stderr) - - def swift(self, action, flags='', params='', fail_ok=False, - endpoint_type='publicURL', merge_stderr=False): - """Executes swift command for the given action. - - :param action: the cli command to run using swift - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param endpoint_type: the type of endpoint for the service - :type endpoint_type: string - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - flags += ' --os-endpoint-type %s' % endpoint_type - return self.cmd_with_auth( - 'swift', action, flags, params, fail_ok, merge_stderr) - - def neutron(self, action, flags='', params='', fail_ok=False, - endpoint_type='publicURL', merge_stderr=False): - """Executes neutron command for the given action. - - :param action: the cli command to run using neutron - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param endpoint_type: the type of endpoint for the service - :type endpoint_type: string - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - flags += ' --endpoint-type %s' % endpoint_type - return self.cmd_with_auth( - 'neutron', action, flags, params, fail_ok, merge_stderr) - - def sahara(self, action, flags='', params='', - fail_ok=False, endpoint_type='publicURL', merge_stderr=True): - """Executes sahara command for the given action. - - :param action: the cli command to run using sahara - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param endpoint_type: the type of endpoint for the service - :type endpoint_type: string - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - flags += ' --endpoint-type %s' % endpoint_type - return self.cmd_with_auth( - 'sahara', action, flags, params, fail_ok, merge_stderr) - - def openstack(self, action, flags='', params='', fail_ok=False, - merge_stderr=False): - """Executes openstack command for the given action. - - :param action: the cli command to run using openstack - :type action: string - :param flags: any optional cli flags to use - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - return self.cmd_with_auth( - 'openstack', action, flags, params, fail_ok, merge_stderr) - - def cmd_with_auth(self, cmd, action, flags='', params='', - fail_ok=False, merge_stderr=False): - """Executes given command with auth attributes appended. - - :param cmd: command to be executed - :type cmd: string - :param action: command on cli to run - :type action: string - :param flags: optional cli flags to use - :type flags: string - :param params: optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the cli return - code is non-zero - :type fail_ok: boolean - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - """ - creds = ('--os-username %s --os-tenant-name %s --os-password %s ' - '--os-auth-url %s' % - (self.username, - self.tenant_name, - self.password, - self.uri)) - if self.insecure: - flags = creds + ' --insecure ' + flags - else: - flags = creds + ' ' + flags - return execute(cmd, action, flags, params, fail_ok, merge_stderr, - self.cli_dir) - - -class ClientTestBase(base.BaseTestCase): - """Base test class for testing the OpenStack client CLI interfaces.""" - - def setUp(self): - super(ClientTestBase, self).setUp() - self.clients = self._get_clients() - self.parser = tempest_lib.cli.output_parser - - def _get_clients(self): - """Abstract method to initialize CLIClient object. - - This method must be overloaded in child test classes. It should be - used to initialize the CLIClient object with the appropriate - credentials during the setUp() phase of tests. - """ - raise NotImplementedError - - def assertTableStruct(self, items, field_names): - """Verify that all items has keys listed in field_names. - - :param items: items to assert are field names in the output table - :type items: list - :param field_names: field names from the output table of the cmd - :type field_names: list - """ - for item in items: - for field in field_names: - self.assertIn(field, item) - - def assertFirstLineStartsWith(self, lines, beginning): - """Verify that the first line starts with a string - - :param lines: strings for each line of output - :type lines: list - :param beginning: verify this is at the beginning of the first line - :type beginning: string - """ - self.assertTrue(lines[0].startswith(beginning), - msg=('Beginning of first line has invalid content: %s' - % lines[:3])) diff --git a/tempest_lib/cli/output_parser.py b/tempest_lib/cli/output_parser.py deleted file mode 100644 index cdc5852..0000000 --- a/tempest_lib/cli/output_parser.py +++ /dev/null @@ -1,170 +0,0 @@ -# Copyright 2013 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. - -"""Collection of utilities for parsing CLI clients output.""" - -import logging -import re - -from tempest_lib import exceptions - - -LOG = logging.getLogger(__name__) - - -delimiter_line = re.compile('^\+\-[\+\-]+\-\+$') - - -def details_multiple(output_lines, with_label=False): - """Return list of dicts with item details from cli output tables. - - If with_label is True, key '__label' is added to each items dict. - For more about 'label' see OutputParser.tables(). - """ - items = [] - tables_ = tables(output_lines) - for table_ in tables_: - if ('Property' not in table_['headers'] - or 'Value' not in table_['headers']): - raise exceptions.InvalidStructure() - item = {} - for value in table_['values']: - item[value[0]] = value[1] - if with_label: - item['__label'] = table_['label'] - items.append(item) - return items - - -def details(output_lines, with_label=False): - """Return dict with details of first item (table) found in output.""" - items = details_multiple(output_lines, with_label) - return items[0] - - -def listing(output_lines): - """Return list of dicts with basic item info parsed from cli output.""" - - items = [] - table_ = table(output_lines) - for row in table_['values']: - item = {} - for col_idx, col_key in enumerate(table_['headers']): - item[col_key] = row[col_idx] - items.append(item) - return items - - -def tables(output_lines): - """Find all ascii-tables in output and parse them. - - Return list of tables parsed from cli output as dicts. - (see OutputParser.table()) - - And, if found, label key (separated line preceding the table) - is added to each tables dict. - """ - tables_ = [] - - table_ = [] - label = None - - start = False - header = False - - if not isinstance(output_lines, list): - output_lines = output_lines.split('\n') - - for line in output_lines: - if delimiter_line.match(line): - if not start: - start = True - elif not header: - # we are after head area - header = True - else: - # table ends here - start = header = None - table_.append(line) - - parsed = table(table_) - parsed['label'] = label - tables_.append(parsed) - - table_ = [] - label = None - continue - if start: - table_.append(line) - else: - if label is None: - label = line - else: - LOG.warning('Invalid line between tables: %s' % line) - if len(table_) > 0: - LOG.warning('Missing end of table') - - return tables_ - - -def table(output_lines): - """Parse single table from cli output. - - Return dict with list of column names in 'headers' key and - rows in 'values' key. - """ - table_ = {'headers': [], 'values': []} - columns = None - - if not isinstance(output_lines, list): - output_lines = output_lines.split('\n') - - if not output_lines[-1]: - # skip last line if empty (just newline at the end) - output_lines = output_lines[:-1] - - for line in output_lines: - if delimiter_line.match(line): - columns = _table_columns(line) - continue - if '|' not in line: - LOG.warning('skipping invalid table line: %s' % line) - continue - row = [] - for col in columns: - row.append(line[col[0]:col[1]].strip()) - if table_['headers']: - table_['values'].append(row) - else: - table_['headers'] = row - - return table_ - - -def _table_columns(first_table_row): - """Find column ranges in output line. - - Return list of tuples (start,end) for each column - detected by plus (+) characters in delimiter line. - """ - positions = [] - start = 1 # there is '+' at 0 - while start < len(first_table_row): - end = first_table_row.find('+', start) - if end == -1: - break - positions.append((start, end)) - start = end + 1 - return positions diff --git a/tempest_lib/cmd/__init__.py b/tempest_lib/cmd/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/cmd/check_uuid.py b/tempest_lib/cmd/check_uuid.py deleted file mode 100755 index 3adeecd..0000000 --- a/tempest_lib/cmd/check_uuid.py +++ /dev/null @@ -1,358 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2014 Mirantis, 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. - -import argparse -import ast -import importlib -import inspect -import os -import sys -import unittest -import uuid - -import six.moves.urllib.parse as urlparse - -DECORATOR_MODULE = 'test' -DECORATOR_NAME = 'idempotent_id' -DECORATOR_IMPORT = 'tempest.%s' % DECORATOR_MODULE -IMPORT_LINE = 'from tempest import %s' % DECORATOR_MODULE -DECORATOR_TEMPLATE = "@%s.%s('%%s')" % (DECORATOR_MODULE, - DECORATOR_NAME) -UNIT_TESTS_EXCLUDE = 'tempest.tests' - - -class SourcePatcher(object): - - """"Lazy patcher for python source files""" - - def __init__(self): - self.source_files = None - self.patches = None - self.clear() - - def clear(self): - """Clear inner state""" - self.source_files = {} - self.patches = {} - - @staticmethod - def _quote(s): - return urlparse.quote(s) - - @staticmethod - def _unquote(s): - return urlparse.unquote(s) - - def add_patch(self, filename, patch, line_no): - """Add lazy patch""" - if filename not in self.source_files: - with open(filename) as f: - self.source_files[filename] = self._quote(f.read()) - patch_id = str(uuid.uuid4()) - if not patch.endswith('\n'): - patch += '\n' - self.patches[patch_id] = self._quote(patch) - lines = self.source_files[filename].split(self._quote('\n')) - lines[line_no - 1] = ''.join(('{%s:s}' % patch_id, lines[line_no - 1])) - self.source_files[filename] = self._quote('\n').join(lines) - - def _save_changes(self, filename, source): - print('%s fixed' % filename) - with open(filename, 'w') as f: - f.write(source) - - def apply_patches(self): - """Apply all patches""" - for filename in self.source_files: - patched_source = self._unquote( - self.source_files[filename].format(**self.patches) - ) - self._save_changes(filename, patched_source) - self.clear() - - -class TestChecker(object): - - def __init__(self, package): - self.package = package - self.base_path = os.path.abspath(os.path.dirname(package.__file__)) - - def _path_to_package(self, path): - relative_path = path[len(self.base_path) + 1:] - if relative_path: - return '.'.join((self.package.__name__,) + - tuple(relative_path.split('/'))) - else: - return self.package.__name__ - - def _modules_search(self): - """Recursive search for python modules in base package""" - modules = [] - for root, dirs, files in os.walk(self.base_path): - if not os.path.exists(os.path.join(root, '__init__.py')): - continue - root_package = self._path_to_package(root) - for item in files: - if item.endswith('.py'): - module_name = '.'.join((root_package, - os.path.splitext(item)[0])) - if not module_name.startswith(UNIT_TESTS_EXCLUDE): - modules.append(module_name) - return modules - - @staticmethod - def _get_idempotent_id(test_node): - """Return key-value dict with all metadata from @test.idempotent_id""" - idempotent_id = None - for decorator in test_node.decorator_list: - if (hasattr(decorator, 'func') and - hasattr(decorator.func, 'attr') and - decorator.func.attr == DECORATOR_NAME and - hasattr(decorator.func, 'value') and - decorator.func.value.id == DECORATOR_MODULE): - for arg in decorator.args: - idempotent_id = ast.literal_eval(arg) - return idempotent_id - - @staticmethod - def _is_decorator(line): - return line.strip().startswith('@') - - @staticmethod - def _is_def(line): - return line.strip().startswith('def ') - - def _add_uuid_to_test(self, patcher, test_node, source_path): - with open(source_path) as src: - src_lines = src.read().split('\n') - lineno = test_node.lineno - insert_position = lineno - while True: - if (self._is_def(src_lines[lineno - 1]) or - (self._is_decorator(src_lines[lineno - 1]) and - (DECORATOR_TEMPLATE.split('(')[0] <= - src_lines[lineno - 1].strip().split('(')[0]))): - insert_position = lineno - break - lineno += 1 - patcher.add_patch( - source_path, - ' ' * test_node.col_offset + DECORATOR_TEMPLATE % uuid.uuid4(), - insert_position - ) - - @staticmethod - def _is_test_case(module, node): - if (node.__class__ is ast.ClassDef and - hasattr(module, node.name) and - inspect.isclass(getattr(module, node.name))): - return issubclass(getattr(module, node.name), unittest.TestCase) - - @staticmethod - def _is_test_method(node): - return (node.__class__ is ast.FunctionDef - and node.name.startswith('test_')) - - @staticmethod - def _next_node(body, node): - if body.index(node) < len(body): - return body[body.index(node) + 1] - - @staticmethod - def _import_name(node): - if type(node) == ast.Import: - return node.names[0].name - elif type(node) == ast.ImportFrom: - return '%s.%s' % (node.module, node.names[0].name) - - def _add_import_for_test_uuid(self, patcher, src_parsed, source_path): - with open(source_path) as f: - src_lines = f.read().split('\n') - line_no = 0 - tempest_imports = [node for node in src_parsed.body - if self._import_name(node) and - 'tempest.' in self._import_name(node)] - if not tempest_imports: - import_snippet = '\n'.join(('', IMPORT_LINE, '')) - else: - for node in tempest_imports: - if self._import_name(node) < DECORATOR_IMPORT: - continue - else: - line_no = node.lineno - import_snippet = IMPORT_LINE - break - else: - line_no = tempest_imports[-1].lineno - while True: - if (not src_lines[line_no - 1] or - getattr(self._next_node(src_parsed.body, - tempest_imports[-1]), - 'lineno') == line_no or - line_no == len(src_lines)): - break - line_no += 1 - import_snippet = '\n'.join((IMPORT_LINE, '')) - patcher.add_patch(source_path, import_snippet, line_no) - - def get_tests(self): - """Get test methods with sources from base package with metadata""" - tests = {} - for module_name in self._modules_search(): - tests[module_name] = {} - module = importlib.import_module(module_name) - source_path = '.'.join( - (os.path.splitext(module.__file__)[0], 'py') - ) - with open(source_path, 'r') as f: - source = f.read() - tests[module_name]['source_path'] = source_path - tests[module_name]['tests'] = {} - source_parsed = ast.parse(source) - tests[module_name]['ast'] = source_parsed - tests[module_name]['import_valid'] = ( - hasattr(module, DECORATOR_MODULE) and - inspect.ismodule(getattr(module, DECORATOR_MODULE)) - ) - test_cases = (node for node in source_parsed.body - if self._is_test_case(module, node)) - for node in test_cases: - for subnode in filter(self._is_test_method, node.body): - test_name = '%s.%s' % (node.name, subnode.name) - tests[module_name]['tests'][test_name] = subnode - return tests - - @staticmethod - def _filter_tests(function, tests): - """Filter tests with condition 'function(test_node) == True'""" - result = {} - for module_name in tests: - for test_name in tests[module_name]['tests']: - if function(module_name, test_name, tests): - if module_name not in result: - result[module_name] = { - 'ast': tests[module_name]['ast'], - 'source_path': tests[module_name]['source_path'], - 'import_valid': tests[module_name]['import_valid'], - 'tests': {} - } - result[module_name]['tests'][test_name] = \ - tests[module_name]['tests'][test_name] - return result - - def find_untagged(self, tests): - """Filter all tests without uuid in metadata""" - def check_uuid_in_meta(module_name, test_name, tests): - idempotent_id = self._get_idempotent_id( - tests[module_name]['tests'][test_name]) - return not idempotent_id - return self._filter_tests(check_uuid_in_meta, tests) - - def report_collisions(self, tests): - """Reports collisions if there are any - - Returns true if collisions exist. - """ - uuids = {} - - def report(module_name, test_name, tests): - test_uuid = self._get_idempotent_id( - tests[module_name]['tests'][test_name]) - if not test_uuid: - return - if test_uuid in uuids: - error_str = "%s:%s\n uuid %s collision: %s<->%s\n%s:%s" % ( - tests[module_name]['source_path'], - tests[module_name]['tests'][test_name].lineno, - test_uuid, - test_name, - uuids[test_uuid]['test_name'], - uuids[test_uuid]['source_path'], - uuids[test_uuid]['test_node'].lineno, - ) - print(error_str) - print("cannot automatically resolve the collision, please " - "manually remove the duplicate value on the new test.") - return True - else: - uuids[test_uuid] = { - 'module': module_name, - 'test_name': test_name, - 'test_node': tests[module_name]['tests'][test_name], - 'source_path': tests[module_name]['source_path'] - } - return bool(self._filter_tests(report, tests)) - - def report_untagged(self, tests): - """Reports untagged tests if there are any - - Returns true if untagged tests exist. - """ - def report(module_name, test_name, tests): - error_str = "%s:%s\nmissing @test.idempotent_id('...')\n%s\n" % ( - tests[module_name]['source_path'], - tests[module_name]['tests'][test_name].lineno, - test_name - ) - print(error_str) - return True - return bool(self._filter_tests(report, tests)) - - def fix_tests(self, tests): - """Add uuids to all specified in tests and fix it in source files""" - patcher = SourcePatcher() - for module_name in tests: - add_import_once = True - for test_name in tests[module_name]['tests']: - if not tests[module_name]['import_valid'] and add_import_once: - self._add_import_for_test_uuid( - patcher, - tests[module_name]['ast'], - tests[module_name]['source_path'] - ) - add_import_once = False - self._add_uuid_to_test( - patcher, tests[module_name]['tests'][test_name], - tests[module_name]['source_path']) - patcher.apply_patches() - - -def run(): - parser = argparse.ArgumentParser() - parser.add_argument('--package', action='store', dest='package', - default='tempest', type=str, - help='Package with tests') - parser.add_argument('--fix', action='store_true', dest='fix_tests', - help='Attempt to fix tests without UUIDs') - args = parser.parse_args() - sys.path.append(os.path.join(os.path.dirname(__file__), '..')) - pkg = importlib.import_module(args.package) - checker = TestChecker(pkg) - errors = False - tests = checker.get_tests() - untagged = checker.find_untagged(tests) - errors = checker.report_collisions(tests) or errors - if args.fix_tests and untagged: - checker.fix_tests(untagged) - else: - errors = checker.report_untagged(untagged) or errors - if errors: - sys.exit("@test.idempotent_id existence and uniqueness checks failed\n" - "Run 'tox -v -euuidgen' to automatically fix tests with\n" - "missing @test.idempotent_id decorators.") - -if __name__ == '__main__': - run() diff --git a/tempest_lib/cmd/skip_tracker.py b/tempest_lib/cmd/skip_tracker.py deleted file mode 100755 index b5c9b95..0000000 --- a/tempest_lib/cmd/skip_tracker.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env python2 - -# 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. - -""" -Track test skips via launchpadlib API and raise alerts if a bug -is fixed but a skip is still in the Tempest test code -""" - -import argparse -import logging -import os -import re - -try: - from launchpadlib import launchpad -except ImportError: - launchpad = None - -LPCACHEDIR = os.path.expanduser('~/.launchpadlib/cache') - - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument('test_path', help='Path of test dir') - return parser.parse_args() - - -def info(msg, *args, **kwargs): - logging.info(msg, *args, **kwargs) - - -def debug(msg, *args, **kwargs): - logging.debug(msg, *args, **kwargs) - - -def find_skips(start): - """Find the entire list of skiped tests. - - Returns a list of tuples (method, bug) that represent - test methods that have been decorated to skip because of - a particular bug. - """ - results = {} - debug("Searching in %s", start) - for root, _dirs, files in os.walk(start): - for name in files: - if name.startswith('test_') and name.endswith('py'): - path = os.path.join(root, name) - debug("Searching in %s", path) - temp_result = find_skips_in_file(path) - for method_name, bug_no in temp_result: - if results.get(bug_no): - result_dict = results.get(bug_no) - if result_dict.get(name): - result_dict[name].append(method_name) - else: - result_dict[name] = [method_name] - results[bug_no] = result_dict - else: - results[bug_no] = {name: [method_name]} - return results - - -def find_skips_in_file(path): - """Return the skip tuples in a test file.""" - BUG_RE = re.compile(r'\s*@.*skip_because\(bug=[\'"](\d+)[\'"]') - DEF_RE = re.compile(r'\s*def (\w+)\(') - bug_found = False - results = [] - lines = open(path, 'rb').readlines() - for x, line in enumerate(lines): - if not bug_found: - res = BUG_RE.match(line) - if res: - bug_no = int(res.group(1)) - debug("Found bug skip %s on line %d", bug_no, x + 1) - bug_found = True - else: - res = DEF_RE.match(line) - if res: - method = res.group(1) - debug("Found test method %s skips for bug %d", method, bug_no) - results.append((method, bug_no)) - bug_found = False - return results - - -def get_results(result_dict): - results = [] - for bug_no in result_dict.keys(): - for method in result_dict[bug_no]: - results.append((method, bug_no)) - return results - - -def main(): - logging.basicConfig(format='%(levelname)s: %(message)s', - level=logging.INFO) - parser = parse_args() - results = find_skips(parser.test_path) - unique_bugs = sorted(set([bug for (method, bug) in get_results(results)])) - unskips = [] - duplicates = [] - info("Total bug skips found: %d", len(results)) - info("Total unique bugs causing skips: %d", len(unique_bugs)) - if launchpad is not None: - lp = launchpad.Launchpad.login_anonymously('grabbing bugs', - 'production', - LPCACHEDIR) - else: - print("To check the bug status launchpadlib should be installed") - exit(1) - - for bug_no in unique_bugs: - bug = lp.bugs[bug_no] - duplicate = bug.duplicate_of_link - if duplicate is not None: - dup_id = duplicate.split('/')[-1] - duplicates.append((bug_no, dup_id)) - for task in bug.bug_tasks: - info("Bug #%7s (%12s - %12s)", bug_no, - task.importance, task.status) - if task.status in ('Fix Released', 'Fix Committed'): - unskips.append(bug_no) - - for bug_id, dup_id in duplicates: - if bug_id not in unskips: - dup_bug = lp.bugs[dup_id] - for task in dup_bug.bug_tasks: - info("Bug #%7s is a duplicate of Bug#%7s (%12s - %12s)", - bug_id, dup_id, task.importance, task.status) - if task.status in ('Fix Released', 'Fix Committed'): - unskips.append(bug_id) - - unskips = sorted(set(unskips)) - if unskips: - print("The following bugs have been fixed and the corresponding skips") - print("should be removed from the test cases:") - print() - for bug in unskips: - message = " %7s in " % bug - locations = ["%s" % x for x in results[bug].keys()] - message += " and ".join(locations) - print(message) - - -if __name__ == '__main__': - main() diff --git a/tempest_lib/common/__init__.py b/tempest_lib/common/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/common/http.py b/tempest_lib/common/http.py deleted file mode 100644 index b3793bc..0000000 --- a/tempest_lib/common/http.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# Copyright 2013 Citrix Systems, Inc. -# 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 httplib2 - - -class ClosingHttp(httplib2.Http): - def request(self, *args, **kwargs): - original_headers = kwargs.get('headers', {}) - new_headers = dict(original_headers, connection='close') - new_kwargs = dict(kwargs, headers=new_headers) - return super(ClosingHttp, self).request(*args, **new_kwargs) diff --git a/tempest_lib/common/rest_client.py b/tempest_lib/common/rest_client.py deleted file mode 100644 index c5886e6..0000000 --- a/tempest_lib/common/rest_client.py +++ /dev/null @@ -1,894 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# Copyright 2013 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 collections -import logging as real_logging -import re -import time - -import jsonschema -from oslo_log import log as logging -from oslo_serialization import jsonutils as json -import six - -from tempest_lib.common import http -from tempest_lib.common.utils import misc as misc_utils -from tempest_lib import exceptions - -# redrive rate limited calls at most twice -MAX_RECURSION_DEPTH = 2 - -# All the successful HTTP status codes from RFC 7231 & 4918 -HTTP_SUCCESS = (200, 201, 202, 203, 204, 205, 206, 207) - -# All the redirection HTTP status codes from RFC 7231 & 4918 -HTTP_REDIRECTION = (300, 301, 302, 303, 304, 305, 306, 307) - -# JSON Schema validator and format checker used for JSON Schema validation -JSONSCHEMA_VALIDATOR = jsonschema.Draft4Validator -FORMAT_CHECKER = jsonschema.draft4_format_checker - - -class RestClient(object): - """Unified OpenStack RestClient class - - This class is used for building openstack api clients on top of. It is - intended to provide a base layer for wrapping outgoing http requests in - keystone auth as well as providing response code checking and error - handling. - - :param auth_provider: an auth provider object used to wrap requests in auth - :param str service: The service name to use for the catalog lookup - :param str region: The region to use for the catalog lookup - :param str endpoint_type: The endpoint type to use for the catalog lookup - :param int build_interval: Time in seconds between to status checks in - wait loops - :param int build_timeout: Timeout in seconds to wait for a wait operation. - :param bool disable_ssl_certificate_validation: Set to true to disable ssl - certificate validation - :param str ca_certs: File containing the CA Bundle to use in verifying a - TLS server cert - :param str trace_request: Regex to use for specifying logging the entirety - of the request and response payload - """ - TYPE = "json" - - # The version of the API this client implements - api_version = None - - LOG = logging.getLogger(__name__) - - def __init__(self, auth_provider, service, region, - endpoint_type='publicURL', - build_interval=1, build_timeout=60, - disable_ssl_certificate_validation=False, ca_certs=None, - trace_requests=''): - self.auth_provider = auth_provider - self.service = service - self.region = region - self.endpoint_type = endpoint_type - self.build_interval = build_interval - self.build_timeout = build_timeout - self.trace_requests = trace_requests - - self._skip_path = False - self.general_header_lc = set(('cache-control', 'connection', - 'date', 'pragma', 'trailer', - 'transfer-encoding', 'via', - 'warning')) - self.response_header_lc = set(('accept-ranges', 'age', 'etag', - 'location', 'proxy-authenticate', - 'retry-after', 'server', - 'vary', 'www-authenticate')) - dscv = disable_ssl_certificate_validation - self.http_obj = http.ClosingHttp( - disable_ssl_certificate_validation=dscv, ca_certs=ca_certs) - - def _get_type(self): - return self.TYPE - - def get_headers(self, accept_type=None, send_type=None): - """Return the default headers which will be used with outgoing requests - - :param str accept_type: The media type to use for the Accept header, if - one isn't provided the object var TYPE will be - used - :param str send_type: The media-type to use for the Content-Type - header, if one isn't provided the object var - TYPE will be used - :rtype: dict - :return: The dictionary of headers which can be used in the headers - dict for outgoing request - """ - if accept_type is None: - accept_type = self._get_type() - if send_type is None: - send_type = self._get_type() - return {'Content-Type': 'application/%s' % send_type, - 'Accept': 'application/%s' % accept_type} - - def __str__(self): - STRING_LIMIT = 80 - str_format = ("service:%s, base_url:%s, " - "filters: %s, build_interval:%s, build_timeout:%s" - "\ntoken:%s..., \nheaders:%s...") - return str_format % (self.service, self.base_url, - self.filters, self.build_interval, - self.build_timeout, - str(self.token)[0:STRING_LIMIT], - str(self.get_headers())[0:STRING_LIMIT]) - - @property - def user(self): - """The username used for requests - - :rtype: string - :return: The username being used for requests - """ - - return self.auth_provider.credentials.username - - @property - def user_id(self): - """The user_id used for requests - - :rtype: string - :return: The user id being used for requests - """ - return self.auth_provider.credentials.user_id - - @property - def tenant_name(self): - """The tenant/project being used for requests - - :rtype: string - :return: The tenant/project name being used for requests - """ - return self.auth_provider.credentials.tenant_name - - @property - def tenant_id(self): - """The tenant/project id being used for requests - - :rtype: string - :return: The tenant/project id being used for requests - """ - return self.auth_provider.credentials.tenant_id - - @property - def password(self): - """The password being used for requests - - :rtype: string - :return: The password being used for requests - """ - return self.auth_provider.credentials.password - - @property - def base_url(self): - return self.auth_provider.base_url(filters=self.filters) - - @property - def token(self): - return self.auth_provider.get_token() - - @property - def filters(self): - _filters = dict( - service=self.service, - endpoint_type=self.endpoint_type, - region=self.region - ) - if self.api_version is not None: - _filters['api_version'] = self.api_version - if self._skip_path: - _filters['skip_path'] = self._skip_path - return _filters - - def skip_path(self): - """When set, ignore the path part of the base URL from the catalog""" - self._skip_path = True - - def reset_path(self): - """When reset, use the base URL from the catalog as-is""" - self._skip_path = False - - @classmethod - def expected_success(cls, expected_code, read_code): - """Check expected success response code against the http response - - :param int expected_code: The response code that is expected. - Optionally a list of integers can be used - to specify multiple valid success codes - :param int read_code: The response code which was returned in the - response - :raises AssertionError: if the expected_code isn't a valid http success - response code - :raises exceptions.InvalidHttpSuccessCode: if the read code isn't an - expected http success code - """ - assert_msg = ("This function only allowed to use for HTTP status" - "codes which explicitly defined in the RFC 7231 & 4918." - "{0} is not a defined Success Code!" - ).format(expected_code) - if isinstance(expected_code, list): - for code in expected_code: - assert code in HTTP_SUCCESS + HTTP_REDIRECTION, assert_msg - else: - assert expected_code in HTTP_SUCCESS + HTTP_REDIRECTION, assert_msg - - # NOTE(afazekas): the http status code above 400 is processed by - # the _error_checker method - if read_code < 400: - pattern = """Unexpected http success status code {0}, - The expected status code is {1}""" - if ((not isinstance(expected_code, list) and - (read_code != expected_code)) or - (isinstance(expected_code, list) and - (read_code not in expected_code))): - details = pattern.format(read_code, expected_code) - raise exceptions.InvalidHttpSuccessCode(details) - - def post(self, url, body, headers=None, extra_headers=False): - """Send a HTTP POST request using keystone auth - - :param str url: the relative url to send the post request to - :param dict body: the request body - :param dict headers: The headers to use for the request - :param dict extra_headers: If the headers returned by the get_headers() - method are to be used but additional headers - are needed in the request pass them in as a - dict - :return: a tuple with the first entry containing the response headers - and the second the response body - :rtype: tuple - """ - return self.request('POST', url, extra_headers, headers, body) - - def get(self, url, headers=None, extra_headers=False): - """Send a HTTP GET request using keystone service catalog and auth - - :param str url: the relative url to send the post request to - :param dict headers: The headers to use for the request - :param dict extra_headers: If the headers returned by the get_headers() - method are to be used but additional headers - are needed in the request pass them in as a - dict - :return: a tuple with the first entry containing the response headers - and the second the response body - :rtype: tuple - """ - return self.request('GET', url, extra_headers, headers) - - def delete(self, url, headers=None, body=None, extra_headers=False): - """Send a HTTP DELETE request using keystone service catalog and auth - - :param str url: the relative url to send the post request to - :param dict headers: The headers to use for the request - :param dict body: the request body - :param dict extra_headers: If the headers returned by the get_headers() - method are to be used but additional headers - are needed in the request pass them in as a - dict - :return: a tuple with the first entry containing the response headers - and the second the response body - :rtype: tuple - """ - return self.request('DELETE', url, extra_headers, headers, body) - - def patch(self, url, body, headers=None, extra_headers=False): - """Send a HTTP PATCH request using keystone service catalog and auth - - :param str url: the relative url to send the post request to - :param dict body: the request body - :param dict headers: The headers to use for the request - :param dict extra_headers: If the headers returned by the get_headers() - method are to be used but additional headers - are needed in the request pass them in as a - dict - :return: a tuple with the first entry containing the response headers - and the second the response body - :rtype: tuple - """ - return self.request('PATCH', url, extra_headers, headers, body) - - def put(self, url, body, headers=None, extra_headers=False): - """Send a HTTP PUT request using keystone service catalog and auth - - :param str url: the relative url to send the post request to - :param dict body: the request body - :param dict headers: The headers to use for the request - :param dict extra_headers: If the headers returned by the get_headers() - method are to be used but additional headers - are needed in the request pass them in as a - dict - :return: a tuple with the first entry containing the response headers - and the second the response body - :rtype: tuple - """ - return self.request('PUT', url, extra_headers, headers, body) - - def head(self, url, headers=None, extra_headers=False): - """Send a HTTP HEAD request using keystone service catalog and auth - - :param str url: the relative url to send the post request to - :param dict headers: The headers to use for the request - :param dict extra_headers: If the headers returned by the get_headers() - method are to be used but additional headers - are needed in the request pass them in as a - dict - :return: a tuple with the first entry containing the response headers - and the second the response body - :rtype: tuple - """ - return self.request('HEAD', url, extra_headers, headers) - - def copy(self, url, headers=None, extra_headers=False): - """Send a HTTP COPY request using keystone service catalog and auth - - :param str url: the relative url to send the post request to - :param dict headers: The headers to use for the request - :param dict extra_headers: If the headers returned by the get_headers() - method are to be used but additional headers - are needed in the request pass them in as a - dict - :return: a tuple with the first entry containing the response headers - and the second the response body - :rtype: tuple - """ - return self.request('COPY', url, extra_headers, headers) - - def get_versions(self): - """Get the versions on a endpoint from the keystone catalog - - This method will make a GET request on the baseurl from the keystone - catalog to return a list of API versions. It is expected that a GET - on the endpoint in the catalog will return a list of supported API - versions. - - :return tuple with response headers and list of version numbers - :rtype: tuple - """ - resp, body = self.get('') - body = self._parse_resp(body) - versions = map(lambda x: x['id'], body) - return resp, versions - - def _get_request_id(self, resp): - for i in ('x-openstack-request-id', 'x-compute-request-id'): - if i in resp: - return resp[i] - return "" - - def _safe_body(self, body, maxlen=4096): - # convert a structure into a string safely - try: - text = six.text_type(body) - except UnicodeDecodeError: - # if this isn't actually text, return marker that - return "" - if len(text) > maxlen: - return text[:maxlen] - else: - return text - - def _log_request_start(self, method, req_url, req_headers=None, - req_body=None): - if req_headers is None: - req_headers = {} - caller_name = misc_utils.find_test_caller() - if self.trace_requests and re.search(self.trace_requests, caller_name): - self.LOG.debug('Starting Request (%s): %s %s' % - (caller_name, method, req_url)) - - def _log_request_full(self, method, req_url, resp, - secs="", req_headers=None, - req_body=None, resp_body=None, - caller_name=None, extra=None): - if 'X-Auth-Token' in req_headers: - req_headers['X-Auth-Token'] = '' - log_fmt = """Request - Headers: %s - Body: %s - Response - Headers: %s - Body: %s""" - - self.LOG.debug( - log_fmt % ( - str(req_headers), - self._safe_body(req_body), - str(resp), - self._safe_body(resp_body)), - extra=extra) - - def _log_request(self, method, req_url, resp, - secs="", req_headers=None, - req_body=None, resp_body=None): - if req_headers is None: - req_headers = {} - # if we have the request id, put it in the right part of the log - extra = dict(request_id=self._get_request_id(resp)) - # NOTE(sdague): while we still have 6 callers to this function - # we're going to just provide work around on who is actually - # providing timings by gracefully adding no content if they don't. - # Once we're down to 1 caller, clean this up. - caller_name = misc_utils.find_test_caller() - if secs: - secs = " %.3fs" % secs - self.LOG.info( - 'Request (%s): %s %s %s%s' % ( - caller_name, - resp['status'], - method, - req_url, - secs), - extra=extra) - - # Also look everything at DEBUG if you want to filter this - # out, don't run at debug. - if self.LOG.isEnabledFor(real_logging.DEBUG): - self._log_request_full(method, req_url, resp, secs, req_headers, - req_body, resp_body, caller_name, extra) - - def _parse_resp(self, body): - try: - body = json.loads(body) - except ValueError: - return body - - # We assume, that if the first value of the deserialized body's - # item set is a dict or a list, that we just return the first value - # of deserialized body. - # Essentially "cutting out" the first placeholder element in a body - # that looks like this: - # - # { - # "users": [ - # ... - # ] - # } - try: - # Ensure there are not more than one top-level keys - # NOTE(freerunner): Ensure, that JSON is not nullable to - # to prevent StopIteration Exception - if len(body.keys()) != 1: - return body - # Just return the "wrapped" element - first_key, first_item = six.next(six.iteritems(body)) - if isinstance(first_item, (dict, list)): - return first_item - except (ValueError, IndexError): - pass - return body - - def response_checker(self, method, resp, resp_body): - """A sanity check on the response from a HTTP request - - This method does a sanity check on whether the response from an HTTP - request conforms the HTTP RFC. - - :param str method: The HTTP verb of the request associated with the - response being passed in. - :param resp: The response headers - :param resp_body: The body of the response - :raises ResponseWithNonEmptyBody: If the response with the status code - is not supposed to have a body - :raises ResponseWithEntity: If the response code is 205 but has an - entity - """ - if (resp.status in set((204, 205, 304)) or resp.status < 200 or - method.upper() == 'HEAD') and resp_body: - raise exceptions.ResponseWithNonEmptyBody(status=resp.status) - # NOTE(afazekas): - # If the HTTP Status Code is 205 - # 'The response MUST NOT include an entity.' - # A HTTP entity has an entity-body and an 'entity-header'. - # In the HTTP response specification (Section 6) the 'entity-header' - # 'generic-header' and 'response-header' are in OR relation. - # All headers not in the above two group are considered as entity - # header in every interpretation. - - if (resp.status == 205 and - 0 != len(set(resp.keys()) - set(('status',)) - - self.response_header_lc - self.general_header_lc)): - raise exceptions.ResponseWithEntity() - # NOTE(afazekas) - # Now the swift sometimes (delete not empty container) - # returns with non json error response, we can create new rest class - # for swift. - # Usually RFC2616 says error responses SHOULD contain an explanation. - # The warning is normal for SHOULD/SHOULD NOT case - - # Likely it will cause an error - if method != 'HEAD' and not resp_body and resp.status >= 400: - self.LOG.warning("status >= 400 response with empty body") - - def _request(self, method, url, headers=None, body=None): - """A simple HTTP request interface.""" - # Authenticate the request with the auth provider - req_url, req_headers, req_body = self.auth_provider.auth_request( - method, url, headers, body, self.filters) - - # Do the actual request, and time it - start = time.time() - self._log_request_start(method, req_url) - resp, resp_body = self.raw_request( - req_url, method, headers=req_headers, body=req_body) - end = time.time() - self._log_request(method, req_url, resp, secs=(end - start), - req_headers=req_headers, req_body=req_body, - resp_body=resp_body) - - # Verify HTTP response codes - self.response_checker(method, resp, resp_body) - - return resp, resp_body - - def raw_request(self, url, method, headers=None, body=None): - """Send a raw HTTP request without the keystone catalog or auth - - This method sends a HTTP request in the same manner as the request() - method, however it does so without using keystone auth or the catalog - to determine the base url. Additionally no response handling is done - the results from the request are just returned. - - :param str url: Full url to send the request - :param str method: The HTTP verb to use for the request - :param str headers: Headers to use for the request if none are specifed - the headers - :param str body: Body to to send with the request - :rtype: tuple - :return: a tuple with the first entry containing the response headers - and the second the response body - """ - if headers is None: - headers = self.get_headers() - return self.http_obj.request(url, method, - headers=headers, body=body) - - def request(self, method, url, extra_headers=False, headers=None, - body=None): - """Send a HTTP request with keystone auth and using the catalog - - This method will send an HTTP request using keystone auth in the - headers and the catalog to determine the endpoint to use for the - baseurl to send the request to. Additionally - - When a response is received it will check it to see if an error - response was received. If it was an exception will be raised to enable - it to be handled quickly. - - This method will also handle rate-limiting, if a 413 response code is - received it will retry the request after waiting the 'retry-after' - duration from the header. - - :param str method: The HTTP verb to use for the request - :param str url: Relative url to send the request to - :param dict extra_headers: If specified without the headers kwarg the - headers sent with the request will be the - combination from the get_headers() method - and this kwarg - :param dict headers: Headers to use for the request if none are - specifed the headers returned from the - get_headers() method are used. If the request - explicitly requires no headers use an empty dict. - :param str body: Body to to send with the request - :rtype: tuple - :return: a tuple with the first entry containing the response headers - and the second the response body - :raises UnexpectedContentType: If the content-type of the response - isn't an expect type - :raises Unauthorized: If a 401 response code is received - :raises Forbidden: If a 403 response code is received - :raises NotFound: If a 404 response code is received - :raises BadRequest: If a 400 response code is received - :raises Gone: If a 410 response code is received - :raises Conflict: If a 409 response code is received - :raises OverLimit: If a 413 response code is received and over_limit is - not in the response body - :raises RateLimitExceeded: If a 413 response code is received and - over_limit is in the response body - :raises InvalidContentType: If a 415 response code is received - :raises UnprocessableEntity: If a 422 response code is received - :raises InvalidHTTPResponseBody: The response body wasn't valid JSON - and couldn't be parsed - :raises NotImplemented: If a 501 response code is received - :raises ServerFault: If a 500 response code is received - :raises UnexpectedResponseCode: If a response code above 400 is - received and it doesn't fall into any - of the handled checks - """ - # if extra_headers is True - # default headers would be added to headers - retry = 0 - - if headers is None: - # NOTE(vponomaryov): if some client do not need headers, - # it should explicitly pass empty dict - headers = self.get_headers() - elif extra_headers: - try: - headers = headers.copy() - headers.update(self.get_headers()) - except (ValueError, TypeError): - headers = self.get_headers() - - resp, resp_body = self._request(method, url, - headers=headers, body=body) - - while (resp.status == 413 and - 'retry-after' in resp and - not self.is_absolute_limit( - resp, self._parse_resp(resp_body)) and - retry < MAX_RECURSION_DEPTH): - retry += 1 - delay = int(resp['retry-after']) - time.sleep(delay) - resp, resp_body = self._request(method, url, - headers=headers, body=body) - self._error_checker(method, url, headers, body, - resp, resp_body) - return resp, resp_body - - def _error_checker(self, method, url, - headers, body, resp, resp_body): - - # NOTE(mtreinish): Check for httplib response from glance_http. The - # object can't be used here because importing httplib breaks httplib2. - # If another object from a class not imported were passed here as - # resp this could possibly fail - if str(type(resp)) == "": - ctype = resp.getheader('content-type') - else: - try: - ctype = resp['content-type'] - # NOTE(mtreinish): Keystone delete user responses doesn't have a - # content-type header. (They don't have a body) So just pretend it - # is set. - except KeyError: - ctype = 'application/json' - - # It is not an error response - if resp.status < 400: - return - - JSON_ENC = ['application/json', 'application/json; charset=utf-8'] - # NOTE(mtreinish): This is for compatibility with Glance and swift - # APIs. These are the return content types that Glance api v1 - # (and occasionally swift) are using. - TXT_ENC = ['text/plain', 'text/html', 'text/html; charset=utf-8', - 'text/plain; charset=utf-8'] - - if ctype.lower() in JSON_ENC: - parse_resp = True - elif ctype.lower() in TXT_ENC: - parse_resp = False - else: - raise exceptions.UnexpectedContentType(str(resp.status), - resp=resp) - - if resp.status == 401: - if parse_resp: - resp_body = self._parse_resp(resp_body) - raise exceptions.Unauthorized(resp_body, resp=resp) - - if resp.status == 403: - if parse_resp: - resp_body = self._parse_resp(resp_body) - raise exceptions.Forbidden(resp_body, resp=resp) - - if resp.status == 404: - if parse_resp: - resp_body = self._parse_resp(resp_body) - raise exceptions.NotFound(resp_body, resp=resp) - - if resp.status == 400: - if parse_resp: - resp_body = self._parse_resp(resp_body) - raise exceptions.BadRequest(resp_body, resp=resp) - - if resp.status == 410: - if parse_resp: - resp_body = self._parse_resp(resp_body) - raise exceptions.Gone(resp_body, resp=resp) - - if resp.status == 409: - if parse_resp: - resp_body = self._parse_resp(resp_body) - raise exceptions.Conflict(resp_body, resp=resp) - - if resp.status == 413: - if parse_resp: - resp_body = self._parse_resp(resp_body) - if self.is_absolute_limit(resp, resp_body): - raise exceptions.OverLimit(resp_body, resp=resp) - else: - raise exceptions.RateLimitExceeded(resp_body, resp=resp) - - if resp.status == 415: - if parse_resp: - resp_body = self._parse_resp(resp_body) - raise exceptions.InvalidContentType(resp_body, resp=resp) - - if resp.status == 422: - if parse_resp: - resp_body = self._parse_resp(resp_body) - raise exceptions.UnprocessableEntity(resp_body, resp=resp) - - if resp.status in (500, 501): - message = resp_body - if parse_resp: - try: - resp_body = self._parse_resp(resp_body) - except ValueError: - # If response body is a non-json string message. - # Use resp_body as is and raise InvalidResponseBody - # exception. - raise exceptions.InvalidHTTPResponseBody(message) - else: - if isinstance(resp_body, dict): - # I'm seeing both computeFault - # and cloudServersFault come back. - # Will file a bug to fix, but leave as is for now. - if 'cloudServersFault' in resp_body: - message = resp_body['cloudServersFault']['message'] - elif 'computeFault' in resp_body: - message = resp_body['computeFault']['message'] - elif 'error' in resp_body: - message = resp_body['error']['message'] - elif 'message' in resp_body: - message = resp_body['message'] - else: - message = resp_body - - if resp.status == 501: - raise exceptions.NotImplemented(resp_body, resp=resp, - message=message) - else: - raise exceptions.ServerFault(resp_body, resp=resp, - message=message) - - if resp.status >= 400: - raise exceptions.UnexpectedResponseCode(str(resp.status), - resp=resp) - - def is_absolute_limit(self, resp, resp_body): - if (not isinstance(resp_body, collections.Mapping) or - 'retry-after' not in resp): - return True - over_limit = resp_body.get('overLimit', None) - if not over_limit: - return True - return 'exceed' in over_limit.get('message', 'blabla') - - def wait_for_resource_deletion(self, id): - """Waits for a resource to be deleted - - This method will loop over is_resource_deleted until either - is_resource_deleted returns True or the build timeout is reached. This - depends on is_resource_deleted being implemented - - :param str id: The id of the resource to check - :raises TimeoutException: If the build_timeout has elapsed and the - resource still hasn't been deleted - """ - start_time = int(time.time()) - while True: - if self.is_resource_deleted(id): - return - if int(time.time()) - start_time >= self.build_timeout: - message = ('Failed to delete %(resource_type)s %(id)s within ' - 'the required time (%(timeout)s s).' % - {'resource_type': self.resource_type, 'id': id, - 'timeout': self.build_timeout}) - caller = misc_utils.find_test_caller() - if caller: - message = '(%s) %s' % (caller, message) - raise exceptions.TimeoutException(message) - time.sleep(self.build_interval) - - def is_resource_deleted(self, id): - """Subclasses override with specific deletion detection.""" - message = ('"%s" does not implement is_resource_deleted' - % self.__class__.__name__) - raise NotImplementedError(message) - - @property - def resource_type(self): - """Returns the primary type of resource this client works with.""" - return 'resource' - - @classmethod - def validate_response(cls, schema, resp, body): - # Only check the response if the status code is a success code - # TODO(cyeoh): Eventually we should be able to verify that a failure - # code if it exists is something that we expect. This is explicitly - # declared in the V3 API and so we should be able to export this in - # the response schema. For now we'll ignore it. - if resp.status in HTTP_SUCCESS + HTTP_REDIRECTION: - cls.expected_success(schema['status_code'], resp.status) - - # Check the body of a response - body_schema = schema.get('response_body') - if body_schema: - try: - jsonschema.validate(body, body_schema, - cls=JSONSCHEMA_VALIDATOR, - format_checker=FORMAT_CHECKER) - except jsonschema.ValidationError as ex: - msg = ("HTTP response body is invalid (%s)") % ex - raise exceptions.InvalidHTTPResponseBody(msg) - else: - if body: - msg = ("HTTP response body should not exist (%s)") % body - raise exceptions.InvalidHTTPResponseBody(msg) - - # Check the header of a response - header_schema = schema.get('response_header') - if header_schema: - try: - jsonschema.validate(resp, header_schema, - cls=JSONSCHEMA_VALIDATOR, - format_checker=FORMAT_CHECKER) - except jsonschema.ValidationError as ex: - msg = ("HTTP response header is invalid (%s)") % ex - raise exceptions.InvalidHTTPResponseHeader(msg) - - -class ResponseBody(dict): - """Class that wraps an http response and dict body into a single value. - - Callers that receive this object will normally use it as a dict but - can extract the response if needed. - """ - - def __init__(self, response, body=None): - body_data = body or {} - self.update(body_data) - self.response = response - - def __str__(self): - body = super(ResponseBody, self).__str__() - return "response: %s\nBody: %s" % (self.response, body) - - -class ResponseBodyData(object): - """Class that wraps an http response and string data into a single value. - - """ - - def __init__(self, response, data): - self.response = response - self.data = data - - def __str__(self): - return "response: %s\nBody: %s" % (self.response, self.data) - - -class ResponseBodyList(list): - """Class that wraps an http response and list body into a single value. - - Callers that receive this object will normally use it as a list but - can extract the response if needed. - """ - - def __init__(self, response, body=None): - body_data = body or [] - self.extend(body_data) - self.response = response - - def __str__(self): - body = super(ResponseBodyList, self).__str__() - return "response: %s\nBody: %s" % (self.response, body) diff --git a/tempest_lib/common/ssh.py b/tempest_lib/common/ssh.py deleted file mode 100644 index e55d359..0000000 --- a/tempest_lib/common/ssh.py +++ /dev/null @@ -1,174 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -import select -import socket -import time -import warnings - -from oslo_log import log as logging -import six - -from tempest_lib import exceptions - - -with warnings.catch_warnings(): - warnings.simplefilter("ignore") - import paramiko - - -LOG = logging.getLogger(__name__) - - -class Client(object): - - def __init__(self, host, username, password=None, timeout=300, pkey=None, - channel_timeout=10, look_for_keys=False, key_filename=None): - self.host = host - self.username = username - self.password = password - if isinstance(pkey, six.string_types): - pkey = paramiko.RSAKey.from_private_key( - six.StringIO(str(pkey))) - self.pkey = pkey - self.look_for_keys = look_for_keys - self.key_filename = key_filename - self.timeout = int(timeout) - self.channel_timeout = float(channel_timeout) - self.buf_size = 1024 - - def _get_ssh_connection(self, sleep=1.5, backoff=1): - """Returns an ssh connection to the specified host.""" - bsleep = sleep - ssh = paramiko.SSHClient() - ssh.set_missing_host_key_policy( - paramiko.AutoAddPolicy()) - _start_time = time.time() - if self.pkey is not None: - LOG.info("Creating ssh connection to '%s' as '%s'" - " with public key authentication", - self.host, self.username) - else: - LOG.info("Creating ssh connection to '%s' as '%s'" - " with password %s", - self.host, self.username, str(self.password)) - attempts = 0 - while True: - try: - ssh.connect(self.host, username=self.username, - password=self.password, - look_for_keys=self.look_for_keys, - key_filename=self.key_filename, - timeout=self.channel_timeout, pkey=self.pkey) - LOG.info("ssh connection to %s@%s successfully created", - self.username, self.host) - return ssh - except (EOFError, - socket.error, - paramiko.SSHException) as e: - if self._is_timed_out(_start_time): - LOG.exception("Failed to establish authenticated ssh" - " connection to %s@%s after %d attempts", - self.username, self.host, attempts) - raise exceptions.SSHTimeout(host=self.host, - user=self.username, - password=self.password) - bsleep += backoff - attempts += 1 - LOG.warning("Failed to establish authenticated ssh" - " connection to %s@%s (%s). Number attempts: %s." - " Retry after %d seconds.", - self.username, self.host, e, attempts, bsleep) - time.sleep(bsleep) - - def _is_timed_out(self, start_time): - return (time.time() - self.timeout) > start_time - - @staticmethod - def _can_system_poll(): - return hasattr(select, 'poll') - - def exec_command(self, cmd, encoding="utf-8"): - """Execute the specified command on the server - - Note that this method is reading whole command outputs to memory, thus - shouldn't be used for large outputs. - - :param str cmd: Command to run at remote server. - :param str encoding: Encoding for result from paramiko. - Result will not be decoded if None. - :returns: data read from standard output of the command. - :raises: SSHExecCommandFailed if command returns nonzero - status. The exception contains command status stderr content. - :raises: TimeoutException if cmd doesn't end when timeout expires. - """ - ssh = self._get_ssh_connection() - transport = ssh.get_transport() - channel = transport.open_session() - channel.fileno() # Register event pipe - channel.exec_command(cmd) - channel.shutdown_write() - exit_status = channel.recv_exit_status() - - # If the executing host is linux-based, poll the channel - if self._can_system_poll(): - out_data_chunks = [] - err_data_chunks = [] - poll = select.poll() - poll.register(channel, select.POLLIN) - start_time = time.time() - - while True: - ready = poll.poll(self.channel_timeout) - if not any(ready): - if not self._is_timed_out(start_time): - continue - raise exceptions.TimeoutException( - "Command: '{0}' executed on host '{1}'.".format( - cmd, self.host)) - if not ready[0]: # If there is nothing to read. - continue - out_chunk = err_chunk = None - if channel.recv_ready(): - out_chunk = channel.recv(self.buf_size) - out_data_chunks += out_chunk, - if channel.recv_stderr_ready(): - err_chunk = channel.recv_stderr(self.buf_size) - err_data_chunks += err_chunk, - if channel.closed and not err_chunk and not out_chunk: - break - out_data = b''.join(out_data_chunks) - err_data = b''.join(err_data_chunks) - # Just read from the channels - else: - out_file = channel.makefile('rb', self.buf_size) - err_file = channel.makefile_stderr('rb', self.buf_size) - out_data = out_file.read() - err_data = err_file.read() - if encoding: - out_data = out_data.decode(encoding) - err_data = err_data.decode(encoding) - - if 0 != exit_status: - raise exceptions.SSHExecCommandFailed( - command=cmd, exit_status=exit_status, - stderr=err_data, stdout=out_data) - return out_data - - def test_connection_auth(self): - """Raises an exception when we can not connect to server via ssh.""" - connection = self._get_ssh_connection() - connection.close() diff --git a/tempest_lib/common/utils/__init__.py b/tempest_lib/common/utils/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/common/utils/data_utils.py b/tempest_lib/common/utils/data_utils.py deleted file mode 100644 index 01b6477..0000000 --- a/tempest_lib/common/utils/data_utils.py +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import itertools -import netaddr -import random -import string -import uuid - - -def rand_uuid(): - """Generate a random UUID string - - :return: a random UUID (e.g. '1dc12c7d-60eb-4b61-a7a2-17cf210155b6') - :rtype: string - """ - return str(uuid.uuid4()) - - -def rand_uuid_hex(): - """Generate a random UUID hex string - - :return: a random UUID (e.g. '0b98cf96d90447bda4b46f31aeb1508c') - :rtype: string - """ - return uuid.uuid4().hex - - -def rand_name(name='', prefix=None): - """Generate a random name that inclues a random number - - :param str name: The name that you want to include - :param str prefix: The prefix that you want to include - :return: a random name. The format is - '---'. - (e.g. 'prefixfoo-1308607012-namebar-154876201') - :rtype: string - """ - randbits = str(random.randint(1, 0x7fffffff)) - rand_name = randbits - if name: - rand_name = name + '-' + rand_name - if prefix: - rand_name = prefix + '-' + rand_name - return rand_name - - -def rand_password(length=15): - """Generate a random password - - :param int length: The length of password that you expect to set - (If it's smaller than 3, it's same as 3.) - :return: a random password. The format is - '-- - -' - (e.g. 'G2*ac8&lKFFgh%2') - :rtype: string - """ - upper = random.choice(string.ascii_uppercase) - ascii_char = string.ascii_letters - digits = string.digits - digit = random.choice(string.digits) - puncs = '~!@#$%^&*_=+' - punc = random.choice(puncs) - seed = ascii_char + digits + puncs - pre = upper + digit + punc - password = pre + ''.join(random.choice(seed) for x in range(length - 3)) - return password - - -def rand_url(): - """Generate a random url that inclues a random number - - :return: a random url. The format is 'https://url-.com'. - (e.g. 'https://url-154876201.com') - :rtype: string - """ - randbits = str(random.randint(1, 0x7fffffff)) - return 'https://url-' + randbits + '.com' - - -def rand_int_id(start=0, end=0x7fffffff): - """Generate a random integer value - - :param int start: The value that you expect to start here - :param int end: The value that you expect to end here - :return: a random integer value - :rtype: int - """ - return random.randint(start, end) - - -def rand_mac_address(): - """Generate an Ethernet MAC address - - :return: an random Ethernet MAC address - :rtype: string - """ - # NOTE(vish): We would prefer to use 0xfe here to ensure that linux - # bridge mac addresses don't change, but it appears to - # conflict with libvirt, so we use the next highest octet - # that has the unicast and locally administered bits set - # properly: 0xfa. - # Discussion: https://bugs.launchpad.net/nova/+bug/921838 - mac = [0xfa, 0x16, 0x3e, - random.randint(0x00, 0xff), - random.randint(0x00, 0xff), - random.randint(0x00, 0xff)] - return ':'.join(["%02x" % x for x in mac]) - - -def parse_image_id(image_ref): - """Return the image id from a given image ref - - This function just returns the last word of the given image ref string - splitting with '/'. - :param str image_ref: a string that includes the image id - :return: the image id string - :rtype: string - """ - return image_ref.rsplit('/')[-1] - - -def arbitrary_string(size=4, base_text=None): - """Return size characters from base_text - - This generates a string with an arbitrary number of characters, generated - by looping the base_text string. If the size is smaller than the size of - base_text, returning string is shrinked to the size. - :param int size: a returning charactors size - :param str base_text: a string you want to repeat - :return: size string - :rtype: string - """ - if not base_text: - base_text = 'test' - return ''.join(itertools.islice(itertools.cycle(base_text), size)) - - -def random_bytes(size=1024): - """Return size randomly selected bytes as a string - - :param int size: a returning bytes size - :return: size randomly bytes - :rtype: string - """ - return ''.join([chr(random.randint(0, 255)) - for i in range(size)]) - - -def get_ipv6_addr_by_EUI64(cidr, mac): - """Generate a IPv6 addr by EUI-64 with CIDR and MAC - - :param str cidr: a IPv6 CIDR - :param str mac: a MAC address - :return: an IPv6 Address - :rtype: netaddr.IPAddress - """ - # Check if the prefix is IPv4 address - is_ipv4 = netaddr.valid_ipv4(cidr) - if is_ipv4: - msg = "Unable to generate IP address by EUI64 for IPv4 prefix" - raise TypeError(msg) - try: - eui64 = int(netaddr.EUI(mac).eui64()) - prefix = netaddr.IPNetwork(cidr) - return netaddr.IPAddress(prefix.first + eui64 ^ (1 << 57)) - except (ValueError, netaddr.AddrFormatError): - raise TypeError('Bad prefix or mac format for generating IPv6 ' - 'address by EUI-64: %(prefix)s, %(mac)s:' - % {'prefix': cidr, 'mac': mac}) - except TypeError: - raise TypeError('Bad prefix type for generate IPv6 address by ' - 'EUI-64: %s' % cidr) diff --git a/tempest_lib/common/utils/misc.py b/tempest_lib/common/utils/misc.py deleted file mode 100644 index b97dd86..0000000 --- a/tempest_lib/common/utils/misc.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import inspect -import re - -from oslo_log import log as logging - -LOG = logging.getLogger(__name__) - - -def singleton(cls): - """Simple wrapper for classes that should only have a single instance.""" - instances = {} - - def getinstance(): - if cls not in instances: - instances[cls] = cls() - return instances[cls] - return getinstance - - -def find_test_caller(): - """Find the caller class and test name. - - Because we know that the interesting things that call us are - test_* methods, and various kinds of setUp / tearDown, we - can look through the call stack to find appropriate methods, - and the class we were in when those were called. - """ - caller_name = None - names = [] - frame = inspect.currentframe() - is_cleanup = False - # Start climbing the ladder until we hit a good method - while True: - try: - frame = frame.f_back - name = frame.f_code.co_name - names.append(name) - if re.search("^(test_|setUp|tearDown)", name): - cname = "" - if 'self' in frame.f_locals: - cname = frame.f_locals['self'].__class__.__name__ - if 'cls' in frame.f_locals: - cname = frame.f_locals['cls'].__name__ - caller_name = cname + ":" + name - break - elif re.search("^_run_cleanup", name): - is_cleanup = True - elif name == 'main': - caller_name = 'main' - break - else: - cname = "" - if 'self' in frame.f_locals: - cname = frame.f_locals['self'].__class__.__name__ - if 'cls' in frame.f_locals: - cname = frame.f_locals['cls'].__name__ - - # the fact that we are running cleanups is indicated pretty - # deep in the stack, so if we see that we want to just - # start looking for a real class name, and declare victory - # once we do. - if is_cleanup and cname: - if not re.search("^RunTest", cname): - caller_name = cname + ":_run_cleanups" - break - except Exception: - break - # prevents frame leaks - del frame - if caller_name is None: - LOG.debug("Sane call name not found in %s" % names) - return caller_name diff --git a/tempest_lib/decorators.py b/tempest_lib/decorators.py deleted file mode 100644 index e78e624..0000000 --- a/tempest_lib/decorators.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2015 Hewlett-Packard 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 functools -import uuid - -import six -import testtools - - -def skip_because(*args, **kwargs): - """A decorator useful to skip tests hitting known bugs - - @param bug: bug number causing the test to skip - @param condition: optional condition to be True for the skip to have place - """ - def decorator(f): - @functools.wraps(f) - def wrapper(self, *func_args, **func_kwargs): - skip = False - if "condition" in kwargs: - if kwargs["condition"] is True: - skip = True - else: - skip = True - if "bug" in kwargs and skip is True: - if not kwargs['bug'].isdigit(): - raise ValueError('bug must be a valid bug number') - msg = "Skipped until Bug: %s is resolved." % kwargs["bug"] - raise testtools.TestCase.skipException(msg) - return f(self, *func_args, **func_kwargs) - return wrapper - return decorator - - -def idempotent_id(id): - """Stub for metadata decorator""" - if not isinstance(id, six.string_types): - raise TypeError('Test idempotent_id must be string not %s' - '' % type(id).__name__) - uuid.UUID(id) - - def decorator(f): - f = testtools.testcase.attr('id-%s' % id)(f) - if f.__doc__: - f.__doc__ = 'Test idempotent id: %s\n%s' % (id, f.__doc__) - else: - f.__doc__ = 'Test idempotent id: %s' % id - return f - return decorator - - -class skip_unless_attr(object): - """Decorator to skip tests if a specified attr does not exists or False""" - def __init__(self, attr, msg=None): - self.attr = attr - self.message = msg or ("Test case attribute %s not found " - "or False") % attr - - def __call__(self, func): - def _skipper(*args, **kw): - """Wrapped skipper function.""" - testobj = args[0] - if not getattr(testobj, self.attr, False): - raise testtools.TestCase.skipException(self.message) - func(*args, **kw) - _skipper.__name__ = func.__name__ - _skipper.__doc__ = func.__doc__ - return _skipper diff --git a/tempest_lib/exceptions.py b/tempest_lib/exceptions.py deleted file mode 100644 index 2bf7cdd..0000000 --- a/tempest_lib/exceptions.py +++ /dev/null @@ -1,205 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import testtools - - -class TempestException(Exception): - """Base Tempest Exception - - To correctly use this class, inherit from it and define - a 'message' property. That message will get printf'd - with the keyword arguments provided to the constructor. - """ - message = "An unknown exception occurred" - - def __init__(self, *args, **kwargs): - super(TempestException, self).__init__() - try: - self._error_string = self.message % kwargs - except Exception: - # at least get the core message out if something happened - self._error_string = self.message - if len(args) > 0: - # If there is a non-kwarg parameter, assume it's the error - # message or reason description and tack it on to the end - # of the exception message - # Convert all arguments into their string representations... - args = ["%s" % arg for arg in args] - self._error_string = (self._error_string + - "\nDetails: %s" % '\n'.join(args)) - - def __str__(self): - return self._error_string - - -class RestClientException(TempestException, - testtools.TestCase.failureException): - def __init__(self, resp_body=None, *args, **kwargs): - if 'resp' in kwargs: - self.resp = kwargs.get('resp') - self.resp_body = resp_body - message = kwargs.get("message", resp_body) - super(RestClientException, self).__init__(message, *args, **kwargs) - - -class OtherRestClientException(RestClientException): - pass - - -class ServerRestClientException(RestClientException): - pass - - -class ClientRestClientException(RestClientException): - pass - - -class InvalidHttpSuccessCode(OtherRestClientException): - message = "The success code is different than the expected one" - - -class NotFound(ClientRestClientException): - message = "Object not found" - - -class Unauthorized(ClientRestClientException): - message = 'Unauthorized' - - -class Forbidden(ClientRestClientException): - message = "Forbidden" - - -class TimeoutException(OtherRestClientException): - message = "Request timed out" - - -class BadRequest(ClientRestClientException): - message = "Bad request" - - -class UnprocessableEntity(ClientRestClientException): - message = "Unprocessable entity" - - -class RateLimitExceeded(ClientRestClientException): - message = "Rate limit exceeded" - - -class OverLimit(ClientRestClientException): - message = "Quota exceeded" - - -class ServerFault(ServerRestClientException): - message = "Got server fault" - - -class NotImplemented(ServerRestClientException): - message = "Got NotImplemented error" - - -class Conflict(ClientRestClientException): - message = "An object with that identifier already exists" - - -class Gone(ClientRestClientException): - message = "The requested resource is no longer available" - - -class ResponseWithNonEmptyBody(OtherRestClientException): - message = ("RFC Violation! Response with %(status)d HTTP Status Code " - "MUST NOT have a body") - - -class ResponseWithEntity(OtherRestClientException): - message = ("RFC Violation! Response with 205 HTTP Status Code " - "MUST NOT have an entity") - - -class InvalidHTTPResponseBody(OtherRestClientException): - message = "HTTP response body is invalid json or xml" - - -class InvalidHTTPResponseHeader(OtherRestClientException): - message = "HTTP response header is invalid" - - -class InvalidContentType(ClientRestClientException): - message = "Invalid content type provided" - - -class UnexpectedContentType(OtherRestClientException): - message = "Unexpected content type provided" - - -class UnexpectedResponseCode(OtherRestClientException): - message = "Unexpected response code received" - - -class InvalidStructure(TempestException): - message = "Invalid structure of table with details" - - -class BadAltAuth(TempestException): - """Used when trying and failing to change to alt creds. - - If alt creds end up the same as primary creds, use this - exception. This is often going to be the case when you assume - project_id is in the url, but it's not. - - """ - message = "The alt auth looks the same as primary auth for %(part)s" - - -class CommandFailed(Exception): - def __init__(self, returncode, cmd, output, stderr): - super(CommandFailed, self).__init__() - self.returncode = returncode - self.cmd = cmd - self.stdout = output - self.stderr = stderr - - def __str__(self): - return ("Command '%s' returned non-zero exit status %d.\n" - "stdout:\n%s\n" - "stderr:\n%s" % (self.cmd, - self.returncode, - self.stdout, - self.stderr)) - - -class IdentityError(TempestException): - message = "Got identity error" - - -class EndpointNotFound(TempestException): - message = "Endpoint not found" - - -class InvalidCredentials(TempestException): - message = "Invalid Credentials" - - -class SSHTimeout(TempestException): - message = ("Connection to the %(host)s via SSH timed out.\n" - "User: %(user)s, Password: %(password)s") - - -class SSHExecCommandFailed(TempestException): - """Raised when remotely executed command returns nonzero status.""" - message = ("Command '%(command)s', exit status: %(exit_status)d, " - "stderr:\n%(stderr)s\n" - "stdout:\n%(stdout)s") diff --git a/tempest_lib/services/__init__.py b/tempest_lib/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/services/compute/__init__.py b/tempest_lib/services/compute/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/services/compute/agents_client.py b/tempest_lib/services/compute/agents_client.py deleted file mode 100644 index a2b80c5..0000000 --- a/tempest_lib/services/compute/agents_client.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright 2014 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 oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import agents as schema -from tempest_lib.common import rest_client - - -class AgentsClient(rest_client.RestClient): - """Tests Agents API""" - - def list_agents(self, **params): - """List all agent builds.""" - url = 'os-agents' - if params: - url += '?%s' % urllib.urlencode(params) - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_agents, resp, body) - return rest_client.ResponseBody(resp, body) - - def create_agent(self, **kwargs): - """Create an agent build. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#agentbuild - """ - post_body = json.dumps({'agent': kwargs}) - resp, body = self.post('os-agents', post_body) - body = json.loads(body) - self.validate_response(schema.create_agent, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_agent(self, agent_id): - """Delete an existing agent build.""" - resp, body = self.delete("os-agents/%s" % agent_id) - self.validate_response(schema.delete_agent, resp, body) - return rest_client.ResponseBody(resp, body) - - def update_agent(self, agent_id, **kwargs): - """Update an agent build. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#updatebuild - """ - put_body = json.dumps({'para': kwargs}) - resp, body = self.put('os-agents/%s' % agent_id, put_body) - body = json.loads(body) - self.validate_response(schema.update_agent, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/aggregates_client.py b/tempest_lib/services/compute/aggregates_client.py deleted file mode 100644 index a90c338..0000000 --- a/tempest_lib/services/compute/aggregates_client.py +++ /dev/null @@ -1,116 +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 oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import aggregates as schema -from tempest_lib.common import rest_client -from tempest_lib import exceptions as lib_exc - - -class AggregatesClient(rest_client.RestClient): - - def list_aggregates(self): - """Get aggregate list.""" - resp, body = self.get("os-aggregates") - body = json.loads(body) - self.validate_response(schema.list_aggregates, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_aggregate(self, aggregate_id): - """Get details of the given aggregate.""" - resp, body = self.get("os-aggregates/%s" % aggregate_id) - body = json.loads(body) - self.validate_response(schema.get_aggregate, resp, body) - return rest_client.ResponseBody(resp, body) - - def create_aggregate(self, **kwargs): - """Create a new aggregate. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createaggregate - """ - post_body = json.dumps({'aggregate': kwargs}) - resp, body = self.post('os-aggregates', post_body) - - body = json.loads(body) - self.validate_response(schema.create_aggregate, resp, body) - return rest_client.ResponseBody(resp, body) - - def update_aggregate(self, aggregate_id, **kwargs): - """Update an aggregate. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#updateaggregate - """ - put_body = json.dumps({'aggregate': kwargs}) - resp, body = self.put('os-aggregates/%s' % aggregate_id, put_body) - - body = json.loads(body) - self.validate_response(schema.update_aggregate, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_aggregate(self, aggregate_id): - """Delete the given aggregate.""" - resp, body = self.delete("os-aggregates/%s" % aggregate_id) - self.validate_response(schema.delete_aggregate, resp, body) - return rest_client.ResponseBody(resp, body) - - def is_resource_deleted(self, id): - try: - self.show_aggregate(id) - except lib_exc.NotFound: - return True - return False - - @property - def resource_type(self): - """Return the primary type of resource this client works with.""" - return 'aggregate' - - def add_host(self, aggregate_id, **kwargs): - """Add a host to the given aggregate. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#addhost - """ - post_body = json.dumps({'add_host': kwargs}) - resp, body = self.post('os-aggregates/%s/action' % aggregate_id, - post_body) - body = json.loads(body) - self.validate_response(schema.aggregate_add_remove_host, resp, body) - return rest_client.ResponseBody(resp, body) - - def remove_host(self, aggregate_id, **kwargs): - """Remove a host from the given aggregate. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#removehost - """ - post_body = json.dumps({'remove_host': kwargs}) - resp, body = self.post('os-aggregates/%s/action' % aggregate_id, - post_body) - body = json.loads(body) - self.validate_response(schema.aggregate_add_remove_host, resp, body) - return rest_client.ResponseBody(resp, body) - - def set_metadata(self, aggregate_id, **kwargs): - """Replace the aggregate's existing metadata with new metadata.""" - post_body = json.dumps({'set_metadata': kwargs}) - resp, body = self.post('os-aggregates/%s/action' % aggregate_id, - post_body) - body = json.loads(body) - self.validate_response(schema.aggregate_set_metadata, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/availability_zone_client.py b/tempest_lib/services/compute/availability_zone_client.py deleted file mode 100644 index f03b8ba..0000000 --- a/tempest_lib/services/compute/availability_zone_client.py +++ /dev/null @@ -1,35 +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 oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import availability_zone \ - as schema -from tempest_lib.common import rest_client - - -class AvailabilityZoneClient(rest_client.RestClient): - - def list_availability_zones(self, detail=False): - url = 'os-availability-zone' - schema_list = schema.list_availability_zone_list - if detail: - url += '/detail' - schema_list = schema.list_availability_zone_list_detail - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema_list, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/baremetal_nodes_client.py b/tempest_lib/services/compute/baremetal_nodes_client.py deleted file mode 100644 index b0c1849..0000000 --- a/tempest_lib/services/compute/baremetal_nodes_client.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2015 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 oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import baremetal_nodes \ - as schema -from tempest_lib.common import rest_client - - -class BaremetalNodesClient(rest_client.RestClient): - """Tests Baremetal API""" - - def list_baremetal_nodes(self, **params): - """List all baremetal nodes.""" - url = 'os-baremetal-nodes' - if params: - url += '?%s' % urllib.urlencode(params) - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_baremetal_nodes, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_baremetal_node(self, baremetal_node_id): - """Return the details of a single baremetal node.""" - url = 'os-baremetal-nodes/%s' % baremetal_node_id - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.get_baremetal_node, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/certificates_client.py b/tempest_lib/services/compute/certificates_client.py deleted file mode 100644 index 546e53c..0000000 --- a/tempest_lib/services/compute/certificates_client.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2013 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. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import certificates as schema -from tempest_lib.common import rest_client - - -class CertificatesClient(rest_client.RestClient): - - def show_certificate(self, certificate_id): - url = "os-certificates/%s" % certificate_id - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.get_certificate, resp, body) - return rest_client.ResponseBody(resp, body) - - def create_certificate(self): - """Create a certificate.""" - url = "os-certificates" - resp, body = self.post(url, None) - body = json.loads(body) - self.validate_response(schema.create_certificate, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/extensions_client.py b/tempest_lib/services/compute/extensions_client.py deleted file mode 100644 index 4a3435f..0000000 --- a/tempest_lib/services/compute/extensions_client.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import extensions as schema -from tempest_lib.common import rest_client - - -class ExtensionsClient(rest_client.RestClient): - - def list_extensions(self): - url = 'extensions' - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_extensions, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_extension(self, extension_alias): - resp, body = self.get('extensions/%s' % extension_alias) - body = json.loads(body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/fixed_ips_client.py b/tempest_lib/services/compute/fixed_ips_client.py deleted file mode 100644 index 1b4afb7..0000000 --- a/tempest_lib/services/compute/fixed_ips_client.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2013 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. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import fixed_ips as schema -from tempest_lib.common import rest_client - - -class FixedIPsClient(rest_client.RestClient): - - def show_fixed_ip(self, fixed_ip): - url = "os-fixed-ips/%s" % fixed_ip - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.get_fixed_ip, resp, body) - return rest_client.ResponseBody(resp, body) - - def reserve_fixed_ip(self, fixed_ip, **kwargs): - """Reserve/Unreserve a fixed IP. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#reserveIP - """ - url = "os-fixed-ips/%s/action" % fixed_ip - resp, body = self.post(url, json.dumps(kwargs)) - self.validate_response(schema.reserve_unreserve_fixed_ip, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/flavors_client.py b/tempest_lib/services/compute/flavors_client.py deleted file mode 100644 index 7e8eda6..0000000 --- a/tempest_lib/services/compute/flavors_client.py +++ /dev/null @@ -1,176 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import flavors as schema -from tempest_lib.api_schema.response.compute.v2_1 import flavors_access \ - as schema_access -from tempest_lib.api_schema.response.compute.v2_1 import flavors_extra_specs \ - as schema_extra_specs -from tempest_lib.common import rest_client - - -class FlavorsClient(rest_client.RestClient): - - def list_flavors(self, detail=False, **params): - url = 'flavors' - _schema = schema.list_flavors - - if detail: - url += '/detail' - _schema = schema.list_flavors_details - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(_schema, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_flavor(self, flavor_id): - resp, body = self.get("flavors/%s" % flavor_id) - body = json.loads(body) - self.validate_response(schema.create_get_flavor_details, resp, body) - return rest_client.ResponseBody(resp, body) - - def create_flavor(self, **kwargs): - """Create a new flavor or instance type. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#create-flavors - """ - if kwargs.get('ephemeral'): - kwargs['OS-FLV-EXT-DATA:ephemeral'] = kwargs.pop('ephemeral') - if kwargs.get('is_public'): - kwargs['os-flavor-access:is_public'] = kwargs.pop('is_public') - - post_body = json.dumps({'flavor': kwargs}) - resp, body = self.post('flavors', post_body) - - body = json.loads(body) - self.validate_response(schema.create_get_flavor_details, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_flavor(self, flavor_id): - """Delete the given flavor.""" - resp, body = self.delete("flavors/{0}".format(flavor_id)) - self.validate_response(schema.delete_flavor, resp, body) - return rest_client.ResponseBody(resp, body) - - def is_resource_deleted(self, id): - # Did not use show_flavor(id) for verification as it gives - # 200 ok even for deleted id. LP #981263 - # we can remove the loop here and use get by ID when bug gets sortedout - flavors = self.list_flavors(detail=True)['flavors'] - for flavor in flavors: - if flavor['id'] == id: - return False - return True - - @property - def resource_type(self): - """Return the primary type of resource this client works with.""" - return 'flavor' - - def set_flavor_extra_spec(self, flavor_id, **kwargs): - """Set extra Specs to the mentioned flavor. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#updateFlavorExtraSpec - """ - post_body = json.dumps({'extra_specs': kwargs}) - resp, body = self.post('flavors/%s/os-extra_specs' % flavor_id, - post_body) - body = json.loads(body) - self.validate_response(schema_extra_specs.set_get_flavor_extra_specs, - resp, body) - return rest_client.ResponseBody(resp, body) - - def list_flavor_extra_specs(self, flavor_id): - """Get extra Specs details of the mentioned flavor.""" - resp, body = self.get('flavors/%s/os-extra_specs' % flavor_id) - body = json.loads(body) - self.validate_response(schema_extra_specs.set_get_flavor_extra_specs, - resp, body) - return rest_client.ResponseBody(resp, body) - - def show_flavor_extra_spec(self, flavor_id, key): - """Get extra Specs key-value of the mentioned flavor and key.""" - resp, body = self.get('flavors/%s/os-extra_specs/%s' % (flavor_id, - key)) - body = json.loads(body) - self.validate_response( - schema_extra_specs.set_get_flavor_extra_specs_key, - resp, body) - return rest_client.ResponseBody(resp, body) - - def update_flavor_extra_spec(self, flavor_id, key, **kwargs): - """Update specified extra Specs of the mentioned flavor and key. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#updateflavorspec - """ - resp, body = self.put('flavors/%s/os-extra_specs/%s' % - (flavor_id, key), json.dumps(kwargs)) - body = json.loads(body) - self.validate_response( - schema_extra_specs.set_get_flavor_extra_specs_key, - resp, body) - return rest_client.ResponseBody(resp, body) - - def unset_flavor_extra_spec(self, flavor_id, key): - """Unset extra Specs from the mentioned flavor.""" - resp, body = self.delete('flavors/%s/os-extra_specs/%s' % - (flavor_id, key)) - self.validate_response(schema.unset_flavor_extra_specs, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_flavor_access(self, flavor_id): - """Get flavor access information given the flavor id.""" - resp, body = self.get('flavors/%s/os-flavor-access' % flavor_id) - body = json.loads(body) - self.validate_response(schema_access.add_remove_list_flavor_access, - resp, body) - return rest_client.ResponseBody(resp, body) - - def add_flavor_access(self, flavor_id, tenant_id): - """Add flavor access for the specified tenant.""" - post_body = { - 'addTenantAccess': { - 'tenant': tenant_id - } - } - post_body = json.dumps(post_body) - resp, body = self.post('flavors/%s/action' % flavor_id, post_body) - body = json.loads(body) - self.validate_response(schema_access.add_remove_list_flavor_access, - resp, body) - return rest_client.ResponseBody(resp, body) - - def remove_flavor_access(self, flavor_id, tenant_id): - """Remove flavor access from the specified tenant.""" - post_body = { - 'removeTenantAccess': { - 'tenant': tenant_id - } - } - post_body = json.dumps(post_body) - resp, body = self.post('flavors/%s/action' % flavor_id, post_body) - body = json.loads(body) - self.validate_response(schema_access.add_remove_list_flavor_access, - resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/floating_ip_pools_client.py b/tempest_lib/services/compute/floating_ip_pools_client.py deleted file mode 100644 index b95e761..0000000 --- a/tempest_lib/services/compute/floating_ip_pools_client.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import floating_ips as schema -from tempest_lib.common import rest_client - - -class FloatingIPPoolsClient(rest_client.RestClient): - - def list_floating_ip_pools(self, params=None): - """Gets all floating IP Pools list.""" - url = 'os-floating-ip-pools' - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_floating_ip_pools, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/floating_ips_bulk_client.py b/tempest_lib/services/compute/floating_ips_bulk_client.py deleted file mode 100644 index c7ec840..0000000 --- a/tempest_lib/services/compute/floating_ips_bulk_client.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import floating_ips as schema -from tempest_lib.common import rest_client - - -class FloatingIPsBulkClient(rest_client.RestClient): - - def create_floating_ips_bulk(self, ip_range, pool, interface): - """Allocate floating IPs in bulk.""" - post_body = { - 'ip_range': ip_range, - 'pool': pool, - 'interface': interface - } - post_body = json.dumps({'floating_ips_bulk_create': post_body}) - resp, body = self.post('os-floating-ips-bulk', post_body) - body = json.loads(body) - self.validate_response(schema.create_floating_ips_bulk, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_floating_ips_bulk(self): - """Gets all floating IPs in bulk.""" - resp, body = self.get('os-floating-ips-bulk') - body = json.loads(body) - self.validate_response(schema.list_floating_ips_bulk, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_floating_ips_bulk(self, ip_range): - """Deletes the provided floating IPs in bulk.""" - post_body = json.dumps({'ip_range': ip_range}) - resp, body = self.put('os-floating-ips-bulk/delete', post_body) - body = json.loads(body) - self.validate_response(schema.delete_floating_ips_bulk, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/floating_ips_client.py b/tempest_lib/services/compute/floating_ips_client.py deleted file mode 100644 index 6abf921..0000000 --- a/tempest_lib/services/compute/floating_ips_client.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import floating_ips as schema -from tempest_lib.common import rest_client -from tempest_lib import exceptions as lib_exc - - -class FloatingIPsClient(rest_client.RestClient): - - def list_floating_ips(self, **params): - """Returns a list of all floating IPs filtered by any parameters.""" - url = 'os-floating-ips' - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_floating_ips, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_floating_ip(self, floating_ip_id): - """Get the details of a floating IP.""" - url = "os-floating-ips/%s" % floating_ip_id - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.create_get_floating_ip, resp, body) - return rest_client.ResponseBody(resp, body) - - def create_floating_ip(self, **kwargs): - """Allocate a floating IP to the project. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createFloatingIP - """ - url = 'os-floating-ips' - post_body = json.dumps(kwargs) - resp, body = self.post(url, post_body) - body = json.loads(body) - self.validate_response(schema.create_get_floating_ip, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_floating_ip(self, floating_ip_id): - """Deletes the provided floating IP from the project.""" - url = "os-floating-ips/%s" % floating_ip_id - resp, body = self.delete(url) - self.validate_response(schema.add_remove_floating_ip, resp, body) - return rest_client.ResponseBody(resp, body) - - def associate_floating_ip_to_server(self, floating_ip, server_id): - """Associate the provided floating IP to a specific server.""" - url = "servers/%s/action" % server_id - post_body = { - 'addFloatingIp': { - 'address': floating_ip, - } - } - - post_body = json.dumps(post_body) - resp, body = self.post(url, post_body) - self.validate_response(schema.add_remove_floating_ip, resp, body) - return rest_client.ResponseBody(resp, body) - - def disassociate_floating_ip_from_server(self, floating_ip, server_id): - """Disassociate the provided floating IP from a specific server.""" - url = "servers/%s/action" % server_id - post_body = { - 'removeFloatingIp': { - 'address': floating_ip, - } - } - - post_body = json.dumps(post_body) - resp, body = self.post(url, post_body) - self.validate_response(schema.add_remove_floating_ip, resp, body) - return rest_client.ResponseBody(resp, body) - - def is_resource_deleted(self, id): - try: - self.show_floating_ip(id) - except lib_exc.NotFound: - return True - return False - - @property - def resource_type(self): - """Returns the primary type of resource this client works with.""" - return 'floating_ip' diff --git a/tempest_lib/services/compute/hosts_client.py b/tempest_lib/services/compute/hosts_client.py deleted file mode 100644 index ecc5d14..0000000 --- a/tempest_lib/services/compute/hosts_client.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright 2013 IBM Corp. -# -# 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 six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import hosts as schema -from tempest_lib.common import rest_client - - -class HostsClient(rest_client.RestClient): - - def list_hosts(self, **params): - """List all hosts.""" - - url = 'os-hosts' - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_hosts, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_host(self, hostname): - """Show detail information for the host.""" - - resp, body = self.get("os-hosts/%s" % hostname) - body = json.loads(body) - self.validate_response(schema.get_host_detail, resp, body) - return rest_client.ResponseBody(resp, body) - - def update_host(self, hostname, **kwargs): - """Update a host. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#enablehost - """ - - request_body = { - 'status': None, - 'maintenance_mode': None, - } - request_body.update(**kwargs) - request_body = json.dumps(request_body) - - resp, body = self.put("os-hosts/%s" % hostname, request_body) - body = json.loads(body) - self.validate_response(schema.update_host, resp, body) - return rest_client.ResponseBody(resp, body) - - def startup_host(self, hostname): - """Startup a host.""" - - resp, body = self.get("os-hosts/%s/startup" % hostname) - body = json.loads(body) - self.validate_response(schema.startup_host, resp, body) - return rest_client.ResponseBody(resp, body) - - def shutdown_host(self, hostname): - """Shutdown a host.""" - - resp, body = self.get("os-hosts/%s/shutdown" % hostname) - body = json.loads(body) - self.validate_response(schema.shutdown_host, resp, body) - return rest_client.ResponseBody(resp, body) - - def reboot_host(self, hostname): - """Reboot a host.""" - - resp, body = self.get("os-hosts/%s/reboot" % hostname) - body = json.loads(body) - self.validate_response(schema.reboot_host, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/hypervisor_client.py b/tempest_lib/services/compute/hypervisor_client.py deleted file mode 100644 index 4276a5c..0000000 --- a/tempest_lib/services/compute/hypervisor_client.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2013 IBM 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 oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import hypervisors as schema -from tempest_lib.common import rest_client - - -class HypervisorClient(rest_client.RestClient): - - def list_hypervisors(self, detail=False): - """List hypervisors information.""" - url = 'os-hypervisors' - _schema = schema.list_search_hypervisors - if detail: - url += '/detail' - _schema = schema.list_hypervisors_detail - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(_schema, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_hypervisor(self, hypervisor_id): - """Display the details of the specified hypervisor.""" - resp, body = self.get('os-hypervisors/%s' % hypervisor_id) - body = json.loads(body) - self.validate_response(schema.get_hypervisor, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_servers_on_hypervisor(self, hypervisor_name): - """List instances belonging to the specified hypervisor.""" - resp, body = self.get('os-hypervisors/%s/servers' % hypervisor_name) - body = json.loads(body) - self.validate_response(schema.get_hypervisors_servers, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_hypervisor_statistics(self): - """Get hypervisor statistics over all compute nodes.""" - resp, body = self.get('os-hypervisors/statistics') - body = json.loads(body) - self.validate_response(schema.get_hypervisor_statistics, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_hypervisor_uptime(self, hypervisor_id): - """Display the uptime of the specified hypervisor.""" - resp, body = self.get('os-hypervisors/%s/uptime' % hypervisor_id) - body = json.loads(body) - self.validate_response(schema.get_hypervisor_uptime, resp, body) - return rest_client.ResponseBody(resp, body) - - def search_hypervisor(self, hypervisor_name): - """Search specified hypervisor.""" - resp, body = self.get('os-hypervisors/%s/search' % hypervisor_name) - body = json.loads(body) - self.validate_response(schema.list_search_hypervisors, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/images_client.py b/tempest_lib/services/compute/images_client.py deleted file mode 100644 index a35da4d..0000000 --- a/tempest_lib/services/compute/images_client.py +++ /dev/null @@ -1,142 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import images as schema -from tempest_lib.common import rest_client -from tempest_lib import exceptions as lib_exc - - -class ImagesClient(rest_client.RestClient): - - def create_image(self, server_id, **kwargs): - """Create an image of the original server. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createImage - """ - - post_body = {'createImage': kwargs} - post_body = json.dumps(post_body) - resp, body = self.post('servers/%s/action' % server_id, - post_body) - self.validate_response(schema.create_image, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_images(self, detail=False, **params): - """Return a list of all images filtered by any parameter. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#listImages - """ - url = 'images' - _schema = schema.list_images - if detail: - url += '/detail' - _schema = schema.list_images_details - - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(_schema, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_image(self, image_id): - """Return the details of a single image.""" - resp, body = self.get("images/%s" % image_id) - self.expected_success(200, resp.status) - body = json.loads(body) - self.validate_response(schema.get_image, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_image(self, image_id): - """Delete the provided image.""" - resp, body = self.delete("images/%s" % image_id) - self.validate_response(schema.delete, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_image_metadata(self, image_id): - """List all metadata items for an image.""" - resp, body = self.get("images/%s/metadata" % image_id) - body = json.loads(body) - self.validate_response(schema.image_metadata, resp, body) - return rest_client.ResponseBody(resp, body) - - def set_image_metadata(self, image_id, meta): - """Set the metadata for an image. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createImageMetadata - """ - post_body = json.dumps({'metadata': meta}) - resp, body = self.put('images/%s/metadata' % image_id, post_body) - body = json.loads(body) - self.validate_response(schema.image_metadata, resp, body) - return rest_client.ResponseBody(resp, body) - - def update_image_metadata(self, image_id, meta): - """Update the metadata for an image. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#updateImageMetadata - """ - post_body = json.dumps({'metadata': meta}) - resp, body = self.post('images/%s/metadata' % image_id, post_body) - body = json.loads(body) - self.validate_response(schema.image_metadata, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_image_metadata_item(self, image_id, key): - """Return the value for a specific image metadata key.""" - resp, body = self.get("images/%s/metadata/%s" % (image_id, key)) - body = json.loads(body) - self.validate_response(schema.image_meta_item, resp, body) - return rest_client.ResponseBody(resp, body) - - def set_image_metadata_item(self, image_id, key, meta): - """Set the value for a specific image metadata key. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#setImageMetadataItem - """ - post_body = json.dumps({'meta': meta}) - resp, body = self.put('images/%s/metadata/%s' % (image_id, key), - post_body) - body = json.loads(body) - self.validate_response(schema.image_meta_item, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_image_metadata_item(self, image_id, key): - """Delete a single image metadata key/value pair.""" - resp, body = self.delete("images/%s/metadata/%s" % - (image_id, key)) - self.validate_response(schema.delete, resp, body) - return rest_client.ResponseBody(resp, body) - - def is_resource_deleted(self, id): - try: - self.show_image(id) - except lib_exc.NotFound: - return True - return False - - @property - def resource_type(self): - """Return the primary type of resource this client works with.""" - return 'image' diff --git a/tempest_lib/services/compute/instance_usage_audit_log_client.py b/tempest_lib/services/compute/instance_usage_audit_log_client.py deleted file mode 100644 index 1b4c61d..0000000 --- a/tempest_lib/services/compute/instance_usage_audit_log_client.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2013 IBM 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 oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import \ - instance_usage_audit_logs as schema -from tempest_lib.common import rest_client - - -class InstanceUsagesAuditLogClient(rest_client.RestClient): - - def list_instance_usage_audit_logs(self): - url = 'os-instance_usage_audit_log' - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_instance_usage_audit_log, - resp, body) - return rest_client.ResponseBody(resp, body) - - def show_instance_usage_audit_log(self, time_before): - url = 'os-instance_usage_audit_log/%s' % time_before - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.get_instance_usage_audit_log, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/interfaces_client.py b/tempest_lib/services/compute/interfaces_client.py deleted file mode 100644 index 799e27c..0000000 --- a/tempest_lib/services/compute/interfaces_client.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2013 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. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import interfaces as schema -from tempest_lib.common import rest_client - - -class InterfacesClient(rest_client.RestClient): - - def list_interfaces(self, server_id): - resp, body = self.get('servers/%s/os-interface' % server_id) - body = json.loads(body) - self.validate_response(schema.list_interfaces, resp, body) - return rest_client.ResponseBody(resp, body) - - def create_interface(self, server_id, **kwargs): - """Create an interface. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createAttachInterface - """ - post_body = {'interfaceAttachment': kwargs} - post_body = json.dumps(post_body) - resp, body = self.post('servers/%s/os-interface' % server_id, - body=post_body) - body = json.loads(body) - self.validate_response(schema.get_create_interfaces, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_interface(self, server_id, port_id): - resp, body = self.get('servers/%s/os-interface/%s' % (server_id, - port_id)) - body = json.loads(body) - self.validate_response(schema.get_create_interfaces, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_interface(self, server_id, port_id): - resp, body = self.delete('servers/%s/os-interface/%s' % (server_id, - port_id)) - self.validate_response(schema.delete_interface, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/keypairs_client.py b/tempest_lib/services/compute/keypairs_client.py deleted file mode 100644 index 6663da6..0000000 --- a/tempest_lib/services/compute/keypairs_client.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import keypairs as schema -from tempest_lib.common import rest_client - - -class KeyPairsClient(rest_client.RestClient): - - def list_keypairs(self): - resp, body = self.get("os-keypairs") - body = json.loads(body) - self.validate_response(schema.list_keypairs, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_keypair(self, keypair_name): - resp, body = self.get("os-keypairs/%s" % keypair_name) - body = json.loads(body) - self.validate_response(schema.get_keypair, resp, body) - return rest_client.ResponseBody(resp, body) - - def create_keypair(self, **kwargs): - """Create a keypair. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createKeypair - """ - post_body = json.dumps({'keypair': kwargs}) - resp, body = self.post("os-keypairs", body=post_body) - body = json.loads(body) - self.validate_response(schema.create_keypair, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_keypair(self, keypair_name): - resp, body = self.delete("os-keypairs/%s" % keypair_name) - self.validate_response(schema.delete_keypair, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/limits_client.py b/tempest_lib/services/compute/limits_client.py deleted file mode 100644 index c056a7f..0000000 --- a/tempest_lib/services/compute/limits_client.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import limits as schema -from tempest_lib.common import rest_client - - -class LimitsClient(rest_client.RestClient): - - def show_limits(self): - resp, body = self.get("limits") - body = json.loads(body) - self.validate_response(schema.get_limit, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/migrations_client.py b/tempest_lib/services/compute/migrations_client.py deleted file mode 100644 index a92d7c1..0000000 --- a/tempest_lib/services/compute/migrations_client.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2014 NEC Corporation. -# -# 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 six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import migrations as schema -from tempest_lib.common import rest_client - - -class MigrationsClient(rest_client.RestClient): - - def list_migrations(self, **params): - """List all migrations. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#returnmigrations - """ - - url = 'os-migrations' - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_migrations, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/networks_client.py b/tempest_lib/services/compute/networks_client.py deleted file mode 100644 index 7e6f3f0..0000000 --- a/tempest_lib/services/compute/networks_client.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json - -from tempest_lib.common import rest_client - - -class NetworksClient(rest_client.RestClient): - - def list_networks(self): - resp, body = self.get("os-networks") - body = json.loads(body) - self.expected_success(200, resp.status) - return rest_client.ResponseBody(resp, body) - - def show_network(self, network_id): - resp, body = self.get("os-networks/%s" % network_id) - body = json.loads(body) - self.expected_success(200, resp.status) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/quota_classes_client.py b/tempest_lib/services/compute/quota_classes_client.py deleted file mode 100644 index 12f79be..0000000 --- a/tempest_lib/services/compute/quota_classes_client.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2012 NTT Data -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1\ - import quota_classes as classes_schema -from tempest_lib.common import rest_client - - -class QuotaClassesClient(rest_client.RestClient): - - def show_quota_class_set(self, quota_class_id): - """List the quota class set for a quota class.""" - - url = 'os-quota-class-sets/%s' % quota_class_id - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(classes_schema.get_quota_class_set, resp, body) - return rest_client.ResponseBody(resp, body) - - def update_quota_class_set(self, quota_class_id, **kwargs): - """Update the quota class's limits for one or more resources. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#updatequota - """ - post_body = json.dumps({'quota_class_set': kwargs}) - - resp, body = self.put('os-quota-class-sets/%s' % quota_class_id, - post_body) - - body = json.loads(body) - self.validate_response(classes_schema.update_quota_class_set, - resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/quotas_client.py b/tempest_lib/services/compute/quotas_client.py deleted file mode 100644 index 470010e..0000000 --- a/tempest_lib/services/compute/quotas_client.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright 2012 NTT Data -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import quotas as schema -from tempest_lib.common import rest_client - - -class QuotasClient(rest_client.RestClient): - - def show_quota_set(self, tenant_id, user_id=None): - """List the quota set for a tenant.""" - - url = 'os-quota-sets/%s' % tenant_id - if user_id: - url += '?user_id=%s' % user_id - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.get_quota_set, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_default_quota_set(self, tenant_id): - """List the default quota set for a tenant.""" - - url = 'os-quota-sets/%s/defaults' % tenant_id - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.get_quota_set, resp, body) - return rest_client.ResponseBody(resp, body) - - def update_quota_set(self, tenant_id, user_id=None, **kwargs): - """Updates the tenant's quota limits for one or more resources. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#updatesquotatenant - """ - - post_body = json.dumps({'quota_set': kwargs}) - - if user_id: - resp, body = self.put('os-quota-sets/%s?user_id=%s' % - (tenant_id, user_id), post_body) - else: - resp, body = self.put('os-quota-sets/%s' % tenant_id, - post_body) - - body = json.loads(body) - self.validate_response(schema.update_quota_set, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_quota_set(self, tenant_id): - """Delete the tenant's quota set.""" - resp, body = self.delete('os-quota-sets/%s' % tenant_id) - self.validate_response(schema.delete_quota, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/security_group_default_rules_client.py b/tempest_lib/services/compute/security_group_default_rules_client.py deleted file mode 100644 index 74a99b3..0000000 --- a/tempest_lib/services/compute/security_group_default_rules_client.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2014 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 oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import \ - security_group_default_rule as schema -from tempest_lib.common import rest_client - - -class SecurityGroupDefaultRulesClient(rest_client.RestClient): - - def create_security_default_group_rule(self, **kwargs): - """Create security group default rule. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html - #createSecGroupDefaultRule - """ - post_body = json.dumps({'security_group_default_rule': kwargs}) - url = 'os-security-group-default-rules' - resp, body = self.post(url, post_body) - body = json.loads(body) - self.validate_response(schema.create_get_security_group_default_rule, - resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_security_group_default_rule(self, - security_group_default_rule_id): - """Delete the provided Security Group default rule.""" - resp, body = self.delete('os-security-group-default-rules/%s' % ( - security_group_default_rule_id)) - self.validate_response(schema.delete_security_group_default_rule, - resp, body) - return rest_client.ResponseBody(resp, body) - - def list_security_group_default_rules(self): - """List all Security Group default rules.""" - resp, body = self.get('os-security-group-default-rules') - body = json.loads(body) - self.validate_response(schema.list_security_group_default_rules, - resp, body) - return rest_client.ResponseBody(resp, body) - - def show_security_group_default_rule(self, security_group_default_rule_id): - """Return the details of provided Security Group default rule.""" - resp, body = self.get('os-security-group-default-rules/%s' % - security_group_default_rule_id) - body = json.loads(body) - self.validate_response(schema.create_get_security_group_default_rule, - resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/security_group_rules_client.py b/tempest_lib/services/compute/security_group_rules_client.py deleted file mode 100644 index 0972284..0000000 --- a/tempest_lib/services/compute/security_group_rules_client.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import \ - security_groups as schema -from tempest_lib.common import rest_client - - -class SecurityGroupRulesClient(rest_client.RestClient): - - def create_security_group_rule(self, **kwargs): - """Create a new security group rule. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createSecGroupRule - """ - post_body = json.dumps({'security_group_rule': kwargs}) - url = 'os-security-group-rules' - resp, body = self.post(url, post_body) - body = json.loads(body) - self.validate_response(schema.create_security_group_rule, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_security_group_rule(self, group_rule_id): - """Deletes the provided Security Group rule.""" - resp, body = self.delete('os-security-group-rules/%s' % - group_rule_id) - self.validate_response(schema.delete_security_group_rule, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/security_groups_client.py b/tempest_lib/services/compute/security_groups_client.py deleted file mode 100644 index 98394eb..0000000 --- a/tempest_lib/services/compute/security_groups_client.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import \ - security_groups as schema -from tempest_lib.common import rest_client -from tempest_lib import exceptions as lib_exc - - -class SecurityGroupsClient(rest_client.RestClient): - - def list_security_groups(self, **params): - """List all security groups for a user.""" - - url = 'os-security-groups' - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_security_groups, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_security_group(self, security_group_id): - """Get the details of a Security Group.""" - url = "os-security-groups/%s" % security_group_id - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.get_security_group, resp, body) - return rest_client.ResponseBody(resp, body) - - def create_security_group(self, **kwargs): - """Create a new security group. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createSecGroup - """ - post_body = json.dumps({'security_group': kwargs}) - resp, body = self.post('os-security-groups', post_body) - body = json.loads(body) - self.validate_response(schema.get_security_group, resp, body) - return rest_client.ResponseBody(resp, body) - - def update_security_group(self, security_group_id, **kwargs): - """Update a security group. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#updateSecGroup - """ - post_body = json.dumps({'security_group': kwargs}) - resp, body = self.put('os-security-groups/%s' % security_group_id, - post_body) - body = json.loads(body) - self.validate_response(schema.update_security_group, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_security_group(self, security_group_id): - """Delete the provided Security Group.""" - resp, body = self.delete( - 'os-security-groups/%s' % security_group_id) - self.validate_response(schema.delete_security_group, resp, body) - return rest_client.ResponseBody(resp, body) - - def is_resource_deleted(self, id): - try: - self.show_security_group(id) - except lib_exc.NotFound: - return True - return False - - @property - def resource_type(self): - """Return the primary type of resource this client works with.""" - return 'security_group' diff --git a/tempest_lib/services/compute/server_groups_client.py b/tempest_lib/services/compute/server_groups_client.py deleted file mode 100644 index 2cbce7e..0000000 --- a/tempest_lib/services/compute/server_groups_client.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# Copyright 2013 Hewlett-Packard Development Company, L.P. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import servers as schema -from tempest_lib.common import rest_client - - -class ServerGroupsClient(rest_client.RestClient): - - def create_server_group(self, **kwargs): - """Create the server group. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createServerGroup - """ - post_body = json.dumps({'server_group': kwargs}) - resp, body = self.post('os-server-groups', post_body) - - body = json.loads(body) - self.validate_response(schema.create_show_server_group, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_server_group(self, server_group_id): - """Delete the given server-group.""" - resp, body = self.delete("os-server-groups/%s" % server_group_id) - self.validate_response(schema.delete_server_group, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_server_groups(self): - """List the server-groups.""" - resp, body = self.get("os-server-groups") - body = json.loads(body) - self.validate_response(schema.list_server_groups, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_server_group(self, server_group_id): - """Get the details of given server_group.""" - resp, body = self.get("os-server-groups/%s" % server_group_id) - body = json.loads(body) - self.validate_response(schema.create_show_server_group, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/servers_client.py b/tempest_lib/services/compute/servers_client.py deleted file mode 100644 index cdb992b..0000000 --- a/tempest_lib/services/compute/servers_client.py +++ /dev/null @@ -1,570 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# Copyright 2013 Hewlett-Packard Development Company, L.P. -# 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 copy - -from oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import servers as schema -from tempest_lib.common import rest_client - - -class ServersClient(rest_client.RestClient): - - def __init__(self, auth_provider, service, region, - enable_instance_password=True, **kwargs): - super(ServersClient, self).__init__( - auth_provider, service, region, **kwargs) - self.enable_instance_password = enable_instance_password - - def create_server(self, **kwargs): - """Create server. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createServer - - Most parameters except the following are passed to the API without - any changes. - :param disk_config: The name is changed to OS-DCF:diskConfig - :param scheduler_hints: The name is changed to os:scheduler_hints and - the parameter is set in the same level as the parameter 'server'. - """ - body = copy.deepcopy(kwargs) - if body.get('disk_config'): - body['OS-DCF:diskConfig'] = body.pop('disk_config') - - hints = None - if body.get('scheduler_hints'): - hints = {'os:scheduler_hints': body.pop('scheduler_hints')} - - post_body = {'server': body} - - if hints: - post_body = dict(post_body.items() + hints.items()) - - post_body = json.dumps(post_body) - resp, body = self.post('servers', post_body) - - body = json.loads(body) - # NOTE(maurosr): this deals with the case of multiple server create - # with return reservation id set True - if 'reservation_id' in body: - return rest_client.ResponseBody(resp, body) - if self.enable_instance_password: - create_schema = schema.create_server_with_admin_pass - else: - create_schema = schema.create_server - self.validate_response(create_schema, resp, body) - return rest_client.ResponseBody(resp, body) - - def update_server(self, server_id, **kwargs): - """Update server. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#updateServer - - Most parameters except the following are passed to the API without - any changes. - :param disk_config: The name is changed to OS-DCF:diskConfig - """ - if kwargs.get('disk_config'): - kwargs['OS-DCF:diskConfig'] = kwargs.pop('disk_config') - - post_body = json.dumps({'server': kwargs}) - resp, body = self.put("servers/%s" % server_id, post_body) - body = json.loads(body) - self.validate_response(schema.update_server, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_server(self, server_id): - """Get server details.""" - resp, body = self.get("servers/%s" % server_id) - body = json.loads(body) - self.validate_response(schema.get_server, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_server(self, server_id): - """Delete server.""" - resp, body = self.delete("servers/%s" % server_id) - self.validate_response(schema.delete_server, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_servers(self, detail=False, **params): - """List servers. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#listServers - and http://developer.openstack.org/ - api-ref-compute-v2.1.html#listDetailServers - """ - - url = 'servers' - _schema = schema.list_servers - - if detail: - url += '/detail' - _schema = schema.list_servers_detail - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(_schema, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_addresses(self, server_id): - """Lists all addresses for a server.""" - resp, body = self.get("servers/%s/ips" % server_id) - body = json.loads(body) - self.validate_response(schema.list_addresses, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_addresses_by_network(self, server_id, network_id): - """Lists all addresses of a specific network type for a server.""" - resp, body = self.get("servers/%s/ips/%s" % - (server_id, network_id)) - body = json.loads(body) - self.validate_response(schema.list_addresses_by_network, resp, body) - return rest_client.ResponseBody(resp, body) - - def action(self, server_id, action_name, - schema=schema.server_actions_common_schema, - **kwargs): - post_body = json.dumps({action_name: kwargs}) - resp, body = self.post('servers/%s/action' % server_id, - post_body) - if body: - body = json.loads(body) - self.validate_response(schema, resp, body) - return rest_client.ResponseBody(resp, body) - - def create_backup(self, server_id, **kwargs): - """Backup a server instance. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createBackup - """ - return self.action(server_id, "createBackup", **kwargs) - - def change_password(self, server_id, **kwargs): - """Change the root password for the server. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#changePassword - """ - return self.action(server_id, 'changePassword', **kwargs) - - def show_password(self, server_id): - resp, body = self.get("servers/%s/os-server-password" % - server_id) - body = json.loads(body) - self.validate_response(schema.show_password, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_password(self, server_id): - """Removes the encrypted server password from the metadata server - - Note that this does not actually change the instance server - password. - """ - resp, body = self.delete("servers/%s/os-server-password" % - server_id) - self.validate_response(schema.server_actions_delete_password, - resp, body) - return rest_client.ResponseBody(resp, body) - - def reboot_server(self, server_id, **kwargs): - """Reboot a server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#reboot - """ - return self.action(server_id, 'reboot', **kwargs) - - def rebuild_server(self, server_id, image_ref, **kwargs): - """Rebuild a server with a new image. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#rebuild - - Most parameters except the following are passed to the API without - any changes. - :param disk_config: The name is changed to OS-DCF:diskConfig - """ - kwargs['imageRef'] = image_ref - if 'disk_config' in kwargs: - kwargs['OS-DCF:diskConfig'] = kwargs.pop('disk_config') - if self.enable_instance_password: - rebuild_schema = schema.rebuild_server_with_admin_pass - else: - rebuild_schema = schema.rebuild_server - return self.action(server_id, 'rebuild', - rebuild_schema, **kwargs) - - def resize_server(self, server_id, flavor_ref, **kwargs): - """Change the flavor of a server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#resize - - Most parameters except the following are passed to the API without - any changes. - :param disk_config: The name is changed to OS-DCF:diskConfig - """ - kwargs['flavorRef'] = flavor_ref - if 'disk_config' in kwargs: - kwargs['OS-DCF:diskConfig'] = kwargs.pop('disk_config') - return self.action(server_id, 'resize', **kwargs) - - def confirm_resize_server(self, server_id, **kwargs): - """Confirm the flavor change for a server. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#confirmResize - """ - return self.action(server_id, 'confirmResize', - schema.server_actions_confirm_resize, - **kwargs) - - def revert_resize_server(self, server_id, **kwargs): - """Revert a server back to its original flavor. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#revertResize - """ - return self.action(server_id, 'revertResize', **kwargs) - - def list_server_metadata(self, server_id): - resp, body = self.get("servers/%s/metadata" % server_id) - body = json.loads(body) - self.validate_response(schema.list_server_metadata, resp, body) - return rest_client.ResponseBody(resp, body) - - def set_server_metadata(self, server_id, meta, no_metadata_field=False): - if no_metadata_field: - post_body = "" - else: - post_body = json.dumps({'metadata': meta}) - resp, body = self.put('servers/%s/metadata' % server_id, - post_body) - body = json.loads(body) - self.validate_response(schema.set_server_metadata, resp, body) - return rest_client.ResponseBody(resp, body) - - def update_server_metadata(self, server_id, meta): - post_body = json.dumps({'metadata': meta}) - resp, body = self.post('servers/%s/metadata' % server_id, - post_body) - body = json.loads(body) - self.validate_response(schema.update_server_metadata, - resp, body) - return rest_client.ResponseBody(resp, body) - - def show_server_metadata_item(self, server_id, key): - resp, body = self.get("servers/%s/metadata/%s" % (server_id, key)) - body = json.loads(body) - self.validate_response(schema.set_show_server_metadata_item, - resp, body) - return rest_client.ResponseBody(resp, body) - - def set_server_metadata_item(self, server_id, key, meta): - post_body = json.dumps({'meta': meta}) - resp, body = self.put('servers/%s/metadata/%s' % (server_id, key), - post_body) - body = json.loads(body) - self.validate_response(schema.set_show_server_metadata_item, - resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_server_metadata_item(self, server_id, key): - resp, body = self.delete("servers/%s/metadata/%s" % - (server_id, key)) - self.validate_response(schema.delete_server_metadata_item, - resp, body) - return rest_client.ResponseBody(resp, body) - - def stop_server(self, server_id, **kwargs): - return self.action(server_id, 'os-stop', **kwargs) - - def start_server(self, server_id, **kwargs): - return self.action(server_id, 'os-start', **kwargs) - - def attach_volume(self, server_id, **kwargs): - """Attaches a volume to a server instance.""" - post_body = json.dumps({'volumeAttachment': kwargs}) - resp, body = self.post('servers/%s/os-volume_attachments' % server_id, - post_body) - body = json.loads(body) - self.validate_response(schema.attach_volume, resp, body) - return rest_client.ResponseBody(resp, body) - - def update_attached_volume(self, server_id, attachment_id, **kwargs): - """Swaps a volume attached to an instance for another volume""" - post_body = json.dumps({'volumeAttachment': kwargs}) - resp, body = self.put('servers/%s/os-volume_attachments/%s' % - (server_id, attachment_id), - post_body) - self.validate_response(schema.update_attached_volume, resp, body) - return rest_client.ResponseBody(resp, body) - - def detach_volume(self, server_id, volume_id): # noqa - """Detaches a volume from a server instance.""" - resp, body = self.delete('servers/%s/os-volume_attachments/%s' % - (server_id, volume_id)) - self.validate_response(schema.detach_volume, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_volume_attachment(self, server_id, volume_id): - """Return details about the given volume attachment.""" - resp, body = self.get('servers/%s/os-volume_attachments/%s' % ( - server_id, volume_id)) - body = json.loads(body) - self.validate_response(schema.show_volume_attachment, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_volume_attachments(self, server_id): - """Returns the list of volume attachments for a given instance.""" - resp, body = self.get('servers/%s/os-volume_attachments' % ( - server_id)) - body = json.loads(body) - self.validate_response(schema.list_volume_attachments, resp, body) - return rest_client.ResponseBody(resp, body) - - def add_security_group(self, server_id, **kwargs): - """Add a security group to the server. - - Available params: TODO - """ - # TODO(oomichi): The api-site doesn't contain this API description. - # So the above should be changed to the api-site link after - # adding the description on the api-site. - # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1524199 - return self.action(server_id, 'addSecurityGroup', **kwargs) - - def remove_security_group(self, server_id, **kwargs): - """Remove a security group from the server. - - Available params: TODO - """ - # TODO(oomichi): The api-site doesn't contain this API description. - # So the above should be changed to the api-site link after - # adding the description on the api-site. - # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1524199 - return self.action(server_id, 'removeSecurityGroup', **kwargs) - - def live_migrate_server(self, server_id, **kwargs): - """This should be called with administrator privileges. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#migrateLive - """ - return self.action(server_id, 'os-migrateLive', **kwargs) - - def migrate_server(self, server_id, **kwargs): - """Migrate a server to a new host. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#migrate - """ - return self.action(server_id, 'migrate', **kwargs) - - def lock_server(self, server_id, **kwargs): - """Lock the given server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#lock - """ - return self.action(server_id, 'lock', **kwargs) - - def unlock_server(self, server_id, **kwargs): - """UNlock the given server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#unlock - """ - return self.action(server_id, 'unlock', **kwargs) - - def suspend_server(self, server_id, **kwargs): - """Suspend the provided server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#suspend - """ - return self.action(server_id, 'suspend', **kwargs) - - def resume_server(self, server_id, **kwargs): - """Un-suspend the provided server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#resume - """ - return self.action(server_id, 'resume', **kwargs) - - def pause_server(self, server_id, **kwargs): - """Pause the provided server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#pause - """ - return self.action(server_id, 'pause', **kwargs) - - def unpause_server(self, server_id, **kwargs): - """Un-pause the provided server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#unpause - """ - return self.action(server_id, 'unpause', **kwargs) - - def reset_state(self, server_id, **kwargs): - """Reset the state of a server to active/error. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#resetState - """ - return self.action(server_id, 'os-resetState', **kwargs) - - def shelve_server(self, server_id, **kwargs): - """Shelve the provided server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#shelve - """ - return self.action(server_id, 'shelve', **kwargs) - - def unshelve_server(self, server_id, **kwargs): - """Un-shelve the provided server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#unshelve - """ - return self.action(server_id, 'unshelve', **kwargs) - - def shelve_offload_server(self, server_id, **kwargs): - """Shelve-offload the provided server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#shelveOffload - """ - return self.action(server_id, 'shelveOffload', **kwargs) - - def get_console_output(self, server_id, **kwargs): - """Get console output. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#getConsoleOutput - """ - return self.action(server_id, 'os-getConsoleOutput', - schema.get_console_output, **kwargs) - - def list_virtual_interfaces(self, server_id): - """List the virtual interfaces used in an instance.""" - resp, body = self.get('/'.join(['servers', server_id, - 'os-virtual-interfaces'])) - body = json.loads(body) - self.validate_response(schema.list_virtual_interfaces, resp, body) - return rest_client.ResponseBody(resp, body) - - def rescue_server(self, server_id, **kwargs): - """Rescue the provided server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#rescue - """ - return self.action(server_id, 'rescue', schema.rescue_server, **kwargs) - - def unrescue_server(self, server_id): - """Unrescue the provided server.""" - return self.action(server_id, 'unrescue') - - def show_server_diagnostics(self, server_id): - """Get the usage data for a server.""" - resp, body = self.get("servers/%s/diagnostics" % server_id) - return rest_client.ResponseBody(resp, json.loads(body)) - - def list_instance_actions(self, server_id): - """List the provided server action.""" - resp, body = self.get("servers/%s/os-instance-actions" % - server_id) - body = json.loads(body) - self.validate_response(schema.list_instance_actions, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_instance_action(self, server_id, request_id): - """Returns the action details of the provided server.""" - resp, body = self.get("servers/%s/os-instance-actions/%s" % - (server_id, request_id)) - body = json.loads(body) - self.validate_response(schema.show_instance_action, resp, body) - return rest_client.ResponseBody(resp, body) - - def force_delete_server(self, server_id, **kwargs): - """Force delete a server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#forceDelete - """ - return self.action(server_id, 'forceDelete', **kwargs) - - def restore_soft_deleted_server(self, server_id, **kwargs): - """Restore a soft-deleted server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#restore - """ - return self.action(server_id, 'restore', **kwargs) - - def reset_network(self, server_id, **kwargs): - """Reset the Network of a server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#resetNetwork - """ - return self.action(server_id, 'resetNetwork', **kwargs) - - def inject_network_info(self, server_id, **kwargs): - """Inject the Network Info into server. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#injectNetworkInfo - """ - return self.action(server_id, 'injectNetworkInfo', **kwargs) - - def get_vnc_console(self, server_id, **kwargs): - """Get URL of VNC console. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#getVNCConsole - """ - return self.action(server_id, "os-getVNCConsole", - schema.get_vnc_console, **kwargs) - - def add_fixed_ip(self, server_id, **kwargs): - """Add a fixed IP to server instance. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#addFixedIp - """ - return self.action(server_id, 'addFixedIp', **kwargs) - - def remove_fixed_ip(self, server_id, **kwargs): - """Remove input fixed IP from input server instance. - - Available params: http://developer.openstack.org/ - api-ref-compute-v2.1.html#removeFixedIp - """ - return self.action(server_id, 'removeFixedIp', **kwargs) diff --git a/tempest_lib/services/compute/services_client.py b/tempest_lib/services/compute/services_client.py deleted file mode 100644 index 7adc1d0..0000000 --- a/tempest_lib/services/compute/services_client.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2013 NEC Corporation -# Copyright 2013 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. - -from oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import services as schema -from tempest_lib.common import rest_client - - -class ServicesClient(rest_client.RestClient): - - def list_services(self, **params): - url = 'os-services' - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_services, resp, body) - return rest_client.ResponseBody(resp, body) - - def enable_service(self, **kwargs): - """Enable service on a host. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#enableScheduling - """ - post_body = json.dumps(kwargs) - resp, body = self.put('os-services/enable', post_body) - body = json.loads(body) - self.validate_response(schema.enable_disable_service, resp, body) - return rest_client.ResponseBody(resp, body) - - def disable_service(self, **kwargs): - """Disable service on a host. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#disableScheduling - """ - post_body = json.dumps(kwargs) - resp, body = self.put('os-services/disable', post_body) - body = json.loads(body) - self.validate_response(schema.enable_disable_service, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/snapshots_client.py b/tempest_lib/services/compute/snapshots_client.py deleted file mode 100644 index 9b65cdc..0000000 --- a/tempest_lib/services/compute/snapshots_client.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2015 Fujitsu(fnst) 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 oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import snapshots as schema -from tempest_lib.common import rest_client -from tempest_lib import exceptions as lib_exc - - -class SnapshotsClient(rest_client.RestClient): - - def create_snapshot(self, volume_id, **kwargs): - """Create a snapshot. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createSnapshot - """ - post_body = { - 'volume_id': volume_id - } - post_body.update(kwargs) - post_body = json.dumps({'snapshot': post_body}) - resp, body = self.post('os-snapshots', post_body) - body = json.loads(body) - self.validate_response(schema.create_get_snapshot, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_snapshot(self, snapshot_id): - url = "os-snapshots/%s" % snapshot_id - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.create_get_snapshot, resp, body) - return rest_client.ResponseBody(resp, body) - - def list_snapshots(self, detail=False, params=None): - url = 'os-snapshots' - - if detail: - url += '/detail' - if params: - url += '?%s' % urllib.urlencode(params) - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_snapshots, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_snapshot(self, snapshot_id): - resp, body = self.delete("os-snapshots/%s" % snapshot_id) - self.validate_response(schema.delete_snapshot, resp, body) - return rest_client.ResponseBody(resp, body) - - def is_resource_deleted(self, id): - try: - self.show_snapshot(id) - except lib_exc.NotFound: - return True - return False - - @property - def resource_type(self): - """Return the primary type of resource this client works with.""" - return 'snapshot' diff --git a/tempest_lib/services/compute/tenant_networks_client.py b/tempest_lib/services/compute/tenant_networks_client.py deleted file mode 100644 index e1ebfea..0000000 --- a/tempest_lib/services/compute/tenant_networks_client.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2015 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 oslo_serialization import jsonutils as json - -from tempest_lib.api_schema.response.compute.v2_1 import tenant_networks -from tempest_lib.common import rest_client - - -class TenantNetworksClient(rest_client.RestClient): - - def list_tenant_networks(self): - resp, body = self.get("os-tenant-networks") - body = json.loads(body) - self.validate_response(tenant_networks.list_tenant_networks, resp, - body) - return rest_client.ResponseBody(resp, body) - - def show_tenant_network(self, network_id): - resp, body = self.get("os-tenant-networks/%s" % network_id) - body = json.loads(body) - self.validate_response(tenant_networks.get_tenant_network, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/tenant_usages_client.py b/tempest_lib/services/compute/tenant_usages_client.py deleted file mode 100644 index 70df4d0..0000000 --- a/tempest_lib/services/compute/tenant_usages_client.py +++ /dev/null @@ -1,43 +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 oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import tenant_usages -from tempest_lib.common import rest_client - - -class TenantUsagesClient(rest_client.RestClient): - - def list_tenant_usages(self, **params): - url = 'os-simple-tenant-usage' - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(tenant_usages.list_tenant_usage, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_tenant_usage(self, tenant_id, **params): - url = 'os-simple-tenant-usage/%s' % tenant_id - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(tenant_usages.get_tenant_usage, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/versions_client.py b/tempest_lib/services/compute/versions_client.py deleted file mode 100644 index 4b7273d..0000000 --- a/tempest_lib/services/compute/versions_client.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright (c) 2015 Hewlett-Packard 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. - -from oslo_serialization import jsonutils as json -from six.moves import urllib - -from tempest_lib.api_schema.response.compute.v2_1 import versions as schema -from tempest_lib.common import rest_client - - -class VersionsClient(rest_client.RestClient): - - def _get_base_version_url(self): - # NOTE: The URL which is gotten from keystone's catalog contains - # API version and project-id like "v2/{project-id}", but we need - # to access the URL which doesn't contain them for getting API - # versions. For that, here should use raw_request() instead of - # get(). - endpoint = self.base_url - url = urllib.parse.urlparse(endpoint) - return '%s://%s/' % (url.scheme, url.netloc) - - def list_versions(self): - version_url = self._get_base_version_url() - resp, body = self.raw_request(version_url, 'GET') - body = json.loads(body) - self.validate_response(schema.list_versions, resp, body) - return rest_client.ResponseBody(resp, body) - - def get_version_by_url(self, version_url): - """Get the version document by url. - - This gets the version document for a url, useful in testing - the contents of things like /v2/ or /v2.1/ in Nova. That - controller needs authenticated access, so we have to get - ourselves a token before making the request. - - """ - # we need a token for this request - resp, body = self.raw_request(version_url, 'GET', - {'X-Auth-Token': self.token}) - body = json.loads(body) - self.validate_response(schema.get_one_version, resp, body) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/compute/volumes_client.py b/tempest_lib/services/compute/volumes_client.py deleted file mode 100644 index 0d767ef..0000000 --- a/tempest_lib/services/compute/volumes_client.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.api_schema.response.compute.v2_1 import volumes as schema -from tempest_lib.common import rest_client -from tempest_lib import exceptions as lib_exc - - -class VolumesClient(rest_client.RestClient): - - def list_volumes(self, detail=False, **params): - """List all the volumes created.""" - url = 'os-volumes' - - if detail: - url += '/detail' - if params: - url += '?%s' % urllib.urlencode(params) - - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.list_volumes, resp, body) - return rest_client.ResponseBody(resp, body) - - def show_volume(self, volume_id): - """Return the details of a single volume.""" - url = "os-volumes/%s" % volume_id - resp, body = self.get(url) - body = json.loads(body) - self.validate_response(schema.create_get_volume, resp, body) - return rest_client.ResponseBody(resp, body) - - def create_volume(self, **kwargs): - """Create a new Volume. - - Available params: see http://developer.openstack.org/ - api-ref-compute-v2.1.html#createVolume - """ - post_body = json.dumps({'volume': kwargs}) - resp, body = self.post('os-volumes', post_body) - body = json.loads(body) - self.validate_response(schema.create_get_volume, resp, body) - return rest_client.ResponseBody(resp, body) - - def delete_volume(self, volume_id): - """Delete the Specified Volume.""" - resp, body = self.delete("os-volumes/%s" % volume_id) - self.validate_response(schema.delete_volume, resp, body) - return rest_client.ResponseBody(resp, body) - - def is_resource_deleted(self, id): - try: - self.show_volume(id) - except lib_exc.NotFound: - return True - return False - - @property - def resource_type(self): - """Return the primary type of resource this client works with.""" - return 'volume' diff --git a/tempest_lib/services/identity/__init__.py b/tempest_lib/services/identity/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/services/identity/v2/__init__.py b/tempest_lib/services/identity/v2/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/services/identity/v2/token_client.py b/tempest_lib/services/identity/v2/token_client.py deleted file mode 100644 index 741bf9f..0000000 --- a/tempest_lib/services/identity/v2/token_client.py +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright 2015 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 oslo_log import log as logging -from oslo_serialization import jsonutils as json - -from tempest_lib.common import rest_client -from tempest_lib import exceptions - - -class TokenClient(rest_client.RestClient): - - def __init__(self, auth_url, disable_ssl_certificate_validation=None, - ca_certs=None, trace_requests=None): - dscv = disable_ssl_certificate_validation - super(TokenClient, self).__init__( - None, None, None, disable_ssl_certificate_validation=dscv, - ca_certs=ca_certs, trace_requests=trace_requests) - - if auth_url is None: - raise exceptions.IdentityError("Couldn't determine auth_url") - - # Normalize URI to ensure /tokens is in it. - if 'tokens' not in auth_url: - auth_url = auth_url.rstrip('/') + '/tokens' - - self.auth_url = auth_url - - def auth(self, user, password, tenant=None): - creds = { - 'auth': { - 'passwordCredentials': { - 'username': user, - 'password': password, - }, - } - } - - if tenant: - creds['auth']['tenantName'] = tenant - - body = json.dumps(creds, sort_keys=True) - resp, body = self.post(self.auth_url, body=body) - self.expected_success(200, resp.status) - - return rest_client.ResponseBody(resp, body['access']) - - def auth_token(self, token_id, tenant=None): - creds = { - 'auth': { - 'token': { - 'id': token_id, - }, - } - } - - if tenant: - creds['auth']['tenantName'] = tenant - - body = json.dumps(creds) - resp, body = self.post(self.auth_url, body=body) - self.expected_success(200, resp.status) - - return rest_client.ResponseBody(resp, body['access']) - - def request(self, method, url, extra_headers=False, headers=None, - body=None): - """A simple HTTP request interface.""" - if headers is None: - headers = self.get_headers(accept_type="json") - elif extra_headers: - try: - headers.update(self.get_headers(accept_type="json")) - except (ValueError, TypeError): - headers = self.get_headers(accept_type="json") - - resp, resp_body = self.raw_request(url, method, - headers=headers, body=body) - self._log_request(method, url, resp, req_headers=headers, - req_body='', resp_body=resp_body) - - if resp.status in [401, 403]: - resp_body = json.loads(resp_body) - raise exceptions.Unauthorized(resp_body['error']['message']) - elif resp.status not in [200, 201]: - raise exceptions.IdentityError( - 'Unexpected status code {0}'.format(resp.status)) - - return resp, json.loads(resp_body) - - def get_token(self, user, password, tenant, auth_data=False): - """Returns (token id, token data) for supplied credentials.""" - body = self.auth(user, password, tenant) - - if auth_data: - return body['token']['id'], body - else: - return body['token']['id'] - - -class TokenClientJSON(TokenClient): - LOG = logging.getLogger(__name__) - - def _warn(self): - self.LOG.warning("%s class was deprecated and renamed to %s" % - (self.__class__.__name__, 'TokenClient')) - - def __init__(self, *args, **kwargs): - self._warn() - super(TokenClientJSON, self).__init__(*args, **kwargs) diff --git a/tempest_lib/services/identity/v3/__init__.py b/tempest_lib/services/identity/v3/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/services/identity/v3/token_client.py b/tempest_lib/services/identity/v3/token_client.py deleted file mode 100644 index 868b4f7..0000000 --- a/tempest_lib/services/identity/v3/token_client.py +++ /dev/null @@ -1,183 +0,0 @@ -# Copyright 2015 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 oslo_log import log as logging -from oslo_serialization import jsonutils as json - -from tempest_lib.common import rest_client -from tempest_lib import exceptions - - -class V3TokenClient(rest_client.RestClient): - - def __init__(self, auth_url, disable_ssl_certificate_validation=None, - ca_certs=None, trace_requests=None): - dscv = disable_ssl_certificate_validation - super(V3TokenClient, self).__init__( - None, None, None, disable_ssl_certificate_validation=dscv, - ca_certs=ca_certs, trace_requests=trace_requests) - - if auth_url is None: - raise exceptions.IdentityError("Couldn't determine auth_url") - - if 'auth/tokens' not in auth_url: - auth_url = auth_url.rstrip('/') + '/auth/tokens' - - self.auth_url = auth_url - - def auth(self, user_id=None, username=None, password=None, project_id=None, - project_name=None, user_domain_id=None, user_domain_name=None, - project_domain_id=None, project_domain_name=None, domain_id=None, - domain_name=None, token=None): - """Obtains a token from the authentication service - - :param user_id: user id - :param username: user name - :param user_domain_id: the user domain id - :param user_domain_name: the user domain name - :param project_domain_id: the project domain id - :param project_domain_name: the project domain name - :param domain_id: a domain id to scope to - :param domain_name: a domain name to scope to - :param project_id: a project id to scope to - :param project_name: a project name to scope to - :param token: a token to re-scope. - - Accepts different combinations of credentials. - Sample sample valid combinations: - - token - - token, project_name, project_domain_id - - user_id, password - - username, password, user_domain_id - - username, password, project_name, user_domain_id, project_domain_id - Validation is left to the server side. - """ - creds = { - 'auth': { - 'identity': { - 'methods': [], - } - } - } - id_obj = creds['auth']['identity'] - if token: - id_obj['methods'].append('token') - id_obj['token'] = { - 'id': token - } - - if (user_id or username) and password: - id_obj['methods'].append('password') - id_obj['password'] = { - 'user': { - 'password': password, - } - } - if user_id: - id_obj['password']['user']['id'] = user_id - else: - id_obj['password']['user']['name'] = username - - _domain = None - if user_domain_id is not None: - _domain = dict(id=user_domain_id) - elif user_domain_name is not None: - _domain = dict(name=user_domain_name) - if _domain: - id_obj['password']['user']['domain'] = _domain - - if (project_id or project_name): - _project = dict() - - if project_id: - _project['id'] = project_id - elif project_name: - _project['name'] = project_name - - if project_domain_id is not None: - _project['domain'] = {'id': project_domain_id} - elif project_domain_name is not None: - _project['domain'] = {'name': project_domain_name} - - creds['auth']['scope'] = dict(project=_project) - elif domain_id: - creds['auth']['scope'] = dict(domain={'id': domain_id}) - elif domain_name: - creds['auth']['scope'] = dict(domain={'name': domain_name}) - - body = json.dumps(creds, sort_keys=True) - resp, body = self.post(self.auth_url, body=body) - self.expected_success(201, resp.status) - return rest_client.ResponseBody(resp, body) - - def request(self, method, url, extra_headers=False, headers=None, - body=None): - """A simple HTTP request interface.""" - if headers is None: - # Always accept 'json', for xml token client too. - # Because XML response is not easily - # converted to the corresponding JSON one - headers = self.get_headers(accept_type="json") - elif extra_headers: - try: - headers.update(self.get_headers(accept_type="json")) - except (ValueError, TypeError): - headers = self.get_headers(accept_type="json") - - resp, resp_body = self.raw_request(url, method, - headers=headers, body=body) - self._log_request(method, url, resp, req_headers=headers, - req_body='', resp_body=resp_body) - - if resp.status in [401, 403]: - resp_body = json.loads(resp_body) - raise exceptions.Unauthorized(resp_body['error']['message']) - elif resp.status not in [200, 201, 204]: - raise exceptions.IdentityError( - 'Unexpected status code {0}'.format(resp.status)) - - return resp, json.loads(resp_body) - - def get_token(self, **kwargs): - """Returns (token id, token data) for supplied credentials""" - - auth_data = kwargs.pop('auth_data', False) - - if not (kwargs.get('user_domain_id') or - kwargs.get('user_domain_name')): - kwargs['user_domain_name'] = 'Default' - - if not (kwargs.get('project_domain_id') or - kwargs.get('project_domain_name')): - kwargs['project_domain_name'] = 'Default' - - body = self.auth(**kwargs) - - token = body.response.get('x-subject-token') - if auth_data: - return token, body['token'] - else: - return token - - -class V3TokenClientJSON(V3TokenClient): - LOG = logging.getLogger(__name__) - - def _warn(self): - self.LOG.warning("%s class was deprecated and renamed to %s" % - (self.__class__.__name__, 'V3TokenClient')) - - def __init__(self, *args, **kwargs): - self._warn() - super(V3TokenClientJSON, self).__init__(*args, **kwargs) diff --git a/tempest_lib/services/network/__init__.py b/tempest_lib/services/network/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/services/network/agents_client.py b/tempest_lib/services/network/agents_client.py deleted file mode 100644 index 21d4839..0000000 --- a/tempest_lib/services/network/agents_client.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright 2015 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_lib.services.network import base - - -class AgentsClient(base.BaseNetworkClient): - - def update_agent(self, agent_id, **kwargs): - """Update agent.""" - # TODO(piyush): Current api-site doesn't contain this API description. - # After fixing the api-site, we need to fix here also for putting the - # link to api-site. - # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1526673 - uri = '/agents/%s' % agent_id - return self.update_resource(uri, kwargs) - - def show_agent(self, agent_id, **fields): - uri = '/agents/%s' % agent_id - return self.show_resource(uri, **fields) - - def list_agents(self, **filters): - uri = '/agents' - return self.list_resources(uri, **filters) - - def list_routers_on_l3_agent(self, agent_id): - uri = '/agents/%s/l3-routers' % agent_id - return self.list_resources(uri) - - def create_router_on_l3_agent(self, agent_id, **kwargs): - # TODO(piyush): Current api-site doesn't contain this API description. - # After fixing the api-site, we need to fix here also for putting the - # link to api-site. - # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1526670 - uri = '/agents/%s/l3-routers' % agent_id - return self.create_resource(uri, kwargs) - - def delete_router_from_l3_agent(self, agent_id, router_id): - uri = '/agents/%s/l3-routers/%s' % (agent_id, router_id) - return self.delete_resource(uri) - - def list_networks_hosted_by_one_dhcp_agent(self, agent_id): - uri = '/agents/%s/dhcp-networks' % agent_id - return self.list_resources(uri) - - def delete_network_from_dhcp_agent(self, agent_id, network_id): - uri = '/agents/%s/dhcp-networks/%s' % (agent_id, - network_id) - return self.delete_resource(uri) - - def add_dhcp_agent_to_network(self, agent_id, **kwargs): - # TODO(piyush): Current api-site doesn't contain this API description. - # After fixing the api-site, we need to fix here also for putting the - # link to api-site. - # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1526212 - uri = '/agents/%s/dhcp-networks' % agent_id - return self.create_resource(uri, kwargs) diff --git a/tempest_lib/services/network/base.py b/tempest_lib/services/network/base.py deleted file mode 100644 index 063e436..0000000 --- a/tempest_lib/services/network/base.py +++ /dev/null @@ -1,71 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_serialization import jsonutils as json -from six.moves.urllib import parse as urllib - -from tempest_lib.common import rest_client - - -class BaseNetworkClient(rest_client.RestClient): - - """Base class for Tempest REST clients for Neutron. - - Child classes use v2 of the Neutron API, since the V1 API has been - removed from the code base. - """ - - version = '2.0' - uri_prefix = "v2.0" - - def list_resources(self, uri, **filters): - req_uri = self.uri_prefix + uri - if filters: - req_uri += '?' + urllib.urlencode(filters, doseq=1) - resp, body = self.get(req_uri) - body = json.loads(body) - self.expected_success(200, resp.status) - return rest_client.ResponseBody(resp, body) - - def delete_resource(self, uri): - req_uri = self.uri_prefix + uri - resp, body = self.delete(req_uri) - self.expected_success(204, resp.status) - return rest_client.ResponseBody(resp, body) - - def show_resource(self, uri, **fields): - # fields is a dict which key is 'fields' and value is a - # list of field's name. An example: - # {'fields': ['id', 'name']} - req_uri = self.uri_prefix + uri - if fields: - req_uri += '?' + urllib.urlencode(fields, doseq=1) - resp, body = self.get(req_uri) - body = json.loads(body) - self.expected_success(200, resp.status) - return rest_client.ResponseBody(resp, body) - - def create_resource(self, uri, post_data): - req_uri = self.uri_prefix + uri - req_post_data = json.dumps(post_data) - resp, body = self.post(req_uri, req_post_data) - body = json.loads(body) - self.expected_success(201, resp.status) - return rest_client.ResponseBody(resp, body) - - def update_resource(self, uri, post_data): - req_uri = self.uri_prefix + uri - req_post_data = json.dumps(post_data) - resp, body = self.put(req_uri, req_post_data) - body = json.loads(body) - self.expected_success(200, resp.status) - return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/services/network/extensions_client.py b/tempest_lib/services/network/extensions_client.py deleted file mode 100644 index 420848b..0000000 --- a/tempest_lib/services/network/extensions_client.py +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest_lib.services.network import base - - -class ExtensionsClient(base.BaseNetworkClient): - - def show_extension(self, ext_alias, **fields): - uri = '/extensions/%s' % ext_alias - return self.show_resource(uri, **fields) - - def list_extensions(self, **filters): - uri = '/extensions' - return self.list_resources(uri, **filters) diff --git a/tempest_lib/services/network/floating_ips_client.py b/tempest_lib/services/network/floating_ips_client.py deleted file mode 100644 index 2ab9d7c..0000000 --- a/tempest_lib/services/network/floating_ips_client.py +++ /dev/null @@ -1,38 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest_lib.services.network import base - - -class FloatingIPsClient(base.BaseNetworkClient): - - def create_floatingip(self, **kwargs): - uri = '/floatingips' - post_data = {'floatingip': kwargs} - return self.create_resource(uri, post_data) - - def update_floatingip(self, floatingip_id, **kwargs): - uri = '/floatingips/%s' % floatingip_id - post_data = {'floatingip': kwargs} - return self.update_resource(uri, post_data) - - def show_floatingip(self, floatingip_id, **fields): - uri = '/floatingips/%s' % floatingip_id - return self.show_resource(uri, **fields) - - def delete_floatingip(self, floatingip_id): - uri = '/floatingips/%s' % floatingip_id - return self.delete_resource(uri) - - def list_floatingips(self, **filters): - uri = '/floatingips' - return self.list_resources(uri, **filters) diff --git a/tempest_lib/services/network/metering_label_rules_client.py b/tempest_lib/services/network/metering_label_rules_client.py deleted file mode 100644 index 5ddea0b..0000000 --- a/tempest_lib/services/network/metering_label_rules_client.py +++ /dev/null @@ -1,33 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest_lib.services.network import base - - -class MeteringLabelRulesClient(base.BaseNetworkClient): - - def create_metering_label_rule(self, **kwargs): - uri = '/metering/metering-label-rules' - post_data = {'metering_label_rule': kwargs} - return self.create_resource(uri, post_data) - - def show_metering_label_rule(self, metering_label_rule_id, **fields): - uri = '/metering/metering-label-rules/%s' % metering_label_rule_id - return self.show_resource(uri, **fields) - - def delete_metering_label_rule(self, metering_label_rule_id): - uri = '/metering/metering-label-rules/%s' % metering_label_rule_id - return self.delete_resource(uri) - - def list_metering_label_rules(self, **filters): - uri = '/metering/metering-label-rules' - return self.list_resources(uri, **filters) diff --git a/tempest_lib/services/network/metering_labels_client.py b/tempest_lib/services/network/metering_labels_client.py deleted file mode 100644 index e71e4ce..0000000 --- a/tempest_lib/services/network/metering_labels_client.py +++ /dev/null @@ -1,33 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest_lib.services.network import base - - -class MeteringLabelsClient(base.BaseNetworkClient): - - def create_metering_label(self, **kwargs): - uri = '/metering/metering-labels' - post_data = {'metering_label': kwargs} - return self.create_resource(uri, post_data) - - def show_metering_label(self, metering_label_id, **fields): - uri = '/metering/metering-labels/%s' % metering_label_id - return self.show_resource(uri, **fields) - - def delete_metering_label(self, metering_label_id): - uri = '/metering/metering-labels/%s' % metering_label_id - return self.delete_resource(uri) - - def list_metering_labels(self, **filters): - uri = '/metering/metering-labels' - return self.list_resources(uri, **filters) diff --git a/tempest_lib/services/network/networks_client.py b/tempest_lib/services/network/networks_client.py deleted file mode 100644 index 541cdab..0000000 --- a/tempest_lib/services/network/networks_client.py +++ /dev/null @@ -1,47 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest_lib.services.network import base - - -class NetworksClient(base.BaseNetworkClient): - - def create_network(self, **kwargs): - uri = '/networks' - post_data = {'network': kwargs} - return self.create_resource(uri, post_data) - - def update_network(self, network_id, **kwargs): - uri = '/networks/%s' % network_id - post_data = {'network': kwargs} - return self.update_resource(uri, post_data) - - def show_network(self, network_id, **fields): - uri = '/networks/%s' % network_id - return self.show_resource(uri, **fields) - - def delete_network(self, network_id): - uri = '/networks/%s' % network_id - return self.delete_resource(uri) - - def list_networks(self, **filters): - uri = '/networks' - return self.list_resources(uri, **filters) - - def create_bulk_networks(self, **kwargs): - """Create multiple networks in a single request. - - Available params: see http://developer.openstack.org/ - api-ref-networking-v2.html#bulkCreateNetwork - """ - uri = '/networks' - return self.create_resource(uri, kwargs) diff --git a/tempest_lib/services/network/ports_client.py b/tempest_lib/services/network/ports_client.py deleted file mode 100644 index 9afbb9c..0000000 --- a/tempest_lib/services/network/ports_client.py +++ /dev/null @@ -1,47 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest_lib.services.network import base - - -class PortsClient(base.BaseNetworkClient): - - def create_port(self, **kwargs): - uri = '/ports' - post_data = {'port': kwargs} - return self.create_resource(uri, post_data) - - def update_port(self, port_id, **kwargs): - uri = '/ports/%s' % port_id - post_data = {'port': kwargs} - return self.update_resource(uri, post_data) - - def show_port(self, port_id, **fields): - uri = '/ports/%s' % port_id - return self.show_resource(uri, **fields) - - def delete_port(self, port_id): - uri = '/ports/%s' % port_id - return self.delete_resource(uri) - - def list_ports(self, **filters): - uri = '/ports' - return self.list_resources(uri, **filters) - - def create_bulk_ports(self, **kwargs): - """Create multiple ports in a single request. - - Available params: see http://developer.openstack.org/ - api-ref-networking-v2.html#bulkCreatePorts - """ - uri = '/ports' - return self.create_resource(uri, kwargs) diff --git a/tempest_lib/services/network/quotas_client.py b/tempest_lib/services/network/quotas_client.py deleted file mode 100644 index 16a4649..0000000 --- a/tempest_lib/services/network/quotas_client.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2015 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_lib.services.network import base - - -class QuotasClient(base.BaseNetworkClient): - - def update_quotas(self, tenant_id, **kwargs): - put_body = {'quota': kwargs} - uri = '/quotas/%s' % tenant_id - return self.update_resource(uri, put_body) - - def reset_quotas(self, tenant_id): - uri = '/quotas/%s' % tenant_id - return self.delete_resource(uri) - - def show_quotas(self, tenant_id, **fields): - uri = '/quotas/%s' % tenant_id - return self.show_resource(uri, **fields) - - def list_quotas(self, **filters): - uri = '/quotas' - return self.list_resources(uri, **filters) diff --git a/tempest_lib/services/network/security_group_rules_client.py b/tempest_lib/services/network/security_group_rules_client.py deleted file mode 100644 index f2b15aa..0000000 --- a/tempest_lib/services/network/security_group_rules_client.py +++ /dev/null @@ -1,33 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest_lib.services.network import base - - -class SecurityGroupRulesClient(base.BaseNetworkClient): - - def create_security_group_rule(self, **kwargs): - uri = '/security-group-rules' - post_data = {'security_group_rule': kwargs} - return self.create_resource(uri, post_data) - - def show_security_group_rule(self, security_group_rule_id, **fields): - uri = '/security-group-rules/%s' % security_group_rule_id - return self.show_resource(uri, **fields) - - def delete_security_group_rule(self, security_group_rule_id): - uri = '/security-group-rules/%s' % security_group_rule_id - return self.delete_resource(uri) - - def list_security_group_rules(self, **filters): - uri = '/security-group-rules' - return self.list_resources(uri, **filters) diff --git a/tempest_lib/services/network/security_groups_client.py b/tempest_lib/services/network/security_groups_client.py deleted file mode 100644 index a30ecc3..0000000 --- a/tempest_lib/services/network/security_groups_client.py +++ /dev/null @@ -1,38 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest_lib.services.network import base - - -class SecurityGroupsClient(base.BaseNetworkClient): - - def create_security_group(self, **kwargs): - uri = '/security-groups' - post_data = {'security_group': kwargs} - return self.create_resource(uri, post_data) - - def update_security_group(self, security_group_id, **kwargs): - uri = '/security-groups/%s' % security_group_id - post_data = {'security_group': kwargs} - return self.update_resource(uri, post_data) - - def show_security_group(self, security_group_id, **fields): - uri = '/security-groups/%s' % security_group_id - return self.show_resource(uri, **fields) - - def delete_security_group(self, security_group_id): - uri = '/security-groups/%s' % security_group_id - return self.delete_resource(uri) - - def list_security_groups(self, **filters): - uri = '/security-groups' - return self.list_resources(uri, **filters) diff --git a/tempest_lib/services/network/subnetpools_client.py b/tempest_lib/services/network/subnetpools_client.py deleted file mode 100644 index c6b0427..0000000 --- a/tempest_lib/services/network/subnetpools_client.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2015 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_lib.services.network import base - - -class SubnetpoolsClient(base.BaseNetworkClient): - - def list_subnetpools(self, **filters): - uri = '/subnetpools' - return self.list_resources(uri, **filters) - - def create_subnetpool(self, **kwargs): - uri = '/subnetpools' - post_data = {'subnetpool': kwargs} - return self.create_resource(uri, post_data) - - def show_subnetpool(self, subnetpool_id, **fields): - uri = '/subnetpools/%s' % subnetpool_id - return self.show_resource(uri, **fields) - - def update_subnetpool(self, subnetpool_id, **kwargs): - uri = '/subnetpools/%s' % subnetpool_id - post_data = {'subnetpool': kwargs} - return self.update_resource(uri, post_data) - - def delete_subnetpool(self, subnetpool_id): - uri = '/subnetpools/%s' % subnetpool_id - return self.delete_resource(uri) diff --git a/tempest_lib/services/network/subnets_client.py b/tempest_lib/services/network/subnets_client.py deleted file mode 100644 index 4b50047..0000000 --- a/tempest_lib/services/network/subnets_client.py +++ /dev/null @@ -1,47 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest_lib.services.network import base - - -class SubnetsClient(base.BaseNetworkClient): - - def create_subnet(self, **kwargs): - uri = '/subnets' - post_data = {'subnet': kwargs} - return self.create_resource(uri, post_data) - - def update_subnet(self, subnet_id, **kwargs): - uri = '/subnets/%s' % subnet_id - post_data = {'subnet': kwargs} - return self.update_resource(uri, post_data) - - def show_subnet(self, subnet_id, **fields): - uri = '/subnets/%s' % subnet_id - return self.show_resource(uri, **fields) - - def delete_subnet(self, subnet_id): - uri = '/subnets/%s' % subnet_id - return self.delete_resource(uri) - - def list_subnets(self, **filters): - uri = '/subnets' - return self.list_resources(uri, **filters) - - def create_bulk_subnets(self, **kwargs): - """Create multiple subnets in a single request. - - Available params: see http://developer.openstack.org/ - api-ref-networking-v2.html#bulkCreateSubnet - """ - uri = '/subnets' - return self.create_resource(uri, kwargs) diff --git a/tempest_lib/tests/__init__.py b/tempest_lib/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/tests/base.py b/tempest_lib/tests/base.py deleted file mode 100644 index fe9268e..0000000 --- a/tempest_lib/tests/base.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2013 IBM Corp. -# -# 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 oslotest import base -from oslotest import moxstubout - - -class TestCase(base.BaseTestCase): - - def setUp(self): - super(TestCase, self).setUp() - mox_fixture = self.useFixture(moxstubout.MoxStubout()) - self.mox = mox_fixture.mox - self.stubs = mox_fixture.stubs - - def patch(self, target, **kwargs): - """Returns a started `mock.patch` object for the supplied target. - - The caller may then call the returned patcher to create a mock object. - - The caller does not need to call stop() on the returned - patcher object, as this method automatically adds a cleanup - to the test class to stop the patcher. - - :param target: String module.class or module.object expression to patch - :param **kwargs: Passed as-is to `mock.patch`. See mock documentation - for details. - """ - p = mock.patch(target, **kwargs) - m = p.start() - self.addCleanup(p.stop) - return m diff --git a/tempest_lib/tests/cli/__init__.py b/tempest_lib/tests/cli/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/tests/cli/test_command_failed.py b/tempest_lib/tests/cli/test_command_failed.py deleted file mode 100644 index 17543e9..0000000 --- a/tempest_lib/tests/cli/test_command_failed.py +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest_lib import exceptions -from tempest_lib.tests import base - - -class TestOutputParser(base.TestCase): - - def test_command_failed_exception(self): - returncode = 1 - cmd = "foo" - stdout = "output" - stderr = "error" - try: - raise exceptions.CommandFailed(returncode, cmd, stdout, stderr) - except exceptions.CommandFailed as e: - self.assertIn(str(returncode), str(e)) - self.assertIn(cmd, str(e)) - self.assertIn(stdout, str(e)) - self.assertIn(stderr, str(e)) diff --git a/tempest_lib/tests/cli/test_execute.py b/tempest_lib/tests/cli/test_execute.py deleted file mode 100644 index c86f190..0000000 --- a/tempest_lib/tests/cli/test_execute.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -from tempest_lib.cli import base as cli_base -from tempest_lib import exceptions -from tempest_lib.tests import base - - -class TestExecute(base.TestCase): - def test_execute_success(self): - result = cli_base.execute("/bin/ls", action="tempest_lib", - flags="-l -a") - self.assertIsInstance(result, str) - self.assertIn("__init__.py", result) - - def test_execute_failure(self): - result = cli_base.execute("/bin/ls", action="tempest_lib", - flags="--foobar", merge_stderr=True, - fail_ok=True) - self.assertIsInstance(result, str) - self.assertIn("--foobar", result) - - def test_execute_failure_raise_exception(self): - self.assertRaises(exceptions.CommandFailed, cli_base.execute, - "/bin/ls", action="tempest_lib", flags="--foobar", - merge_stderr=True) diff --git a/tempest_lib/tests/cli/test_output_parser.py b/tempest_lib/tests/cli/test_output_parser.py deleted file mode 100644 index 3aa7e91..0000000 --- a/tempest_lib/tests/cli/test_output_parser.py +++ /dev/null @@ -1,177 +0,0 @@ -# Copyright 2014 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_lib.cli import output_parser -from tempest_lib import exceptions -from tempest_lib.tests import base - - -class TestOutputParser(base.TestCase): - OUTPUT_LINES = """ -+----+------+---------+ -| ID | Name | Status | -+----+------+---------+ -| 11 | foo | BUILD | -| 21 | bar | ERROR | -| 31 | bee | None | -+----+------+---------+ -""" - OUTPUT_LINES2 = """ -+----+-------+---------+ -| ID | Name2 | Status2 | -+----+-------+---------+ -| 41 | aaa | SSSSS | -| 51 | bbb | TTTTT | -| 61 | ccc | AAAAA | -+----+-------+---------+ -""" - - EXPECTED_TABLE = {'headers': ['ID', 'Name', 'Status'], - 'values': [['11', 'foo', 'BUILD'], - ['21', 'bar', 'ERROR'], - ['31', 'bee', 'None']]} - EXPECTED_TABLE2 = {'headers': ['ID', 'Name2', 'Status2'], - 'values': [['41', 'aaa', 'SSSSS'], - ['51', 'bbb', 'TTTTT'], - ['61', 'ccc', 'AAAAA']]} - - def test_table_with_normal_values(self): - actual = output_parser.table(self.OUTPUT_LINES) - self.assertIsInstance(actual, dict) - self.assertEqual(self.EXPECTED_TABLE, actual) - - def test_table_with_list(self): - output_lines = self.OUTPUT_LINES.split('\n') - actual = output_parser.table(output_lines) - self.assertIsInstance(actual, dict) - self.assertEqual(self.EXPECTED_TABLE, actual) - - def test_table_with_invalid_line(self): - output_lines = self.OUTPUT_LINES + "aaaa" - actual = output_parser.table(output_lines) - self.assertIsInstance(actual, dict) - self.assertEqual(self.EXPECTED_TABLE, actual) - - def test_tables_with_normal_values(self): - output_lines = ('test' + self.OUTPUT_LINES + - 'test2' + self.OUTPUT_LINES2) - expected = [{'headers': self.EXPECTED_TABLE['headers'], - 'label': 'test', - 'values': self.EXPECTED_TABLE['values']}, - {'headers': self.EXPECTED_TABLE2['headers'], - 'label': 'test2', - 'values': self.EXPECTED_TABLE2['values']}] - actual = output_parser.tables(output_lines) - self.assertIsInstance(actual, list) - self.assertEqual(expected, actual) - - def test_tables_with_invalid_values(self): - output_lines = ('test' + self.OUTPUT_LINES + - 'test2' + self.OUTPUT_LINES2 + '\n') - expected = [{'headers': self.EXPECTED_TABLE['headers'], - 'label': 'test', - 'values': self.EXPECTED_TABLE['values']}, - {'headers': self.EXPECTED_TABLE2['headers'], - 'label': 'test2', - 'values': self.EXPECTED_TABLE2['values']}] - actual = output_parser.tables(output_lines) - self.assertIsInstance(actual, list) - self.assertEqual(expected, actual) - - def test_tables_with_invalid_line(self): - output_lines = ('test' + self.OUTPUT_LINES + - 'test2' + self.OUTPUT_LINES2 + - '+----+-------+---------+') - expected = [{'headers': self.EXPECTED_TABLE['headers'], - 'label': 'test', - 'values': self.EXPECTED_TABLE['values']}, - {'headers': self.EXPECTED_TABLE2['headers'], - 'label': 'test2', - 'values': self.EXPECTED_TABLE2['values']}] - - actual = output_parser.tables(output_lines) - self.assertIsInstance(actual, list) - self.assertEqual(expected, actual) - - LISTING_OUTPUT = """ -+----+ -| ID | -+----+ -| 11 | -| 21 | -| 31 | -+----+ -""" - - def test_listing(self): - expected = [{'ID': '11'}, {'ID': '21'}, {'ID': '31'}] - actual = output_parser.listing(self.LISTING_OUTPUT) - self.assertIsInstance(actual, list) - self.assertEqual(expected, actual) - - def test_details_multiple_with_invalid_line(self): - self.assertRaises(exceptions.InvalidStructure, - output_parser.details_multiple, - self.OUTPUT_LINES) - - DETAILS_LINES1 = """First Table -+----------+--------+ -| Property | Value | -+----------+--------+ -| foo | BUILD | -| bar | ERROR | -| bee | None | -+----------+--------+ -""" - DETAILS_LINES2 = """Second Table -+----------+--------+ -| Property | Value | -+----------+--------+ -| aaa | VVVVV | -| bbb | WWWWW | -| ccc | XXXXX | -+----------+--------+ -""" - - def test_details_with_normal_line_label_false(self): - expected = {'foo': 'BUILD', 'bar': 'ERROR', 'bee': 'None'} - actual = output_parser.details(self.DETAILS_LINES1) - self.assertEqual(expected, actual) - - def test_details_with_normal_line_label_true(self): - expected = {'__label': 'First Table', - 'foo': 'BUILD', 'bar': 'ERROR', 'bee': 'None'} - actual = output_parser.details(self.DETAILS_LINES1, with_label=True) - self.assertEqual(expected, actual) - - def test_details_multiple_with_normal_line_label_false(self): - expected = [{'foo': 'BUILD', 'bar': 'ERROR', 'bee': 'None'}, - {'aaa': 'VVVVV', 'bbb': 'WWWWW', 'ccc': 'XXXXX'}] - actual = output_parser.details_multiple(self.DETAILS_LINES1 + - self.DETAILS_LINES2) - self.assertIsInstance(actual, list) - self.assertEqual(expected, actual) - - def test_details_multiple_with_normal_line_label_true(self): - expected = [{'__label': 'First Table', - 'foo': 'BUILD', 'bar': 'ERROR', 'bee': 'None'}, - {'__label': 'Second Table', - 'aaa': 'VVVVV', 'bbb': 'WWWWW', 'ccc': 'XXXXX'}] - actual = output_parser.details_multiple(self.DETAILS_LINES1 + - self.DETAILS_LINES2, - with_label=True) - self.assertIsInstance(actual, list) - self.assertEqual(expected, actual) diff --git a/tempest_lib/tests/common/__init__.py b/tempest_lib/tests/common/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/tests/common/utils/__init__.py b/tempest_lib/tests/common/utils/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/tests/common/utils/test_data_utils.py b/tempest_lib/tests/common/utils/test_data_utils.py deleted file mode 100644 index 2d7b8fc..0000000 --- a/tempest_lib/tests/common/utils/test_data_utils.py +++ /dev/null @@ -1,162 +0,0 @@ -# Copyright 2014 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 netaddr - -from tempest_lib.common.utils import data_utils -from tempest_lib.tests import base - - -class TestDataUtils(base.TestCase): - - def test_rand_uuid(self): - actual = data_utils.rand_uuid() - self.assertIsInstance(actual, str) - self.assertRegexpMatches(actual, "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]" - "{4}-[0-9a-f]{4}-[0-9a-f]{12}$") - actual2 = data_utils.rand_uuid() - self.assertNotEqual(actual, actual2) - - def test_rand_uuid_hex(self): - actual = data_utils.rand_uuid_hex() - self.assertIsInstance(actual, str) - self.assertRegexpMatches(actual, "^[0-9a-f]{32}$") - - actual2 = data_utils.rand_uuid_hex() - self.assertNotEqual(actual, actual2) - - def test_rand_name(self): - actual = data_utils.rand_name() - self.assertIsInstance(actual, str) - actual2 = data_utils.rand_name() - self.assertNotEqual(actual, actual2) - - actual = data_utils.rand_name('foo') - self.assertTrue(actual.startswith('foo')) - actual2 = data_utils.rand_name('foo') - self.assertTrue(actual.startswith('foo')) - self.assertNotEqual(actual, actual2) - - def test_rand_name_with_prefix(self): - actual = data_utils.rand_name(prefix='prefix-str') - self.assertIsInstance(actual, str) - self.assertRegexpMatches(actual, "^prefix-str-") - actual2 = data_utils.rand_name(prefix='prefix-str') - self.assertNotEqual(actual, actual2) - - def test_rand_password(self): - actual = data_utils.rand_password() - self.assertIsInstance(actual, str) - self.assertRegexpMatches(actual, "[A-Za-z0-9~!@#$%^&*_=+]{15,}") - actual2 = data_utils.rand_password() - self.assertNotEqual(actual, actual2) - - def test_rand_password_with_len(self): - actual = data_utils.rand_password(8) - self.assertIsInstance(actual, str) - self.assertEqual(len(actual), 8) - self.assertRegexpMatches(actual, "[A-Za-z0-9~!@#$%^&*_=+]{8}") - actual2 = data_utils.rand_password(8) - self.assertNotEqual(actual, actual2) - - def test_rand_password_with_len_2(self): - actual = data_utils.rand_password(2) - self.assertIsInstance(actual, str) - self.assertEqual(len(actual), 3) - self.assertRegexpMatches(actual, "[A-Za-z0-9~!@#$%^&*_=+]{3}") - actual2 = data_utils.rand_password(2) - self.assertNotEqual(actual, actual2) - - def test_rand_url(self): - actual = data_utils.rand_url() - self.assertIsInstance(actual, str) - self.assertRegexpMatches(actual, "^https://url-[0-9]*\.com$") - actual2 = data_utils.rand_url() - self.assertNotEqual(actual, actual2) - - def test_rand_int(self): - actual = data_utils.rand_int_id() - self.assertIsInstance(actual, int) - - actual2 = data_utils.rand_int_id() - self.assertNotEqual(actual, actual2) - - def test_rand_mac_address(self): - actual = data_utils.rand_mac_address() - self.assertIsInstance(actual, str) - self.assertRegexpMatches(actual, "^([0-9a-f][0-9a-f]:){5}" - "[0-9a-f][0-9a-f]$") - - actual2 = data_utils.rand_mac_address() - self.assertNotEqual(actual, actual2) - - def test_parse_image_id(self): - actual = data_utils.parse_image_id("/foo/bar/deadbeaf") - self.assertEqual("deadbeaf", actual) - - def test_arbitrary_string(self): - actual = data_utils.arbitrary_string() - self.assertEqual(actual, "test") - actual = data_utils.arbitrary_string(size=30, base_text="abc") - self.assertEqual(actual, "abc" * int(30 / len("abc"))) - actual = data_utils.arbitrary_string(size=5, base_text="deadbeaf") - self.assertEqual(actual, "deadb") - - def test_random_bytes(self): - actual = data_utils.random_bytes() # default size=1024 - self.assertIsInstance(actual, str) - self.assertRegexpMatches(actual, "^[\x00-\xFF]{1024}") - actual2 = data_utils.random_bytes() - self.assertNotEqual(actual, actual2) - - actual = data_utils.random_bytes(size=2048) - self.assertRegexpMatches(actual, "^[\x00-\xFF]{2048}") - - def test_get_ipv6_addr_by_EUI64(self): - actual = data_utils.get_ipv6_addr_by_EUI64('2001:db8::', - '00:16:3e:33:44:55') - self.assertIsInstance(actual, netaddr.IPAddress) - self.assertEqual(actual, - netaddr.IPAddress('2001:db8::216:3eff:fe33:4455')) - - def test_get_ipv6_addr_by_EUI64_with_IPv4_prefix(self): - ipv4_prefix = '10.0.8' - mac = '00:16:3e:33:44:55' - self.assertRaises(TypeError, data_utils.get_ipv6_addr_by_EUI64, - ipv4_prefix, mac) - - def test_get_ipv6_addr_by_EUI64_bad_cidr_type(self): - bad_cidr = 123 - mac = '00:16:3e:33:44:55' - self.assertRaises(TypeError, data_utils.get_ipv6_addr_by_EUI64, - bad_cidr, mac) - - def test_get_ipv6_addr_by_EUI64_bad_cidr_value(self): - bad_cidr = 'bb' - mac = '00:16:3e:33:44:55' - self.assertRaises(TypeError, data_utils.get_ipv6_addr_by_EUI64, - bad_cidr, mac) - - def test_get_ipv6_addr_by_EUI64_bad_mac_value(self): - cidr = '2001:db8::' - bad_mac = '00:16:3e:33:44:5Z' - self.assertRaises(TypeError, data_utils.get_ipv6_addr_by_EUI64, - cidr, bad_mac) - - def test_get_ipv6_addr_by_EUI64_bad_mac_type(self): - cidr = '2001:db8::' - bad_mac = 99999999999999999999 - self.assertRaises(TypeError, data_utils.get_ipv6_addr_by_EUI64, - cidr, bad_mac) diff --git a/tempest_lib/tests/common/utils/test_misc.py b/tempest_lib/tests/common/utils/test_misc.py deleted file mode 100644 index aefaeef..0000000 --- a/tempest_lib/tests/common/utils/test_misc.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright 2014 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_lib.common.utils import misc -from tempest_lib.tests import base - - -@misc.singleton -class TestFoo(object): - - count = 0 - - def increment(self): - self.count += 1 - return self.count - - -@misc.singleton -class TestBar(object): - - count = 0 - - def increment(self): - self.count += 1 - return self.count - - -class TestMisc(base.TestCase): - - def test_singleton(self): - test = TestFoo() - self.assertEqual(0, test.count) - self.assertEqual(1, test.increment()) - test2 = TestFoo() - self.assertEqual(1, test.count) - self.assertEqual(1, test2.count) - self.assertEqual(test, test2) - test3 = TestBar() - self.assertNotEqual(test, test3) - - def test_find_test_caller_test_case(self): - # Calling it from here should give us the method we're in. - self.assertEqual('TestMisc:test_find_test_caller_test_case', - misc.find_test_caller()) - - def test_find_test_caller_setup_self(self): - def setUp(self): - return misc.find_test_caller() - self.assertEqual('TestMisc:setUp', setUp(self)) - - def test_find_test_caller_setup_no_self(self): - def setUp(): - return misc.find_test_caller() - self.assertEqual(':setUp', setUp()) - - def test_find_test_caller_setupclass_cls(self): - def setUpClass(cls): # noqa - return misc.find_test_caller() - self.assertEqual('TestMisc:setUpClass', setUpClass(self.__class__)) - - def test_find_test_caller_teardown_self(self): - def tearDown(self): - return misc.find_test_caller() - self.assertEqual('TestMisc:tearDown', tearDown(self)) - - def test_find_test_caller_teardown_no_self(self): - def tearDown(): - return misc.find_test_caller() - self.assertEqual(':tearDown', tearDown()) - - def test_find_test_caller_teardown_class(self): - def tearDownClass(cls): # noqa - return misc.find_test_caller() - self.assertEqual('TestMisc:tearDownClass', - tearDownClass(self.__class__)) diff --git a/tempest_lib/tests/fake_auth_provider.py b/tempest_lib/tests/fake_auth_provider.py deleted file mode 100644 index 280df66..0000000 --- a/tempest_lib/tests/fake_auth_provider.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# 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. - - -class FakeAuthProvider(object): - - def __init__(self, creds_dict={}): - self.credentials = FakeCredentials(creds_dict) - - def auth_request(self, method, url, headers=None, body=None, filters=None): - return url, headers, body - - def base_url(self, filters, auth_data=None): - return "https://example.com" - - -class FakeCredentials(object): - - def __init__(self, creds_dict): - for key in creds_dict.keys(): - setattr(self, key, creds_dict[key]) diff --git a/tempest_lib/tests/fake_credentials.py b/tempest_lib/tests/fake_credentials.py deleted file mode 100644 index 32105a1..0000000 --- a/tempest_lib/tests/fake_credentials.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# 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_lib import auth - - -class FakeCredentials(auth.Credentials): - - def is_valid(self): - return True - - -class FakeKeystoneV2Credentials(auth.KeystoneV2Credentials): - - def __init__(self): - creds = dict( - username='fake_username', - password='fake_password', - tenant_name='fake_tenant_name' - ) - super(FakeKeystoneV2Credentials, self).__init__(**creds) - - -class FakeKeystoneV3Credentials(auth.KeystoneV3Credentials): - """Fake credentials suitable for the Keystone Identity V3 API""" - - def __init__(self): - creds = dict( - username='fake_username', - password='fake_password', - user_domain_name='fake_domain_name', - project_name='fake_tenant_name', - project_domain_name='fake_domain_name' - ) - super(FakeKeystoneV3Credentials, self).__init__(**creds) - - -class FakeKeystoneV3DomainCredentials(auth.KeystoneV3Credentials): - """Fake credentials for the Keystone Identity V3 API, with no scope""" - - def __init__(self): - creds = dict( - username='fake_username', - password='fake_password', - user_domain_name='fake_domain_name' - ) - super(FakeKeystoneV3DomainCredentials, self).__init__(**creds) diff --git a/tempest_lib/tests/fake_http.py b/tempest_lib/tests/fake_http.py deleted file mode 100644 index eda202d..0000000 --- a/tempest_lib/tests/fake_http.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2013 IBM Corp. -# -# 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 copy - -import httplib2 - - -class fake_httplib2(object): - - def __init__(self, return_type=None, *args, **kwargs): - self.return_type = return_type - - def request(self, uri, method="GET", body=None, headers=None, - redirections=5, connection_type=None): - if not self.return_type: - fake_headers = httplib2.Response(headers) - return_obj = { - 'uri': uri, - 'method': method, - 'body': body, - 'headers': headers - } - return (fake_headers, return_obj) - elif isinstance(self.return_type, int): - body = body or "fake_body" - header_info = { - 'content-type': 'text/plain', - 'status': str(self.return_type), - 'content-length': len(body) - } - resp_header = httplib2.Response(header_info) - return (resp_header, body) - else: - msg = "unsupported return type %s" % self.return_type - raise TypeError(msg) - - -class fake_httplib(object): - def __init__(self, headers, body=None, - version=1.0, status=200, reason="Ok"): - """Fake httplib implementation - - :param headers: dict representing HTTP response headers - :param body: file-like object - :param version: HTTP Version - :param status: Response status code - :param reason: Status code related message. - """ - self.body = body - self.status = status - self.reason = reason - self.version = version - self.headers = headers - - def getheaders(self): - return copy.deepcopy(self.headers).items() - - def getheader(self, key, default): - return self.headers.get(key, default) - - def read(self, amt): - return self.body.read(amt) diff --git a/tempest_lib/tests/fake_identity.py b/tempest_lib/tests/fake_identity.py deleted file mode 100644 index bac2676..0000000 --- a/tempest_lib/tests/fake_identity.py +++ /dev/null @@ -1,164 +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 json - -import httplib2 - -FAKE_AUTH_URL = 'http://fake_uri.com/auth' - -TOKEN = "fake_token" -ALT_TOKEN = "alt_fake_token" - -# Fake Identity v2 constants -COMPUTE_ENDPOINTS_V2 = { - "endpoints": [ - { - "adminURL": "http://fake_url/v2/first_endpoint/admin", - "region": "NoMatchRegion", - "internalURL": "http://fake_url/v2/first_endpoint/internal", - "publicURL": "http://fake_url/v2/first_endpoint/public" - }, - { - "adminURL": "http://fake_url/v2/second_endpoint/admin", - "region": "FakeRegion", - "internalURL": "http://fake_url/v2/second_endpoint/internal", - "publicURL": "http://fake_url/v2/second_endpoint/public" - }, - ], - "type": "compute", - "name": "nova" -} - -CATALOG_V2 = [COMPUTE_ENDPOINTS_V2, ] - -ALT_IDENTITY_V2_RESPONSE = { - "access": { - "token": { - "expires": "2020-01-01T00:00:10Z", - "id": ALT_TOKEN, - "tenant": { - "id": "fake_alt_tenant_id" - }, - }, - "user": { - "id": "fake_alt_user_id", - }, - "serviceCatalog": CATALOG_V2, - }, -} - -IDENTITY_V2_RESPONSE = { - "access": { - "token": { - "expires": "2020-01-01T00:00:10Z", - "id": TOKEN, - "tenant": { - "id": "fake_tenant_id" - }, - }, - "user": { - "id": "fake_user_id", - }, - "serviceCatalog": CATALOG_V2, - }, -} - -# Fake Identity V3 constants -COMPUTE_ENDPOINTS_V3 = { - "endpoints": [ - { - "id": "first_compute_fake_service", - "interface": "public", - "region": "NoMatchRegion", - "url": "http://fake_url/v3/first_endpoint/api" - }, - { - "id": "second_fake_service", - "interface": "public", - "region": "FakeRegion", - "url": "http://fake_url/v3/second_endpoint/api" - }, - { - "id": "third_fake_service", - "interface": "admin", - "region": "MiddleEarthRegion", - "url": "http://fake_url/v3/third_endpoint/api" - } - - ], - "type": "compute", - "id": "fake_compute_endpoint" -} - -CATALOG_V3 = [COMPUTE_ENDPOINTS_V3, ] - -IDENTITY_V3_RESPONSE = { - "token": { - "methods": [ - "token", - "password" - ], - "expires_at": "2020-01-01T00:00:10.000123Z", - "project": { - "domain": { - "id": "fake_domain_id", - "name": "fake" - }, - "id": "project_id", - "name": "project_name" - }, - "user": { - "domain": { - "id": "fake_domain_id", - "name": "domain_name" - }, - "id": "fake_user_id", - "name": "username" - }, - "issued_at": "2013-05-29T16:55:21.468960Z", - "catalog": CATALOG_V3 - } -} - -ALT_IDENTITY_V3 = IDENTITY_V3_RESPONSE - - -def _fake_v3_response(self, uri, method="GET", body=None, headers=None, - redirections=5, connection_type=None): - fake_headers = { - "status": "201", - "x-subject-token": TOKEN - } - return (httplib2.Response(fake_headers), - json.dumps(IDENTITY_V3_RESPONSE)) - - -def _fake_v2_response(self, uri, method="GET", body=None, headers=None, - redirections=5, connection_type=None): - return (httplib2.Response({"status": "200"}), - json.dumps(IDENTITY_V2_RESPONSE)) - - -def _fake_auth_failure_response(): - # the response body isn't really used in this case, but lets send it anyway - # to have a safe check in some future change on the rest client. - body = { - "unauthorized": { - "message": "Unauthorized", - "code": "401" - } - } - return httplib2.Response({"status": "401"}), json.dumps(body) diff --git a/tempest_lib/tests/services/__init__.py b/tempest_lib/tests/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/tests/services/compute/__init__.py b/tempest_lib/tests/services/compute/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/tests/services/compute/base.py b/tempest_lib/tests/services/compute/base.py deleted file mode 100644 index 3e4a200..0000000 --- a/tempest_lib/tests/services/compute/base.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2015 Deutsche Telekom AG. 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 httplib2 -from oslo_serialization import jsonutils as json -from oslotest import mockpatch - -from tempest_lib.tests import base - - -class BaseComputeServiceTest(base.TestCase): - def create_response(self, body, to_utf=False, status=200, headers=None): - json_body = {} - if body: - json_body = json.dumps(body) - if to_utf: - json_body = json_body.encode('utf-8') - resp_dict = {'status': status} - if headers: - resp_dict.update(headers) - response = (httplib2.Response(resp_dict), json_body) - return response - - def check_service_client_function(self, function, function2mock, - body, to_utf=False, status=200, - headers=None, **kwargs): - mocked_response = self.create_response(body, to_utf, status, headers) - self.useFixture(mockpatch.Patch( - function2mock, return_value=mocked_response)) - if kwargs: - resp = function(**kwargs) - else: - resp = function() - self.assertEqual(body, resp) diff --git a/tempest_lib/tests/services/compute/test_agents_client.py b/tempest_lib/tests/services/compute/test_agents_client.py deleted file mode 100644 index 5a480c4..0000000 --- a/tempest_lib/tests/services/compute/test_agents_client.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright 2015 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_lib.services.compute import agents_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestAgentsClient(base.BaseComputeServiceTest): - FAKE_CREATE_AGENT = { - "agent": { - "url": "http://foo.com", - "hypervisor": "kvm", - "md5hash": "md5", - "version": "2", - "architecture": "x86_64", - "os": "linux", - "agent_id": 1 - } - } - - FAKE_UPDATE_AGENT = { - "agent": { - "url": "http://foo.com", - "md5hash": "md5", - "version": "2", - "agent_id": 1 - } - } - - def setUp(self): - super(TestAgentsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = agents_client.AgentsClient(fake_auth, - 'compute', 'regionOne') - - def _test_list_agents(self, bytes_body=False): - self.check_service_client_function( - self.client.list_agents, - 'tempest_lib.common.rest_client.RestClient.get', - {"agents": []}, - bytes_body) - self.check_service_client_function( - self.client.list_agents, - 'tempest_lib.common.rest_client.RestClient.get', - {"agents": []}, - bytes_body, - hypervisor="kvm") - - def _test_create_agent(self, bytes_body=False): - self.check_service_client_function( - self.client.create_agent, - 'tempest_lib.common.rest_client.RestClient.post', - self.FAKE_CREATE_AGENT, - bytes_body, - url="http://foo.com", hypervisor="kvm", md5hash="md5", - version="2", architecture="x86_64", os="linux") - - def _test_delete_agent(self): - self.check_service_client_function( - self.client.delete_agent, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, agent_id="1") - - def _test_update_agent(self, bytes_body=False): - self.check_service_client_function( - self.client.update_agent, - 'tempest_lib.common.rest_client.RestClient.put', - self.FAKE_UPDATE_AGENT, - bytes_body, - agent_id="1", url="http://foo.com", md5hash="md5", version="2") - - def test_list_agents_with_str_body(self): - self._test_list_agents() - - def test_list_agents_with_bytes_body(self): - self._test_list_agents(bytes_body=True) - - def test_create_agent_with_str_body(self): - self._test_create_agent() - - def test_create_agent_with_bytes_body(self): - self._test_create_agent(bytes_body=True) - - def test_delete_agent(self): - self._test_delete_agent() - - def test_update_agent_with_str_body(self): - self._test_update_agent() - - def test_update_agent_with_bytes_body(self): - self._test_update_agent(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_aggregates_client.py b/tempest_lib/tests/services/compute/test_aggregates_client.py deleted file mode 100644 index b63ed72..0000000 --- a/tempest_lib/tests/services/compute/test_aggregates_client.py +++ /dev/null @@ -1,192 +0,0 @@ -# Copyright 2015 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_lib.services.compute import aggregates_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestAggregatesClient(base.BaseComputeServiceTest): - FAKE_SHOW_AGGREGATE = { - "aggregate": - { - "name": "hoge", - "availability_zone": None, - "deleted": False, - "created_at": - "2015-07-16T03:07:32.000000", - "updated_at": None, - "hosts": [], - "deleted_at": None, - "id": 1, - "metadata": {} - } - } - - FAKE_CREATE_AGGREGATE = { - "aggregate": - { - "name": u'\xf4', - "availability_zone": None, - "deleted": False, - "created_at": "2015-07-21T04:11:18.000000", - "updated_at": None, - "deleted_at": None, - "id": 1 - } - } - - FAKE_UPDATE_AGGREGATE = { - "aggregate": - { - "name": u'\xe9', - "availability_zone": None, - "deleted": False, - "created_at": "2015-07-16T03:07:32.000000", - "updated_at": "2015-07-23T05:16:29.000000", - "hosts": [], - "deleted_at": None, - "id": 1, - "metadata": {} - } - } - - FAKE_AGGREGATE = { - "availability_zone": "nova", - "created_at": "2013-08-18T12:17:56.297823", - "deleted": False, - "deleted_at": None, - "hosts": [ - "21549b2f665945baaa7101926a00143c" - ], - "id": 1, - "metadata": { - "availability_zone": "nova" - }, - "name": u'\xe9', - "updated_at": None - } - - FAKE_ADD_HOST = {'aggregate': FAKE_AGGREGATE} - FAKE_REMOVE_HOST = {'aggregate': FAKE_AGGREGATE} - FAKE_SET_METADATA = {'aggregate': FAKE_AGGREGATE} - - def setUp(self): - super(TestAggregatesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = aggregates_client.AggregatesClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_aggregates(self, bytes_body=False): - self.check_service_client_function( - self.client.list_aggregates, - 'tempest_lib.common.rest_client.RestClient.get', - {"aggregates": []}, - bytes_body) - - def test_list_aggregates_with_str_body(self): - self._test_list_aggregates() - - def test_list_aggregates_with_bytes_body(self): - self._test_list_aggregates(bytes_body=True) - - def _test_show_aggregate(self, bytes_body=False): - self.check_service_client_function( - self.client.show_aggregate, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_SHOW_AGGREGATE, - bytes_body, - aggregate_id=1) - - def test_show_aggregate_with_str_body(self): - self._test_show_aggregate() - - def test_show_aggregate_with_bytes_body(self): - self._test_show_aggregate(bytes_body=True) - - def _test_create_aggregate(self, bytes_body=False): - self.check_service_client_function( - self.client.create_aggregate, - 'tempest_lib.common.rest_client.RestClient.post', - self.FAKE_CREATE_AGGREGATE, - bytes_body, - name='hoge') - - def test_create_aggregate_with_str_body(self): - self._test_create_aggregate() - - def test_create_aggregate_with_bytes_body(self): - self._test_create_aggregate(bytes_body=True) - - def test_delete_aggregate(self): - self.check_service_client_function( - self.client.delete_aggregate, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, aggregate_id="1") - - def _test_update_aggregate(self, bytes_body=False): - self.check_service_client_function( - self.client.update_aggregate, - 'tempest_lib.common.rest_client.RestClient.put', - self.FAKE_UPDATE_AGGREGATE, - bytes_body, - aggregate_id=1) - - def test_update_aggregate_with_str_body(self): - self._test_update_aggregate() - - def test_update_aggregate_with_bytes_body(self): - self._test_update_aggregate(bytes_body=True) - - def _test_add_host(self, bytes_body=False): - self.check_service_client_function( - self.client.add_host, - 'tempest_lib.common.rest_client.RestClient.post', - self.FAKE_ADD_HOST, - bytes_body, - aggregate_id=1) - - def test_add_host_with_str_body(self): - self._test_add_host() - - def test_add_host_with_bytes_body(self): - self._test_add_host(bytes_body=True) - - def _test_remove_host(self, bytes_body=False): - self.check_service_client_function( - self.client.remove_host, - 'tempest_lib.common.rest_client.RestClient.post', - self.FAKE_REMOVE_HOST, - bytes_body, - aggregate_id=1) - - def test_remove_host_with_str_body(self): - self._test_remove_host() - - def test_remove_host_with_bytes_body(self): - self._test_remove_host(bytes_body=True) - - def _test_set_metadata(self, bytes_body=False): - self.check_service_client_function( - self.client.set_metadata, - 'tempest_lib.common.rest_client.RestClient.post', - self.FAKE_SET_METADATA, - bytes_body, - aggregate_id=1) - - def test_set_metadata_with_str_body(self): - self._test_set_metadata() - - def test_set_metadata_with_bytes_body(self): - self._test_set_metadata(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_availability_zone_client.py b/tempest_lib/tests/services/compute/test_availability_zone_client.py deleted file mode 100644 index 0a97bbf..0000000 --- a/tempest_lib/tests/services/compute/test_availability_zone_client.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2015 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_lib.services.compute import availability_zone_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestAvailabilityZoneClient(base.BaseComputeServiceTest): - - FAKE_AVAILABIRITY_ZONE_INFO = { - "availabilityZoneInfo": - [ - { - "zoneState": { - "available": True - }, - "hosts": None, - "zoneName": u'\xf4' - } - ] - } - - def setUp(self): - super(TestAvailabilityZoneClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = availability_zone_client.AvailabilityZoneClient( - fake_auth, 'compute', 'regionOne') - - def test_list_availability_zones_with_str_body(self): - self.check_service_client_function( - self.client.list_availability_zones, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_AVAILABIRITY_ZONE_INFO) - - def test_list_availability_zones_with_bytes_body(self): - self.check_service_client_function( - self.client.list_availability_zones, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_AVAILABIRITY_ZONE_INFO, to_utf=True) diff --git a/tempest_lib/tests/services/compute/test_baremetal_nodes_client.py b/tempest_lib/tests/services/compute/test_baremetal_nodes_client.py deleted file mode 100644 index 0844fef..0000000 --- a/tempest_lib/tests/services/compute/test_baremetal_nodes_client.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2015 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 copy - -from tempest_lib.services.compute import baremetal_nodes_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestBareMetalNodesClient(base.BaseComputeServiceTest): - - FAKE_NODE_INFO = {'cpus': '8', - 'disk_gb': '64', - 'host': '10.0.2.15', - 'id': 'Identifier', - 'instance_uuid': "null", - 'interfaces': [ - { - "address": "20::01", - "datapath_id": "null", - "id": 1, - "port_no": None - } - ], - 'memory_mb': '8192', - 'task_state': None} - - def setUp(self): - super(TestBareMetalNodesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.baremetal_nodes_client = (baremetal_nodes_client. - BaremetalNodesClient - (fake_auth, 'compute', - 'regionOne')) - - def _test_bareMetal_nodes(self, operation='list', bytes_body=False): - if operation != 'list': - expected = {"node": self.FAKE_NODE_INFO} - function = self.baremetal_nodes_client.show_baremetal_node - else: - node_info = copy.deepcopy(self.FAKE_NODE_INFO) - del node_info['instance_uuid'] - expected = {"nodes": [node_info]} - function = self.baremetal_nodes_client.list_baremetal_nodes - - self.check_service_client_function( - function, - 'tempest_lib.common.rest_client.RestClient.get', - expected, bytes_body, 200, - baremetal_node_id='Identifier') - - def test_list_bareMetal_nodes_with_str_body(self): - self._test_bareMetal_nodes() - - def test_list_bareMetal_nodes_with_bytes_body(self): - self._test_bareMetal_nodes(bytes_body=True) - - def test_show_bareMetal_node_with_str_body(self): - self._test_bareMetal_nodes('show') - - def test_show_bareMetal_node_with_bytes_body(self): - self._test_bareMetal_nodes('show', True) diff --git a/tempest_lib/tests/services/compute/test_certificates_client.py b/tempest_lib/tests/services/compute/test_certificates_client.py deleted file mode 100644 index 9d5e50a..0000000 --- a/tempest_lib/tests/services/compute/test_certificates_client.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2015 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 copy - -from tempest_lib.services.compute import certificates_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestCertificatesClient(base.BaseComputeServiceTest): - - FAKE_CERTIFICATE = { - "certificate": { - "data": "-----BEGIN----MIICyzCCAjSgAwI----END CERTIFICATE-----\n", - "private_key": None - } - } - - def setUp(self): - super(TestCertificatesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = certificates_client.CertificatesClient( - fake_auth, 'compute', 'regionOne') - - def _test_show_certificate(self, bytes_body=False): - self.check_service_client_function( - self.client.show_certificate, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_CERTIFICATE, - bytes_body, - certificate_id="fake-id") - - def test_show_certificate_with_str_body(self): - self._test_show_certificate() - - def test_show_certificate_with_bytes_body(self): - self._test_show_certificate(bytes_body=True) - - def _test_create_certificate(self, bytes_body=False): - cert = copy.deepcopy(self.FAKE_CERTIFICATE) - cert['certificate']['private_key'] = "my_private_key" - self.check_service_client_function( - self.client.create_certificate, - 'tempest_lib.common.rest_client.RestClient.post', - cert, - bytes_body) - - def test_create_certificate_with_str_body(self): - self._test_create_certificate() - - def test_create_certificate_with_bytes_body(self): - self._test_create_certificate(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_extensions_client.py b/tempest_lib/tests/services/compute/test_extensions_client.py deleted file mode 100644 index 084300f..0000000 --- a/tempest_lib/tests/services/compute/test_extensions_client.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2015 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_lib.services.compute import extensions_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestExtensionsClient(base.BaseComputeServiceTest): - - FAKE_SHOW_EXTENSION = { - "extension": { - "updated": "2011-06-09T00:00:00Z", - "name": "Multinic", - "links": [], - "namespace": - "http://docs.openstack.org/compute/ext/multinic/api/v1.1", - "alias": "NMN", - "description": u'\u2740(*\xb4\u25e1`*)\u2740' - } - } - - def setUp(self): - super(TestExtensionsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = extensions_client.ExtensionsClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_extensions(self, bytes_body=False): - self.check_service_client_function( - self.client.list_extensions, - 'tempest_lib.common.rest_client.RestClient.get', - {"extensions": []}, - bytes_body) - - def test_list_extensions_with_str_body(self): - self._test_list_extensions() - - def test_list_extensions_with_bytes_body(self): - self._test_list_extensions(bytes_body=True) - - def _test_show_extension(self, bytes_body=False): - self.check_service_client_function( - self.client.show_extension, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_SHOW_EXTENSION, - bytes_body, - extension_alias="NMN") - - def test_show_extension_with_str_body(self): - self._test_show_extension() - - def test_show_extension_with_bytes_body(self): - self._test_show_extension(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_fixedIPs_client.py b/tempest_lib/tests/services/compute/test_fixedIPs_client.py deleted file mode 100644 index efa4e22..0000000 --- a/tempest_lib/tests/services/compute/test_fixedIPs_client.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2015 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_lib.services.compute import fixed_ips_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestFixedIPsClient(base.BaseComputeServiceTest): - FIXED_IP_INFO = {"fixed_ip": {"address": "10.0.0.1", - "cidr": "10.11.12.0/24", - "host": "localhost", - "hostname": "OpenStack"}} - - def setUp(self): - super(TestFixedIPsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.fixedIPsClient = (fixed_ips_client. - FixedIPsClient - (fake_auth, 'compute', - 'regionOne')) - - def _test_show_fixed_ip(self, bytes_body=False): - self.check_service_client_function( - self.fixedIPsClient.show_fixed_ip, - 'tempest_lib.common.rest_client.RestClient.get', - self.FIXED_IP_INFO, bytes_body, - status=200, fixed_ip='Identifier') - - def test_show_fixed_ip_with_str_body(self): - self._test_show_fixed_ip() - - def test_show_fixed_ip_with_bytes_body(self): - self._test_show_fixed_ip(True) - - def _test_reserve_fixed_ip(self, bytes_body=False): - self.check_service_client_function( - self.fixedIPsClient.reserve_fixed_ip, - 'tempest_lib.common.rest_client.RestClient.post', - {}, bytes_body, - status=202, fixed_ip='Identifier') - - def test_reserve_fixed_ip_with_str_body(self): - self._test_reserve_fixed_ip() - - def test_reserve_fixed_ip_with_bytes_body(self): - self._test_reserve_fixed_ip(True) diff --git a/tempest_lib/tests/services/compute/test_flavors_client.py b/tempest_lib/tests/services/compute/test_flavors_client.py deleted file mode 100644 index a6cec39..0000000 --- a/tempest_lib/tests/services/compute/test_flavors_client.py +++ /dev/null @@ -1,255 +0,0 @@ -# Copyright 2015 IBM Corp. -# -# 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 copy -import httplib2 - -from oslo_serialization import jsonutils as json -from oslotest import mockpatch - -from tempest_lib.services.compute import flavors_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestFlavorsClient(base.BaseComputeServiceTest): - - FAKE_FLAVOR = { - "disk": 1, - "id": "1", - "links": [{ - "href": "http://openstack.example.com/v2/openstack/flavors/1", - "rel": "self"}, { - "href": "http://openstack.example.com/openstack/flavors/1", - "rel": "bookmark"}], - "name": "m1.tiny", - "ram": 512, - "swap": 1, - "vcpus": 1 - } - - EXTRA_SPECS = {"extra_specs": { - "key1": "value1", - "key2": "value2"} - } - - FAKE_FLAVOR_ACCESS = { - "flavor_id": "10", - "tenant_id": "1a951d988e264818afe520e78697dcbf" - } - - def setUp(self): - super(TestFlavorsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = flavors_client.FlavorsClient(fake_auth, - 'compute', 'regionOne') - - def _test_list_flavors(self, bytes_body=False): - flavor = copy.deepcopy(TestFlavorsClient.FAKE_FLAVOR) - # Remove extra attributes - for attribute in ('disk', 'vcpus', 'ram', 'swap'): - del flavor[attribute] - expected = {'flavors': [flavor]} - self.check_service_client_function( - self.client.list_flavors, - 'tempest_lib.common.rest_client.RestClient.get', - expected, - bytes_body) - - def test_list_flavors_str_body(self): - self._test_list_flavors(bytes_body=False) - - def test_list_flavors_byte_body(self): - self._test_list_flavors(bytes_body=True) - - def _test_show_flavor(self, bytes_body=False): - expected = {"flavor": TestFlavorsClient.FAKE_FLAVOR} - self.check_service_client_function( - self.client.show_flavor, - 'tempest_lib.common.rest_client.RestClient.get', - expected, - bytes_body, - flavor_id='fake-id') - - def test_show_flavor_str_body(self): - self._test_show_flavor(bytes_body=False) - - def test_show_flavor_byte_body(self): - self._test_show_flavor(bytes_body=True) - - def _test_create_flavor(self, bytes_body=False): - expected = {"flavor": TestFlavorsClient.FAKE_FLAVOR} - request = copy.deepcopy(TestFlavorsClient.FAKE_FLAVOR) - # The 'links' parameter should not be passed in - del request['links'] - self.check_service_client_function( - self.client.create_flavor, - 'tempest_lib.common.rest_client.RestClient.post', - expected, - bytes_body, - **request) - - def test_create_flavor_str_body(self): - self._test_create_flavor(bytes_body=False) - - def test_create_flavor__byte_body(self): - self._test_create_flavor(bytes_body=True) - - def test_delete_flavor(self): - self.check_service_client_function( - self.client.delete_flavor, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, status=202, flavor_id='c782b7a9-33cd-45f0-b795-7f87f456408b') - - def _test_is_resource_deleted(self, flavor_id, is_deleted=True, - bytes_body=False): - body = json.dumps({'flavors': [TestFlavorsClient.FAKE_FLAVOR]}) - if bytes_body: - body = body.encode('utf-8') - response = (httplib2.Response({'status': 200}), body) - self.useFixture(mockpatch.Patch( - 'tempest_lib.common.rest_client.RestClient.get', - return_value=response)) - self.assertEqual(is_deleted, - self.client.is_resource_deleted(flavor_id)) - - def test_is_resource_deleted_true_str_body(self): - self._test_is_resource_deleted('2', bytes_body=False) - - def test_is_resource_deleted_true_byte_body(self): - self._test_is_resource_deleted('2', bytes_body=True) - - def test_is_resource_deleted_false_str_body(self): - self._test_is_resource_deleted('1', is_deleted=False, bytes_body=False) - - def test_is_resource_deleted_false_byte_body(self): - self._test_is_resource_deleted('1', is_deleted=False, bytes_body=True) - - def _test_set_flavor_extra_spec(self, bytes_body=False): - self.check_service_client_function( - self.client.set_flavor_extra_spec, - 'tempest_lib.common.rest_client.RestClient.post', - TestFlavorsClient.EXTRA_SPECS, - bytes_body, - flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6', - **TestFlavorsClient.EXTRA_SPECS) - - def test_set_flavor_extra_spec_str_body(self): - self._test_set_flavor_extra_spec(bytes_body=False) - - def test_set_flavor_extra_spec_byte_body(self): - self._test_set_flavor_extra_spec(bytes_body=True) - - def _test_list_flavor_extra_specs(self, bytes_body=False): - self.check_service_client_function( - self.client.list_flavor_extra_specs, - 'tempest_lib.common.rest_client.RestClient.get', - TestFlavorsClient.EXTRA_SPECS, - bytes_body, - flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6') - - def test_list_flavor_extra_specs_str_body(self): - self._test_list_flavor_extra_specs(bytes_body=False) - - def test_list_flavor_extra_specs__byte_body(self): - self._test_list_flavor_extra_specs(bytes_body=True) - - def _test_show_flavor_extra_spec(self, bytes_body=False): - expected = {"key": "value"} - self.check_service_client_function( - self.client.show_flavor_extra_spec, - 'tempest_lib.common.rest_client.RestClient.get', - expected, - bytes_body, - flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6', - key='key') - - def test_show_flavor_extra_spec_str_body(self): - self._test_show_flavor_extra_spec(bytes_body=False) - - def test_show_flavor_extra_spec__byte_body(self): - self._test_show_flavor_extra_spec(bytes_body=True) - - def _test_update_flavor_extra_spec(self, bytes_body=False): - expected = {"key1": "value"} - self.check_service_client_function( - self.client.update_flavor_extra_spec, - 'tempest_lib.common.rest_client.RestClient.put', - expected, - bytes_body, - flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6', - key='key1', **expected) - - def test_update_flavor_extra_spec_str_body(self): - self._test_update_flavor_extra_spec(bytes_body=False) - - def test_update_flavor_extra_spec_byte_body(self): - self._test_update_flavor_extra_spec(bytes_body=True) - - def test_unset_flavor_extra_spec(self): - self.check_service_client_function( - self.client.unset_flavor_extra_spec, - 'tempest_lib.common.rest_client.RestClient.delete', {}, - flavor_id='c782b7a9-33cd-45f0-b795-7f87f456408b', key='key') - - def _test_list_flavor_access(self, bytes_body=False): - expected = {'flavor_access': [TestFlavorsClient.FAKE_FLAVOR_ACCESS]} - self.check_service_client_function( - self.client.list_flavor_access, - 'tempest_lib.common.rest_client.RestClient.get', - expected, - bytes_body, - flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6') - - def test_list_flavor_access_str_body(self): - self._test_list_flavor_access(bytes_body=False) - - def test_list_flavor_access_byte_body(self): - self._test_list_flavor_access(bytes_body=True) - - def _test_add_flavor_access(self, bytes_body=False): - expected = { - "flavor_access": [TestFlavorsClient.FAKE_FLAVOR_ACCESS] - } - self.check_service_client_function( - self.client.add_flavor_access, - 'tempest_lib.common.rest_client.RestClient.post', - expected, - bytes_body, - flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6', - tenant_id='1a951d988e264818afe520e78697dcbf') - - def test_add_flavor_access_str_body(self): - self._test_add_flavor_access(bytes_body=False) - - def test_add_flavor_access_byte_body(self): - self._test_add_flavor_access(bytes_body=True) - - def _test_remove_flavor_access(self, bytes_body=False): - expected = { - "flavor_access": [TestFlavorsClient.FAKE_FLAVOR_ACCESS] - } - self.check_service_client_function( - self.client.remove_flavor_access, - 'tempest_lib.common.rest_client.RestClient.post', - expected, - bytes_body, - flavor_id='10', - tenant_id='a6edd4d66ad04245b5d2d8716ecc91e3') - - def test_remove_flavor_access_str_body(self): - self._test_remove_flavor_access(bytes_body=False) - - def test_remove_flavor_access_byte_body(self): - self._test_remove_flavor_access(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_floating_ip_pools_client.py b/tempest_lib/tests/services/compute/test_floating_ip_pools_client.py deleted file mode 100644 index 21f9c46..0000000 --- a/tempest_lib/tests/services/compute/test_floating_ip_pools_client.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2015 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_lib.services.compute import floating_ip_pools_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestFloatingIPPoolsClient(base.BaseComputeServiceTest): - - FAKE_FLOATING_IP_POOLS = { - "floating_ip_pools": - [ - {"name": u'\u3042'}, - {"name": u'\u3044'} - ] - } - - def setUp(self): - super(TestFloatingIPPoolsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = floating_ip_pools_client.FloatingIPPoolsClient( - fake_auth, 'compute', 'regionOne') - - def test_list_floating_ip_pools_with_str_body(self): - self.check_service_client_function( - self.client.list_floating_ip_pools, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_FLOATING_IP_POOLS) - - def test_list_floating_ip_pools_with_bytes_body(self): - self.check_service_client_function( - self.client.list_floating_ip_pools, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_FLOATING_IP_POOLS, to_utf=True) diff --git a/tempest_lib/tests/services/compute/test_floating_ips_bulk_client.py b/tempest_lib/tests/services/compute/test_floating_ips_bulk_client.py deleted file mode 100644 index 6926c35..0000000 --- a/tempest_lib/tests/services/compute/test_floating_ips_bulk_client.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright 2015 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_lib.tests import fake_auth_provider - -from tempest_lib.services.compute import floating_ips_bulk_client -from tempest_lib.tests.services.compute import base - - -class TestFloatingIPsBulkClient(base.BaseComputeServiceTest): - - FAKE_FIP_BULK_LIST = {"floating_ip_info": [{ - "address": "10.10.10.1", - "instance_uuid": None, - "fixed_ip": None, - "interface": "eth0", - "pool": "nova", - "project_id": None - }, - { - "address": "10.10.10.2", - "instance_uuid": None, - "fixed_ip": None, - "interface": "eth0", - "pool": "nova", - "project_id": None - }]} - - def setUp(self): - super(TestFloatingIPsBulkClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = floating_ips_bulk_client.FloatingIPsBulkClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_floating_ips_bulk(self, bytes_body=False): - self.check_service_client_function( - self.client.list_floating_ips_bulk, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_FIP_BULK_LIST, - to_utf=bytes_body) - - def _test_create_floating_ips_bulk(self, bytes_body=False): - fake_fip_create_data = {"floating_ips_bulk_create": { - "ip_range": "192.168.1.0/24", "pool": "nova", "interface": "eth0"}} - self.check_service_client_function( - self.client.create_floating_ips_bulk, - 'tempest_lib.common.rest_client.RestClient.post', - fake_fip_create_data, - to_utf=bytes_body, - ip_range="192.168.1.0/24", pool="nova", interface="eth0") - - def _test_delete_floating_ips_bulk(self, bytes_body=False): - fake_fip_delete_data = {"floating_ips_bulk_delete": "192.168.1.0/24"} - self.check_service_client_function( - self.client.delete_floating_ips_bulk, - 'tempest_lib.common.rest_client.RestClient.put', - fake_fip_delete_data, - to_utf=bytes_body, - ip_range="192.168.1.0/24") - - def test_list_floating_ips_bulk_with_str_body(self): - self._test_list_floating_ips_bulk() - - def test_list_floating_ips_bulk_with_bytes_body(self): - self._test_list_floating_ips_bulk(True) - - def test_create_floating_ips_bulk_with_str_body(self): - self._test_create_floating_ips_bulk() - - def test_create_floating_ips_bulk_with_bytes_body(self): - self._test_create_floating_ips_bulk(True) - - def test_delete_floating_ips_bulk_with_str_body(self): - self._test_delete_floating_ips_bulk() - - def test_delete_floating_ips_bulk_with_bytes_body(self): - self._test_delete_floating_ips_bulk(True) diff --git a/tempest_lib/tests/services/compute/test_floating_ips_client.py b/tempest_lib/tests/services/compute/test_floating_ips_client.py deleted file mode 100644 index 01796e5..0000000 --- a/tempest_lib/tests/services/compute/test_floating_ips_client.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright 2015 IBM Corp. -# -# 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 oslotest import mockpatch - -from tempest_lib import exceptions as lib_exc -from tempest_lib.services.compute import floating_ips_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestFloatingIpsClient(base.BaseComputeServiceTest): - - floating_ip = {"fixed_ip": None, - "id": "46d61064-13ba-4bf0-9557-69de824c3d6f", - "instance_id": "a1daa443-a6bb-463e-aea2-104b7d912eb8", - "ip": "10.10.10.1", - "pool": "nova"} - - def setUp(self): - super(TestFloatingIpsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = floating_ips_client.FloatingIPsClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_floating_ips(self, bytes_body=False): - expected = {'floating_ips': [TestFloatingIpsClient.floating_ip]} - self.check_service_client_function( - self.client.list_floating_ips, - 'tempest_lib.common.rest_client.RestClient.get', - expected, - bytes_body) - - def test_list_floating_ips_str_body(self): - self._test_list_floating_ips(bytes_body=False) - - def test_list_floating_ips_byte_body(self): - self._test_list_floating_ips(bytes_body=True) - - def _test_show_floating_ip(self, bytes_body=False): - expected = {"floating_ip": TestFloatingIpsClient.floating_ip} - self.check_service_client_function( - self.client.show_floating_ip, - 'tempest_lib.common.rest_client.RestClient.get', - expected, - bytes_body, - floating_ip_id='a1daa443-a6bb-463e-aea2-104b7d912eb8') - - def test_show_floating_ip_str_body(self): - self._test_show_floating_ip(bytes_body=False) - - def test_show_floating_ip_byte_body(self): - self._test_show_floating_ip(bytes_body=True) - - def _test_create_floating_ip(self, bytes_body=False): - expected = {"floating_ip": TestFloatingIpsClient.floating_ip} - self.check_service_client_function( - self.client.create_floating_ip, - 'tempest_lib.common.rest_client.RestClient.post', - expected, - bytes_body, - pool_name='nova') - - def test_create_floating_ip_str_body(self): - self._test_create_floating_ip(bytes_body=False) - - def test_create_floating_ip_byte_body(self): - self._test_create_floating_ip(bytes_body=True) - - def test_delete_floating_ip(self): - self.check_service_client_function( - self.client.delete_floating_ip, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, status=202, floating_ip_id='fake-id') - - def test_associate_floating_ip_to_server(self): - self.check_service_client_function( - self.client.associate_floating_ip_to_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, status=202, floating_ip='10.10.10.1', - server_id='c782b7a9-33cd-45f0-b795-7f87f456408b') - - def test_disassociate_floating_ip_from_server(self): - self.check_service_client_function( - self.client.disassociate_floating_ip_from_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, status=202, floating_ip='10.10.10.1', - server_id='c782b7a9-33cd-45f0-b795-7f87f456408b') - - def test_is_resource_deleted_true(self): - self.useFixture(mockpatch.Patch( - 'tempest_lib.services.compute.floating_ips_client.' - 'FloatingIPsClient.show_floating_ip', - side_effect=lib_exc.NotFound())) - self.assertTrue(self.client.is_resource_deleted('fake-id')) - - def test_is_resource_deleted_false(self): - self.useFixture(mockpatch.Patch( - 'tempest_lib.services.compute.floating_ips_client.' - 'FloatingIPsClient.show_floating_ip', - return_value={"floating_ip": TestFloatingIpsClient.floating_ip})) - self.assertFalse(self.client.is_resource_deleted('fake-id')) diff --git a/tempest_lib/tests/services/compute/test_hosts_client.py b/tempest_lib/tests/services/compute/test_hosts_client.py deleted file mode 100644 index c1e053a..0000000 --- a/tempest_lib/tests/services/compute/test_hosts_client.py +++ /dev/null @@ -1,147 +0,0 @@ -# Copyright 2015 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_lib.services.compute import hosts_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestHostsClient(base.BaseComputeServiceTest): - FAKE_HOST_DATA = { - "host": { - "resource": { - "cpu": 1, - "disk_gb": 1028, - "host": "c1a7de0ac9d94e4baceae031d05caae3", - "memory_mb": 8192, - "project": "(total)" - } - }, - "hosts": { - "host_name": "c1a7de0ac9d94e4baceae031d05caae3", - "service": "conductor", - "zone": "internal" - }, - "enable_hosts": { - "host": "65c5d5b7e3bd44308e67fc50f362aee6", - "maintenance_mode": "off_maintenance", - "status": "enabled" - } - } - - FAKE_CONTROL_DATA = { - "shutdown": { - "host": "c1a7de0ac9d94e4baceae031d05caae3", - "power_action": "shutdown" - }, - "startup": { - "host": "c1a7de0ac9d94e4baceae031d05caae3", - "power_action": "startup" - }, - "reboot": { - "host": "c1a7de0ac9d94e4baceae031d05caae3", - "power_action": "reboot" - }} - - HOST_DATA = {'host': [FAKE_HOST_DATA['host']]} - HOSTS_DATA = {'hosts': [FAKE_HOST_DATA['hosts']]} - ENABLE_HOST_DATA = FAKE_HOST_DATA['enable_hosts'] - HOST_ID = "c1a7de0ac9d94e4baceae031d05caae3" - TEST_HOST_DATA = { - "status": "enable", - "maintenance_mode": "disable" - } - - def setUp(self): - super(TestHostsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = hosts_client.HostsClient(fake_auth, 'compute', - 'regionOne') - self.params = {'hostname': self.HOST_ID} - self.func2mock = { - 'get': 'tempest_lib.common.rest_client.RestClient.get', - 'put': 'tempest_lib.common.rest_client.RestClient.put'} - - def _test_host_data(self, test_type='list', bytes_body=False): - expected_resp = self.HOST_DATA - if test_type != 'list': - function_call = self.client.show_host - else: - expected_resp = self.HOSTS_DATA - function_call = self.client.list_hosts - self.params = {'host_name': self.HOST_ID} - - self.check_service_client_function( - function_call, self.func2mock['get'], - expected_resp, bytes_body, - 200, **self.params) - - def _test_update_hosts(self, bytes_body=False): - expected_resp = self.ENABLE_HOST_DATA - self.check_service_client_function( - self.client.update_host, self.func2mock['put'], - expected_resp, bytes_body, - 200, **self.params) - - def _test_control_host(self, control_op='reboot', bytes_body=False): - if control_op == 'start': - expected_resp = self.FAKE_CONTROL_DATA['startup'] - function_call = self.client.startup_host - elif control_op == 'stop': - expected_resp = self.FAKE_CONTROL_DATA['shutdown'] - function_call = self.client.shutdown_host - else: - expected_resp = self.FAKE_CONTROL_DATA['reboot'] - function_call = self.client.reboot_host - - self.check_service_client_function( - function_call, self.func2mock['get'], - expected_resp, bytes_body, - 200, **self.params) - - def test_show_host_with_str_body(self): - self._test_host_data('show') - - def test_show_host_with_bytes_body(self): - self._test_host_data('show', True) - - def test_list_host_with_str_body(self): - self._test_host_data() - - def test_list_host_with_bytes_body(self): - self._test_host_data(bytes_body=True) - - def test_start_host_with_str_body(self): - self._test_control_host('start') - - def test_start_host_with_bytes_body(self): - self._test_control_host('start', True) - - def test_stop_host_with_str_body(self): - self._test_control_host('stop') - - def test_stop_host_with_bytes_body(self): - self._test_control_host('stop', True) - - def test_reboot_host_with_str_body(self): - self._test_control_host('reboot') - - def test_reboot_host_with_bytes_body(self): - self._test_control_host('reboot', True) - - def test_update_host_with_str_body(self): - self._test_update_hosts() - - def test_update_host_with_bytes_body(self): - self._test_update_hosts(True) diff --git a/tempest_lib/tests/services/compute/test_hypervisor_client.py b/tempest_lib/tests/services/compute/test_hypervisor_client.py deleted file mode 100644 index 1cb85a9..0000000 --- a/tempest_lib/tests/services/compute/test_hypervisor_client.py +++ /dev/null @@ -1,167 +0,0 @@ -# Copyright 2015 IBM Corp. -# -# 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_lib.services.compute import hypervisor_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestHypervisorClient(base.BaseComputeServiceTest): - - hypervisor_id = "1" - hypervisor_name = "hyper.hostname.com" - - def setUp(self): - super(TestHypervisorClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = hypervisor_client.HypervisorClient( - fake_auth, 'compute', 'regionOne') - - def test_list_hypervisor_str_body(self): - self._test_list_hypervisor(bytes_body=False) - - def test_list_hypervisor_byte_body(self): - self._test_list_hypervisor(bytes_body=True) - - def _test_list_hypervisor(self, bytes_body=False): - expected = {"hypervisors": [{ - "id": 1, - "hypervisor_hostname": "hypervisor1.hostname.com"}, - { - "id": 2, - "hypervisor_hostname": "hypervisor2.hostname.com"}]} - self.check_service_client_function( - self.client.list_hypervisors, - 'tempest_lib.common.rest_client.RestClient.get', - expected, bytes_body) - - def test_show_hypervisor_str_body(self): - self._test_show_hypervisor(bytes_body=False) - - def test_show_hypervisor_byte_body(self): - self._test_show_hypervisor(bytes_body=True) - - def _test_show_hypervisor(self, bytes_body=False): - expected = {"hypervisor": { - "cpu_info": "?", - "current_workload": 0, - "disk_available_least": 1, - "host_ip": "10.10.10.10", - "free_disk_gb": 1028, - "free_ram_mb": 7680, - "hypervisor_hostname": "fake-mini", - "hypervisor_type": "fake", - "hypervisor_version": 1, - "id": 1, - "local_gb": 1028, - "local_gb_used": 0, - "memory_mb": 8192, - "memory_mb_used": 512, - "running_vms": 0, - "service": { - "host": "fake_host", - "id": 2}, - "vcpus": 1, - "vcpus_used": 0}} - self.check_service_client_function( - self.client.show_hypervisor, - 'tempest_lib.common.rest_client.RestClient.get', - expected, bytes_body, - hypervisor_id=self.hypervisor_id) - - def test_list_servers_on_hypervisor_str_body(self): - self._test_list_servers_on_hypervisor(bytes_body=False) - - def test_list_servers_on_hypervisor_byte_body(self): - self._test_list_servers_on_hypervisor(bytes_body=True) - - def _test_list_servers_on_hypervisor(self, bytes_body=False): - expected = {"hypervisors": [{ - "id": 1, - "hypervisor_hostname": "hyper.hostname.com", - "servers": [{ - "uuid": "e1ae8fc4-b72d-4c2f-a427-30dd420b6277", - "name": "instance-00000001"}, - { - "uuid": "e1ae8fc4-b72d-4c2f-a427-30dd42066666", - "name": "instance-00000002"} - ]} - ]} - self.check_service_client_function( - self.client.list_servers_on_hypervisor, - 'tempest_lib.common.rest_client.RestClient.get', - expected, bytes_body, - hypervisor_name=self.hypervisor_name) - - def test_show_hypervisor_statistics_str_body(self): - self._test_show_hypervisor_statistics(bytes_body=False) - - def test_show_hypervisor_statistics_byte_body(self): - self._test_show_hypervisor_statistics(bytes_body=True) - - def _test_show_hypervisor_statistics(self, bytes_body=False): - expected = { - "hypervisor_statistics": { - "count": 1, - "current_workload": 0, - "disk_available_least": 0, - "free_disk_gb": 1028, - "free_ram_mb": 7680, - "local_gb": 1028, - "local_gb_used": 0, - "memory_mb": 8192, - "memory_mb_used": 512, - "running_vms": 0, - "vcpus": 1, - "vcpus_used": 0}} - self.check_service_client_function( - self.client.show_hypervisor_statistics, - 'tempest_lib.common.rest_client.RestClient.get', - expected, bytes_body) - - def test_show_hypervisor_uptime_str_body(self): - self._test_show_hypervisor_uptime(bytes_body=False) - - def test_show_hypervisor_uptime_byte_body(self): - self._test_show_hypervisor_uptime(bytes_body=True) - - def _test_show_hypervisor_uptime(self, bytes_body=False): - expected = { - "hypervisor": { - "hypervisor_hostname": "fake-mini", - "id": 1, - "uptime": (" 08:32:11 up 93 days, 18:25, 12 users, " - " load average: 0.20, 0.12, 0.14") - }} - self.check_service_client_function( - self.client.show_hypervisor_uptime, - 'tempest_lib.common.rest_client.RestClient.get', - expected, bytes_body, - hypervisor_id=self.hypervisor_id) - - def test_search_hypervisor_str_body(self): - self._test_search_hypervisor(bytes_body=False) - - def test_search_hypervisor_byte_body(self): - self._test_search_hypervisor(bytes_body=True) - - def _test_search_hypervisor(self, bytes_body=False): - expected = {"hypervisors": [{ - "id": 2, - "hypervisor_hostname": "hyper.hostname.com"}]} - self.check_service_client_function( - self.client.search_hypervisor, - 'tempest_lib.common.rest_client.RestClient.get', - expected, bytes_body, - hypervisor_name=self.hypervisor_name) diff --git a/tempest_lib/tests/services/compute/test_images_client.py b/tempest_lib/tests/services/compute/test_images_client.py deleted file mode 100644 index f0079c0..0000000 --- a/tempest_lib/tests/services/compute/test_images_client.py +++ /dev/null @@ -1,265 +0,0 @@ -# Copyright 2015 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 copy - -from oslotest import mockpatch - -from tempest_lib import exceptions as lib_exc -from tempest_lib.services.compute import images_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestImagesClient(base.BaseComputeServiceTest): - # Data Dictionaries used for testing # - FAKE_IMAGE_METADATA = { - "list": - {"metadata": { - "auto_disk_config": "True", - "Label": "Changed" - }}, - "set_item": - {"meta": { - "auto_disk_config": "True" - }}, - "show_item": - {"meta": { - "kernel_id": "nokernel", - }}, - "update": - {"metadata": { - "kernel_id": "False", - "Label": "UpdatedImage" - }}, - "set": - {"metadata": { - "Label": "Changed", - "auto_disk_config": "True" - }}, - "delete_item": {} - } - - FAKE_IMAGE_DATA = { - "list": - {"images": [ - {"id": "70a599e0-31e7-49b7-b260-868f441e862b", - "links": [ - {"href": "http://openstack.example.com/v2/openstack" + - "/images/70a599e0-31e7-49b7-b260-868f441e862b", - "rel": "self" - } - ], - "name": "fakeimage7" - }]}, - "show": {"image": { - "created": "2011-01-01T01:02:03Z", - "id": "70a599e0-31e7-49b7-b260-868f441e862b", - "links": [ - { - "href": "http://openstack.example.com/v2/openstack" + - "/images/70a599e0-31e7-49b7-b260-868f441e862b", - "rel": "self" - }, - ], - "metadata": { - "architecture": "x86_64", - "auto_disk_config": "True", - "kernel_id": "nokernel", - "ramdisk_id": "nokernel" - }, - "minDisk": 0, - "minRam": 0, - "name": "fakeimage7", - "progress": 100, - "status": "ACTIVE", - "updated": "2011-01-01T01:02:03Z"}}, - "create": {}, - "delete": {} - } - func2mock = { - 'get': 'tempest_lib.common.rest_client.RestClient.get', - 'post': 'tempest_lib.common.rest_client.RestClient.post', - 'put': 'tempest_lib.common.rest_client.RestClient.put', - 'delete': 'tempest_lib.common.rest_client.RestClient.delete'} - # Variable definition - FAKE_IMAGE_ID = FAKE_IMAGE_DATA['show']['image']['id'] - FAKE_SERVER_ID = "80a599e0-31e7-49b7-b260-868f441e343f" - FAKE_CREATE_INFO = {'location': 'None'} - FAKE_METADATA = FAKE_IMAGE_METADATA['show_item']['meta'] - - def setUp(self): - super(TestImagesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = images_client.ImagesClient(fake_auth, - "compute", "regionOne") - - def _test_image_operation(self, operation="delete", bytes_body=False): - response_code = 200 - mock_operation = self.func2mock['get'] - expected_op = self.FAKE_IMAGE_DATA[operation] - params = {"image_id": self.FAKE_IMAGE_ID} - headers = None - if operation == 'list': - function = self.client.list_images - elif operation == 'show': - function = self.client.show_image - elif operation == 'create': - function = self.client.create_image - mock_operation = self.func2mock['post'] - params = {"server_id": self.FAKE_SERVER_ID} - response_code = 202 - headers = { - 'connection': 'keep-alive', - 'content-length': '0', - 'content-type': 'application/json', - 'status': '202', - 'x-compute-request-id': 'req-fake', - 'vary': 'accept-encoding', - 'x-openstack-nova-api-version': 'v2.1', - 'date': '13 Oct 2015 05:55:36 GMT', - 'location': 'http://fake.com/images/fake' - } - else: - function = self.client.delete_image - mock_operation = self.func2mock['delete'] - response_code = 204 - - self.check_service_client_function( - function, mock_operation, expected_op, - bytes_body, response_code, headers, **params) - - def _test_image_metadata(self, operation="set_item", bytes_body=False): - response_code = 200 - expected_op = self.FAKE_IMAGE_METADATA[operation] - if operation == 'list': - function = self.client.list_image_metadata - mock_operation = self.func2mock['get'] - params = {"image_id": self.FAKE_IMAGE_ID} - - elif operation == 'set': - function = self.client.set_image_metadata - mock_operation = self.func2mock['put'] - params = {"image_id": "_dummy_data", - "meta": self.FAKE_METADATA} - - elif operation == 'update': - function = self.client.update_image_metadata - mock_operation = self.func2mock['post'] - params = {"image_id": self.FAKE_IMAGE_ID, - "meta": self.FAKE_METADATA} - - elif operation == 'show_item': - mock_operation = self.func2mock['get'] - function = self.client.show_image_metadata_item - params = {"image_id": self.FAKE_IMAGE_ID, - "key": "123"} - - elif operation == 'delete_item': - function = self.client.delete_image_metadata_item - mock_operation = self.func2mock['delete'] - response_code = 204 - params = {"image_id": self.FAKE_IMAGE_ID, - "key": "123"} - - else: - function = self.client.set_image_metadata_item - mock_operation = self.func2mock['put'] - params = {"image_id": self.FAKE_IMAGE_ID, - "key": "123", - "meta": self.FAKE_METADATA} - - self.check_service_client_function( - function, mock_operation, expected_op, - bytes_body, response_code, **params) - - def _test_resource_deleted(self, bytes_body=False): - params = {"id": self.FAKE_IMAGE_ID} - expected_op = self.FAKE_IMAGE_DATA['show']['image'] - self.useFixture(mockpatch.Patch('tempest_lib.services.compute' - '.images_client.ImagesClient.show_image', - side_effect=lib_exc.NotFound)) - self.assertEqual(True, self.client.is_resource_deleted(**params)) - tempdata = copy.deepcopy(self.FAKE_IMAGE_DATA['show']) - tempdata['image']['id'] = None - self.useFixture(mockpatch.Patch('tempest_lib.services.compute' - '.images_client.ImagesClient.show_image', - return_value=expected_op)) - self.assertEqual(False, self.client.is_resource_deleted(**params)) - - def test_list_images_with_str_body(self): - self._test_image_operation('list') - - def test_list_images_with_bytes_body(self): - self._test_image_operation('list', True) - - def test_show_image_with_str_body(self): - self._test_image_operation('show') - - def test_show_image_with_bytes_body(self): - self._test_image_operation('show', True) - - def test_create_image_with_str_body(self): - self._test_image_operation('create') - - def test_create_image_with_bytes_body(self): - self._test_image_operation('create', True) - - def test_delete_image_with_str_body(self): - self._test_image_operation('delete') - - def test_delete_image_with_bytes_body(self): - self._test_image_operation('delete', True) - - def test_list_image_metadata_with_str_body(self): - self._test_image_metadata('list') - - def test_list_image_metadata_with_bytes_body(self): - self._test_image_metadata('list', True) - - def test_set_image_metadata_with_str_body(self): - self._test_image_metadata('set') - - def test_set_image_metadata_with_bytes_body(self): - self._test_image_metadata('set', True) - - def test_update_image_metadata_with_str_body(self): - self._test_image_metadata('update') - - def test_update_image_metadata_with_bytes_body(self): - self._test_image_metadata('update', True) - - def test_set_image_metadata_item_with_str_body(self): - self._test_image_metadata() - - def test_set_image_metadata_item_with_bytes_body(self): - self._test_image_metadata(bytes_body=True) - - def test_show_image_metadata_item_with_str_body(self): - self._test_image_metadata('show_item') - - def test_show_image_metadata_item_with_bytes_body(self): - self._test_image_metadata('show_item', True) - - def test_delete_image_metadata_item_with_str_body(self): - self._test_image_metadata('delete_item') - - def test_delete_image_metadata_item_with_bytes_body(self): - self._test_image_metadata('delete_item', True) - - def test_resource_delete_with_str_body(self): - self._test_resource_deleted() - - def test_resource_delete_with_bytes_body(self): - self._test_resource_deleted(True) diff --git a/tempest_lib/tests/services/compute/test_instance_usage_audit_log_client.py b/tempest_lib/tests/services/compute/test_instance_usage_audit_log_client.py deleted file mode 100644 index 78ade47..0000000 --- a/tempest_lib/tests/services/compute/test_instance_usage_audit_log_client.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2015 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 datetime - -from tempest_lib.services.compute import instance_usage_audit_log_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestInstanceUsagesAuditLogClient(base.BaseComputeServiceTest): - - FAKE_AUDIT_LOG = { - "hosts_not_run": [ - "f4eb7cfd155f4574967f8b55a7faed75" - ], - "log": {}, - "num_hosts": 1, - "num_hosts_done": 0, - "num_hosts_not_run": 1, - "num_hosts_running": 0, - "overall_status": "0 of 1 hosts done. 0 errors.", - "period_beginning": "2012-12-01 00:00:00", - "period_ending": "2013-01-01 00:00:00", - "total_errors": 0, - "total_instances": 0 - } - - def setUp(self): - super(TestInstanceUsagesAuditLogClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = (instance_usage_audit_log_client. - InstanceUsagesAuditLogClient(fake_auth, 'compute', - 'regionOne')) - - def _test_list_instance_usage_audit_logs(self, bytes_body=False): - self.check_service_client_function( - self.client.list_instance_usage_audit_logs, - 'tempest_lib.common.rest_client.RestClient.get', - {"instance_usage_audit_logs": self.FAKE_AUDIT_LOG}, - bytes_body) - - def test_list_instance_usage_audit_logs_with_str_body(self): - self._test_list_instance_usage_audit_logs() - - def test_list_instance_usage_audit_logs_with_bytes_body(self): - self._test_list_instance_usage_audit_logs(bytes_body=True) - - def _test_show_instance_usage_audit_log(self, bytes_body=False): - before_time = datetime.datetime(2012, 12, 1, 0, 0) - self.check_service_client_function( - self.client.show_instance_usage_audit_log, - 'tempest_lib.common.rest_client.RestClient.get', - {"instance_usage_audit_log": self.FAKE_AUDIT_LOG}, - bytes_body, - time_before=before_time) - - def test_show_instance_usage_audit_log_with_str_body(self): - self._test_show_instance_usage_audit_log() - - def test_show_network_with_bytes_body_with_bytes_body(self): - self._test_show_instance_usage_audit_log(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_interfaces_client.py b/tempest_lib/tests/services/compute/test_interfaces_client.py deleted file mode 100644 index 4456ce7..0000000 --- a/tempest_lib/tests/services/compute/test_interfaces_client.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright 2015 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_lib.services.compute import interfaces_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestInterfacesClient(base.BaseComputeServiceTest): - # Data Values to be used for testing # - FAKE_INTERFACE_DATA = { - "fixed_ips": [{ - "ip_address": "192.168.1.1", - "subnet_id": "f8a6e8f8-c2ec-497c-9f23-da9616de54ef" - }], - "mac_addr": "fa:16:3e:4c:2c:30", - "net_id": "3cb9bc59-5699-4588-a4b1-b87f96708bc6", - "port_id": "ce531f90-199f-48c0-816c-13e38010b442", - "port_state": "ACTIVE"} - - FAKE_SHOW_DATA = { - "interfaceAttachment": FAKE_INTERFACE_DATA} - FAKE_LIST_DATA = { - "interfaceAttachments": [FAKE_INTERFACE_DATA]} - - FAKE_SERVER_ID = "ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5" - FAKE_PORT_ID = FAKE_SHOW_DATA['interfaceAttachment']['port_id'] - func2mock = { - 'delete': 'tempest_lib.common.rest_client.RestClient.delete', - 'get': 'tempest_lib.common.rest_client.RestClient.get', - 'post': 'tempest_lib.common.rest_client.RestClient.post'} - - def setUp(self): - super(TestInterfacesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = interfaces_client.InterfacesClient(fake_auth, - "compute", - "regionOne") - - def _test_interface_operation(self, operation="create", bytes_body=False): - response_code = 200 - expected_op = self.FAKE_SHOW_DATA - mock_operation = self.func2mock['get'] - params = {'server_id': self.FAKE_SERVER_ID, - 'port_id': self.FAKE_PORT_ID} - if operation == 'list': - expected_op = self.FAKE_LIST_DATA - function = self.client.list_interfaces - params = {'server_id': self.FAKE_SERVER_ID} - elif operation == 'show': - function = self.client.show_interface - elif operation == 'delete': - expected_op = {} - mock_operation = self.func2mock['delete'] - function = self.client.delete_interface - response_code = 202 - else: - function = self.client.create_interface - mock_operation = self.func2mock['post'] - - self.check_service_client_function( - function, mock_operation, expected_op, - bytes_body, response_code, **params) - - def test_list_interfaces_with_str_body(self): - self._test_interface_operation('list') - - def test_list_interfaces_with_bytes_body(self): - self._test_interface_operation('list', True) - - def test_show_interface_with_str_body(self): - self._test_interface_operation('show') - - def test_show_interface_with_bytes_body(self): - self._test_interface_operation('show', True) - - def test_delete_interface_with_str_body(self): - self._test_interface_operation('delete') - - def test_delete_interface_with_bytes_body(self): - self._test_interface_operation('delete', True) - - def test_create_interface_with_str_body(self): - self._test_interface_operation() - - def test_create_interface_with_bytes_body(self): - self._test_interface_operation(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_keypairs_client.py b/tempest_lib/tests/services/compute/test_keypairs_client.py deleted file mode 100644 index 6458e67..0000000 --- a/tempest_lib/tests/services/compute/test_keypairs_client.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2015 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 copy - -from tempest_lib.services.compute import keypairs_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestKeyPairsClient(base.BaseComputeServiceTest): - - FAKE_KEYPAIR = {"keypair": { - "public_key": "ssh-rsa foo Generated-by-Nova", - "name": u'\u2740(*\xb4\u25e1`*)\u2740', - "user_id": "525d55f98980415ba98e634972fa4a10", - "fingerprint": "76:24:66:49:d7:ca:6e:5c:77:ea:8e:bb:9c:15:5f:98" - }} - - def setUp(self): - super(TestKeyPairsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = keypairs_client.KeyPairsClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_keypairs(self, bytes_body=False): - self.check_service_client_function( - self.client.list_keypairs, - 'tempest_lib.common.rest_client.RestClient.get', - {"keypairs": []}, - bytes_body) - - def test_list_keypairs_with_str_body(self): - self._test_list_keypairs() - - def test_list_keypairs_with_bytes_body(self): - self._test_list_keypairs(bytes_body=True) - - def _test_show_keypair(self, bytes_body=False): - fake_keypair = copy.deepcopy(self.FAKE_KEYPAIR) - fake_keypair["keypair"].update({ - "deleted": False, - "created_at": "2015-07-22T04:53:52.000000", - "updated_at": None, - "deleted_at": None, - "id": 1 - }) - - self.check_service_client_function( - self.client.show_keypair, - 'tempest_lib.common.rest_client.RestClient.get', - fake_keypair, - bytes_body, - keypair_name="test") - - def test_show_keypair_with_str_body(self): - self._test_show_keypair() - - def test_show_keypair_with_bytes_body(self): - self._test_show_keypair(bytes_body=True) - - def _test_create_keypair(self, bytes_body=False): - fake_keypair = copy.deepcopy(self.FAKE_KEYPAIR) - fake_keypair["keypair"].update({"private_key": "foo"}) - - self.check_service_client_function( - self.client.create_keypair, - 'tempest_lib.common.rest_client.RestClient.post', - fake_keypair, - bytes_body, - name="test") - - def test_create_keypair_with_str_body(self): - self._test_create_keypair() - - def test_create_keypair_with_bytes_body(self): - self._test_create_keypair(bytes_body=True) - - def test_delete_keypair(self): - self.check_service_client_function( - self.client.delete_keypair, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, status=202, keypair_name='test') diff --git a/tempest_lib/tests/services/compute/test_limits_client.py b/tempest_lib/tests/services/compute/test_limits_client.py deleted file mode 100644 index c84b75e..0000000 --- a/tempest_lib/tests/services/compute/test_limits_client.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2015 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_lib.services.compute import limits_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestLimitsClient(base.BaseComputeServiceTest): - - def setUp(self): - super(TestLimitsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = limits_client.LimitsClient( - fake_auth, 'compute', 'regionOne') - - def _test_show_limits(self, bytes_body=False): - expected = { - "limits": { - "rate": [], - "absolute": { - "maxServerMeta": 128, - "maxPersonality": 5, - "totalServerGroupsUsed": 0, - "maxImageMeta": 128, - "maxPersonalitySize": 10240, - "maxServerGroups": 10, - "maxSecurityGroupRules": 20, - "maxTotalKeypairs": 100, - "totalCoresUsed": 0, - "totalRAMUsed": 0, - "totalInstancesUsed": 0, - "maxSecurityGroups": 10, - "totalFloatingIpsUsed": 0, - "maxTotalCores": 20, - "totalSecurityGroupsUsed": 0, - "maxTotalFloatingIps": 10, - "maxTotalInstances": 10, - "maxTotalRAMSize": 51200, - "maxServerGroupMembers": 10 - } - } - } - - self.check_service_client_function( - self.client.show_limits, - 'tempest_lib.common.rest_client.RestClient.get', - expected, - bytes_body) - - def test_show_limits_with_str_body(self): - self._test_show_limits() - - def test_show_limits_with_bytes_body(self): - self._test_show_limits(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_migrations_client.py b/tempest_lib/tests/services/compute/test_migrations_client.py deleted file mode 100644 index a949d67..0000000 --- a/tempest_lib/tests/services/compute/test_migrations_client.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2015 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_lib.services.compute import migrations_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestMigrationsClient(base.BaseComputeServiceTest): - FAKE_MIGRATION_INFO = {"migrations": [{ - "created_at": "2012-10-29T13:42:02", - "dest_compute": "compute2", - "dest_host": "1.2.3.4", - "dest_node": "node2", - "id": 1234, - "instance_uuid": "e9e4fdd7-f956-44ff-bfeb-d654a96ab3a2", - "new_instance_type_id": 2, - "old_instance_type_id": 1, - "source_compute": "compute1", - "source_node": "node1", - "status": "finished", - "updated_at": "2012-10-29T13:42:02"}]} - - def setUp(self): - super(TestMigrationsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.mg_client_obj = migrations_client.MigrationsClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_migrations(self, bytes_body=False): - self.check_service_client_function( - self.mg_client_obj.list_migrations, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_MIGRATION_INFO, - bytes_body) - - def test_list_migration_with_str_body(self): - self._test_list_migrations() - - def test_list_migration_with_bytes_body(self): - self._test_list_migrations(True) diff --git a/tempest_lib/tests/services/compute/test_networks_client.py b/tempest_lib/tests/services/compute/test_networks_client.py deleted file mode 100644 index c3b2a98..0000000 --- a/tempest_lib/tests/services/compute/test_networks_client.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2015 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_lib.services.compute import networks_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestNetworksClient(base.BaseComputeServiceTest): - - FAKE_NETWORK = { - "bridge": None, - "vpn_public_port": None, - "dhcp_start": None, - "bridge_interface": None, - "share_address": None, - "updated_at": None, - "id": "34d5ae1e-5659-49cf-af80-73bccd7d7ad3", - "cidr_v6": None, - "deleted_at": None, - "gateway": None, - "rxtx_base": None, - "label": u'30d7', - "priority": None, - "project_id": None, - "vpn_private_address": None, - "deleted": None, - "vlan": None, - "broadcast": None, - "netmask": None, - "injected": None, - "cidr": None, - "vpn_public_address": None, - "multi_host": None, - "enable_dhcp": None, - "dns2": None, - "created_at": None, - "host": None, - "mtu": None, - "gateway_v6": None, - "netmask_v6": None, - "dhcp_server": None, - "dns1": None - } - - network_id = "34d5ae1e-5659-49cf-af80-73bccd7d7ad3" - - FAKE_NETWORKS = [FAKE_NETWORK] - - def setUp(self): - super(TestNetworksClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = networks_client.NetworksClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_networks(self, bytes_body=False): - fake_list = {"networks": self.FAKE_NETWORKS} - self.check_service_client_function( - self.client.list_networks, - 'tempest_lib.common.rest_client.RestClient.get', - fake_list, - bytes_body) - - def test_list_networks_with_str_body(self): - self._test_list_networks() - - def test_list_networks_with_bytes_body(self): - self._test_list_networks(bytes_body=True) - - def _test_show_network(self, bytes_body=False): - self.check_service_client_function( - self.client.show_network, - 'tempest_lib.common.rest_client.RestClient.get', - {"network": self.FAKE_NETWORK}, - bytes_body, - network_id=self.network_id - ) - - def test_show_network_with_str_body(self): - self._test_show_network() - - def test_show_network_with_bytes_body(self): - self._test_show_network(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_quota_classes_client.py b/tempest_lib/tests/services/compute/test_quota_classes_client.py deleted file mode 100644 index 309e026..0000000 --- a/tempest_lib/tests/services/compute/test_quota_classes_client.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2015 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 copy - -from tempest_lib.services.compute import quota_classes_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestQuotaClassesClient(base.BaseComputeServiceTest): - - FAKE_QUOTA_CLASS_SET = { - "injected_file_content_bytes": 10240, - "metadata_items": 128, - "server_group_members": 10, - "server_groups": 10, - "ram": 51200, - "floating_ips": 10, - "key_pairs": 100, - "id": u'\u2740(*\xb4\u25e1`*)\u2740', - "instances": 10, - "security_group_rules": 20, - "security_groups": 10, - "injected_files": 5, - "cores": 20, - "fixed_ips": -1, - "injected_file_path_bytes": 255, - } - - def setUp(self): - super(TestQuotaClassesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = quota_classes_client.QuotaClassesClient( - fake_auth, 'compute', 'regionOne') - - def _test_show_quota_class_set(self, bytes_body=False): - fake_body = {'quota_class_set': self.FAKE_QUOTA_CLASS_SET} - self.check_service_client_function( - self.client.show_quota_class_set, - 'tempest_lib.common.rest_client.RestClient.get', - fake_body, - bytes_body, - quota_class_id="test") - - def test_show_quota_class_set_with_str_body(self): - self._test_show_quota_class_set() - - def test_show_quota_class_set_with_bytes_body(self): - self._test_show_quota_class_set(bytes_body=True) - - def test_update_quota_class_set(self): - fake_quota_class_set = copy.deepcopy(self.FAKE_QUOTA_CLASS_SET) - fake_quota_class_set.pop("id") - fake_body = {'quota_class_set': fake_quota_class_set} - self.check_service_client_function( - self.client.update_quota_class_set, - 'tempest_lib.common.rest_client.RestClient.put', - fake_body, - quota_class_id="test") diff --git a/tempest_lib/tests/services/compute/test_quotas_client.py b/tempest_lib/tests/services/compute/test_quotas_client.py deleted file mode 100644 index 9c8fb49..0000000 --- a/tempest_lib/tests/services/compute/test_quotas_client.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright 2015 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 copy - -from tempest_lib.services.compute import quotas_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestQuotasClient(base.BaseComputeServiceTest): - - FAKE_QUOTA_SET = { - "quota_set": { - "injected_file_content_bytes": 10240, - "metadata_items": 128, - "server_group_members": 10, - "server_groups": 10, - "ram": 51200, - "floating_ips": 10, - "key_pairs": 100, - "id": "8421f7be61064f50b680465c07f334af", - "instances": 10, - "security_group_rules": 20, - "injected_files": 5, - "cores": 20, - "fixed_ips": -1, - "injected_file_path_bytes": 255, - "security_groups": 10} - } - - project_id = "8421f7be61064f50b680465c07f334af" - fake_user_id = "65f09168cbb04eb593f3138b63b67b67" - - def setUp(self): - super(TestQuotasClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = quotas_client.QuotasClient( - fake_auth, 'compute', 'regionOne') - - def _test_show_quota_set(self, bytes_body=False, user_id=None): - if user_id: - self.check_service_client_function( - self.client.show_quota_set, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_QUOTA_SET, - to_utf=bytes_body, - tenant_id=self.project_id, - user_id=user_id) - else: - self.check_service_client_function( - self.client.show_quota_set, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_QUOTA_SET, - to_utf=bytes_body, - tenant_id=self.project_id) - - def test_show_quota_set_with_str_body(self): - self._test_show_quota_set() - - def test_show_quota_set_with_bytes_body(self): - self._test_show_quota_set(bytes_body=True) - - def test_show_quota_set_for_user_with_str_body(self): - self._test_show_quota_set(user_id=self.fake_user_id) - - def test_show_quota_set_for_user_with_bytes_body(self): - self._test_show_quota_set(bytes_body=True, user_id=self.fake_user_id) - - def _test_show_default_quota_set(self, bytes_body=False): - self.check_service_client_function( - self.client.show_default_quota_set, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_QUOTA_SET, - to_utf=bytes_body, - tenant_id=self.project_id) - - def test_show_default_quota_set_with_str_body(self): - self._test_show_default_quota_set() - - def test_show_default_quota_set_with_bytes_body(self): - self._test_show_default_quota_set(bytes_body=True) - - def _test_update_quota_set(self, bytes_body=False, user_id=None): - fake_quota_set = copy.deepcopy(self.FAKE_QUOTA_SET) - fake_quota_set['quota_set'].pop("id") - if user_id: - self.check_service_client_function( - self.client.update_quota_set, - 'tempest_lib.common.rest_client.RestClient.put', - fake_quota_set, - to_utf=bytes_body, - tenant_id=self.project_id, - user_id=user_id) - else: - self.check_service_client_function( - self.client.update_quota_set, - 'tempest_lib.common.rest_client.RestClient.put', - fake_quota_set, - to_utf=bytes_body, - tenant_id=self.project_id) - - def test_update_quota_set_with_str_body(self): - self._test_update_quota_set() - - def test_update_quota_set_with_bytes_body(self): - self._test_update_quota_set(bytes_body=True) - - def test_update_quota_set_for_user_with_str_body(self): - self._test_update_quota_set(user_id=self.fake_user_id) - - def test_update_quota_set_for_user_with_bytes_body(self): - self._test_update_quota_set(bytes_body=True, user_id=self.fake_user_id) - - def test_delete_quota_set(self): - self.check_service_client_function( - self.client.delete_quota_set, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, status=202, tenant_id=self.project_id) diff --git a/tempest_lib/tests/services/compute/test_security_group_default_rules_client.py b/tempest_lib/tests/services/compute/test_security_group_default_rules_client.py deleted file mode 100644 index d8a5f64..0000000 --- a/tempest_lib/tests/services/compute/test_security_group_default_rules_client.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright 2015 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_lib.services.compute import security_group_default_rules_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestSecurityGroupDefaultRulesClient(base.BaseComputeServiceTest): - FAKE_RULE = { - "from_port": 80, - "id": 1, - "ip_protocol": "TCP", - "ip_range": { - "cidr": "10.10.10.0/24" - }, - "to_port": 80 - } - - def setUp(self): - super(TestSecurityGroupDefaultRulesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = (security_group_default_rules_client. - SecurityGroupDefaultRulesClient(fake_auth, 'compute', - 'regionOne')) - - def _test_list_security_group_default_rules(self, bytes_body=False): - self.check_service_client_function( - self.client.list_security_group_default_rules, - 'tempest_lib.common.rest_client.RestClient.get', - {"security_group_default_rules": [self.FAKE_RULE]}, - to_utf=bytes_body) - - def test_list_security_group_default_rules_with_str_body(self): - self._test_list_security_group_default_rules() - - def test_list_security_group_default_rules_with_bytes_body(self): - self._test_list_security_group_default_rules(bytes_body=True) - - def _test_show_security_group_default_rule(self, bytes_body=False): - self.check_service_client_function( - self.client.show_security_group_default_rule, - 'tempest_lib.common.rest_client.RestClient.get', - {"security_group_default_rule": self.FAKE_RULE}, - to_utf=bytes_body, - security_group_default_rule_id=1) - - def test_show_security_group_default_rule_with_str_body(self): - self._test_show_security_group_default_rule() - - def test_show_security_group_default_rule_with_bytes_body(self): - self._test_show_security_group_default_rule(bytes_body=True) - - def _test_create_security_default_group_rule(self, bytes_body=False): - request_body = { - "to_port": 80, - "from_port": 80, - "ip_protocol": "TCP", - "cidr": "10.10.10.0/24" - } - self.check_service_client_function( - self.client.create_security_default_group_rule, - 'tempest_lib.common.rest_client.RestClient.post', - {"security_group_default_rule": self.FAKE_RULE}, - to_utf=bytes_body, **request_body) - - def test_create_security_default_group_rule_with_str_body(self): - self._test_create_security_default_group_rule() - - def test_create_security_default_group_rule_with_bytes_body(self): - self._test_create_security_default_group_rule(bytes_body=True) - - def test_delete_security_group_default_rule(self): - self.check_service_client_function( - self.client.delete_security_group_default_rule, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, status=204, security_group_default_rule_id=1) diff --git a/tempest_lib/tests/services/compute/test_security_group_rules_client.py b/tempest_lib/tests/services/compute/test_security_group_rules_client.py deleted file mode 100644 index 2ff3229..0000000 --- a/tempest_lib/tests/services/compute/test_security_group_rules_client.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2015 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_lib.services.compute import security_group_rules_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestSecurityGroupRulesClient(base.BaseComputeServiceTest): - - FAKE_SECURITY_GROUP_RULE = { - "security_group_rule": { - "id": "2d021cf1-ce4b-4292-994f-7a785d62a144", - "ip_range": { - "cidr": "0.0.0.0/0" - }, - "parent_group_id": "48700ff3-30b8-4e63-845f-a79c9633e9fb", - "to_port": 443, - "ip_protocol": "tcp", - "group": {}, - "from_port": 443 - } - } - - def setUp(self): - super(TestSecurityGroupRulesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = security_group_rules_client.SecurityGroupRulesClient( - fake_auth, 'compute', 'regionOne') - - def _test_create_security_group_rule(self, bytes_body=False): - req_body = { - "from_port": "443", - "ip_protocol": "tcp", - "to_port": "443", - "cidr": "0.0.0.0/0", - "parent_group_id": "48700ff3-30b8-4e63-845f-a79c9633e9fb" - } - self.check_service_client_function( - self.client.create_security_group_rule, - 'tempest_lib.common.rest_client.RestClient.post', - self.FAKE_SECURITY_GROUP_RULE, - to_utf=bytes_body, **req_body) - - def test_create_security_group_rule_with_str_body(self): - self._test_create_security_group_rule() - - def test_create_security_group_rule_with_bytes_body(self): - self._test_create_security_group_rule(bytes_body=True) - - def test_delete_security_group_rule(self): - self.check_service_client_function( - self.client.delete_security_group_rule, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, status=202, group_rule_id='group-id') diff --git a/tempest_lib/tests/services/compute/test_security_groups_client.py b/tempest_lib/tests/services/compute/test_security_groups_client.py deleted file mode 100644 index 1d44b89..0000000 --- a/tempest_lib/tests/services/compute/test_security_groups_client.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright 2015 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 oslotest import mockpatch - -from tempest_lib import exceptions as lib_exc -from tempest_lib.services.compute import security_groups_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestSecurityGroupsClient(base.BaseComputeServiceTest): - - FAKE_SECURITY_GROUP_INFO = [{ - "description": "default", - "id": "3fb26eb3-581b-4420-9963-b0879a026506", - "name": "default", - "rules": [], - "tenant_id": "openstack" - }] - - def setUp(self): - super(TestSecurityGroupsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = security_groups_client.SecurityGroupsClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_security_groups(self, bytes_body=False): - self.check_service_client_function( - self.client.list_security_groups, - 'tempest_lib.common.rest_client.RestClient.get', - {"security_groups": self.FAKE_SECURITY_GROUP_INFO}, - to_utf=bytes_body) - - def test_list_security_groups_with_str_body(self): - self._test_list_security_groups() - - def test_list_security_groups_with_bytes_body(self): - self._test_list_security_groups(bytes_body=True) - - def _test_show_security_group(self, bytes_body=False): - self.check_service_client_function( - self.client.show_security_group, - 'tempest_lib.common.rest_client.RestClient.get', - {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]}, - to_utf=bytes_body, - security_group_id='fake-id') - - def test_show_security_group_with_str_body(self): - self._test_show_security_group() - - def test_show_security_group_with_bytes_body(self): - self._test_show_security_group(bytes_body=True) - - def _test_create_security_group(self, bytes_body=False): - post_body = {"name": "test", "description": "test_group"} - self.check_service_client_function( - self.client.create_security_group, - 'tempest_lib.common.rest_client.RestClient.post', - {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]}, - to_utf=bytes_body, - kwargs=post_body) - - def test_create_security_group_with_str_body(self): - self._test_create_security_group() - - def test_create_security_group_with_bytes_body(self): - self._test_create_security_group(bytes_body=True) - - def _test_update_security_group(self, bytes_body=False): - req_body = {"name": "test", "description": "test_group"} - self.check_service_client_function( - self.client.update_security_group, - 'tempest_lib.common.rest_client.RestClient.put', - {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]}, - to_utf=bytes_body, - security_group_id='fake-id', - kwargs=req_body) - - def test_update_security_group_with_str_body(self): - self._test_update_security_group() - - def test_update_security_group_with_bytes_body(self): - self._test_update_security_group(bytes_body=True) - - def test_delete_security_group(self): - self.check_service_client_function( - self.client.delete_security_group, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, status=202, security_group_id='fake-id') - - def test_is_resource_deleted_true(self): - mod = ('tempest_lib.services.compute.security_groups_client.' - 'SecurityGroupsClient.show_security_group') - self.useFixture(mockpatch.Patch(mod, side_effect=lib_exc.NotFound)) - self.assertTrue(self.client.is_resource_deleted('fake-id')) - - def test_is_resource_deleted_false(self): - mod = ('tempest_lib.services.compute.security_groups_client.' - 'SecurityGroupsClient.show_security_group') - self.useFixture(mockpatch.Patch(mod, return_value='success')) - self.assertFalse(self.client.is_resource_deleted('fake-id')) diff --git a/tempest_lib/tests/services/compute/test_server_groups_client.py b/tempest_lib/tests/services/compute/test_server_groups_client.py deleted file mode 100644 index 93e1bde..0000000 --- a/tempest_lib/tests/services/compute/test_server_groups_client.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2015 IBM Corp. -# -# 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 httplib2 - -from oslotest import mockpatch -from tempest_lib.tests import fake_auth_provider - -from tempest_lib.services.compute import server_groups_client -from tempest_lib.tests.services.compute import base - - -class TestServerGroupsClient(base.BaseComputeServiceTest): - - server_group = { - "id": "5bbcc3c4-1da2-4437-a48a-66f15b1b13f9", - "name": "test", - "policies": ["anti-affinity"], - "members": [], - "metadata": {}} - - def setUp(self): - super(TestServerGroupsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = server_groups_client.ServerGroupsClient( - fake_auth, 'compute', 'regionOne') - - def _test_create_server_group(self, bytes_body=False): - expected = {"server_group": TestServerGroupsClient.server_group} - self.check_service_client_function( - self.client.create_server_group, - 'tempest_lib.common.rest_client.RestClient.post', expected, - bytes_body, name='fake-group', policies=['affinity']) - - def test_create_server_group_str_body(self): - self._test_create_server_group(bytes_body=False) - - def test_create_server_group_byte_body(self): - self._test_create_server_group(bytes_body=True) - - def test_delete_server_group(self): - response = (httplib2.Response({'status': 204}), None) - self.useFixture(mockpatch.Patch( - 'tempest_lib.common.rest_client.RestClient.delete', - return_value=response)) - self.client.delete_server_group('fake-group') - - def _test_list_server_groups(self, bytes_body=False): - expected = {"server_groups": [TestServerGroupsClient.server_group]} - self.check_service_client_function( - self.client.list_server_groups, - 'tempest_lib.common.rest_client.RestClient.get', - expected, bytes_body) - - def test_list_server_groups_str_body(self): - self._test_list_server_groups(bytes_body=False) - - def test_list_server_groups_byte_body(self): - self._test_list_server_groups(bytes_body=True) - - def _test_show_server_group(self, bytes_body=False): - expected = {"server_group": TestServerGroupsClient.server_group} - self.check_service_client_function( - self.client.show_server_group, - 'tempest_lib.common.rest_client.RestClient.get', - expected, bytes_body, - server_group_id='5bbcc3c4-1da2-4437-a48a-66f15b1b13f9') - - def test_show_server_group_str_body(self): - self._test_show_server_group(bytes_body=False) - - def test_show_server_group_byte_body(self): - self._test_show_server_group(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_servers_client.py b/tempest_lib/tests/services/compute/test_servers_client.py deleted file mode 100644 index d3a4e83..0000000 --- a/tempest_lib/tests/services/compute/test_servers_client.py +++ /dev/null @@ -1,1011 +0,0 @@ -# Copyright 2015 IBM Corp. -# -# 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 copy - -from tempest_lib.services.compute import servers_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestServersClient(base.BaseComputeServiceTest): - - FAKE_SERVERS = {'servers': [{ - "id": "616fb98f-46ca-475e-917e-2563e5a8cd19", - "links": [ - { - "href": "http://os.co/v2/616fb98f-46ca-475e-917e-2563e5a8cd19", - "rel": "self" - }, - { - "href": "http://os.co/616fb98f-46ca-475e-917e-2563e5a8cd19", - "rel": "bookmark" - } - ], - "name": u"new\u1234-server-test"}] - } - - FAKE_SERVER_DIAGNOSTICS = { - "cpu0_time": 17300000000, - "memory": 524288, - "vda_errors": -1, - "vda_read": 262144, - "vda_read_req": 112, - "vda_write": 5778432, - "vda_write_req": 488, - "vnet1_rx": 2070139, - "vnet1_rx_drop": 0, - "vnet1_rx_errors": 0, - "vnet1_rx_packets": 26701, - "vnet1_tx": 140208, - "vnet1_tx_drop": 0, - "vnet1_tx_errors": 0, - "vnet1_tx_packets": 662 - } - - FAKE_SERVER_GET = {'server': { - "accessIPv4": "", - "accessIPv6": "", - "addresses": { - "private": [ - { - "addr": "192.168.0.3", - "version": 4 - } - ] - }, - "created": "2012-08-20T21:11:09Z", - "flavor": { - "id": "1", - "links": [ - { - "href": "http://os.com/openstack/flavors/1", - "rel": "bookmark" - } - ] - }, - "hostId": "65201c14a29663e06d0748e561207d998b343e1d164bfa0aafa9c45d", - "id": "893c7791-f1df-4c3d-8383-3caae9656c62", - "image": { - "id": "70a599e0-31e7-49b7-b260-868f441e862b", - "links": [ - { - "href": "http://imgs/70a599e0-31e7-49b7-b260-868f441e862b", - "rel": "bookmark" - } - ] - }, - "links": [ - { - "href": "http://v2/srvs/893c7791-f1df-4c3d-8383-3caae9656c62", - "rel": "self" - }, - { - "href": "http://srvs/893c7791-f1df-4c3d-8383-3caae9656c62", - "rel": "bookmark" - } - ], - "metadata": { - u"My Server N\u1234me": u"Apa\u1234che1" - }, - "name": u"new\u1234-server-test", - "progress": 0, - "status": "ACTIVE", - "tenant_id": "openstack", - "updated": "2012-08-20T21:11:09Z", - "user_id": "fake"} - } - - FAKE_SERVER_POST = {"server": { - "id": "616fb98f-46ca-475e-917e-2563e5a8cd19", - "adminPass": "fake-admin-pass", - "security_groups": [ - 'fake-security-group-1', - 'fake-security-group-2' - ], - "links": [ - { - "href": "http://os.co/v2/616fb98f-46ca-475e-917e-2563e5a8cd19", - "rel": "self" - }, - { - "href": "http://os.co/616fb98f-46ca-475e-917e-2563e5a8cd19", - "rel": "bookmark" - } - ], - "OS-DCF:diskConfig": "fake-disk-config"} - } - - FAKE_ADDRESS = {"addresses": { - "private": [ - { - "addr": "192.168.0.3", - "version": 4 - } - ]} - } - - FAKE_COMMON_VOLUME = { - "id": "a6b0875b-6b5d-4a5a-81eb-0c3aa62e5fdb", - "device": "fake-device", - "volumeId": "a6b0875b-46ca-475e-917e-0c3aa62e5fdb", - "serverId": "616fb98f-46ca-475e-917e-2563e5a8cd19" - } - - FAKE_VIRTUAL_INTERFACES = { - "id": "a6b0875b-46ca-475e-917e-0c3aa62e5fdb", - "mac_address": "00:25:90:5b:f8:c3", - "OS-EXT-VIF-NET:net_id": "fake-os-net-id" - } - - FAKE_INSTANCE_ACTIONS = { - "action": "fake-action", - "request_id": "16fb98f-46ca-475e-917e-2563e5a8cd19", - "user_id": "16fb98f-46ca-475e-917e-2563e5a8cd12", - "project_id": "16fb98f-46ca-475e-917e-2563e5a8cd34", - "start_time": "09MAR2015 11:15", - "message": "fake-msg", - "instance_uuid": "16fb98f-46ca-475e-917e-2563e5a8cd12" - } - - FAKE_VNC_CONSOLE = { - "type": "fake-type", - "url": "http://os.co/v2/616fb98f-46ca-475e-917e-2563e5a8cd19" - } - - FAKE_INSTANCE_ACTION_EVENTS = { - "event": "fake-event", - "start_time": "09MAR2015 11:15", - "finish_time": "09MAR2015 11:15", - "result": "fake-result", - "traceback": "fake-trace-back" - } - - FAKE_INSTANCE_WITH_EVENTS = copy.deepcopy(FAKE_INSTANCE_ACTIONS) - FAKE_INSTANCE_WITH_EVENTS['events'] = [FAKE_INSTANCE_ACTION_EVENTS] - - FAKE_REBUILD_SERVER = copy.deepcopy(FAKE_SERVER_GET) - FAKE_REBUILD_SERVER['server']['adminPass'] = 'fake-admin-pass' - - server_id = FAKE_SERVER_GET['server']['id'] - network_id = 'a6b0875b-6b5d-4a5a-81eb-0c3aa62e5fdb' - - def setUp(self): - super(TestServersClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = servers_client.ServersClient( - fake_auth, 'compute', 'regionOne') - - def test_list_servers_with_str_body(self): - self._test_list_servers() - - def test_list_servers_with_bytes_body(self): - self._test_list_servers(bytes_body=True) - - def _test_list_servers(self, bytes_body=False): - self.check_service_client_function( - self.client.list_servers, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_SERVERS, - bytes_body) - - def test_show_server_with_str_body(self): - self._test_show_server() - - def test_show_server_with_bytes_body(self): - self._test_show_server(bytes_body=True) - - def _test_show_server(self, bytes_body=False): - self.check_service_client_function( - self.client.show_server, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_SERVER_GET, - bytes_body, - server_id=self.server_id - ) - - def test_delete_server(self, bytes_body=False): - self.check_service_client_function( - self.client.delete_server, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, - status=204, - server_id=self.server_id - ) - - def test_create_server_with_str_body(self): - self._test_create_server() - - def test_create_server_with_bytes_body(self): - self._test_create_server(True) - - def _test_create_server(self, bytes_body=False): - self.check_service_client_function( - self.client.create_server, - 'tempest_lib.common.rest_client.RestClient.post', - self.FAKE_SERVER_POST, - bytes_body, - status=202, - name='fake-name', - imageRef='fake-image-ref', - flavorRef='fake-flavor-ref' - ) - - def test_list_addresses_with_str_body(self): - self._test_list_addresses() - - def test_list_addresses_with_bytes_body(self): - self._test_list_addresses(True) - - def _test_list_addresses(self, bytes_body=False): - self.check_service_client_function( - self.client.list_addresses, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_ADDRESS, - bytes_body, - server_id=self.server_id - ) - - def test_list_addresses_by_network_with_str_body(self): - self._test_list_addresses_by_network() - - def test_list_addresses_by_network_with_bytes_body(self): - self._test_list_addresses_by_network(True) - - def _test_list_addresses_by_network(self, bytes_body=False): - self.check_service_client_function( - self.client.list_addresses_by_network, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_ADDRESS['addresses'], - server_id=self.server_id, - network_id=self.network_id - ) - - def test_action_with_str_body(self): - self._test_action() - - def test_action_with_bytes_body(self): - self._test_action(True) - - def _test_action(self, bytes_body=False): - self.check_service_client_function( - self.client.action, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - server_id=self.server_id, - action_name='fake-action-name', - schema={'status_code': 200} - ) - - def test_create_backup_with_str_body(self): - self._test_create_backup() - - def test_create_backup_with_bytes_body(self): - self._test_create_backup(True) - - def _test_create_backup(self, bytes_body=False): - self.check_service_client_function( - self.client.create_backup, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id, - backup_type='fake-backup', - rotation='fake-rotation', - name='fake-name' - ) - - def test_change_password_with_str_body(self): - self._test_change_password() - - def test_change_password_with_bytes_body(self): - self._test_change_password(True) - - def _test_change_password(self, bytes_body=False): - self.check_service_client_function( - self.client.change_password, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id, - adminPass='fake-admin-pass' - ) - - def test_show_password_with_str_body(self): - self._test_show_password() - - def test_show_password_with_bytes_body(self): - self._test_show_password(True) - - def _test_show_password(self, bytes_body=False): - self.check_service_client_function( - self.client.show_password, - 'tempest_lib.common.rest_client.RestClient.get', - {'password': 'fake-password'}, - server_id=self.server_id - ) - - def test_delete_password_with_str_body(self): - self._test_delete_password() - - def test_delete_password_with_bytes_body(self): - self._test_delete_password(True) - - def _test_delete_password(self, bytes_body=False): - self.check_service_client_function( - self.client.delete_password, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, - status=204, - server_id=self.server_id - ) - - def test_reboot_server_with_str_body(self): - self._test_reboot_server() - - def test_reboot_server_with_bytes_body(self): - self._test_reboot_server(True) - - def _test_reboot_server(self, bytes_body=False): - self.check_service_client_function( - self.client.reboot_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id, - type='fake-reboot-type' - ) - - def test_rebuild_server_with_str_body(self): - self._test_rebuild_server() - - def test_rebuild_server_with_bytes_body(self): - self._test_rebuild_server(True) - - def _test_rebuild_server(self, bytes_body=False): - self.check_service_client_function( - self.client.rebuild_server, - 'tempest_lib.common.rest_client.RestClient.post', - self.FAKE_REBUILD_SERVER, - status=202, - server_id=self.server_id, - image_ref='fake-image-ref' - ) - - def test_resize_server_with_str_body(self): - self._test_resize_server() - - def test_resize_server_with_bytes_body(self): - self._test_resize_server(True) - - def _test_resize_server(self, bytes_body=False): - self.check_service_client_function( - self.client.resize_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id, - flavor_ref='fake-flavor-ref' - ) - - def test_confirm_resize_server_with_str_body(self): - self._test_confirm_resize_server() - - def test_confirm_resize_server_with_bytes_body(self): - self._test_confirm_resize_server(True) - - def _test_confirm_resize_server(self, bytes_body=False): - self.check_service_client_function( - self.client.confirm_resize_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=204, - server_id=self.server_id - ) - - def test_revert_resize_server_with_str_body(self): - self._test_revert_resize() - - def test_revert_resize_server_with_bytes_body(self): - self._test_revert_resize(True) - - def _test_revert_resize(self, bytes_body=False): - self.check_service_client_function( - self.client.revert_resize_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_list_server_metadata_with_str_body(self): - self._test_list_server_metadata() - - def test_list_server_metadata_with_bytes_body(self): - self._test_list_server_metadata() - - def _test_list_server_metadata(self, bytes_body=False): - self.check_service_client_function( - self.client.list_server_metadata, - 'tempest_lib.common.rest_client.RestClient.get', - {'metadata': {'fake-key': 'fake-meta-data'}}, - server_id=self.server_id - ) - - def test_set_server_metadata_with_str_body(self): - self._test_set_server_metadata() - - def test_set_server_metadata_with_bytes_body(self): - self._test_set_server_metadata(True) - - def _test_set_server_metadata(self, bytes_body=False): - self.check_service_client_function( - self.client.set_server_metadata, - 'tempest_lib.common.rest_client.RestClient.put', - {'metadata': {'fake-key': 'fake-meta-data'}}, - server_id=self.server_id, - meta='fake-meta' - ) - - def test_update_server_metadata_with_str_body(self): - self._test_update_server_metadata() - - def test_update_server_metadata_with_bytes_body(self): - self._test_update_server_metadata(True) - - def _test_update_server_metadata(self, bytes_body=False): - self.check_service_client_function( - self.client.update_server_metadata, - 'tempest_lib.common.rest_client.RestClient.post', - {'metadata': {'fake-key': 'fake-meta-data'}}, - server_id=self.server_id, - meta='fake-meta' - ) - - def test_show_server_metadata_item_with_str_body(self): - self._test_show_server_metadata() - - def test_show_server_metadata_item_with_bytes_body(self): - self._test_show_server_metadata(True) - - def _test_show_server_metadata(self, bytes_body=False): - self.check_service_client_function( - self.client.show_server_metadata_item, - 'tempest_lib.common.rest_client.RestClient.get', - {'meta': {'fake-key': 'fake-meta-data'}}, - server_id=self.server_id, - key='fake-key' - ) - - def test_set_server_metadata_item_with_str_body(self): - self._test_set_server_metadata_item() - - def test_set_server_metadata_item_with_bytes_body(self): - self._test_set_server_metadata_item(True) - - def _test_set_server_metadata_item(self, bytes_body=False): - self.check_service_client_function( - self.client.set_server_metadata_item, - 'tempest_lib.common.rest_client.RestClient.put', - {'meta': {'fake-key': 'fake-meta-data'}}, - server_id=self.server_id, - key='fake-key', - meta='fake-meta' - ) - - def test_delete_server_metadata_item_with_str_body(self): - self._test_delete_server_metadata() - - def test_delete_server_metadata_item_with_bytes_body(self): - self._test_delete_server_metadata(True) - - def _test_delete_server_metadata(self, bytes_body=False): - self.check_service_client_function( - self.client.delete_server_metadata_item, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, - status=204, - server_id=self.server_id, - key='fake-key' - ) - - def test_stop_server_with_str_body(self): - self._test_stop_server() - - def test_stop_server_with_bytes_body(self): - self._test_stop_server(True) - - def _test_stop_server(self, bytes_body=False): - self.check_service_client_function( - self.client.stop_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_start_server_with_str_body(self): - self._test_start_server() - - def test_start_server_with_bytes_body(self): - self._test_start_server(True) - - def _test_start_server(self, bytes_body=False): - self.check_service_client_function( - self.client.start_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_attach_volume_with_str_body(self): - self._test_attach_volume_server() - - def test_attach_volume_with_bytes_body(self): - self._test_attach_volume_server(True) - - def _test_attach_volume_server(self, bytes_body=False): - self.check_service_client_function( - self.client.attach_volume, - 'tempest_lib.common.rest_client.RestClient.post', - {'volumeAttachment': self.FAKE_COMMON_VOLUME}, - server_id=self.server_id - ) - - def test_update_attached_volume(self): - self.check_service_client_function( - self.client.update_attached_volume, - 'tempest_lib.common.rest_client.RestClient.put', - {}, - status=202, - server_id=self.server_id, - attachment_id='fake-attachment-id', - volumeId='fake-volume-id' - ) - - def test_detach_volume_with_str_body(self): - self._test_detach_volume_server() - - def test_detach_volume_with_bytes_body(self): - self._test_detach_volume_server(True) - - def _test_detach_volume_server(self, bytes_body=False): - self.check_service_client_function( - self.client.detach_volume, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, - status=202, - server_id=self.server_id, - volume_id=self.FAKE_COMMON_VOLUME['volumeId'] - ) - - def test_show_volume_attachment_with_str_body(self): - self._test_show_volume_attachment() - - def test_show_volume_attachment_with_bytes_body(self): - self._test_show_volume_attachment(True) - - def _test_show_volume_attachment(self, bytes_body=False): - self.check_service_client_function( - self.client.show_volume_attachment, - 'tempest_lib.common.rest_client.RestClient.get', - {'volumeAttachment': self.FAKE_COMMON_VOLUME}, - server_id=self.server_id, - volume_id=self.FAKE_COMMON_VOLUME['volumeId'] - ) - - def test_list_volume_attachments_with_str_body(self): - self._test_list_volume_attachments() - - def test_list_volume_attachments_with_bytes_body(self): - self._test_list_volume_attachments(True) - - def _test_list_volume_attachments(self, bytes_body=False): - self.check_service_client_function( - self.client.list_volume_attachments, - 'tempest_lib.common.rest_client.RestClient.get', - {'volumeAttachments': [self.FAKE_COMMON_VOLUME]}, - server_id=self.server_id - ) - - def test_add_security_group_with_str_body(self): - self._test_add_security_group() - - def test_add_security_group_with_bytes_body(self): - self._test_add_security_group(True) - - def _test_add_security_group(self, bytes_body=False): - self.check_service_client_function( - self.client.add_security_group, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id, - name='fake-name' - ) - - def test_remove_security_group_with_str_body(self): - self._test_remove_security_group() - - def test_remove_security_group_with_bytes_body(self): - self._test_remove_security_group(True) - - def _test_remove_security_group(self, bytes_body=False): - self.check_service_client_function( - self.client.remove_security_group, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id, - name='fake-name' - ) - - def test_live_migrate_server_with_str_body(self): - self._test_live_migrate_server() - - def test_live_migrate_server_with_bytes_body(self): - self._test_live_migrate_server(True) - - def _test_live_migrate_server(self, bytes_body=False): - self.check_service_client_function( - self.client.live_migrate_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_migrate_server_with_str_body(self): - self._test_migrate_server() - - def test_migrate_server_with_bytes_body(self): - self._test_migrate_server(True) - - def _test_migrate_server(self, bytes_body=False): - self.check_service_client_function( - self.client.migrate_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_lock_server_with_str_body(self): - self._test_lock_server() - - def test_lock_server_with_bytes_body(self): - self._test_lock_server(True) - - def _test_lock_server(self, bytes_body=False): - self.check_service_client_function( - self.client.lock_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_unlock_server_with_str_body(self): - self._test_unlock_server() - - def test_unlock_server_with_bytes_body(self): - self._test_unlock_server(True) - - def _test_unlock_server(self, bytes_body=False): - self.check_service_client_function( - self.client.unlock_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_suspend_server_with_str_body(self): - self._test_suspend_server() - - def test_suspend_server_with_bytes_body(self): - self._test_suspend_server(True) - - def _test_suspend_server(self, bytes_body=False): - self.check_service_client_function( - self.client.suspend_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_resume_server_with_str_body(self): - self._test_resume_server() - - def test_resume_server_with_bytes_body(self): - self._test_resume_server(True) - - def _test_resume_server(self, bytes_body=False): - self.check_service_client_function( - self.client.resume_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_pause_server_with_str_body(self): - self._test_pause_server() - - def test_pause_server_with_bytes_body(self): - self._test_pause_server(True) - - def _test_pause_server(self, bytes_body=False): - self.check_service_client_function( - self.client.pause_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_unpause_server_with_str_body(self): - self._test_unpause_server() - - def test_unpause_server_with_bytes_body(self): - self._test_unpause_server(True) - - def _test_unpause_server(self, bytes_body=False): - self.check_service_client_function( - self.client.unpause_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_reset_state_with_str_body(self): - self._test_reset_state() - - def test_reset_state_with_bytes_body(self): - self._test_reset_state(True) - - def _test_reset_state(self, bytes_body=False): - self.check_service_client_function( - self.client.reset_state, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id, - state='fake-state' - ) - - def test_shelve_server_with_str_body(self): - self._test_shelve_server() - - def test_shelve_server_with_bytes_body(self): - self._test_shelve_server(True) - - def _test_shelve_server(self, bytes_body=False): - self.check_service_client_function( - self.client.shelve_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_unshelve_server_with_str_body(self): - self._test_unshelve_server() - - def test_unshelve_server_with_bytes_body(self): - self._test_unshelve_server(True) - - def _test_unshelve_server(self, bytes_body=False): - self.check_service_client_function( - self.client.unshelve_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_shelve_offload_server_with_str_body(self): - self._test_shelve_offload_server() - - def test_shelve_offload_server_with_bytes_body(self): - self._test_shelve_offload_server(True) - - def _test_shelve_offload_server(self, bytes_body=False): - self.check_service_client_function( - self.client.shelve_offload_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_get_console_output_with_str_body(self): - self._test_get_console_output() - - def test_get_console_output_with_bytes_body(self): - self._test_get_console_output(True) - - def _test_get_console_output(self, bytes_body=False): - self.check_service_client_function( - self.client.get_console_output, - 'tempest_lib.common.rest_client.RestClient.post', - {'output': 'fake-output'}, - server_id=self.server_id, - length='fake-length' - ) - - def test_list_virtual_interfaces_with_str_body(self): - self._test_list_virtual_interfaces() - - def test_list_virtual_interfaces_with_bytes_body(self): - self._test_list_virtual_interfaces(True) - - def _test_list_virtual_interfaces(self, bytes_body=False): - self.check_service_client_function( - self.client.list_virtual_interfaces, - 'tempest_lib.common.rest_client.RestClient.get', - {'virtual_interfaces': [self.FAKE_VIRTUAL_INTERFACES]}, - server_id=self.server_id - ) - - def test_rescue_server_with_str_body(self): - self._test_rescue_server() - - def test_rescue_server_with_bytes_body(self): - self._test_rescue_server(True) - - def _test_rescue_server(self, bytes_body=False): - self.check_service_client_function( - self.client.rescue_server, - 'tempest_lib.common.rest_client.RestClient.post', - {'adminPass': 'fake-admin-pass'}, - server_id=self.server_id - ) - - def test_unrescue_server_with_str_body(self): - self._test_unrescue_server() - - def test_unrescue_server_with_bytes_body(self): - self._test_unrescue_server(True) - - def _test_unrescue_server(self, bytes_body=False): - self.check_service_client_function( - self.client.unrescue_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_show_server_diagnostics_with_str_body(self): - self._test_show_server_diagnostics() - - def test_show_server_diagnostics_with_bytes_body(self): - self._test_show_server_diagnostics(True) - - def _test_show_server_diagnostics(self, bytes_body=False): - self.check_service_client_function( - self.client.show_server_diagnostics, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_SERVER_DIAGNOSTICS, - status=200, - server_id=self.server_id - ) - - def test_list_instance_actions_with_str_body(self): - self._test_list_instance_actions() - - def test_list_instance_actions_with_bytes_body(self): - self._test_list_instance_actions(True) - - def _test_list_instance_actions(self, bytes_body=False): - self.check_service_client_function( - self.client.list_instance_actions, - 'tempest_lib.common.rest_client.RestClient.get', - {'instanceActions': [self.FAKE_INSTANCE_ACTIONS]}, - server_id=self.server_id - ) - - def test_show_instance_action_with_str_body(self): - self._test_show_instance_action() - - def test_show_instance_action_with_bytes_body(self): - self._test_show_instance_action(True) - - def _test_show_instance_action(self, bytes_body=False): - self.check_service_client_function( - self.client.show_instance_action, - 'tempest_lib.common.rest_client.RestClient.get', - {'instanceAction': self.FAKE_INSTANCE_WITH_EVENTS}, - server_id=self.server_id, - request_id='fake-request-id' - ) - - def test_force_delete_server_with_str_body(self): - self._test_force_delete_server() - - def test_force_delete_server_with_bytes_body(self): - self._test_force_delete_server(True) - - def _test_force_delete_server(self, bytes_body=False): - self.check_service_client_function( - self.client.force_delete_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_restore_soft_deleted_server_with_str_body(self): - self._test_restore_soft_deleted_server() - - def test_restore_soft_deleted_server_with_bytes_body(self): - self._test_restore_soft_deleted_server(True) - - def _test_restore_soft_deleted_server(self, bytes_body=False): - self.check_service_client_function( - self.client.restore_soft_deleted_server, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_reset_network_with_str_body(self): - self._test_reset_network() - - def test_reset_network_with_bytes_body(self): - self._test_reset_network(True) - - def _test_reset_network(self, bytes_body=False): - self.check_service_client_function( - self.client.reset_network, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_inject_network_info_with_str_body(self): - self._test_inject_network_info() - - def test_inject_network_info_with_bytes_body(self): - self._test_inject_network_info(True) - - def _test_inject_network_info(self, bytes_body=False): - self.check_service_client_function( - self.client.inject_network_info, - 'tempest_lib.common.rest_client.RestClient.post', - {}, - status=202, - server_id=self.server_id - ) - - def test_get_vnc_console_with_str_body(self): - self._test_get_vnc_console() - - def test_get_vnc_console_with_bytes_body(self): - self._test_get_vnc_console(True) - - def _test_get_vnc_console(self, bytes_body=False): - self.check_service_client_function( - self.client.get_vnc_console, - 'tempest_lib.common.rest_client.RestClient.post', - {'console': self.FAKE_VNC_CONSOLE}, - server_id=self.server_id, - type='fake-console-type' - ) diff --git a/tempest_lib/tests/services/compute/test_services_client.py b/tempest_lib/tests/services/compute/test_services_client.py deleted file mode 100644 index 67d717a..0000000 --- a/tempest_lib/tests/services/compute/test_services_client.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2015 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 copy - -from tempest_lib.services.compute import services_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestServicesClient(base.BaseComputeServiceTest): - - FAKE_SERVICES = { - "services": - [{ - "status": "enabled", - "binary": "nova-conductor", - "zone": "internal", - "state": "up", - "updated_at": "2015-08-19T06:50:55.000000", - "host": "controller", - "disabled_reason": None, - "id": 1 - }] - } - - FAKE_SERVICE = { - "service": - { - "status": "enabled", - "binary": "nova-conductor", - "host": "controller" - } - } - - def setUp(self): - super(TestServicesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = services_client.ServicesClient( - fake_auth, 'compute', 'regionOne') - - def test_list_services_with_str_body(self): - self.check_service_client_function( - self.client.list_services, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_SERVICES) - - def test_list_services_with_bytes_body(self): - self.check_service_client_function( - self.client.list_services, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_SERVICES, to_utf=True) - - def _test_enable_service(self, bytes_body=False): - self.check_service_client_function( - self.client.enable_service, - 'tempest_lib.common.rest_client.RestClient.put', - self.FAKE_SERVICE, - bytes_body, - host_name="nova-conductor", binary="controller") - - def test_enable_service_with_str_body(self): - self._test_enable_service() - - def test_enable_service_with_bytes_body(self): - self._test_enable_service(bytes_body=True) - - def _test_disable_service(self, bytes_body=False): - fake_service = copy.deepcopy(self.FAKE_SERVICE) - fake_service["service"]["status"] = "disable" - - self.check_service_client_function( - self.client.disable_service, - 'tempest_lib.common.rest_client.RestClient.put', - fake_service, - bytes_body, - host_name="nova-conductor", binary="controller") - - def test_disable_service_with_str_body(self): - self._test_disable_service() - - def test_disable_service_with_bytes_body(self): - self._test_disable_service(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_snapshots_client.py b/tempest_lib/tests/services/compute/test_snapshots_client.py deleted file mode 100644 index 008a7ea..0000000 --- a/tempest_lib/tests/services/compute/test_snapshots_client.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright 2015 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 oslotest import mockpatch - -from tempest_lib import exceptions as lib_exc -from tempest_lib.services.compute import snapshots_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestSnapshotsClient(base.BaseComputeServiceTest): - - FAKE_SNAPSHOT = { - "createdAt": "2015-10-02T16:27:54.724209", - "displayDescription": u"Another \u1234.", - "displayName": u"v\u1234-001", - "id": "100", - "size": 100, - "status": "available", - "volumeId": "12" - } - - FAKE_SNAPSHOTS = {"snapshots": [FAKE_SNAPSHOT]} - - def setUp(self): - super(TestSnapshotsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = snapshots_client.SnapshotsClient( - fake_auth, 'compute', 'regionOne') - - def _test_create_snapshot(self, bytes_body=False): - self.check_service_client_function( - self.client.create_snapshot, - 'tempest_lib.common.rest_client.RestClient.post', - {"snapshot": self.FAKE_SNAPSHOT}, - to_utf=bytes_body, status=200, - volume_id=self.FAKE_SNAPSHOT["volumeId"]) - - def test_create_snapshot_with_str_body(self): - self._test_create_snapshot() - - def test_create_shapshot_with_bytes_body(self): - self._test_create_snapshot(bytes_body=True) - - def _test_show_snapshot(self, bytes_body=False): - self.check_service_client_function( - self.client.show_snapshot, - 'tempest_lib.common.rest_client.RestClient.get', - {"snapshot": self.FAKE_SNAPSHOT}, - to_utf=bytes_body, snapshot_id=self.FAKE_SNAPSHOT["id"]) - - def test_show_snapshot_with_str_body(self): - self._test_show_snapshot() - - def test_show_snapshot_with_bytes_body(self): - self._test_show_snapshot(bytes_body=True) - - def _test_list_snapshots(self, bytes_body=False, **params): - self.check_service_client_function( - self.client.list_snapshots, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_SNAPSHOTS, to_utf=bytes_body, **params) - - def test_list_snapshots_with_str_body(self): - self._test_list_snapshots() - - def test_list_snapshots_with_byte_body(self): - self._test_list_snapshots(bytes_body=True) - - def test_list_snapshots_with_params(self): - self._test_list_snapshots('fake') - - def test_delete_snapshot(self): - self.check_service_client_function( - self.client.delete_snapshot, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, status=202, snapshot_id=self.FAKE_SNAPSHOT['id']) - - def test_is_resource_deleted_true(self): - module = ('tempest_lib.services.compute.snapshots_client.' - 'SnapshotsClient.show_snapshot') - self.useFixture(mockpatch.Patch( - module, side_effect=lib_exc.NotFound)) - self.assertTrue(self.client.is_resource_deleted('fake-id')) - - def test_is_resource_deleted_false(self): - module = ('tempest_lib.services.compute.snapshots_client.' - 'SnapshotsClient.show_snapshot') - self.useFixture(mockpatch.Patch( - module, return_value={})) - self.assertFalse(self.client.is_resource_deleted('fake-id')) diff --git a/tempest_lib/tests/services/compute/test_tenant_networks_client.py b/tempest_lib/tests/services/compute/test_tenant_networks_client.py deleted file mode 100644 index d21d85c..0000000 --- a/tempest_lib/tests/services/compute/test_tenant_networks_client.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright 2015 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_lib.services.compute import tenant_networks_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestTenantNetworksClient(base.BaseComputeServiceTest): - - FAKE_NETWORK = { - "cidr": "None", - "id": "c2329eb4-cc8e-4439-ac4c-932369309e36", - "label": u'\u30d7' - } - - FAKE_NETWORKS = [FAKE_NETWORK] - - NETWORK_ID = FAKE_NETWORK['id'] - - def setUp(self): - super(TestTenantNetworksClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = tenant_networks_client.TenantNetworksClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_tenant_networks(self, bytes_body=False): - self.check_service_client_function( - self.client.list_tenant_networks, - 'tempest_lib.common.rest_client.RestClient.get', - {"networks": self.FAKE_NETWORKS}, - bytes_body) - - def test_list_tenant_networks_with_str_body(self): - self._test_list_tenant_networks() - - def test_list_tenant_networks_with_bytes_body(self): - self._test_list_tenant_networks(bytes_body=True) - - def _test_show_tenant_network(self, bytes_body=False): - self.check_service_client_function( - self.client.show_tenant_network, - 'tempest_lib.common.rest_client.RestClient.get', - {"network": self.FAKE_NETWORK}, - bytes_body, - network_id=self.NETWORK_ID) - - def test_show_tenant_network_with_str_body(self): - self._test_show_tenant_network() - - def test_show_tenant_network_with_bytes_body(self): - self._test_show_tenant_network(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_tenant_usages_client.py b/tempest_lib/tests/services/compute/test_tenant_usages_client.py deleted file mode 100644 index 9ccb392..0000000 --- a/tempest_lib/tests/services/compute/test_tenant_usages_client.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright 2015 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_lib.services.compute import tenant_usages_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestTenantUsagesClient(base.BaseComputeServiceTest): - - FAKE_SERVER_USAGES = [{ - "ended_at": None, - "flavor": "m1.tiny", - "hours": 1.0, - "instance_id": "1f1deceb-17b5-4c04-84c7-e0d4499c8fe0", - "local_gb": 1, - "memory_mb": 512, - "name": "new-server-test", - "started_at": "2012-10-08T20:10:44.541277", - "state": "active", - "tenant_id": "openstack", - "uptime": 3600, - "vcpus": 1 - }] - - FAKE_TENANT_USAGES = [{ - "server_usages": FAKE_SERVER_USAGES, - "start": "2012-10-08T21:10:44.587336", - "stop": "2012-10-08T22:10:44.587336", - "tenant_id": "openstack", - "total_hours": 1, - "total_local_gb_usage": 1, - "total_memory_mb_usage": 512, - "total_vcpus_usage": 1 - }] - - def setUp(self): - super(TestTenantUsagesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = tenant_usages_client.TenantUsagesClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_tenant_usages(self, bytes_body=False): - self.check_service_client_function( - self.client.list_tenant_usages, - 'tempest_lib.common.rest_client.RestClient.get', - {"tenant_usages": self.FAKE_TENANT_USAGES}, - to_utf=bytes_body) - - def test_list_tenant_usages_with_str_body(self): - self._test_list_tenant_usages() - - def test_list_tenant_usages_with_bytes_body(self): - self._test_list_tenant_usages(bytes_body=True) - - def _test_show_tenant_usage(self, bytes_body=False): - self.check_service_client_function( - self.client.show_tenant_usage, - 'tempest_lib.common.rest_client.RestClient.get', - {"tenant_usage": self.FAKE_TENANT_USAGES[0]}, - to_utf=bytes_body, - tenant_id='openstack') - - def test_show_tenant_usage_with_str_body(self): - self._test_show_tenant_usage() - - def test_show_tenant_usage_with_bytes_body(self): - self._test_show_tenant_usage(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_versions_client.py b/tempest_lib/tests/services/compute/test_versions_client.py deleted file mode 100644 index f79934e..0000000 --- a/tempest_lib/tests/services/compute/test_versions_client.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright 2015 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 copy -from oslotest import mockpatch - -from tempest_lib.services.compute import versions_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestVersionsClient(base.BaseComputeServiceTest): - - FAKE_INIT_VERSION = { - "version": { - "id": "v2.1", - "links": [ - { - "href": "http://openstack.example.com/v2.1/", - "rel": "self" - }, - { - "href": "http://docs.openstack.org/", - "rel": "describedby", - "type": "text/html" - } - ], - "status": "CURRENT", - "updated": "2013-07-23T11:33:21Z", - "version": "2.1", - "min_version": "2.1" - } - } - - FAKE_VERSIONS_INFO = { - "versions": [FAKE_INIT_VERSION["version"]] - } - - FAKE_VERSION_INFO = copy.deepcopy(FAKE_INIT_VERSION) - - FAKE_VERSION_INFO["version"]["media-types"] = [ - { - "base": "application/json", - "type": "application/vnd.openstack.compute+json;version=2.1" - } - ] - - def setUp(self): - super(TestVersionsClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.versions_client = ( - versions_client.VersionsClient - (fake_auth, 'compute', 'regionOne')) - - def _test_versions_client(self, bytes_body=False): - self.check_service_client_function( - self.versions_client.list_versions, - 'tempest_lib.common.rest_client.RestClient.raw_request', - self.FAKE_VERSIONS_INFO, - bytes_body, - 200) - - def _test_get_version_by_url(self, bytes_body=False): - self.useFixture(mockpatch.Patch( - "tempest_lib.common.rest_client.RestClient.token", - return_value="Dummy Token")) - params = {"version_url": self.versions_client._get_base_version_url()} - self.check_service_client_function( - self.versions_client.get_version_by_url, - 'tempest_lib.common.rest_client.RestClient.raw_request', - self.FAKE_VERSION_INFO, - bytes_body, - 200, **params) - - def test_list_versions_client_with_str_body(self): - self._test_versions_client() - - def test_list_versions_client_with_bytes_body(self): - self._test_versions_client(bytes_body=True) - - def test_get_version_by_url_with_str_body(self): - self._test_get_version_by_url() - - def test_get_version_by_url_with_bytes_body(self): - self._test_get_version_by_url(bytes_body=True) diff --git a/tempest_lib/tests/services/compute/test_volumes_client.py b/tempest_lib/tests/services/compute/test_volumes_client.py deleted file mode 100644 index 0687f35..0000000 --- a/tempest_lib/tests/services/compute/test_volumes_client.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright 2015 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 copy - -from oslotest import mockpatch - -from tempest_lib import exceptions as lib_exc -from tempest_lib.services.compute import volumes_client -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests.services.compute import base - - -class TestVolumesClient(base.BaseComputeServiceTest): - - FAKE_VOLUME = { - "id": "521752a6-acf6-4b2d-bc7a-119f9148cd8c", - "displayName": u"v\u12345ol-001", - "displayDescription": u"Another \u1234volume.", - "size": 30, - "status": "Active", - "volumeType": "289da7f8-6440-407c-9fb4-7db01ec49164", - "metadata": { - "contents": "junk" - }, - "availabilityZone": "us-east1", - "snapshotId": None, - "attachments": [], - "createdAt": "2012-02-14T20:53:07Z" - } - - FAKE_VOLUMES = {"volumes": [FAKE_VOLUME]} - - def setUp(self): - super(TestVolumesClient, self).setUp() - fake_auth = fake_auth_provider.FakeAuthProvider() - self.client = volumes_client.VolumesClient( - fake_auth, 'compute', 'regionOne') - - def _test_list_volumes(self, bytes_body=False, **params): - self.check_service_client_function( - self.client.list_volumes, - 'tempest_lib.common.rest_client.RestClient.get', - self.FAKE_VOLUMES, to_utf=bytes_body, **params) - - def test_list_volumes_with_str_body(self): - self._test_list_volumes() - - def test_list_volumes_with_byte_body(self): - self._test_list_volumes(bytes_body=True) - - def test_list_volumes_with_params(self): - self._test_list_volumes(name='fake') - - def _test_show_volume(self, bytes_body=False): - self.check_service_client_function( - self.client.show_volume, - 'tempest_lib.common.rest_client.RestClient.get', - {"volume": self.FAKE_VOLUME}, - to_utf=bytes_body, volume_id=self.FAKE_VOLUME['id']) - - def test_show_volume_with_str_body(self): - self._test_show_volume() - - def test_show_volume_with_bytes_body(self): - self._test_show_volume(bytes_body=True) - - def _test_create_volume(self, bytes_body=False): - post_body = copy.deepcopy(self.FAKE_VOLUME) - del post_body['id'] - del post_body['createdAt'] - del post_body['status'] - self.check_service_client_function( - self.client.create_volume, - 'tempest_lib.common.rest_client.RestClient.post', - {"volume": self.FAKE_VOLUME}, - to_utf=bytes_body, status=200, **post_body) - - def test_create_volume_with_str_body(self): - self._test_create_volume() - - def test_create_volume_with_bytes_body(self): - self._test_create_volume(bytes_body=True) - - def test_delete_volume(self): - self.check_service_client_function( - self.client.delete_volume, - 'tempest_lib.common.rest_client.RestClient.delete', - {}, status=202, volume_id=self.FAKE_VOLUME['id']) - - def test_is_resource_deleted_true(self): - module = ('tempest_lib.services.compute.volumes_client.' - 'VolumesClient.show_volume') - self.useFixture(mockpatch.Patch( - module, side_effect=lib_exc.NotFound)) - self.assertTrue(self.client.is_resource_deleted('fake-id')) - - def test_is_resource_deleted_false(self): - module = ('tempest_lib.services.compute.volumes_client.' - 'VolumesClient.show_volume') - self.useFixture(mockpatch.Patch( - module, return_value={})) - self.assertFalse(self.client.is_resource_deleted('fake-id')) diff --git a/tempest_lib/tests/services/identity/__init__.py b/tempest_lib/tests/services/identity/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/tests/services/identity/v2/__init__.py b/tempest_lib/tests/services/identity/v2/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/tests/services/identity/v2/test_token_client.py b/tempest_lib/tests/services/identity/v2/test_token_client.py deleted file mode 100644 index 57e439c..0000000 --- a/tempest_lib/tests/services/identity/v2/test_token_client.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright 2015 Hewlett-Packard 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 json - -import httplib2 -from oslotest import mockpatch - -from tempest_lib.common import rest_client -from tempest_lib import exceptions -from tempest_lib.services.identity.v2 import token_client -from tempest_lib.tests import base -from tempest_lib.tests import fake_http - - -class TestTokenClientV2(base.TestCase): - - def setUp(self): - super(TestTokenClientV2, self).setUp() - self.fake_200_http = fake_http.fake_httplib2(return_type=200) - - def test_init_without_authurl(self): - self.assertRaises(exceptions.IdentityError, - token_client.TokenClient, None) - - def test_auth(self): - token_client_v2 = token_client.TokenClient('fake_url') - post_mock = self.useFixture(mockpatch.PatchObject( - token_client_v2, 'post', return_value=self.fake_200_http.request( - 'fake_url', body={'access': {'token': 'fake_token'}}))) - resp = token_client_v2.auth('fake_user', 'fake_pass') - self.assertIsInstance(resp, rest_client.ResponseBody) - req_dict = json.dumps({ - 'auth': { - 'passwordCredentials': { - 'username': 'fake_user', - 'password': 'fake_pass', - }, - } - }, sort_keys=True) - post_mock.mock.assert_called_once_with('fake_url/tokens', - body=req_dict) - - def test_auth_with_tenant(self): - token_client_v2 = token_client.TokenClient('fake_url') - post_mock = self.useFixture(mockpatch.PatchObject( - token_client_v2, 'post', return_value=self.fake_200_http.request( - 'fake_url', body={'access': {'token': 'fake_token'}}))) - resp = token_client_v2.auth('fake_user', 'fake_pass', 'fake_tenant') - self.assertIsInstance(resp, rest_client.ResponseBody) - req_dict = json.dumps({ - 'auth': { - 'tenantName': 'fake_tenant', - 'passwordCredentials': { - 'username': 'fake_user', - 'password': 'fake_pass', - }, - } - }, sort_keys=True) - post_mock.mock.assert_called_once_with('fake_url/tokens', - body=req_dict) - - def test_request_with_str_body(self): - token_client_v2 = token_client.TokenClient('fake_url') - self.useFixture(mockpatch.PatchObject( - token_client_v2, 'raw_request', return_value=( - httplib2.Response({'status': '200'}), - str('{"access": {"token": "fake_token"}}')))) - resp, body = token_client_v2.request('GET', 'fake_uri') - self.assertIsInstance(resp, httplib2.Response) - self.assertIsInstance(body, dict) - - def test_request_with_bytes_body(self): - token_client_v2 = token_client.TokenClient('fake_url') - self.useFixture(mockpatch.PatchObject( - token_client_v2, 'raw_request', return_value=( - httplib2.Response({'status': '200'}), - bytes(b'{"access": {"token": "fake_token"}}')))) - resp, body = token_client_v2.request('GET', 'fake_uri') - self.assertIsInstance(resp, httplib2.Response) - self.assertIsInstance(body, dict) diff --git a/tempest_lib/tests/services/identity/v3/__init__.py b/tempest_lib/tests/services/identity/v3/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tempest_lib/tests/services/identity/v3/test_token_client.py b/tempest_lib/tests/services/identity/v3/test_token_client.py deleted file mode 100644 index b3a8b28..0000000 --- a/tempest_lib/tests/services/identity/v3/test_token_client.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright 2015 Hewlett-Packard 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 json - -import httplib2 -from oslotest import mockpatch - -from tempest_lib.common import rest_client -from tempest_lib import exceptions -from tempest_lib.services.identity.v3 import token_client -from tempest_lib.tests import base -from tempest_lib.tests import fake_http - - -class TestTokenClientV2(base.TestCase): - - def setUp(self): - super(TestTokenClientV2, self).setUp() - self.fake_201_http = fake_http.fake_httplib2(return_type=201) - - def test_init_without_authurl(self): - self.assertRaises(exceptions.IdentityError, - token_client.V3TokenClient, None) - - def test_auth(self): - token_client_v3 = token_client.V3TokenClient('fake_url') - post_mock = self.useFixture(mockpatch.PatchObject( - token_client_v3, 'post', return_value=self.fake_201_http.request( - 'fake_url', body={'access': {'token': 'fake_token'}}))) - resp = token_client_v3.auth(username='fake_user', password='fake_pass') - self.assertIsInstance(resp, rest_client.ResponseBody) - req_dict = json.dumps({ - 'auth': { - 'identity': { - 'methods': ['password'], - 'password': { - 'user': { - 'name': 'fake_user', - 'password': 'fake_pass', - } - } - }, - } - }, sort_keys=True) - post_mock.mock.assert_called_once_with('fake_url/auth/tokens', - body=req_dict) - - def test_auth_with_project_id_and_domain_id(self): - token_client_v3 = token_client.V3TokenClient('fake_url') - post_mock = self.useFixture(mockpatch.PatchObject( - token_client_v3, 'post', return_value=self.fake_201_http.request( - 'fake_url', body={'access': {'token': 'fake_token'}}))) - resp = token_client_v3.auth( - username='fake_user', password='fake_pass', - project_id='fcac2a055a294e4c82d0a9c21c620eb4', - user_domain_id='14f4a9a99973404d8c20ba1d2af163ff', - project_domain_id='291f63ae9ac54ee292ca09e5f72d9676') - self.assertIsInstance(resp, rest_client.ResponseBody) - req_dict = json.dumps({ - 'auth': { - 'identity': { - 'methods': ['password'], - 'password': { - 'user': { - 'name': 'fake_user', - 'password': 'fake_pass', - 'domain': { - 'id': '14f4a9a99973404d8c20ba1d2af163ff' - } - } - } - }, - 'scope': { - 'project': { - 'id': 'fcac2a055a294e4c82d0a9c21c620eb4', - 'domain': { - 'id': '291f63ae9ac54ee292ca09e5f72d9676' - } - } - } - } - }, sort_keys=True) - post_mock.mock.assert_called_once_with('fake_url/auth/tokens', - body=req_dict) - - def test_auth_with_tenant(self): - token_client_v2 = token_client.V3TokenClient('fake_url') - post_mock = self.useFixture(mockpatch.PatchObject( - token_client_v2, 'post', return_value=self.fake_201_http.request( - 'fake_url', body={'access': {'token': 'fake_token'}}))) - resp = token_client_v2.auth(username='fake_user', password='fake_pass', - project_name='fake_tenant') - self.assertIsInstance(resp, rest_client.ResponseBody) - req_dict = json.dumps({ - 'auth': { - 'identity': { - 'methods': ['password'], - 'password': { - 'user': { - 'name': 'fake_user', - 'password': 'fake_pass', - } - }}, - 'scope': { - 'project': { - 'name': 'fake_tenant' - } - }, - } - }, sort_keys=True) - - post_mock.mock.assert_called_once_with('fake_url/auth/tokens', - body=req_dict) - - def test_request_with_str_body(self): - token_client_v3 = token_client.V3TokenClient('fake_url') - self.useFixture(mockpatch.PatchObject( - token_client_v3, 'raw_request', return_value=( - httplib2.Response({"status": "200"}), - str('{"access": {"token": "fake_token"}}')))) - resp, body = token_client_v3.request('GET', 'fake_uri') - self.assertIsInstance(resp, httplib2.Response) - self.assertIsInstance(body, dict) - - def test_request_with_bytes_body(self): - token_client_v3 = token_client.V3TokenClient('fake_url') - self.useFixture(mockpatch.PatchObject( - token_client_v3, 'raw_request', return_value=( - httplib2.Response({"status": "200"}), - bytes(b'{"access": {"token": "fake_token"}}')))) - resp, body = token_client_v3.request('GET', 'fake_uri') - self.assertIsInstance(resp, httplib2.Response) - self.assertIsInstance(body, dict) diff --git a/tempest_lib/tests/test_auth.py b/tempest_lib/tests/test_auth.py deleted file mode 100644 index 62d95f4..0000000 --- a/tempest_lib/tests/test_auth.py +++ /dev/null @@ -1,480 +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 copy -import datetime - -from oslotest import mockpatch - -from tempest_lib import auth -from tempest_lib import exceptions -from tempest_lib.services.identity.v2 import token_client as v2_client -from tempest_lib.services.identity.v3 import token_client as v3_client -from tempest_lib.tests import base -from tempest_lib.tests import fake_credentials -from tempest_lib.tests import fake_http -from tempest_lib.tests import fake_identity - - -def fake_get_credentials(fill_in=True, identity_version='v2', **kwargs): - return fake_credentials.FakeCredentials() - - -class BaseAuthTestsSetUp(base.TestCase): - _auth_provider_class = None - credentials = fake_credentials.FakeCredentials() - - def _auth(self, credentials, auth_url, **params): - """returns auth method according to keystone""" - return self._auth_provider_class(credentials, auth_url, **params) - - def setUp(self): - super(BaseAuthTestsSetUp, self).setUp() - self.fake_http = fake_http.fake_httplib2(return_type=200) - self.stubs.Set(auth, 'get_credentials', fake_get_credentials) - self.auth_provider = self._auth(self.credentials, - fake_identity.FAKE_AUTH_URL) - - -class TestBaseAuthProvider(BaseAuthTestsSetUp): - """Tests for base AuthProvider - - This tests auth.AuthProvider class which is base for the other so we - obviously don't test not implemented method or the ones which strongly - depends on them. - """ - - class FakeAuthProviderImpl(auth.AuthProvider): - def _decorate_request(self): - pass - - def _fill_credentials(self): - pass - - def _get_auth(self): - pass - - def base_url(self): - pass - - def is_expired(self): - pass - - _auth_provider_class = FakeAuthProviderImpl - - def _auth(self, credentials, auth_url, **params): - """returns auth method according to keystone""" - return self._auth_provider_class(credentials, **params) - - def test_check_credentials_bad_type(self): - self.assertFalse(self.auth_provider.check_credentials([])) - - def test_auth_data_property_when_cache_exists(self): - self.auth_provider.cache = 'foo' - self.useFixture(mockpatch.PatchObject(self.auth_provider, - 'is_expired', - return_value=False)) - self.assertEqual('foo', getattr(self.auth_provider, 'auth_data')) - - def test_delete_auth_data_property_through_deleter(self): - self.auth_provider.cache = 'foo' - del self.auth_provider.auth_data - self.assertIsNone(self.auth_provider.cache) - - def test_delete_auth_data_property_through_clear_auth(self): - self.auth_provider.cache = 'foo' - self.auth_provider.clear_auth() - self.assertIsNone(self.auth_provider.cache) - - def test_set_and_reset_alt_auth_data(self): - self.auth_provider.set_alt_auth_data('foo', 'bar') - self.assertEqual(self.auth_provider.alt_part, 'foo') - self.assertEqual(self.auth_provider.alt_auth_data, 'bar') - - self.auth_provider.reset_alt_auth_data() - self.assertIsNone(self.auth_provider.alt_part) - self.assertIsNone(self.auth_provider.alt_auth_data) - - def test_auth_class(self): - self.assertRaises(TypeError, - auth.AuthProvider, - fake_credentials.FakeCredentials) - - -class TestKeystoneV2AuthProvider(BaseAuthTestsSetUp): - _endpoints = fake_identity.IDENTITY_V2_RESPONSE['access']['serviceCatalog'] - _auth_provider_class = auth.KeystoneV2AuthProvider - credentials = fake_credentials.FakeKeystoneV2Credentials() - - def setUp(self): - super(TestKeystoneV2AuthProvider, self).setUp() - self.stubs.Set(v2_client.TokenClient, 'raw_request', - fake_identity._fake_v2_response) - self.target_url = 'test_api' - - def _get_fake_identity(self): - return fake_identity.IDENTITY_V2_RESPONSE['access'] - - def _get_fake_alt_identity(self): - return fake_identity.ALT_IDENTITY_V2_RESPONSE['access'] - - def _get_result_url_from_endpoint(self, ep, endpoint_type='publicURL', - replacement=None): - if replacement: - return ep[endpoint_type].replace('v2', replacement) - return ep[endpoint_type] - - def _get_token_from_fake_identity(self): - return fake_identity.TOKEN - - def _get_from_fake_identity(self, attr): - access = fake_identity.IDENTITY_V2_RESPONSE['access'] - if attr == 'user_id': - return access['user']['id'] - elif attr == 'tenant_id': - return access['token']['tenant']['id'] - - def _test_request_helper(self, filters, expected): - url, headers, body = self.auth_provider.auth_request('GET', - self.target_url, - filters=filters) - - self.assertEqual(expected['url'], url) - self.assertEqual(expected['token'], headers['X-Auth-Token']) - self.assertEqual(expected['body'], body) - - def _auth_data_with_expiry(self, date_as_string): - token, access = self.auth_provider.auth_data - access['token']['expires'] = date_as_string - return token, access - - def test_request(self): - filters = { - 'service': 'compute', - 'endpoint_type': 'publicURL', - 'region': 'FakeRegion' - } - - url = self._get_result_url_from_endpoint( - self._endpoints[0]['endpoints'][1]) + '/' + self.target_url - - expected = { - 'body': None, - 'url': url, - 'token': self._get_token_from_fake_identity(), - } - self._test_request_helper(filters, expected) - - def test_request_with_alt_auth_cleans_alt(self): - """Test alternate auth data for headers - - Assert that when the alt data is provided for headers, after an - auth_request the data alt_data is cleaned-up. - """ - self.auth_provider.set_alt_auth_data( - 'headers', - (fake_identity.ALT_TOKEN, self._get_fake_alt_identity())) - filters = { - 'service': 'compute', - 'endpoint_type': 'publicURL', - 'region': 'fakeRegion' - } - self.auth_provider.auth_request('GET', self.target_url, - filters=filters) - - # Assert alt auth data is clear after it - self.assertIsNone(self.auth_provider.alt_part) - self.assertIsNone(self.auth_provider.alt_auth_data) - - def _test_request_with_identical_alt_auth(self, part): - """Test alternate but identical auth data for headers - - Assert that when the alt data is provided, but it's actually - identical, an exception is raised. - """ - self.auth_provider.set_alt_auth_data( - part, - (fake_identity.TOKEN, self._get_fake_identity())) - filters = { - 'service': 'compute', - 'endpoint_type': 'publicURL', - 'region': 'fakeRegion' - } - - self.assertRaises(exceptions.BadAltAuth, - self.auth_provider.auth_request, - 'GET', self.target_url, filters=filters) - - def test_request_with_identical_alt_auth_headers(self): - self._test_request_with_identical_alt_auth('headers') - - def test_request_with_identical_alt_auth_url(self): - self._test_request_with_identical_alt_auth('url') - - def test_request_with_identical_alt_auth_body(self): - self._test_request_with_identical_alt_auth('body') - - def test_request_with_alt_part_without_alt_data(self): - """Test empty alternate auth data - - Assert that when alt_part is defined, the corresponding original - request element is kept the same. - """ - filters = { - 'service': 'compute', - 'endpoint_type': 'publicURL', - 'region': 'fakeRegion' - } - self.auth_provider.set_alt_auth_data('headers', None) - - url, headers, body = self.auth_provider.auth_request('GET', - self.target_url, - filters=filters) - # The original headers where empty - self.assertNotEqual(url, self.target_url) - self.assertIsNone(headers) - self.assertEqual(body, None) - - def _test_request_with_alt_part_without_alt_data_no_change(self, body): - """Test empty alternate auth data with no effect - - Assert that when alt_part is defined, no auth_data is provided, - and the the corresponding original request element was not going to - be changed anyways, and exception is raised - """ - filters = { - 'service': 'compute', - 'endpoint_type': 'publicURL', - 'region': 'fakeRegion' - } - self.auth_provider.set_alt_auth_data('body', None) - - self.assertRaises(exceptions.BadAltAuth, - self.auth_provider.auth_request, - 'GET', self.target_url, filters=filters) - - def test_request_with_alt_part_without_alt_data_no_change_headers(self): - self._test_request_with_alt_part_without_alt_data_no_change('headers') - - def test_request_with_alt_part_without_alt_data_no_change_url(self): - self._test_request_with_alt_part_without_alt_data_no_change('url') - - def test_request_with_alt_part_without_alt_data_no_change_body(self): - self._test_request_with_alt_part_without_alt_data_no_change('body') - - def test_request_with_bad_service(self): - filters = { - 'service': 'BAD_SERVICE', - 'endpoint_type': 'publicURL', - 'region': 'fakeRegion' - } - self.assertRaises(exceptions.EndpointNotFound, - self.auth_provider.auth_request, 'GET', - self.target_url, filters=filters) - - def test_request_without_service(self): - filters = { - 'service': None, - 'endpoint_type': 'publicURL', - 'region': 'fakeRegion' - } - self.assertRaises(exceptions.EndpointNotFound, - self.auth_provider.auth_request, 'GET', - self.target_url, filters=filters) - - def test_check_credentials_missing_attribute(self): - for attr in ['username', 'password']: - cred = copy.copy(self.credentials) - del cred[attr] - self.assertFalse(self.auth_provider.check_credentials(cred)) - - def test_fill_credentials(self): - self.auth_provider.fill_credentials() - creds = self.auth_provider.credentials - for attr in ['user_id', 'tenant_id']: - self.assertEqual(self._get_from_fake_identity(attr), - getattr(creds, attr)) - - def _test_base_url_helper(self, expected_url, filters, - auth_data=None): - - url = self.auth_provider.base_url(filters, auth_data) - self.assertEqual(url, expected_url) - - def test_base_url(self): - self.filters = { - 'service': 'compute', - 'endpoint_type': 'publicURL', - 'region': 'FakeRegion' - } - expected = self._get_result_url_from_endpoint( - self._endpoints[0]['endpoints'][1]) - self._test_base_url_helper(expected, self.filters) - - def test_base_url_to_get_admin_endpoint(self): - self.filters = { - 'service': 'compute', - 'endpoint_type': 'adminURL', - 'region': 'FakeRegion' - } - expected = self._get_result_url_from_endpoint( - self._endpoints[0]['endpoints'][1], endpoint_type='adminURL') - self._test_base_url_helper(expected, self.filters) - - def test_base_url_unknown_region(self): - """If the region is unknown, the first endpoint is returned.""" - self.filters = { - 'service': 'compute', - 'endpoint_type': 'publicURL', - 'region': 'AintNoBodyKnowThisRegion' - } - expected = self._get_result_url_from_endpoint( - self._endpoints[0]['endpoints'][0]) - self._test_base_url_helper(expected, self.filters) - - def test_base_url_with_non_existent_service(self): - self.filters = { - 'service': 'BAD_SERVICE', - 'endpoint_type': 'publicURL', - 'region': 'FakeRegion' - } - self.assertRaises(exceptions.EndpointNotFound, - self._test_base_url_helper, None, self.filters) - - def test_base_url_without_service(self): - self.filters = { - 'endpoint_type': 'publicURL', - 'region': 'FakeRegion' - } - self.assertRaises(exceptions.EndpointNotFound, - self._test_base_url_helper, None, self.filters) - - def test_base_url_with_api_version_filter(self): - self.filters = { - 'service': 'compute', - 'endpoint_type': 'publicURL', - 'region': 'FakeRegion', - 'api_version': 'v12' - } - expected = self._get_result_url_from_endpoint( - self._endpoints[0]['endpoints'][1], replacement='v12') - self._test_base_url_helper(expected, self.filters) - - def test_base_url_with_skip_path_filter(self): - self.filters = { - 'service': 'compute', - 'endpoint_type': 'publicURL', - 'region': 'FakeRegion', - 'skip_path': True - } - expected = 'http://fake_url/' - self._test_base_url_helper(expected, self.filters) - - def test_token_not_expired(self): - expiry_data = datetime.datetime.utcnow() + datetime.timedelta(days=1) - self._verify_expiry(expiry_data=expiry_data, should_be_expired=False) - - def test_token_expired(self): - expiry_data = datetime.datetime.utcnow() - datetime.timedelta(hours=1) - self._verify_expiry(expiry_data=expiry_data, should_be_expired=True) - - def test_token_not_expired_to_be_renewed(self): - expiry_data = (datetime.datetime.utcnow() + - self.auth_provider.token_expiry_threshold / 2) - self._verify_expiry(expiry_data=expiry_data, should_be_expired=True) - - def _verify_expiry(self, expiry_data, should_be_expired): - for expiry_format in self.auth_provider.EXPIRY_DATE_FORMATS: - auth_data = self._auth_data_with_expiry( - expiry_data.strftime(expiry_format)) - self.assertEqual(self.auth_provider.is_expired(auth_data), - should_be_expired) - - -class TestKeystoneV3AuthProvider(TestKeystoneV2AuthProvider): - _endpoints = fake_identity.IDENTITY_V3_RESPONSE['token']['catalog'] - _auth_provider_class = auth.KeystoneV3AuthProvider - credentials = fake_credentials.FakeKeystoneV3Credentials() - - def setUp(self): - super(TestKeystoneV3AuthProvider, self).setUp() - self.stubs.Set(v3_client.V3TokenClient, 'raw_request', - fake_identity._fake_v3_response) - - def _get_fake_identity(self): - return fake_identity.IDENTITY_V3_RESPONSE['token'] - - def _get_fake_alt_identity(self): - return fake_identity.ALT_IDENTITY_V3['token'] - - def _get_result_url_from_endpoint(self, ep, replacement=None): - if replacement: - return ep['url'].replace('v3', replacement) - return ep['url'] - - def _auth_data_with_expiry(self, date_as_string): - token, access = self.auth_provider.auth_data - access['expires_at'] = date_as_string - return token, access - - def _get_from_fake_identity(self, attr): - token = fake_identity.IDENTITY_V3_RESPONSE['token'] - if attr == 'user_id': - return token['user']['id'] - elif attr == 'project_id': - return token['project']['id'] - elif attr == 'user_domain_id': - return token['user']['domain']['id'] - elif attr == 'project_domain_id': - return token['project']['domain']['id'] - - def test_check_credentials_missing_attribute(self): - # reset credentials to fresh ones - self.credentials.reset() - for attr in ['username', 'password', 'user_domain_name', - 'project_domain_name']: - cred = copy.copy(self.credentials) - del cred[attr] - self.assertFalse(self.auth_provider.check_credentials(cred), - "Credentials should be invalid without %s" % attr) - - def test_check_domain_credentials_missing_attribute(self): - # reset credentials to fresh ones - self.credentials.reset() - domain_creds = fake_credentials.FakeKeystoneV3DomainCredentials() - for attr in ['username', 'password', 'user_domain_name']: - cred = copy.copy(domain_creds) - del cred[attr] - self.assertFalse(self.auth_provider.check_credentials(cred), - "Credentials should be invalid without %s" % attr) - - def test_fill_credentials(self): - self.auth_provider.fill_credentials() - creds = self.auth_provider.credentials - for attr in ['user_id', 'project_id', 'user_domain_id', - 'project_domain_id']: - self.assertEqual(self._get_from_fake_identity(attr), - getattr(creds, attr)) - - # Overwrites v2 test - def test_base_url_to_get_admin_endpoint(self): - self.filters = { - 'service': 'compute', - 'endpoint_type': 'admin', - 'region': 'MiddleEarthRegion' - } - expected = self._get_result_url_from_endpoint( - self._endpoints[0]['endpoints'][2]) - self._test_base_url_helper(expected, self.filters) diff --git a/tempest_lib/tests/test_base.py b/tempest_lib/tests/test_base.py deleted file mode 100644 index 825327b..0000000 --- a/tempest_lib/tests/test_base.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2014 Mirantis Inc. -# 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 testtools - -from tempest_lib import base -from tempest_lib import exceptions - - -class TestAttr(base.BaseTestCase): - - def test_has_no_attrs(self): - self.assertEqual( - 'tempest_lib.tests.test_base.TestAttr.test_has_no_attrs', - self.id() - ) - - @testtools.testcase.attr('foo') - def test_has_one_attr(self): - self.assertEqual( - 'tempest_lib.tests.test_base.TestAttr.test_has_one_attr[foo]', - self.id() - ) - - @testtools.testcase.attr('foo') - @testtools.testcase.attr('bar') - def test_has_two_attrs(self): - self.assertEqual( - 'tempest_lib.tests.test_base.TestAttr.test_has_two_attrs[bar,foo]', - self.id(), - ) - - -class TestSetUpClass(base.BaseTestCase): - - @classmethod - def setUpClass(cls): - """Simulate absence of super() call.""" - - def setUp(self): - try: - # We expect here RuntimeError exception because 'setUpClass' - # has not called 'super'. - super(TestSetUpClass, self).setUp() - except RuntimeError: - pass - else: - raise exceptions.TempestException( - "If you see this, then expected exception was not raised.") - - def test_setup_class_raises_runtime_error(self): - """No-op test just to call setUp.""" diff --git a/tempest_lib/tests/test_credentials.py b/tempest_lib/tests/test_credentials.py deleted file mode 100644 index f0ebf25..0000000 --- a/tempest_lib/tests/test_credentials.py +++ /dev/null @@ -1,180 +0,0 @@ -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# 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 copy - -from tempest_lib import auth -from tempest_lib import exceptions -from tempest_lib.services.identity.v2 import token_client as v2_client -from tempest_lib.services.identity.v3 import token_client as v3_client -from tempest_lib.tests import base -from tempest_lib.tests import fake_identity - - -class CredentialsTests(base.TestCase): - attributes = {} - credentials_class = auth.Credentials - - def _get_credentials(self, attributes=None): - if attributes is None: - attributes = self.attributes - return self.credentials_class(**attributes) - - def _check(self, credentials, credentials_class, filled): - # Check the right version of credentials has been returned - self.assertIsInstance(credentials, credentials_class) - # Check the id attributes are filled in - attributes = [x for x in credentials.ATTRIBUTES if ( - '_id' in x and x != 'domain_id')] - for attr in attributes: - if filled: - self.assertIsNotNone(getattr(credentials, attr)) - else: - self.assertIsNone(getattr(credentials, attr)) - - def test_create(self): - creds = self._get_credentials() - self.assertEqual(self.attributes, creds._initial) - - def test_create_invalid_attr(self): - self.assertRaises(exceptions.InvalidCredentials, - self._get_credentials, - attributes=dict(invalid='fake')) - - def test_is_valid(self): - creds = self._get_credentials() - self.assertRaises(NotImplementedError, creds.is_valid) - - -class KeystoneV2CredentialsTests(CredentialsTests): - attributes = { - 'username': 'fake_username', - 'password': 'fake_password', - 'tenant_name': 'fake_tenant_name' - } - - identity_response = fake_identity._fake_v2_response - credentials_class = auth.KeystoneV2Credentials - tokenclient_class = v2_client.TokenClient - identity_version = 'v2' - - def setUp(self): - super(KeystoneV2CredentialsTests, self).setUp() - self.stubs.Set(self.tokenclient_class, 'raw_request', - self.identity_response) - - def _verify_credentials(self, credentials_class, creds_dict, filled=True): - creds = auth.get_credentials(fake_identity.FAKE_AUTH_URL, - fill_in=filled, - identity_version=self.identity_version, - **creds_dict) - self._check(creds, credentials_class, filled) - - def test_get_credentials(self): - self._verify_credentials(credentials_class=self.credentials_class, - creds_dict=self.attributes) - - def test_get_credentials_not_filled(self): - self._verify_credentials(credentials_class=self.credentials_class, - creds_dict=self.attributes, - filled=False) - - def test_is_valid(self): - creds = self._get_credentials() - self.assertTrue(creds.is_valid()) - - def _test_is_not_valid(self, ignore_key): - creds = self._get_credentials() - for attr in self.attributes.keys(): - if attr == ignore_key: - continue - temp_attr = getattr(creds, attr) - delattr(creds, attr) - self.assertFalse(creds.is_valid(), - "Credentials should be invalid without %s" % attr) - setattr(creds, attr, temp_attr) - - def test_is_not_valid(self): - # NOTE(mtreinish): A KeystoneV2 credential object is valid without - # a tenant_name. So skip that check. See tempest.auth for the valid - # credential requirements - self._test_is_not_valid('tenant_name') - - def test_reset_all_attributes(self): - creds = self._get_credentials() - initial_creds = copy.deepcopy(creds) - set_attr = creds.__dict__.keys() - missing_attr = set(creds.ATTRIBUTES).difference(set_attr) - # Set all unset attributes, then reset - for attr in missing_attr: - setattr(creds, attr, 'fake' + attr) - creds.reset() - # Check reset credentials are same as initial ones - self.assertEqual(creds, initial_creds) - - def test_reset_single_attribute(self): - creds = self._get_credentials() - initial_creds = copy.deepcopy(creds) - set_attr = creds.__dict__.keys() - missing_attr = set(creds.ATTRIBUTES).difference(set_attr) - # Set one unset attributes, then reset - for attr in missing_attr: - setattr(creds, attr, 'fake' + attr) - creds.reset() - # Check reset credentials are same as initial ones - self.assertEqual(creds, initial_creds) - - -class KeystoneV3CredentialsTests(KeystoneV2CredentialsTests): - attributes = { - 'username': 'fake_username', - 'password': 'fake_password', - 'project_name': 'fake_project_name', - 'user_domain_name': 'fake_domain_name' - } - - credentials_class = auth.KeystoneV3Credentials - identity_response = fake_identity._fake_v3_response - tokenclient_class = v3_client.V3TokenClient - identity_version = 'v3' - - def test_is_not_valid(self): - # NOTE(mtreinish) For a Keystone V3 credential object a project name - # is not required to be valid, so we skip that check. See tempest.auth - # for the valid credential requirements - self._test_is_not_valid('project_name') - - def test_synced_attributes(self): - attributes = self.attributes - # Create V3 credentials with tenant instead of project, and user_domain - for attr in ['project_id', 'user_domain_id']: - attributes[attr] = 'fake_' + attr - creds = self._get_credentials(attributes) - self.assertEqual(creds.project_name, creds.tenant_name) - self.assertEqual(creds.project_id, creds.tenant_id) - self.assertEqual(creds.user_domain_name, creds.project_domain_name) - self.assertEqual(creds.user_domain_id, creds.project_domain_id) - # Replace user_domain with project_domain - del attributes['user_domain_name'] - del attributes['user_domain_id'] - del attributes['project_name'] - del attributes['project_id'] - for attr in ['project_domain_name', 'project_domain_id', - 'tenant_name', 'tenant_id']: - attributes[attr] = 'fake_' + attr - self.assertEqual(creds.tenant_name, creds.project_name) - self.assertEqual(creds.tenant_id, creds.project_id) - self.assertEqual(creds.project_domain_name, creds.user_domain_name) - self.assertEqual(creds.project_domain_id, creds.user_domain_id) diff --git a/tempest_lib/tests/test_decorators.py b/tempest_lib/tests/test_decorators.py deleted file mode 100644 index 252e009..0000000 --- a/tempest_lib/tests/test_decorators.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright 2013 IBM Corp -# Copyright 2015 Hewlett-Packard 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 uuid - -import testtools - -from tempest_lib import base as test -from tempest_lib import decorators -from tempest_lib.tests import base - - -class TestSkipBecauseDecorator(base.TestCase): - def _test_skip_because_helper(self, expected_to_skip=True, - **decorator_args): - class TestFoo(test.BaseTestCase): - _interface = 'json' - - @decorators.skip_because(**decorator_args) - def test_bar(self): - return 0 - - t = TestFoo('test_bar') - if expected_to_skip: - self.assertRaises(testtools.TestCase.skipException, t.test_bar) - else: - # assert that test_bar returned 0 - self.assertEqual(TestFoo('test_bar').test_bar(), 0) - - def test_skip_because_bug(self): - self._test_skip_because_helper(bug='12345') - - def test_skip_because_bug_and_condition_true(self): - self._test_skip_because_helper(bug='12348', condition=True) - - def test_skip_because_bug_and_condition_false(self): - self._test_skip_because_helper(expected_to_skip=False, - bug='12349', condition=False) - - def test_skip_because_bug_without_bug_never_skips(self): - """Never skip without a bug parameter.""" - self._test_skip_because_helper(expected_to_skip=False, - condition=True) - self._test_skip_because_helper(expected_to_skip=False) - - def test_skip_because_invalid_bug_number(self): - """Raise ValueError if with an invalid bug number""" - self.assertRaises(ValueError, self._test_skip_because_helper, - bug='critical_bug') - - -class TestIdempotentIdDecorator(base.TestCase): - def _test_helper(self, _id, **decorator_args): - @decorators.idempotent_id(_id) - def foo(): - """Docstring""" - pass - - return foo - - def _test_helper_without_doc(self, _id, **decorator_args): - @decorators.idempotent_id(_id) - def foo(): - pass - - return foo - - def test_positive(self): - _id = str(uuid.uuid4()) - foo = self._test_helper(_id) - self.assertIn('id-%s' % _id, getattr(foo, '__testtools_attrs')) - self.assertTrue(foo.__doc__.startswith('Test idempotent id: %s' % _id)) - - def test_positive_without_doc(self): - _id = str(uuid.uuid4()) - foo = self._test_helper_without_doc(_id) - self.assertTrue(foo.__doc__.startswith('Test idempotent id: %s' % _id)) - - def test_idempotent_id_not_str(self): - _id = 42 - self.assertRaises(TypeError, self._test_helper, _id) - - def test_idempotent_id_not_valid_uuid(self): - _id = '42' - self.assertRaises(ValueError, self._test_helper, _id) - - -class TestSkipUnlessAttrDecorator(base.TestCase): - def _test_skip_unless_attr(self, attr, expected_to_skip=True): - class TestFoo(test.BaseTestCase): - expected_attr = not expected_to_skip - - @decorators.skip_unless_attr(attr) - def test_foo(self): - pass - - t = TestFoo('test_foo') - if expected_to_skip: - self.assertRaises(testtools.TestCase.skipException, - t.test_foo()) - else: - try: - t.test_foo() - except Exception: - raise testtools.TestCase.failureException() - - def test_skip_attr_does_not_exist(self): - self._test_skip_unless_attr('unexpected_attr') - - def test_skip_attr_false(self): - self._test_skip_unless_attr('expected_attr') - - def test_no_skip_for_attr_exist_and_true(self): - self._test_skip_unless_attr('expected_attr', expected_to_skip=False) diff --git a/tempest_lib/tests/test_rest_client.py b/tempest_lib/tests/test_rest_client.py deleted file mode 100644 index 452cef5..0000000 --- a/tempest_lib/tests/test_rest_client.py +++ /dev/null @@ -1,1065 +0,0 @@ -# Copyright 2013 IBM Corp. -# -# 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 copy -import json - -import httplib2 -import jsonschema -from oslotest import mockpatch -import six - -from tempest_lib.common import rest_client -from tempest_lib import exceptions -from tempest_lib.tests import base -from tempest_lib.tests import fake_auth_provider -from tempest_lib.tests import fake_http - - -class BaseRestClientTestClass(base.TestCase): - - url = 'fake_endpoint' - - def setUp(self): - super(BaseRestClientTestClass, self).setUp() - self.fake_auth_provider = fake_auth_provider.FakeAuthProvider() - self.rest_client = rest_client.RestClient( - self.fake_auth_provider, None, None) - self.stubs.Set(httplib2.Http, 'request', self.fake_http.request) - self.useFixture(mockpatch.PatchObject(self.rest_client, - '_log_request')) - - -class TestRestClientHTTPMethods(BaseRestClientTestClass): - def setUp(self): - self.fake_http = fake_http.fake_httplib2() - super(TestRestClientHTTPMethods, self).setUp() - self.useFixture(mockpatch.PatchObject(self.rest_client, - '_error_checker')) - - def test_post(self): - __, return_dict = self.rest_client.post(self.url, {}, {}) - self.assertEqual('POST', return_dict['method']) - - def test_get(self): - __, return_dict = self.rest_client.get(self.url) - self.assertEqual('GET', return_dict['method']) - - def test_delete(self): - __, return_dict = self.rest_client.delete(self.url) - self.assertEqual('DELETE', return_dict['method']) - - def test_patch(self): - __, return_dict = self.rest_client.patch(self.url, {}, {}) - self.assertEqual('PATCH', return_dict['method']) - - def test_put(self): - __, return_dict = self.rest_client.put(self.url, {}, {}) - self.assertEqual('PUT', return_dict['method']) - - def test_head(self): - self.useFixture(mockpatch.PatchObject(self.rest_client, - 'response_checker')) - __, return_dict = self.rest_client.head(self.url) - self.assertEqual('HEAD', return_dict['method']) - - def test_copy(self): - __, return_dict = self.rest_client.copy(self.url) - self.assertEqual('COPY', return_dict['method']) - - -class TestRestClientNotFoundHandling(BaseRestClientTestClass): - def setUp(self): - self.fake_http = fake_http.fake_httplib2(404) - super(TestRestClientNotFoundHandling, self).setUp() - - def test_post(self): - self.assertRaises(exceptions.NotFound, self.rest_client.post, - self.url, {}, {}) - - -class TestRestClientHeadersJSON(TestRestClientHTTPMethods): - TYPE = "json" - - def _verify_headers(self, resp): - self.assertEqual(self.rest_client._get_type(), self.TYPE) - resp = dict((k.lower(), v) for k, v in six.iteritems(resp)) - self.assertEqual(self.header_value, resp['accept']) - self.assertEqual(self.header_value, resp['content-type']) - - def setUp(self): - super(TestRestClientHeadersJSON, self).setUp() - self.rest_client.TYPE = self.TYPE - self.header_value = 'application/%s' % self.rest_client._get_type() - - def test_post(self): - resp, __ = self.rest_client.post(self.url, {}) - self._verify_headers(resp) - - def test_get(self): - resp, __ = self.rest_client.get(self.url) - self._verify_headers(resp) - - def test_delete(self): - resp, __ = self.rest_client.delete(self.url) - self._verify_headers(resp) - - def test_patch(self): - resp, __ = self.rest_client.patch(self.url, {}) - self._verify_headers(resp) - - def test_put(self): - resp, __ = self.rest_client.put(self.url, {}) - self._verify_headers(resp) - - def test_head(self): - self.useFixture(mockpatch.PatchObject(self.rest_client, - 'response_checker')) - resp, __ = self.rest_client.head(self.url) - self._verify_headers(resp) - - def test_copy(self): - resp, __ = self.rest_client.copy(self.url) - self._verify_headers(resp) - - -class TestRestClientUpdateHeaders(BaseRestClientTestClass): - def setUp(self): - self.fake_http = fake_http.fake_httplib2() - super(TestRestClientUpdateHeaders, self).setUp() - self.useFixture(mockpatch.PatchObject(self.rest_client, - '_error_checker')) - self.headers = {'X-Configuration-Session': 'session_id'} - - def test_post_update_headers(self): - __, return_dict = self.rest_client.post(self.url, {}, - extra_headers=True, - headers=self.headers) - - self.assertDictContainsSubset( - {'X-Configuration-Session': 'session_id', - 'Content-Type': 'application/json', - 'Accept': 'application/json'}, - return_dict['headers'] - ) - - def test_get_update_headers(self): - __, return_dict = self.rest_client.get(self.url, - extra_headers=True, - headers=self.headers) - - self.assertDictContainsSubset( - {'X-Configuration-Session': 'session_id', - 'Content-Type': 'application/json', - 'Accept': 'application/json'}, - return_dict['headers'] - ) - - def test_delete_update_headers(self): - __, return_dict = self.rest_client.delete(self.url, - extra_headers=True, - headers=self.headers) - - self.assertDictContainsSubset( - {'X-Configuration-Session': 'session_id', - 'Content-Type': 'application/json', - 'Accept': 'application/json'}, - return_dict['headers'] - ) - - def test_patch_update_headers(self): - __, return_dict = self.rest_client.patch(self.url, {}, - extra_headers=True, - headers=self.headers) - - self.assertDictContainsSubset( - {'X-Configuration-Session': 'session_id', - 'Content-Type': 'application/json', - 'Accept': 'application/json'}, - return_dict['headers'] - ) - - def test_put_update_headers(self): - __, return_dict = self.rest_client.put(self.url, {}, - extra_headers=True, - headers=self.headers) - - self.assertDictContainsSubset( - {'X-Configuration-Session': 'session_id', - 'Content-Type': 'application/json', - 'Accept': 'application/json'}, - return_dict['headers'] - ) - - def test_head_update_headers(self): - self.useFixture(mockpatch.PatchObject(self.rest_client, - 'response_checker')) - - __, return_dict = self.rest_client.head(self.url, - extra_headers=True, - headers=self.headers) - - self.assertDictContainsSubset( - {'X-Configuration-Session': 'session_id', - 'Content-Type': 'application/json', - 'Accept': 'application/json'}, - return_dict['headers'] - ) - - def test_copy_update_headers(self): - __, return_dict = self.rest_client.copy(self.url, - extra_headers=True, - headers=self.headers) - - self.assertDictContainsSubset( - {'X-Configuration-Session': 'session_id', - 'Content-Type': 'application/json', - 'Accept': 'application/json'}, - return_dict['headers'] - ) - - -class TestRestClientParseRespJSON(BaseRestClientTestClass): - TYPE = "json" - - keys = ["fake_key1", "fake_key2"] - values = ["fake_value1", "fake_value2"] - item_expected = dict((key, value) for (key, value) in zip(keys, values)) - list_expected = {"body_list": [ - {keys[0]: values[0]}, - {keys[1]: values[1]}, - ]} - dict_expected = {"body_dict": { - keys[0]: values[0], - keys[1]: values[1], - }} - null_dict = {} - - def setUp(self): - self.fake_http = fake_http.fake_httplib2() - super(TestRestClientParseRespJSON, self).setUp() - self.rest_client.TYPE = self.TYPE - - def test_parse_resp_body_item(self): - body = self.rest_client._parse_resp(json.dumps(self.item_expected)) - self.assertEqual(self.item_expected, body) - - def test_parse_resp_body_list(self): - body = self.rest_client._parse_resp(json.dumps(self.list_expected)) - self.assertEqual(self.list_expected["body_list"], body) - - def test_parse_resp_body_dict(self): - body = self.rest_client._parse_resp(json.dumps(self.dict_expected)) - self.assertEqual(self.dict_expected["body_dict"], body) - - def test_parse_resp_two_top_keys(self): - dict_two_keys = self.dict_expected.copy() - dict_two_keys.update({"second_key": ""}) - body = self.rest_client._parse_resp(json.dumps(dict_two_keys)) - self.assertEqual(dict_two_keys, body) - - def test_parse_resp_one_top_key_without_list_or_dict(self): - data = {"one_top_key": "not_list_or_dict_value"} - body = self.rest_client._parse_resp(json.dumps(data)) - self.assertEqual(data, body) - - def test_parse_nullable_dict(self): - body = self.rest_client._parse_resp(json.dumps(self.null_dict)) - self.assertEqual(self.null_dict, body) - - -class TestRestClientErrorCheckerJSON(base.TestCase): - c_type = "application/json" - - def set_data(self, r_code, enc=None, r_body=None, absolute_limit=True): - if enc is None: - enc = self.c_type - resp_dict = {'status': r_code, 'content-type': enc} - resp_body = {'resp_body': 'fake_resp_body'} - - if absolute_limit is False: - resp_dict.update({'retry-after': 120}) - resp_body.update({'overLimit': {'message': 'fake_message'}}) - resp = httplib2.Response(resp_dict) - data = { - "method": "fake_method", - "url": "fake_url", - "headers": "fake_headers", - "body": "fake_body", - "resp": resp, - "resp_body": json.dumps(resp_body) - } - if r_body is not None: - data.update({"resp_body": r_body}) - return data - - def setUp(self): - super(TestRestClientErrorCheckerJSON, self).setUp() - self.rest_client = rest_client.RestClient( - fake_auth_provider.FakeAuthProvider(), None, None) - - def test_response_less_than_400(self): - self.rest_client._error_checker(**self.set_data("399")) - - def _test_error_checker(self, exception_type, data): - e = self.assertRaises(exception_type, - self.rest_client._error_checker, - **data) - self.assertEqual(e.resp, data['resp']) - self.assertTrue(hasattr(e, 'resp_body')) - return e - - def test_response_400(self): - self._test_error_checker(exceptions.BadRequest, self.set_data("400")) - - def test_response_401(self): - self._test_error_checker(exceptions.Unauthorized, self.set_data("401")) - - def test_response_403(self): - self._test_error_checker(exceptions.Forbidden, self.set_data("403")) - - def test_response_404(self): - self._test_error_checker(exceptions.NotFound, self.set_data("404")) - - def test_response_409(self): - self._test_error_checker(exceptions.Conflict, self.set_data("409")) - - def test_response_410(self): - self._test_error_checker(exceptions.Gone, self.set_data("410")) - - def test_response_413(self): - self._test_error_checker(exceptions.OverLimit, self.set_data("413")) - - def test_response_413_without_absolute_limit(self): - self._test_error_checker(exceptions.RateLimitExceeded, - self.set_data("413", absolute_limit=False)) - - def test_response_415(self): - self._test_error_checker(exceptions.InvalidContentType, - self.set_data("415")) - - def test_response_422(self): - self._test_error_checker(exceptions.UnprocessableEntity, - self.set_data("422")) - - def test_response_500_with_text(self): - # _parse_resp is expected to return 'str' - self._test_error_checker(exceptions.ServerFault, self.set_data("500")) - - def test_response_501_with_text(self): - self._test_error_checker(exceptions.NotImplemented, - self.set_data("501")) - - def test_response_400_with_dict(self): - r_body = '{"resp_body": {"err": "fake_resp_body"}}' - e = self._test_error_checker(exceptions.BadRequest, - self.set_data("400", r_body=r_body)) - - if self.c_type == 'application/json': - expected = {"err": "fake_resp_body"} - else: - expected = r_body - self.assertEqual(expected, e.resp_body) - - def test_response_401_with_dict(self): - r_body = '{"resp_body": {"err": "fake_resp_body"}}' - e = self._test_error_checker(exceptions.Unauthorized, - self.set_data("401", r_body=r_body)) - - if self.c_type == 'application/json': - expected = {"err": "fake_resp_body"} - else: - expected = r_body - self.assertEqual(expected, e.resp_body) - - def test_response_403_with_dict(self): - r_body = '{"resp_body": {"err": "fake_resp_body"}}' - e = self._test_error_checker(exceptions.Forbidden, - self.set_data("403", r_body=r_body)) - - if self.c_type == 'application/json': - expected = {"err": "fake_resp_body"} - else: - expected = r_body - self.assertEqual(expected, e.resp_body) - - def test_response_404_with_dict(self): - r_body = '{"resp_body": {"err": "fake_resp_body"}}' - e = self._test_error_checker(exceptions.NotFound, - self.set_data("404", r_body=r_body)) - - if self.c_type == 'application/json': - expected = {"err": "fake_resp_body"} - else: - expected = r_body - self.assertEqual(expected, e.resp_body) - - def test_response_404_with_invalid_dict(self): - r_body = '{"foo": "bar"]' - e = self._test_error_checker(exceptions.NotFound, - self.set_data("404", r_body=r_body)) - - expected = r_body - self.assertEqual(expected, e.resp_body) - - def test_response_410_with_dict(self): - r_body = '{"resp_body": {"err": "fake_resp_body"}}' - e = self._test_error_checker(exceptions.Gone, - self.set_data("410", r_body=r_body)) - - if self.c_type == 'application/json': - expected = {"err": "fake_resp_body"} - else: - expected = r_body - self.assertEqual(expected, e.resp_body) - - def test_response_410_with_invalid_dict(self): - r_body = '{"foo": "bar"]' - e = self._test_error_checker(exceptions.Gone, - self.set_data("410", r_body=r_body)) - - expected = r_body - self.assertEqual(expected, e.resp_body) - - def test_response_409_with_dict(self): - r_body = '{"resp_body": {"err": "fake_resp_body"}}' - e = self._test_error_checker(exceptions.Conflict, - self.set_data("409", r_body=r_body)) - - if self.c_type == 'application/json': - expected = {"err": "fake_resp_body"} - else: - expected = r_body - self.assertEqual(expected, e.resp_body) - - def test_response_500_with_dict(self): - r_body = '{"resp_body": {"err": "fake_resp_body"}}' - e = self._test_error_checker(exceptions.ServerFault, - self.set_data("500", r_body=r_body)) - - if self.c_type == 'application/json': - expected = {"err": "fake_resp_body"} - else: - expected = r_body - self.assertEqual(expected, e.resp_body) - - def test_response_501_with_dict(self): - r_body = '{"resp_body": {"err": "fake_resp_body"}}' - self._test_error_checker(exceptions.NotImplemented, - self.set_data("501", r_body=r_body)) - - def test_response_bigger_than_400(self): - # Any response code, that bigger than 400, and not in - # (401, 403, 404, 409, 413, 422, 500, 501) - self._test_error_checker(exceptions.UnexpectedResponseCode, - self.set_data("402")) - - -class TestRestClientErrorCheckerTEXT(TestRestClientErrorCheckerJSON): - c_type = "text/plain" - - def test_fake_content_type(self): - # This test is required only in one exemplar - # Any response code, that bigger than 400, and not in - # (401, 403, 404, 409, 413, 422, 500, 501) - self._test_error_checker(exceptions.UnexpectedContentType, - self.set_data("405", enc="fake_enc")) - - def test_response_413_without_absolute_limit(self): - # Skip this test because rest_client cannot get overLimit message - # from text body. - pass - - -class TestRestClientUtils(BaseRestClientTestClass): - - def _is_resource_deleted(self, resource_id): - if not isinstance(self.retry_pass, int): - return False - if self.retry_count >= self.retry_pass: - return True - self.retry_count = self.retry_count + 1 - return False - - def setUp(self): - self.fake_http = fake_http.fake_httplib2() - super(TestRestClientUtils, self).setUp() - self.retry_count = 0 - self.retry_pass = None - self.original_deleted_method = self.rest_client.is_resource_deleted - self.rest_client.is_resource_deleted = self._is_resource_deleted - - def test_wait_for_resource_deletion(self): - self.retry_pass = 2 - # Ensure timeout long enough for loop execution to hit retry count - self.rest_client.build_timeout = 500 - sleep_mock = self.patch('time.sleep') - self.rest_client.wait_for_resource_deletion('1234') - self.assertEqual(len(sleep_mock.mock_calls), 2) - - def test_wait_for_resource_deletion_not_deleted(self): - self.patch('time.sleep') - # Set timeout to be very quick to force exception faster - self.rest_client.build_timeout = 1 - self.assertRaises(exceptions.TimeoutException, - self.rest_client.wait_for_resource_deletion, - '1234') - - def test_wait_for_deletion_with_unimplemented_deleted_method(self): - self.rest_client.is_resource_deleted = self.original_deleted_method - self.assertRaises(NotImplementedError, - self.rest_client.wait_for_resource_deletion, - '1234') - - def test_get_versions(self): - self.rest_client._parse_resp = lambda x: [{'id': 'v1'}, {'id': 'v2'}] - actual_resp, actual_versions = self.rest_client.get_versions() - self.assertEqual(['v1', 'v2'], list(actual_versions)) - - def test__str__(self): - def get_token(): - return "deadbeef" - - self.fake_auth_provider.get_token = get_token - self.assertIsNotNone(str(self.rest_client)) - - -class TestProperties(BaseRestClientTestClass): - - def setUp(self): - self.fake_http = fake_http.fake_httplib2() - super(TestProperties, self).setUp() - creds_dict = { - 'username': 'test-user', - 'user_id': 'test-user_id', - 'tenant_name': 'test-tenant_name', - 'tenant_id': 'test-tenant_id', - 'password': 'test-password' - } - self.rest_client = rest_client.RestClient( - fake_auth_provider.FakeAuthProvider(creds_dict=creds_dict), - None, None) - - def test_properties(self): - self.assertEqual('test-user', self.rest_client.user) - self.assertEqual('test-user_id', self.rest_client.user_id) - self.assertEqual('test-tenant_name', self.rest_client.tenant_name) - self.assertEqual('test-tenant_id', self.rest_client.tenant_id) - self.assertEqual('test-password', self.rest_client.password) - - self.rest_client.api_version = 'v1' - expected = {'api_version': 'v1', - 'endpoint_type': 'publicURL', - 'region': None, - 'service': None, - 'skip_path': True} - self.rest_client.skip_path() - self.assertEqual(expected, self.rest_client.filters) - - self.rest_client.reset_path() - self.rest_client.api_version = 'v1' - expected = {'api_version': 'v1', - 'endpoint_type': 'publicURL', - 'region': None, - 'service': None} - self.assertEqual(expected, self.rest_client.filters) - - -class TestExpectedSuccess(BaseRestClientTestClass): - - def setUp(self): - self.fake_http = fake_http.fake_httplib2() - super(TestExpectedSuccess, self).setUp() - - def test_expected_succes_int_match(self): - expected_code = 202 - read_code = 202 - resp = self.rest_client.expected_success(expected_code, read_code) - # Assert None resp on success - self.assertFalse(resp) - - def test_expected_succes_int_no_match(self): - expected_code = 204 - read_code = 202 - self.assertRaises(exceptions.InvalidHttpSuccessCode, - self.rest_client.expected_success, - expected_code, read_code) - - def test_expected_succes_list_match(self): - expected_code = [202, 204] - read_code = 202 - resp = self.rest_client.expected_success(expected_code, read_code) - # Assert None resp on success - self.assertFalse(resp) - - def test_expected_succes_list_no_match(self): - expected_code = [202, 204] - read_code = 200 - self.assertRaises(exceptions.InvalidHttpSuccessCode, - self.rest_client.expected_success, - expected_code, read_code) - - def test_non_success_expected_int(self): - expected_code = 404 - read_code = 202 - self.assertRaises(AssertionError, self.rest_client.expected_success, - expected_code, read_code) - - def test_non_success_expected_list(self): - expected_code = [404, 202] - read_code = 202 - self.assertRaises(AssertionError, self.rest_client.expected_success, - expected_code, read_code) - - -class TestResponseBody(base.TestCase): - - def test_str(self): - response = {'status': 200} - body = {'key1': 'value1'} - actual = rest_client.ResponseBody(response, body) - self.assertEqual("response: %s\nBody: %s" % (response, body), - str(actual)) - - -class TestResponseBodyData(base.TestCase): - - def test_str(self): - response = {'status': 200} - data = 'data1' - actual = rest_client.ResponseBodyData(response, data) - self.assertEqual("response: %s\nBody: %s" % (response, data), - str(actual)) - - -class TestResponseBodyList(base.TestCase): - - def test_str(self): - response = {'status': 200} - body = ['value1', 'value2', 'value3'] - actual = rest_client.ResponseBodyList(response, body) - self.assertEqual("response: %s\nBody: %s" % (response, body), - str(actual)) - - -class TestJSONSchemaValidationBase(base.TestCase): - - class Response(dict): - - def __getattr__(self, attr): - return self[attr] - - def __setattr__(self, attr, value): - self[attr] = value - - def setUp(self): - super(TestJSONSchemaValidationBase, self).setUp() - self.fake_auth_provider = fake_auth_provider.FakeAuthProvider() - self.rest_client = rest_client.RestClient( - self.fake_auth_provider, None, None) - - def _test_validate_pass(self, schema, resp_body, status=200): - resp = self.Response() - resp.status = status - self.rest_client.validate_response(schema, resp, resp_body) - - def _test_validate_fail(self, schema, resp_body, status=200, - error_msg="HTTP response body is invalid"): - resp = self.Response() - resp.status = status - ex = self.assertRaises(exceptions.InvalidHTTPResponseBody, - self.rest_client.validate_response, - schema, resp, resp_body) - self.assertIn(error_msg, ex._error_string) - - -class TestRestClientJSONSchemaValidation(TestJSONSchemaValidationBase): - - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': { - 'type': 'integer', - }, - }, - 'required': ['foo'] - } - } - - def test_validate_pass_with_http_success_code(self): - body = {'foo': 12} - self._test_validate_pass(self.schema, body, status=200) - - def test_validate_pass_with_http_redirect_code(self): - body = {'foo': 12} - schema = copy.deepcopy(self.schema) - schema['status_code'] = 300 - self._test_validate_pass(schema, body, status=300) - - def test_validate_not_http_success_code(self): - schema = { - 'status_code': [200] - } - body = {} - self._test_validate_pass(schema, body, status=400) - - def test_validate_multiple_allowed_type(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': { - 'type': ['integer', 'string'], - }, - }, - 'required': ['foo'] - } - } - body = {'foo': 12} - self._test_validate_pass(schema, body) - body = {'foo': '12'} - self._test_validate_pass(schema, body) - - def test_validate_enable_additional_property_pass(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': {'type': 'integer'} - }, - 'additionalProperties': True, - 'required': ['foo'] - } - } - body = {'foo': 12, 'foo2': 'foo2value'} - self._test_validate_pass(schema, body) - - def test_validate_disable_additional_property_pass(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': {'type': 'integer'} - }, - 'additionalProperties': False, - 'required': ['foo'] - } - } - body = {'foo': 12} - self._test_validate_pass(schema, body) - - def test_validate_disable_additional_property_fail(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': {'type': 'integer'} - }, - 'additionalProperties': False, - 'required': ['foo'] - } - } - body = {'foo': 12, 'foo2': 'foo2value'} - self._test_validate_fail(schema, body) - - def test_validate_wrong_status_code(self): - schema = { - 'status_code': [202] - } - body = {} - resp = self.Response() - resp.status = 200 - ex = self.assertRaises(exceptions.InvalidHttpSuccessCode, - self.rest_client.validate_response, - schema, resp, body) - self.assertIn("Unexpected http success status code", ex._error_string) - - def test_validate_wrong_attribute_type(self): - body = {'foo': 1.2} - self._test_validate_fail(self.schema, body) - - def test_validate_unexpected_response_body(self): - schema = { - 'status_code': [200], - } - body = {'foo': 12} - self._test_validate_fail( - schema, body, - error_msg="HTTP response body should not exist") - - def test_validate_missing_response_body(self): - body = {} - self._test_validate_fail(self.schema, body) - - def test_validate_missing_required_attribute(self): - body = {'notfoo': 12} - self._test_validate_fail(self.schema, body) - - def test_validate_response_body_not_list(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'list_items': { - 'type': 'array', - 'items': {'foo': {'type': 'integer'}} - } - }, - 'required': ['list_items'], - } - } - body = {'foo': 12} - self._test_validate_fail(schema, body) - - def test_validate_response_body_list_pass(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'list_items': { - 'type': 'array', - 'items': {'foo': {'type': 'integer'}} - } - }, - 'required': ['list_items'], - } - } - body = {'list_items': [{'foo': 12}, {'foo': 10}]} - self._test_validate_pass(schema, body) - - -class TestRestClientJSONHeaderSchemaValidation(TestJSONSchemaValidationBase): - - schema = { - 'status_code': [200], - 'response_header': { - 'type': 'object', - 'properties': { - 'foo': {'type': 'integer'} - }, - 'required': ['foo'] - } - } - - def test_validate_header_schema_pass(self): - resp_body = {} - resp = self.Response() - resp.status = 200 - resp.foo = 12 - self.rest_client.validate_response(self.schema, resp, resp_body) - - def test_validate_header_schema_fail(self): - resp_body = {} - resp = self.Response() - resp.status = 200 - resp.foo = 1.2 - ex = self.assertRaises(exceptions.InvalidHTTPResponseHeader, - self.rest_client.validate_response, - self.schema, resp, resp_body) - self.assertIn("HTTP response header is invalid", ex._error_string) - - -class TestRestClientJSONSchemaFormatValidation(TestJSONSchemaValidationBase): - - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': { - 'type': 'string', - 'format': 'email' - } - }, - 'required': ['foo'] - } - } - - def test_validate_format_pass(self): - body = {'foo': 'example@example.com'} - self._test_validate_pass(self.schema, body) - - def test_validate_format_fail(self): - body = {'foo': 'wrong_email'} - self._test_validate_fail(self.schema, body) - - def test_validate_formats_in_oneOf_pass(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': { - 'type': 'string', - 'oneOf': [ - {'format': 'ipv4'}, - {'format': 'ipv6'} - ] - } - }, - 'required': ['foo'] - } - } - body = {'foo': '10.0.0.0'} - self._test_validate_pass(schema, body) - body = {'foo': 'FE80:0000:0000:0000:0202:B3FF:FE1E:8329'} - self._test_validate_pass(schema, body) - - def test_validate_formats_in_oneOf_fail_both_match(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': { - 'type': 'string', - 'oneOf': [ - {'format': 'ipv4'}, - {'format': 'ipv4'} - ] - } - }, - 'required': ['foo'] - } - } - body = {'foo': '10.0.0.0'} - self._test_validate_fail(schema, body) - - def test_validate_formats_in_oneOf_fail_no_match(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': { - 'type': 'string', - 'oneOf': [ - {'format': 'ipv4'}, - {'format': 'ipv6'} - ] - } - }, - 'required': ['foo'] - } - } - body = {'foo': 'wrong_ip_format'} - self._test_validate_fail(schema, body) - - def test_validate_formats_in_anyOf_pass(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': { - 'type': 'string', - 'anyOf': [ - {'format': 'ipv4'}, - {'format': 'ipv6'} - ] - } - }, - 'required': ['foo'] - } - } - body = {'foo': '10.0.0.0'} - self._test_validate_pass(schema, body) - body = {'foo': 'FE80:0000:0000:0000:0202:B3FF:FE1E:8329'} - self._test_validate_pass(schema, body) - - def test_validate_formats_in_anyOf_pass_both_match(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': { - 'type': 'string', - 'anyOf': [ - {'format': 'ipv4'}, - {'format': 'ipv4'} - ] - } - }, - 'required': ['foo'] - } - } - body = {'foo': '10.0.0.0'} - self._test_validate_pass(schema, body) - - def test_validate_formats_in_anyOf_fail_no_match(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': { - 'type': 'string', - 'anyOf': [ - {'format': 'ipv4'}, - {'format': 'ipv6'} - ] - } - }, - 'required': ['foo'] - } - } - body = {'foo': 'wrong_ip_format'} - self._test_validate_fail(schema, body) - - def test_validate_formats_pass_for_unknow_format(self): - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': { - 'type': 'string', - 'format': 'UNKNOWN' - } - }, - 'required': ['foo'] - } - } - body = {'foo': 'example@example.com'} - self._test_validate_pass(schema, body) - - -class TestRestClientJSONSchemaValidatorVersion(TestJSONSchemaValidationBase): - - schema = { - 'status_code': [200], - 'response_body': { - 'type': 'object', - 'properties': { - 'foo': {'type': 'string'} - } - } - } - - def test_current_json_schema_validator_version(self): - with mockpatch.PatchObject(jsonschema.Draft4Validator, - "check_schema") as chk_schema: - body = {'foo': 'test'} - self._test_validate_pass(self.schema, body) - chk_schema.mock.assert_called_once_with( - self.schema['response_body']) diff --git a/tempest_lib/tests/test_ssh.py b/tempest_lib/tests/test_ssh.py deleted file mode 100644 index 140bdf0..0000000 --- a/tempest_lib/tests/test_ssh.py +++ /dev/null @@ -1,253 +0,0 @@ -# Copyright 2014 OpenStack Foundation -# -# 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 io import StringIO -import socket -import time - -import mock -import six -import testtools - -from tempest_lib.common import ssh -from tempest_lib import exceptions -from tempest_lib.tests import base - - -class TestSshClient(base.TestCase): - - SELECT_POLLIN = 1 - - @mock.patch('paramiko.RSAKey.from_private_key') - @mock.patch('six.StringIO') - def test_pkey_calls_paramiko_RSAKey(self, cs_mock, rsa_mock): - cs_mock.return_value = mock.sentinel.csio - pkey = 'mykey' - ssh.Client('localhost', 'root', pkey=pkey) - rsa_mock.assert_called_once_with(mock.sentinel.csio) - cs_mock.assert_called_once_with('mykey') - rsa_mock.reset_mock() - cs_mock.reset_mock() - pkey = mock.sentinel.pkey - # Shouldn't call out to load a file from RSAKey, since - # a sentinel isn't a basestring... - ssh.Client('localhost', 'root', pkey=pkey) - self.assertEqual(0, rsa_mock.call_count) - self.assertEqual(0, cs_mock.call_count) - - def _set_ssh_connection_mocks(self): - client_mock = mock.MagicMock() - client_mock.connect.return_value = True - return (self.patch('paramiko.SSHClient'), - self.patch('paramiko.AutoAddPolicy'), - client_mock) - - def test_get_ssh_connection(self): - c_mock, aa_mock, client_mock = self._set_ssh_connection_mocks() - s_mock = self.patch('time.sleep') - - c_mock.return_value = client_mock - aa_mock.return_value = mock.sentinel.aa - - # Test normal case for successful connection on first try - client = ssh.Client('localhost', 'root', timeout=2) - client._get_ssh_connection(sleep=1) - - aa_mock.assert_called_once_with() - client_mock.set_missing_host_key_policy.assert_called_once_with( - mock.sentinel.aa) - expected_connect = [mock.call( - 'localhost', - username='root', - pkey=None, - key_filename=None, - look_for_keys=False, - timeout=10.0, - password=None - )] - self.assertEqual(expected_connect, client_mock.connect.mock_calls) - self.assertEqual(0, s_mock.call_count) - - def test_get_ssh_connection_two_attemps(self): - c_mock, aa_mock, client_mock = self._set_ssh_connection_mocks() - - c_mock.return_value = client_mock - client_mock.connect.side_effect = [ - socket.error, - mock.MagicMock() - ] - - client = ssh.Client('localhost', 'root', timeout=1) - start_time = int(time.time()) - client._get_ssh_connection(sleep=1) - end_time = int(time.time()) - self.assertLess((end_time - start_time), 4) - self.assertGreater((end_time - start_time), 1) - - def test_get_ssh_connection_timeout(self): - c_mock, aa_mock, client_mock = self._set_ssh_connection_mocks() - - c_mock.return_value = client_mock - client_mock.connect.side_effect = [ - socket.error, - socket.error, - socket.error, - ] - - client = ssh.Client('localhost', 'root', timeout=2) - start_time = int(time.time()) - with testtools.ExpectedException(exceptions.SSHTimeout): - client._get_ssh_connection() - end_time = int(time.time()) - self.assertLess((end_time - start_time), 5) - self.assertGreaterEqual((end_time - start_time), 2) - - @mock.patch('select.POLLIN', SELECT_POLLIN, create=True) - def test_timeout_in_exec_command(self): - chan_mock, poll_mock, _ = self._set_mocks_for_select([0, 0, 0], True) - - # Test for a timeout condition immediately raised - client = ssh.Client('localhost', 'root', timeout=2) - with testtools.ExpectedException(exceptions.TimeoutException): - client.exec_command("test") - - chan_mock.fileno.assert_called_once_with() - chan_mock.exec_command.assert_called_once_with("test") - chan_mock.shutdown_write.assert_called_once_with() - - poll_mock.register.assert_called_once_with( - chan_mock, self.SELECT_POLLIN) - poll_mock.poll.assert_called_once_with(10) - - @mock.patch('select.POLLIN', SELECT_POLLIN, create=True) - def test_exec_command(self): - chan_mock, poll_mock, select_mock = ( - self._set_mocks_for_select([[1, 0, 0]], True)) - closed_prop = mock.PropertyMock(return_value=True) - type(chan_mock).closed = closed_prop - - chan_mock.recv_exit_status.return_value = 0 - chan_mock.recv.return_value = b'' - chan_mock.recv_stderr.return_value = b'' - - client = ssh.Client('localhost', 'root', timeout=2) - client.exec_command("test") - - chan_mock.fileno.assert_called_once_with() - chan_mock.exec_command.assert_called_once_with("test") - chan_mock.shutdown_write.assert_called_once_with() - - select_mock.assert_called_once_with() - poll_mock.register.assert_called_once_with( - chan_mock, self.SELECT_POLLIN) - poll_mock.poll.assert_called_once_with(10) - chan_mock.recv_ready.assert_called_once_with() - chan_mock.recv.assert_called_once_with(1024) - chan_mock.recv_stderr_ready.assert_called_once_with() - chan_mock.recv_stderr.assert_called_once_with(1024) - chan_mock.recv_exit_status.assert_called_once_with() - closed_prop.assert_called_once_with() - - def _set_mocks_for_select(self, poll_data, ito_value=False): - gsc_mock = self.patch('tempest_lib.common.ssh.Client.' - '_get_ssh_connection') - ito_mock = self.patch('tempest_lib.common.ssh.Client._is_timed_out') - csp_mock = self.patch( - 'tempest_lib.common.ssh.Client._can_system_poll') - csp_mock.return_value = True - - select_mock = self.patch('select.poll', create=True) - client_mock = mock.MagicMock() - tran_mock = mock.MagicMock() - chan_mock = mock.MagicMock() - poll_mock = mock.MagicMock() - - select_mock.return_value = poll_mock - gsc_mock.return_value = client_mock - ito_mock.return_value = ito_value - client_mock.get_transport.return_value = tran_mock - tran_mock.open_session.return_value = chan_mock - if isinstance(poll_data[0], list): - poll_mock.poll.side_effect = poll_data - else: - poll_mock.poll.return_value = poll_data - - return chan_mock, poll_mock, select_mock - - _utf8_string = six.unichr(1071) - _utf8_bytes = _utf8_string.encode("utf-8") - - @mock.patch('select.POLLIN', SELECT_POLLIN, create=True) - def test_exec_good_command_output(self): - chan_mock, poll_mock, _ = self._set_mocks_for_select([1, 0, 0]) - closed_prop = mock.PropertyMock(return_value=True) - type(chan_mock).closed = closed_prop - - chan_mock.recv_exit_status.return_value = 0 - chan_mock.recv.side_effect = [self._utf8_bytes[0:1], - self._utf8_bytes[1:], b'R', b''] - chan_mock.recv_stderr.return_value = b'' - - client = ssh.Client('localhost', 'root', timeout=2) - out_data = client.exec_command("test") - self.assertEqual(self._utf8_string + 'R', out_data) - - @mock.patch('select.POLLIN', SELECT_POLLIN, create=True) - def test_exec_bad_command_output(self): - chan_mock, poll_mock, _ = self._set_mocks_for_select([1, 0, 0]) - closed_prop = mock.PropertyMock(return_value=True) - type(chan_mock).closed = closed_prop - - chan_mock.recv_exit_status.return_value = 1 - chan_mock.recv.return_value = b'' - chan_mock.recv_stderr.side_effect = [b'R', self._utf8_bytes[0:1], - self._utf8_bytes[1:], b''] - - client = ssh.Client('localhost', 'root', timeout=2) - exc = self.assertRaises(exceptions.SSHExecCommandFailed, - client.exec_command, "test") - self.assertIn('R' + self._utf8_string, six.text_type(exc)) - - def test_exec_command_no_select(self): - gsc_mock = self.patch('tempest_lib.common.ssh.Client.' - '_get_ssh_connection') - csp_mock = self.patch( - 'tempest_lib.common.ssh.Client._can_system_poll') - csp_mock.return_value = False - - select_mock = self.patch('select.poll', create=True) - client_mock = mock.MagicMock() - tran_mock = mock.MagicMock() - chan_mock = mock.MagicMock() - - # Test for proper reading of STDOUT and STDERROR - - gsc_mock.return_value = client_mock - client_mock.get_transport.return_value = tran_mock - tran_mock.open_session.return_value = chan_mock - chan_mock.recv_exit_status.return_value = 0 - - std_out_mock = mock.MagicMock(StringIO) - std_err_mock = mock.MagicMock(StringIO) - chan_mock.makefile.return_value = std_out_mock - chan_mock.makefile_stderr.return_value = std_err_mock - - client = ssh.Client('localhost', 'root', timeout=2) - client.exec_command("test") - - chan_mock.makefile.assert_called_once_with('rb', 1024) - chan_mock.makefile_stderr.assert_called_once_with('rb', 1024) - std_out_mock.read.assert_called_once_with() - std_err_mock.read.assert_called_once_with() - self.assertFalse(select_mock.called) diff --git a/tempest_lib/tests/test_tempest_lib.py b/tempest_lib/tests/test_tempest_lib.py deleted file mode 100644 index 76d74a6..0000000 --- a/tempest_lib/tests/test_tempest_lib.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- 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. - -""" -test_tempest_lib ----------------------------------- - -Tests for `tempest_lib` module. -""" - -from tempest_lib.tests import base - - -class TestTempest_lib(base.TestCase): - - def test_something(self): - pass diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index d44530f..0000000 --- a/test-requirements.txt +++ /dev/null @@ -1,18 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. -hacking<0.11,>=0.10.0 - - -coverage>=3.6 # Apache-2.0 -discover # BSD -python-subunit>=0.0.18 # Apache-2.0/BSD -sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD -oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0 -oslotest>=1.10.0 # Apache-2.0 -testrepository>=0.0.18 # Apache-2.0/BSD -testscenarios>=0.4 # Apache-2.0/BSD -testtools>=1.4.0 # MIT -mock>=1.2 # BSD -ddt>=1.0.1 # MIT -reno>=1.6.2 # Apache2 diff --git a/tools/migrate_from_tempest.sh b/tools/migrate_from_tempest.sh deleted file mode 100755 index c31614f..0000000 --- a/tools/migrate_from_tempest.sh +++ /dev/null @@ -1,117 +0,0 @@ -#!/bin/bash -# -# Use this script to move over a set of files from tempest master into -# tempest-lib with the commit history for the files in the commit message. -# This should only be done for files that haven't been migrated over already. -# To use: -# 1. Create a new branch in the tempest-lib repo so not to destroy your current -# working branch -# 2. Run the script from the repo dir and specify the file paths relative to -# the root tempest dir(only code and unit tests): -# -# tools/migrate_from_tempest.sh tempest/file.py tempest/sub_dir - - -function usage { - echo "Usage: $0 [OPTION] file1 file2" - echo "Migrate files from tempest" - echo "" - echo "-o, --output_dir Specify a directory relative to the repo root to move the migrated files into." - echo "-u, --tempest_git_url Specify the repo to clone tempest from for the migration." -} - -set -e - -output_dir="" -service_client=0 - -while [ $# -gt 0 ]; do - case "$1" in - -h|--help) usage; exit;; - -o|--output_dir) output_dir="$2"; shift;; - -u|--tempest_git_url) tempest_git_url="$2"; shift;; - -s|--service_client) service_client=1;; - *) files="$files $1";; - esac - shift -done - -TEMPEST_GIT_URL=${tempest_git_url:-git://git.openstack.org/openstack/tempest} - -tmpdir=$(mktemp -d -t tempest-migrate.XXXX) -tempest_lib_dir=$(dirname "$0") - -function count_commits { - echo - echo "Have $(git log --oneline | wc -l) commits" -} - -# Clone tempest and cd into it -git clone $TEMPEST_GIT_URL $tmpdir -cd $tmpdir - -for file in $files; do - # Get the latest change-id for each file - change_id=`git log -n1 --grep "Change-Id: " -- $file | grep "Change-Id: " | awk '{print $2}'` - filename=`basename $file` - CHANGE_LIST=`echo -e "$CHANGE_LIST\n * $filename: $change_id"` -done - -# Move files and commit -cd - -file_list='' -for file in $files; do - filename=`basename $file` - dirname=`dirname $file` - if [ -n "$output_dir" ]; then - dirname="$output_dir" - else - dirname=`echo $dirname | sed s@tempest\/@tempest_lib/\@` - if [ $service_client -eq 1 ]; then - # Remove /json path because tempest-lib supports JSON only without XML - dirname=`echo $dirname | sed s@\/json@@` - fi - fi - dest_file="$dirname/$filename" - cp -r "$tmpdir/$file" "$dest_file" - - if [ $service_client -eq 1 ]; then - # service_client module is not necessary in tempest-lib because rest_client can be used instead - sed -i='' s/"from tempest.common import service_client"/"from tempest_lib.common import rest_client"/ $dest_file - sed -i='' s/"service_client.ServiceClient"/"rest_client.RestClient"/ $dest_file - sed -i='' s/"service_client.ResponseBody"/"rest_client.ResponseBody"/ $dest_file - sed -i='' s/"from tempest\."/"from tempest_lib\."/ $dest_file - - # Replace mocked path in unit tests - sed -i='' s/"tempest.common.rest_client"/"tempest_lib.common.rest_client"/ $dest_file - - # Remove ".json" from import line - sed -i='' -e "s/^\(from tempest_lib\.services\..*\)\.json\(.*\)/\1\2/" $dest_file - fi - - git add "$dest_file" - if [[ -z "$file_list" ]]; then - file_list="$filename" - else - tmp_file_list="$file_list, $filename" - char_size=`echo $tmp_file_list | wc -c` - if [ "$char_size" -lt 27 ]; then - file_list="$file_list, $filename" - fi - fi -done -# Cleanup temporary tempest repo -rm -rf $tmpdir - -# Generate a migration commit -commit_message="Migrated $file_list from tempest" -pre_list=$"This migrates the above files from tempest.\nThis includes tempest commits:" -pre_list=`echo -e $pre_list` -post_list=$"to see the commit history for these files refer to the above Change-Ids \nin the tempest repository." -post_list=`echo -e $post_list` -if [ $service_client -eq 1 ]; then - bp_msg="Partially implements blueprint migrate-service-clients-to-tempest-lib" -else - bp_msg="" -fi -git commit -m "$commit_message" -m "$pre_list" -m "$CHANGE_LIST" -m "$post_list" -m "$bp_msg" diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 8e8c966..0000000 --- a/tox.ini +++ /dev/null @@ -1,39 +0,0 @@ -[tox] -minversion = 1.6 -envlist = py34,py27,pypy,pep8 -skipsdist = True - -[testenv] -usedevelop = True -install_command = pip install -U {opts} {packages} -whitelist_externals = bash -setenv = - VIRTUAL_ENV={envdir} -deps = -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt -commands = ostestr {posargs} -passenv = http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY - -[testenv:pep8] -commands = flake8 - -[testenv:venv] -commands = {posargs} - -[testenv:cover] -commands = python setup.py test --coverage --coverage-package-name='tempest_lib' --testr-args='{posargs}' - -[testenv:docs] -commands = python setup.py build_sphinx - -[flake8] -# E125 skipped as it is invalid PEP-8. -# E123 skipped because it is ignored by default in the default pep8 -# E129 skipped because it is too limiting when combined with other rules -show-source = True -ignore = E125,E123,E129 -builtins = _ -exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,releasenotes - -[testenv:releasenotes] -commands = sphinx-build -a -E -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html