diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 97187b2..0000000 --- a/.coveragerc +++ /dev/null @@ -1,6 +0,0 @@ -[run] -branch = True -source = oswin_tempest_plugin - -[report] -ignore_errors = True diff --git a/.gitignore b/.gitignore deleted file mode 100644 index f3981d5..0000000 --- a/.gitignore +++ /dev/null @@ -1,56 +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 -.stestr -.venv - -# Translations -*.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - -# Complexity -output/*.html -output/*/index.html - -# Sphinx -doc/build - -# pbr generates these -AUTHORS -ChangeLog - -# Editors -*~ -.*.swp -.*sw? - diff --git a/.mailmap b/.mailmap deleted file mode 100644 index 516ae6f..0000000 --- a/.mailmap +++ /dev/null @@ -1,3 +0,0 @@ -# Format is: -# -# diff --git a/.stestr.conf b/.stestr.conf deleted file mode 100644 index 29b9ed9..0000000 --- a/.stestr.conf +++ /dev/null @@ -1,3 +0,0 @@ -[DEFAULT] -test_path=${OS_TEST_PATH:-./oswin_tempest_plugin/tests} -top_dir=./ diff --git a/.zuul.yaml b/.zuul.yaml deleted file mode 100644 index 39bf5ec..0000000 --- a/.zuul.yaml +++ /dev/null @@ -1,5 +0,0 @@ -- project: - templates: - - openstack-python3-zed-jobs - - check-requirements - queue: os-win diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index bc57d4a..0000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,19 +0,0 @@ -The source repository for this project can be found at: - - https://opendev.org/openstack/oswin-tempest-plugin - -Pull requests submitted through GitHub are not monitored. - -To start contributing to OpenStack, follow the steps in the contribution guide -to set up and use Gerrit: - - https://docs.openstack.org/contributors/code-and-documentation/quick-start.html - -Bugs should be filed on Launchpad: - - https://bugs.launchpad.net/oswin-tempest-plugin - -For more specific information about contributing to this repository, see the -oswin-tempest-plugin contributor guide: - - https://docs.openstack.org/oswin-tempest-plugin/latest/contributor/contributing.html diff --git a/HACKING.rst b/HACKING.rst deleted file mode 100644 index f168632..0000000 --- a/HACKING.rst +++ /dev/null @@ -1,4 +0,0 @@ -oswin-tempest-plugin Style Commandments -======================================= - -Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 68c771a..0000000 --- a/LICENSE +++ /dev/null @@ -1,176 +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 8b7398b..e85d62c 100644 --- a/README.rst +++ b/README.rst @@ -1,19 +1,10 @@ -==================== -oswin-tempest-plugin -==================== +This project is no longer maintained. + +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". -This project contains Tempest tests to cover the os_win project, as well as a plugin to automatically load these tests into Tempest. - -Please fill here a long description which must be at least 3 lines wrapped on -80 cols, so that distribution package maintainers can use it in their packages. -Note that this is a hard requirement. - -* Free software: Apache license -* Documentation: http://docs.openstack.org/developer/oswin-tempest-plugin -* Source: http://opendev.org/openstack/oswin-tempest-plugin -* Bugs: http://bugs.launchpad.net/oswin-tempest-plugin - -Features --------- - -* TODO +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 15cd6cb..0000000 --- a/babel.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[python: **.py] - diff --git a/devstack/plugin.sh b/devstack/plugin.sh deleted file mode 100644 index 39556ea..0000000 --- a/devstack/plugin.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -DIR_OSWIN_TEMPEST_PLUGIN=$DEST/oswin-tempest-plugin - -if [[ "$1" == "stack" && "$2" == "install" ]]; then - cd $DIR_OSWIN_TEMPEST_PLUGIN - echo "Installing oswin-tempest-plugin" - setup_develop $DIR_OSWIN_TEMPEST_PLUGIN - - echo "Sucessfully installed oswin-tempest-plugin" - -fi diff --git a/doc/requirements.txt b/doc/requirements.txt deleted file mode 100644 index eccc937..0000000 --- a/doc/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -sphinx>=2.0.0,!=2.1.0 # BSD -openstackdocstheme>=2.2.1 # Apache-2.0 diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100755 index 62259bd..0000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,82 +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', - 'openstackdocstheme' -] - -# openstackdocstheme options -openstackdocs_repo_name = 'openstack/oswin-tempest-plugin' -openstackdocs_auto_name = False -openstackdocs_bug_project = 'os-win' -openstackdocs_bug_tag = '' - -# 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 = 'oswin-tempest-plugin' -copyright = '2017, Cloudbase Solutions' - -# 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 = 'native' - -# -- 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'] -html_theme = 'openstackdocs' - -# 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, - '%s Documentation' % project, - 'Cloudbase Solutions', 'manual'), -] - -# Example configuration for intersphinx: refer to the Python standard library. -#intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst deleted file mode 100644 index b15d66d..0000000 --- a/doc/source/contributing.rst +++ /dev/null @@ -1,93 +0,0 @@ -============ -Contributing -============ - -For general information on contributing to OpenStack, please check out the -`contributor guide `_ to get started. -It covers all the basics that are common to all OpenStack projects: the accounts -you need, the basics of interacting with our Gerrit review system, how we -communicate as a community, etc. - -Below will cover the more project specific information you need to get started -with oswin-tempest-plugin. - -Communication -~~~~~~~~~~~~~ -.. This would be a good place to put the channel you chat in as a project; when/ - where your meeting is, the tags you prepend to your ML threads, etc. - -We recommend using the standard communication channels, such as the OpenStack -mailing list or IRC channels. The official IRC channel (#openstack-hyper-v) is -not archived at the moment, so we recommend using #openstack-dev. - -Please include one of the following tags when using the OpenStack mailing -list: - -* winstackers -* windows -* hyper-v - -Feel free to reach out to the Winstackers PTL or other core members. - -Contacting the Core Team -~~~~~~~~~~~~~~~~~~~~~~~~ -.. This section should list the core team, their irc nicks, emails, timezones - etc. If all this info is maintained elsewhere (i.e. a wiki), you can link to - that instead of enumerating everyone here. - -The Winstackers core team is composed of: - -* Lucian Petrut (lpetrut) -* Claudiu Belu (claudiub) -* Alessandro Pilotti (apilotti) - -New Feature Planning -~~~~~~~~~~~~~~~~~~~~ -.. This section is for talking about the process to get a new feature in. Some - projects use blueprints, some want specs, some want both! Some projects - stick to a strict schedule when selecting what new features will be reviewed - for a release. - -If you want to propose a new feature, we recommend `filing a blueprint -`__ and then contacting -the core team. - -Once the feature is approved, please propose the patches on Gerrit, following -the Openstack contributor guide. - -Task Tracking -~~~~~~~~~~~~~ -.. This section is about where you track tasks- launchpad? storyboard? is there - more than one launchpad project? what's the name of the project group in - storyboard? - -We track our tasks in `Launchpad `__. - -Reporting a Bug -~~~~~~~~~~~~~~~ -.. Pretty self explanatory section, link directly to where people should report - bugs for your project. - -You found an issue and want to make sure we are aware of it? You can do so on -`Launchpad `__. -More info about Launchpad usage can be found on `OpenStack docs page -`_. - -Getting Your Patch Merged -~~~~~~~~~~~~~~~~~~~~~~~~~ -.. This section should have info about what it takes to get something merged. Do - you require one or two +2's before +W? Do some of your repos require unit - test changes with all patches? etc. - -Changes proposed to oswin-tempest-plugin generally require two ``Code-Review +2`` -votes from oswin-tempest-plugin core reviewers before merging. In case of trivial -patches and urgent bug fixes, this rule is sometimes ignored. - -Project Team Lead Duties -~~~~~~~~~~~~~~~~~~~~~~~~ -.. this section is where you can put PTL specific duties not already listed in - the common PTL guide (linked below), or if you already have them written - up elsewhere you can link to that doc here. - -All common PTL duties are enumerated in the `PTL guide -`_. diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index d88ed63..0000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,25 +0,0 @@ -.. oswin-tempest-plugin 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 oswin-tempest-plugin's documentation! -================================================ - -Contents: - -.. toctree:: - :maxdepth: 2 - - readme - installation - usage - contributing - -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 dc7c36e..0000000 --- a/doc/source/installation.rst +++ /dev/null @@ -1,12 +0,0 @@ -============ -Installation -============ - -At the command line:: - - $ pip install oswin-tempest-plugin - -Or, if you have virtualenvwrapper installed:: - - $ mkvirtualenv oswin-tempest-plugin - $ pip install oswin-tempest-plugin diff --git a/doc/source/readme.rst b/doc/source/readme.rst deleted file mode 100644 index a6210d3..0000000 --- a/doc/source/readme.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../README.rst diff --git a/doc/source/usage.rst b/doc/source/usage.rst deleted file mode 100644 index 29ab037..0000000 --- a/doc/source/usage.rst +++ /dev/null @@ -1,7 +0,0 @@ -===== -Usage -===== - -To use oswin-tempest-plugin in a project:: - - import oswin_tempest_plugin diff --git a/oswin_tempest_plugin/__init__.py b/oswin_tempest_plugin/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oswin_tempest_plugin/clients/__init__.py b/oswin_tempest_plugin/clients/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oswin_tempest_plugin/clients/wsman.py b/oswin_tempest_plugin/clients/wsman.py deleted file mode 100644 index 2e6f214..0000000 --- a/oswin_tempest_plugin/clients/wsman.py +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright 2013 Cloudbase Solutions Srl -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os - -from oslo_log import log as logging -from winrm import protocol - -from oswin_tempest_plugin import config -from oswin_tempest_plugin import exceptions - -LOG = logging.getLogger(__name__) -CONF = config.CONF - -protocol.Protocol.DEFAULT_TIMEOUT = "PT3600S" - - -def run_wsman_cmd(host, cmd, username, password=None, - cert_pem_path=None, cert_key_pem_path=None, - transport_method='plaintext', fail_on_error=True): - url = 'https://%s:5986/wsman' % host - - if transport_method == 'ssl': - if not (os.path.exists(cert_pem_path) - and os.path.exists(cert_key_pem_path)): - raise exceptions.WSManException('Could not find certificate path ' - 'or certificate key path.') - - LOG.debug('Connecting to: %s', host) - p = protocol.Protocol(endpoint=url, - transport=transport_method, - server_cert_validation='ignore', - username=username, - password=password, - cert_pem=cert_pem_path, - cert_key_pem=cert_key_pem_path) - - shell_id = p.open_shell() - LOG.debug('Running command on host %(host)s: %(cmd)s', - {'host': host, 'cmd': cmd}) - command_id = p.run_command(shell_id, cmd) - std_out, std_err, return_code = p.get_command_output(shell_id, command_id) - - p.cleanup_command(shell_id, command_id) - p.close_shell(shell_id) - - LOG.debug('Results from %(host)s: return_code: %(return_code)s, std_out: ' - '%(std_out)s, std_err: %(std_err)s', - {'host': host, 'return_code': return_code, 'std_out': std_out, - 'std_err': std_err}) - - if fail_on_error and return_code: - raise exceptions.WSManException( - cmd=cmd, host=host, return_code=return_code, - std_out=std_out, std_err=std_err) - - return (std_out, std_err, return_code) - - -def run_wsman_ps(host, cmd, username, password, cert_pem_path=None, - cert_key_pem_path=None, transport_method='plaintext', - fail_on_error=True): - - cmd = ("powershell -NonInteractive -ExecutionPolicy RemoteSigned " - "-Command \"%s\"" % cmd) - return run_wsman_cmd(host, cmd, username, password, cert_pem_path, - cert_key_pem_path, transport_method, fail_on_error) - - -def run_hv_host_wsman_ps(host, cmd, fail_on_error=True): - return run_wsman_ps( - host, cmd, - username=CONF.hyperv_host_auth.username, - password=CONF.hyperv_host_auth.password, - cert_pem_path=CONF.hyperv_host_auth.cert_pem_path, - cert_key_pem_path=CONF.hyperv_host_auth.cert_key_pem_path, - transport_method=CONF.hyperv_host_auth.transport_method, - fail_on_error=fail_on_error) diff --git a/oswin_tempest_plugin/config.py b/oswin_tempest_plugin/config.py deleted file mode 100644 index e74736d..0000000 --- a/oswin_tempest_plugin/config.py +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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_config import cfg -from oslo_config import types -from tempest import config - -CONF = config.CONF - - -hyperv_group = cfg.OptGroup(name='hyperv', - title='Hyper-V Driver Tempest Options') - -HyperVGroup = [ - cfg.IntOpt('hypervisor_version', - default=0, - help="Compute nodes' hypervisor version, used to determine " - "which tests to run. It must have following value: " - "major_version * 1000 + minor_version" - "For example, Windows / Hyper-V Server 2012 R2 would have " - "the value 6003"), - cfg.StrOpt('vhd_image_ref', - help="Valid VHD image reference to be used in tests."), - cfg.StrOpt('vhdx_image_ref', - help="Valid VHDX image reference to be used in tests."), - cfg.StrOpt('gen2_image_ref', - help="Valid Generation 2 VM VHDX image reference to be used " - "in tests."), - cfg.StrOpt('secure_boot_image_ref', - help="Valid secure boot VM VHDX image reference to be used " - "in tests."), - cfg.StrOpt('secure_boot_image_ssh_user', - help='User for secure boot image to be used in tests.'), - cfg.BoolOpt('cluster_enabled', - default=False, - help="The compute nodes are joined into a Hyper-V Cluster."), - cfg.IntOpt('failover_timeout', - default=120, - help='The maximum amount of time to wait for a failover to ' - 'occur.'), - cfg.IntOpt('failover_sleep_interval', - default=5, - help='The amount of time to wait between failover checks.'), - cfg.BoolOpt('remotefx_enabled', - default=False, - help="RemoteFX feature is enabled and supported on the " - "compute nodes."), - cfg.IntOpt('available_numa_nodes', - default=1, - help="The maximum number of NUMA cells the compute nodes " - "have. If it's less than 2, resize negative tests for " - "vNUMA will be skipped."), - cfg.ListOpt('collected_metrics', - item_type=types.String( - choices=('cpu', 'network.outgoing.bytes', - 'disk.read.bytes')), - default=[], - help="The ceilometer metrics to check. If this config value " - "is empty, the telemetry tests are skipped. This config " - "option assumes that the compute nodes are configured " - "and capable of collecting ceilometer metrics. WARNING: " - "neutron-ovs-agent is not capable of enabling network " - "metrics collection."), - cfg.IntOpt('polled_metrics_delay', - default=620, - help="The number of seconds to wait for the metrics to be " - "published by the compute node's ceilometer-polling " - "agent. The value must be greater by ~15-20 seconds " - "than the agent's publish interval, defined in its " - "polling.yaml file (typically, the intervals are 600 " - "seconds)."), -] - -hyperv_host_auth_group = cfg.OptGroup(name='hyperv_host_auth', - title='Hyper-V host ' - 'authentication options') - -hyperv_host_auth_opts = [ - cfg.StrOpt('username', - help="The username of the Hyper-V hosts."), - cfg.StrOpt('password', - secret=True, - help='The password of the Hyper-V hosts.'), - cfg.StrOpt('cert_pem_path', - default=None, - help='SSL certificate for WinRM remote PS connection.'), - cfg.StrOpt('cert_key_pem_path', - default=None, - help='SSL key paired with cert_pem_path for WinRM remote PS ' - 'connection.'), - cfg.StrOpt('transport_method', - default='plaintext', - choices=('ssl', 'ntlm', 'plaintext'), - help='The method that should be used to establish a connection ' - 'to a Hyper-V host.') -] - -_opts = [ - (hyperv_group, HyperVGroup), - (hyperv_host_auth_group, hyperv_host_auth_opts), -] - - -def list_opts(): - return _opts diff --git a/oswin_tempest_plugin/exceptions.py b/oswin_tempest_plugin/exceptions.py deleted file mode 100644 index 87343a0..0000000 --- a/oswin_tempest_plugin/exceptions.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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 exceptions - - -class ResizeException(exceptions.TempestException): - message = ("Server %(server_id)s failed to resize to the given " - "flavor %(flavor)s") - - -class NotFoundException(exceptions.TempestException): - message = "Resource %(resource)s (%(res_type)s) was not found." - - -class WSManException(exceptions.TempestException): - message = ('Command "%(cmd)s" failed on host %(host)s failed with the ' - 'return code %(return_code)s. std_out: %(std_out)s, ' - 'std_err: %(std_err)s') diff --git a/oswin_tempest_plugin/plugin.py b/oswin_tempest_plugin/plugin.py deleted file mode 100644 index de865cd..0000000 --- a/oswin_tempest_plugin/plugin.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os - -from tempest import config -from tempest.test_discover import plugins - -from oswin_tempest_plugin import config as project_config - - -class OSWinTempestPlugin(plugins.TempestPlugin): - def load_tests(self): - base_path = os.path.split(os.path.dirname( - os.path.abspath(__file__)))[0] - test_dir = "oswin_tempest_plugin/tests" - full_test_dir = os.path.join(base_path, test_dir) - return full_test_dir, base_path - - def register_opts(self, conf): - """Add additional configuration options to tempest. - - This method will be run for the plugin during the register_opts() - function in tempest.config - - :param conf: The conf object that can be used to register additional - config options on. - """ - - for config_opt_group, config_opts in project_config.list_opts(): - config.register_opt_group(conf, config_opt_group, config_opts) - - def get_opt_lists(self): - """Get a list of options for sample config generation. - - :return: A list of tuples with the group name and options in that - group. - :return type: list - """ - return [(group.name, opts) - for group, opts in project_config.list_opts()] - - def get_service_clients(self): - metric_config = config.service_client_config('metric') - metric_v1_params = { - 'name': 'metric_v1', - 'service_version': 'metric.v1', - 'module_path': 'oswin_tempest_plugin.services.gnocchi_client', - 'client_names': ['GnocchiClient'], - } - metric_v1_params.update(metric_config) - - return [metric_v1_params] diff --git a/oswin_tempest_plugin/services/__init__.py b/oswin_tempest_plugin/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oswin_tempest_plugin/services/gnocchi_client.py b/oswin_tempest_plugin/services/gnocchi_client.py deleted file mode 100644 index 17f8cf6..0000000 --- a/oswin_tempest_plugin/services/gnocchi_client.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2018 Cloudbase Solutions Srl -# -# 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 - -from oswin_tempest_plugin import config - -CONF = config.CONF - - -class GnocchiClient(rest_client.RestClient): - - uri_prefix = 'v1' - - def deserialize(self, body): - return json.loads(body.replace("\n", "")) - - def _helper_list(self, uri): - resp, body = self.get(uri) - self.expected_success(200, resp.status) - body = self.deserialize(body) - return rest_client.ResponseBodyList(resp, body) - - def list_resources(self): - uri = '%s/resource/generic' % self.uri_prefix - return self._helper_list(uri) - - def list_samples(self, resource_id, meter_name): - """Returns a list of samples for the given resource and meter. - - :returns: list, each item being a list containing the following values - in this order: timestamp, granularity, value. - """ - uri = '%s/resource/generic/%s/metric/%s/measures' % ( - self.uri_prefix, resource_id, meter_name) - return self._helper_list(uri) diff --git a/oswin_tempest_plugin/tests/__init__.py b/oswin_tempest_plugin/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oswin_tempest_plugin/tests/_mixins/__init__.py b/oswin_tempest_plugin/tests/_mixins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oswin_tempest_plugin/tests/_mixins/migrate.py b/oswin_tempest_plugin/tests/_mixins/migrate.py deleted file mode 100644 index e4639c8..0000000 --- a/oswin_tempest_plugin/tests/_mixins/migrate.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest.common import waiters -import testtools - -from oswin_tempest_plugin import config - -CONF = config.CONF - - -class _MigrateMixin(object): - """Cold migration mixin. - - This mixin will add a cold migration test. It will perform the - following operations: - - * Spawn instance. - * Cold migrate the instance. - * Check the server connectivity. - """ - - def _migrate_server(self, server_tuple): - server = server_tuple.server - self.admin_servers_client.migrate_server(server['id']) - self._wait_for_server_status(server, 'VERIFY_RESIZE') - self.servers_client.confirm_resize_server(server['id']) - - @testtools.skipUnless(CONF.compute.min_compute_nodes >= 2, - 'Expected at least 2 compute nodes.') - def test_migration(self): - server_tuple = self._create_server() - self._migrate_server(server_tuple) - self._check_scenario(server_tuple) - - -class _LiveMigrateMixin(object): - """Live migration mixin. - - This mixin will add a live migration test. It will perform the - following operations: - - * Spawn instance. - * Live migrate the instance. - * Check the server connectivity. - """ - - # TODO(amuresan): Different mixins may be used at the same time. - # Each of them may override some fields such as - # 'max_microversion'. This has to be sorted out. - max_microversion = '2.24' - - def _live_migrate_server(self, server_tuple, destination_host=None, - state='ACTIVE', volume_backed=False): - server = server_tuple.server - admin_server = self._get_server_as_admin(server) - current_host = admin_server['OS-EXT-SRV-ATTR:host'] - - block_migration = (CONF.compute_feature_enabled. - block_migration_for_live_migration - and not volume_backed) - - self.admin_servers_client.live_migrate_server( - server['id'], - host=destination_host, - block_migration=block_migration, - disk_over_commit=False) - - waiters.wait_for_server_status(self.admin_servers_client, server['id'], - state) - - admin_server = self._get_server_as_admin(server) - after_migration_host = admin_server['OS-EXT-SRV-ATTR:host'] - - migration_list = (self.admin_migrations_client.list_migrations() - ['migrations']) - - msg = ("Live Migration failed. Migrations list for Instance " - "%s: [" % server['id']) - for live_migration in migration_list: - if live_migration['instance_uuid'] == server['id']: - msg += "\n%s" % live_migration - msg += "]" - - if destination_host: - self.assertEqual(destination_host, after_migration_host, msg) - else: - self.assertNotEqual(current_host, after_migration_host, msg) - - @testtools.skipUnless(CONF.compute_feature_enabled.live_migration, - 'Live migration option enabled.') - def test_live_migration(self): - server_tuple = self._create_server() - self._live_migrate_server(server_tuple) - self._check_scenario(server_tuple) diff --git a/oswin_tempest_plugin/tests/_mixins/optional_feature.py b/oswin_tempest_plugin/tests/_mixins/optional_feature.py deleted file mode 100644 index 7ae1ea4..0000000 --- a/oswin_tempest_plugin/tests/_mixins/optional_feature.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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 oswin_tempest_plugin import config -from oswin_tempest_plugin.tests._mixins import resize - -CONF = config.CONF - - -class _OptionalFeatureMixin(resize._ResizeUtils): - """Optional Feature mixin. - - Some features are optional, and can be turned on / off through resize - with certain flavors. - Examples of optional features: vNUMA, QoS, SR-IOV, PCI passthrough, - RemoteFX. - - This mixin will add the following tests: - * test_feature - * test_resize_add_feature - * test_resize_remove_feature - - The resize tests will create a new instance, resize it to a new flavor ( - turning on / off the optional feature), and check its network - connectivity. - - The optional feature flavor is based on the test suite's configured - _FLAVOR_REF (typically compute.flavor_ref or compute.flavor_ref_alt), - with some updates. For example, if the vNUMA configuration is to be tested, - the new flavor would contain the flavor extra_spec {'hw:numa_nodes="1"'}. - Keep in mind that all the extra_spec keys and values have to be strings. - """ - - # NOTE(claudiub): This flavor dict contains updates to the base flavor - # tempest is configured with. For example, _FEATURE_FLAVOR can be: - # _BIGGER_FLAVOR = {'extra_specs': {'hw:numa_nodes': 1'}} - # which means a flavor having that flavor extra_spec will be created, and - # a created instance will be resize to / from it. - - _FEATURE_FLAVOR = {} - - def _get_flavor_ref(self): - """Gets a new optional feature flavor ref. - - Creates a new flavor based on the test suite's configured _FLAVOR_REF, - with some updates specific to the optional feature. - - :returns: nova flavor ID. - """ - # NOTE(claudiub): Unless explicitly given another flavor, - # _create_server will call this method to get the flavor reference - # needed to spawn a new instance. Thus, any other test will spawn - # instances with this Optional Feature. - new_flavor = self._create_new_flavor(self._FLAVOR_REF, - self._FEATURE_FLAVOR) - return new_flavor['id'] - - def test_feature(self): - server_tuple = self._create_server() - self._check_scenario(server_tuple) - - @testtools.skipUnless(CONF.compute_feature_enabled.resize, - 'Resize is not available.') - def test_resize_add_feature(self): - new_flavor = self._get_flavor_ref() - self._check_resize(new_flavor, self._FLAVOR_REF) - - @testtools.skipUnless(CONF.compute_feature_enabled.resize, - 'Resize is not available.') - def test_resize_remove_feature(self): - new_flavor = self._get_flavor_ref() - self._check_resize(self._FLAVOR_REF, new_flavor) diff --git a/oswin_tempest_plugin/tests/_mixins/resize.py b/oswin_tempest_plugin/tests/_mixins/resize.py deleted file mode 100644 index b4c4b91..0000000 --- a/oswin_tempest_plugin/tests/_mixins/resize.py +++ /dev/null @@ -1,127 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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 time - -from oslo_log import log as logging -import testtools - -from oswin_tempest_plugin import config -from oswin_tempest_plugin import exceptions - -CONF = config.CONF -LOG = logging.getLogger(__name__) - - -class _ResizeUtils(object): - - def _get_server_migration(self, server_id): - final_states = ['error', 'confirmed'] - for i in range(10): - migrations = ( - self.admin_migrations_client.list_migrations()['migrations']) - server_migration = [m for m in migrations - if m['instance_uuid'] == server_id] - if server_migration: - migration_status = server_migration[0]['status'] - LOG.debug("Server's %s migration status: %s", - server_id, migration_status) - if migration_status in final_states: - return server_migration[0] - else: - # NOTE(claudiub): the migration might not appear *immediately* - # after the cold resize was requested. - LOG.info("Server's %s migration was not found.", server_id) - - time.sleep(1) - - return server_migration[0] if server_migration else None - - def _resize_server(self, server_tuple, new_flavor_id): - server = server_tuple.server - self.servers_client.resize_server(server['id'], - flavor_ref=new_flavor_id) - - migration = self._get_server_migration(server['id']) - if migration and migration['status'] == 'error': - # the migration ended up in an error state. Raise an exception. - raise exceptions.ResizeException(server_id=server['id'], - flavor=new_flavor_id) - - self._wait_for_server_status(server, 'VERIFY_RESIZE') - self.servers_client.confirm_resize_server(server['id']) - - def _check_resize(self, resize_flavor_id, original_flavor_id=None, - expected_fail=False): - original_flavor_id = original_flavor_id or self._get_flavor_ref() - server_tuple = self._create_server(original_flavor_id) - - if expected_fail: - self.assertRaises(exceptions.ResizeException, - self._resize_server, - server_tuple, resize_flavor_id) - else: - self._resize_server(server_tuple, resize_flavor_id) - - # assert that the server is still reachable, even if the resize - # failed. - self._check_scenario(server_tuple) - - -class _ResizeMixin(_ResizeUtils): - """Cold resize mixin. - - This mixin will add cold resize tests. The tests will create a new - instance, resize it to a new flavor, and check its network connectivity. - - The new flavor is based on the test suite's configured _FLAVOR_REF ( - typically compute.flavor_ref or compute.flavor_ref_alt), with some - updates. For example, if the vNUMA configuration is to be tested, the new - flavor would contain the flavor extra_spec 'hw:numa_nodes=1'. - """ - - # NOTE(claudiub): These flavor dicts are updates to the base flavor - # tempest is configured with. For example, _BIGGER_FLAVOR can be: - # _BIGGER_FLAVOR = {'disk': 1} - # which means a flavor having +1 GB disk size will be created, and - # a created instance will be resized to it. - - _SMALLER_FLAVOR = {} - _BIGGER_FLAVOR = {} - - @testtools.skipUnless(CONF.compute_feature_enabled.resize, - 'Resize is not available.') - def test_resize(self): - new_flavor = self._create_new_flavor(self._get_flavor_ref(), - self._BIGGER_FLAVOR) - self._check_resize(new_flavor['id']) - - -class _ResizeNegativeMixin(_ResizeUtils): - """Cold resize negative mixin. - - This mixin will add cold resize negative tests. The tests will create a - new instance, resize it to an invalid flavor, check that the resize - failed, and check the instance's connectivity. - """ - - _BAD_FLAVOR = {} - - @testtools.skipUnless(CONF.compute_feature_enabled.resize, - 'Resize is not available.') - def test_resize_negative(self): - new_flavor = self._create_new_flavor(self._get_flavor_ref(), - self._BAD_FLAVOR) - self._check_resize(new_flavor['id'], expected_fail=True) diff --git a/oswin_tempest_plugin/tests/scenario/__init__.py b/oswin_tempest_plugin/tests/scenario/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oswin_tempest_plugin/tests/scenario/test_cluster.py b/oswin_tempest_plugin/tests/scenario/test_cluster.py deleted file mode 100644 index fd3022a..0000000 --- a/oswin_tempest_plugin/tests/scenario/test_cluster.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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 time - -from oslo_log import log as logging -from tempest.lib import exceptions as lib_exc - -from oswin_tempest_plugin.clients import wsman -from oswin_tempest_plugin import config -from oswin_tempest_plugin import exceptions -from oswin_tempest_plugin.tests._mixins import migrate -from oswin_tempest_plugin.tests._mixins import resize -from oswin_tempest_plugin.tests import test_base - -CONF = config.CONF -LOG = logging.getLogger(__name__) - - -class HyperVClusterTest(migrate._MigrateMixin, - migrate._LiveMigrateMixin, - resize._ResizeMixin, - test_base.TestBase): - - """The test suite for the Hyper-V Cluster. - - This test suite will test the functionality of the Hyper-V Cluster Driver - in OpenStack. The tests will force a failover on its newly created - instance, and asserts the following: - - * the instance moves to another host. - * the nova instance's host is properly updated. - * the instance's network connection still works. - * different nova operations can be performed properly. - - This test suite relies on the fact that there are at least 2 compute nodes - available, that they are clustered, and have WSMan configured. - - The test suite contains the following tests: - - * test_check_clustered_vm - * test_check_migration - * test_check_resize - * test_check_resize_negative - """ - - _BIGGER_FLAVOR = {'disk': 1} - - @classmethod - def skip_checks(cls): - super(HyperVClusterTest, cls).skip_checks() - - # check if the cluster Tests can be run. - if not CONF.hyperv.cluster_enabled: - msg = 'Hyper-V cluster tests are disabled.' - raise cls.skipException(msg) - - if not CONF.hyperv_host_auth.username: - msg = ('No Hyper-V host username has been provided. ' - 'Skipping cluster tests.') - raise cls.skipException(msg) - - if not CONF.compute.min_compute_nodes >= 2: - msg = 'Expected at least 2 compute nodes.' - raise cls.skipException(msg) - - def _failover_server(self, server_name, host_ip): - """Triggers the failover for the given server on the given host.""" - - resource_name = "Virtual Machine %s" % server_name - cmd = "Test-ClusterResourceFailure -Name '%s'" % resource_name - # NOTE(claudiub): we issue the failover command twice, because on - # the first failure, the Hyper-V Cluster will prefer the current - # node, and will try to reactivate the VM on the it, and it will - # succeed. On the 2nd failure, the VM will failover to another - # node. Also, there needs to be a delay between commands, so the - # original failover has time to finish. - wsman.run_hv_host_wsman_ps(host_ip, cmd) - time.sleep(CONF.hyperv.failover_sleep_interval) - wsman.run_hv_host_wsman_ps(host_ip, cmd) - - def _wait_for_failover(self, server, original_host): - """Waits for the given server to failover to another host. - - :raises TimeoutException: if the given server did not failover to - another host within the configured "CONF.hyperv.failover_timeout" - interval. - """ - LOG.debug('Waiting for server %(server)s to failover from ' - 'compute node %(host)s', - dict(server=server['id'], host=original_host)) - - start_time = int(time.time()) - timeout = CONF.hyperv.failover_timeout - while True: - elapsed_time = int(time.time()) - start_time - admin_server = self._get_server_as_admin(server) - current_host = admin_server['OS-EXT-SRV-ATTR:host'] - if current_host != original_host: - LOG.debug('Server %(server)s failovered from compute node ' - '%(host)s in %(seconds)s seconds.', - dict(server=server['id'], host=original_host, - seconds=elapsed_time)) - return - - if elapsed_time >= timeout: - msg = ('Server %(server)s did not failover in the given ' - 'amount of time (%(timeout)s s).') - raise lib_exc.TimeoutException( - msg % dict(server=server['id'], timeout=timeout)) - - time.sleep(CONF.hyperv.failover_sleep_interval) - - def _get_hypervisor(self, hostname): - hypervisors = self.admin_hypervisor_client.list_hypervisors( - detail=True)['hypervisors'] - hypervisor = [h for h in hypervisors if - h['hypervisor_hostname'] == hostname] - - if not hypervisor: - raise exceptions.NotFoundException(resource=hostname, - res_type='hypervisor') - return hypervisor[0] - - def _create_server(self, flavor=None): - server_tuple = super(HyperVClusterTest, self)._create_server(flavor) - server = server_tuple.server - admin_server = self._get_server_as_admin(server) - - server_name = admin_server['OS-EXT-SRV-ATTR:instance_name'] - hostname = admin_server['OS-EXT-SRV-ATTR:host'] - host_ip = self._get_hypervisor(hostname)['host_ip'] - - self._failover_server(server_name, host_ip) - self._wait_for_failover(server, hostname) - - return server_tuple - - def test_clustered_vm(self): - server_tuple = self._create_server() - self._check_scenario(server_tuple) diff --git a/oswin_tempest_plugin/tests/scenario/test_disks.py b/oswin_tempest_plugin/tests/scenario/test_disks.py deleted file mode 100644 index cd44ade..0000000 --- a/oswin_tempest_plugin/tests/scenario/test_disks.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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 oswin_tempest_plugin import config -from oswin_tempest_plugin.tests._mixins import migrate -from oswin_tempest_plugin.tests._mixins import resize -from oswin_tempest_plugin.tests import test_base - -CONF = config.CONF - - -class _BaseDiskTestMixin(migrate._MigrateMixin, - resize._ResizeMixin, - resize._ResizeNegativeMixin): - """Image types / formats test suite. - - This test suite will spawn instances with a configured image and will - check their network connectivity. The purpose of this test suite is to - cover different image formats and types (VHD, VHDX, Generation 2 VMs). - """ - - _CONF_OPTION_NAME = '' - - _BIGGER_FLAVOR = {'disk': 1} - _BAD_FLAVOR = {'disk': -1} - - @classmethod - def skip_checks(cls): - super(_BaseDiskTestMixin, cls).skip_checks() - # check if the needed image ref has been configured. - if not cls._IMAGE_REF: - msg = ('The config option "%s" has not been set. Skipping.' % - cls._CONF_OPTION_NAME) - raise cls.skipException(msg) - - def test_disk(self): - server_tuple = self._create_server() - self._check_scenario(server_tuple) - - @testtools.skipUnless(CONF.compute_feature_enabled.resize, - 'Resize is not available.') - def test_resize_negative(self): - # NOTE(claudiub): This test will try to downsize a VM's disk, which is - # unsupported. The configured flavor might have disk set to 1GB. - # The nova-api does not allow disks to be resized on 0 GB. - flavor = self._get_flavor_ref() - new_flavor = self._create_new_flavor(flavor, self._BIGGER_FLAVOR) - self._check_resize(flavor, new_flavor['id'], expected_fail=True) - - -class VhdDiskTest(_BaseDiskTestMixin, test_base.TestBase): - - _IMAGE_REF = CONF.hyperv.vhd_image_ref - _CONF_OPTION_NAME = 'hyperv.vhd_image_ref' - _FLAVOR_SUFFIX = 'vhd' - - # TODO(claudiub): validate that the images really are VHD / VHDX. - - -class VhdxDiskTest(_BaseDiskTestMixin, test_base.TestBase): - - _IMAGE_REF = CONF.hyperv.vhdx_image_ref - _CONF_OPTION_NAME = 'hyperv.vhdx_image_ref' - _FLAVOR_SUFFIX = 'vhdx' - - -class Generation2DiskTest(_BaseDiskTestMixin, test_base.TestBase): - - # Generation 2 VMs have been introduced in Windows / Hyper-V Server 2012 R2 - _MIN_HYPERV_VERSION = 6003 - - _IMAGE_REF = CONF.hyperv.gen2_image_ref - _CONF_OPTION_NAME = 'hyperv.gen2_image_ref' - _FLAVOR_SUFFIX = 'gen2' - - # TODO(claudiub): Add validation that the given gen2_image_ref really has - # the 'hw_machine_type=hyperv-gen2' property. diff --git a/oswin_tempest_plugin/tests/scenario/test_metrics_collection.py b/oswin_tempest_plugin/tests/scenario/test_metrics_collection.py deleted file mode 100644 index c30a3ab..0000000 --- a/oswin_tempest_plugin/tests/scenario/test_metrics_collection.py +++ /dev/null @@ -1,166 +0,0 @@ -# Copyright 2017 Cloudbase Solutions -# 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 time - -from oslo_log import log as logging -from tempest import clients - -from oswin_tempest_plugin import config -from oswin_tempest_plugin.tests import test_base - -CONF = config.CONF -LOG = logging.getLogger(__name__) - - -class ClientManager(clients.Manager): - - def __init__(self, *args, **kwargs): - super(ClientManager, self).__init__(*args, **kwargs) - - self.set_gnocchi_client() - - def set_gnocchi_client(self): - self.gnocchi_client = self.metric_v1.GnocchiClient() - - -class MetricsCollectionTestCase(test_base.TestBase): - """Adds metrics collection scenario tests. - - This test suite verifies that the instance metrics are properly published - and collected and have non-zero values. The verification is done via the - ceilometer API. - - setup: - 1. spins a new instance. - 2. waits until the instance was created succesfully (ACTIVE status). - 3. wait an interval of time which represents the polling period of the - ceilometer-polling agent. - - Waiting for the ceilometer-polling agent to poll the resources is crucial, - otherwise the test suite will fail due to the fact that no samples - would be found published before checking the samples. - - The test suite's polled_metrics_delay must have a greater value than the - ceilometer agent's polling interval. This can be done in two ways: - a. Configure tempest's polled_metric_delay, by adding the - following line in tempest.conf, in the hyperv section: - polled_metrics_delay = - b. Set the interval value in polling.yaml on the compute node to - the desired value and restart the ceilometer polling agent. The - interval value is set either for the 'meter_source' or for each - of the following: 'cpu_source', 'disk_source', 'network_source'. - - Note: If the polled_metrics_delay value is too low, the tests might not - find any samples and fail because of this. As a recommandation, - polled_metrics_delay's value should be: - polled_metric_delay = + <15-20 seconds> - - tests: - 1. test_metrics - tests values for the following metrics: - - cpu - - network.outgoing.bytes - - disk.read.bytes - - assumptions: - 1. Ceilometer agent on the compute node is running. - 2. Ceilometer agent on the compute node has the polling interval - defined in polling.yaml lower than the polled_metrics_delay defined - in this test suite. - 3. The compute nodes' nova-compute and neutron-hyperv-agent services - have been configured to enable metrics collection. - """ - - client_manager = ClientManager - - @classmethod - def skip_checks(cls): - super(MetricsCollectionTestCase, cls).skip_checks() - - for service in ['ceilometer', 'gnocchi']: - if not getattr(CONF.service_available, service): - raise cls.skipException("%s service is required." % service) - - if not CONF.hyperv.collected_metrics: - raise cls.skipException("Collected metrics not configured.") - - @classmethod - def setup_clients(cls): - super(MetricsCollectionTestCase, cls).setup_clients() - - # Telemetry client - cls.telemetry_client = cls.os_primary.gnocchi_client - - def _check_samples(self, resource_id, meter_name): - LOG.info("Checking %(meter_name)s for resource %(resource_id)s" % { - 'meter_name': meter_name, 'resource_id': resource_id}) - - samples = self.telemetry_client.list_samples(resource_id, meter_name) - self.assertNotEmpty( - samples, - 'Client returned no samples for the given resource ' - '"%(resource_id)s" and meter "%(meter_name)s".' % { - 'resource_id': resource_id, 'meter_name': meter_name}) - - non_zero_valued_samples = [s for s in samples if s[2] > 0] - self.assertNotEmpty( - non_zero_valued_samples, - 'All meter %(meter_name)s samples for resource ' - '%(resource_id)s are 0.' % {'meter_name': meter_name, - 'resource_id': resource_id}) - - def _get_instance_cpu_resource_id(self, server): - return server['id'] - - def _get_instance_disk_resource_id(self, server): - return server['id'] - - def _get_instance_port_resource_id(self, server): - # Note(claudiub): the format for the instance_port_resource_id is: - # %(OS-EXT-SRV-ATTR:instance_name)s-%(instance_id)s-%(port_id)s - # the instance returned by self.servers_client does not contain the - # OS-EXT-SRV-ATTR:instance_name field. Which means that the resource_id - # must be found in gnocchi's resources. - start_res_id = server['id'] - resources = self.telemetry_client.list_resources() - res_ids = [r['id'] for r in resources - if r['original_resource_id'].startswith('instance-') - and start_res_id in r['original_resource_id']] - - self.assertEqual(1, len(res_ids)) - return res_ids[0] - - def _check_scenario(self, server_tuple): - server = server_tuple.server - LOG.info("Waiting %s seconds for the ceilometer compute agents to " - "publish the samples.", CONF.hyperv.polled_metrics_delay) - time.sleep(CONF.hyperv.polled_metrics_delay) - - # TODO(claudiub): Add more metrics. - if 'cpu' in CONF.hyperv.collected_metrics: - cpu_res_id = self._get_instance_cpu_resource_id(server) - self._check_samples(cpu_res_id, 'cpu') - - if 'network.outgoing.bytes' in CONF.hyperv.collected_metrics: - port_res_id = self._get_instance_port_resource_id(server) - self._check_samples(port_res_id, 'network.outgoing.bytes') - - if 'disk.read.bytes' in CONF.hyperv.collected_metrics: - disk_resource_id = self._get_instance_disk_resource_id(server) - self._check_samples(disk_resource_id, 'disk.read.bytes') - - def test_metrics(self): - server_tuple = self._create_server() - self._check_scenario(server_tuple) diff --git a/oswin_tempest_plugin/tests/scenario/test_qos.py b/oswin_tempest_plugin/tests/scenario/test_qos.py deleted file mode 100644 index 9235dcb..0000000 --- a/oswin_tempest_plugin/tests/scenario/test_qos.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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_utils import units - -from oswin_tempest_plugin.tests._mixins import optional_feature -from oswin_tempest_plugin.tests import test_base - - -class QosTestCase(optional_feature._OptionalFeatureMixin, - test_base.TestBase): - """QoS test suite. - - This test suite will spawn instances with QoS specs. - - Hyper-V uses normalized IOPS (8 KB increments), and the minimum IOPS that - can be set is 1. - """ - - # Hyper-V disk QoS is supported on Windows / Hyper-v Server 2012 R2 - # or newer. - _MIN_HYPERV_VERSION = 6003 - - _FEATURE_FLAVOR = { - 'extra_specs': {'quota:disk_total_bytes_sec': str(units.Mi)}} diff --git a/oswin_tempest_plugin/tests/scenario/test_remotefx.py b/oswin_tempest_plugin/tests/scenario/test_remotefx.py deleted file mode 100644 index dbb39a6..0000000 --- a/oswin_tempest_plugin/tests/scenario/test_remotefx.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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 oswin_tempest_plugin import config -from oswin_tempest_plugin.tests._mixins import optional_feature -from oswin_tempest_plugin.tests import test_base - -CONF = config.CONF - - -class RemoteFxTestCase(optional_feature._OptionalFeatureMixin, - test_base.TestBase): - """RemoteFX test suite. - - This test suit will spawn instances with RemoteFX enabled. - """ - - # RemoteFX is supported in Windows / Hyper-V Server 2012 R2 and newer. - _MIN_HYPERV_VERSION = 6003 - - _FEATURE_FLAVOR = {'extra_specs': {'os_resolution': '1920x1200', - 'os_monitors': '1', - 'os_vram': '1024'}} - - @classmethod - def skip_checks(cls): - super(RemoteFxTestCase, cls).skip_checks() - # the CONF.hyperv.remotefx_enabled config option needs to be enabled. - if not CONF.hyperv.remotefx_enabled: - msg = ('The config option "hyperv.remotefx_enabled" is False. ' - 'Skipping.') - raise cls.skipException(msg) diff --git a/oswin_tempest_plugin/tests/scenario/test_secure_boot.py b/oswin_tempest_plugin/tests/scenario/test_secure_boot.py deleted file mode 100644 index 54b319b..0000000 --- a/oswin_tempest_plugin/tests/scenario/test_secure_boot.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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 oswin_tempest_plugin import config -from oswin_tempest_plugin.tests._mixins import optional_feature -from oswin_tempest_plugin.tests import test_base - -CONF = config.CONF - - -class SecureBootTestCase(optional_feature._OptionalFeatureMixin, - test_base.TestBase): - """Secure boot test suite. - - This test suite will spawn instances requiring secure boot to be - enabled. - - This test suite will require a Generation 2 VHDX image, with a - Linux guest OS (it tests connectivity via SSH). - - The configured image must contain the following properties: - * os_type=linux - * hw_machine_type=hyperv-gen2 - - Hyper-V Secure Boot was first introduced in Windows / Hyper-V Server 2012 - R2, but support for Linux guests was introduced in Windows / Hyper-V - Server 2016, which is why this test suite will require compute nodes - with the OS version 10.0 or newer. - """ - - _MIN_HYPERV_VERSION = 10000 - - # NOTE(amuresan):Images supporting secure boot usually require more disk - # space. We're trying to use the largest of the configured - # flavors. - - _FLAVOR_REF = CONF.compute.flavor_ref_alt - _IMAGE_REF = CONF.hyperv.secure_boot_image_ref - _IMAGE_SSH_USER = CONF.hyperv.secure_boot_image_ssh_user - _FEATURE_FLAVOR = {'extra_specs': {'os:secure_boot': 'required'}} - - # TODO(amuresan): the secure_boot_image_ref should be reused in - # more than one test case so we don't have to add a different - # image for every test. - - @classmethod - def skip_checks(cls): - super(SecureBootTestCase, cls).skip_checks() - # check if the needed image ref has been configured. - if not cls._IMAGE_REF: - msg = ('The config option "hyperv.secure_boot_image_ref" ' - 'has not been set. Skipping secure boot tests.') - raise cls.skipException(msg) - - if not cls._IMAGE_SSH_USER: - msg = ('The config option "hyperv.secure_boot_image_ssh_user" ' - 'has not been set. Skipping.') - raise cls.skipException(msg) diff --git a/oswin_tempest_plugin/tests/scenario/test_vnuma.py b/oswin_tempest_plugin/tests/scenario/test_vnuma.py deleted file mode 100644 index d7e0ddd..0000000 --- a/oswin_tempest_plugin/tests/scenario/test_vnuma.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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 oswin_tempest_plugin import config -from oswin_tempest_plugin.tests._mixins import migrate -from oswin_tempest_plugin.tests._mixins import optional_feature -from oswin_tempest_plugin.tests._mixins import resize -from oswin_tempest_plugin.tests import test_base - -CONF = config.CONF - - -class HyperVvNumaTestCase(migrate._MigrateMixin, - migrate._LiveMigrateMixin, - optional_feature._OptionalFeatureMixin, - resize._ResizeMixin, - resize._ResizeNegativeMixin, - test_base.TestBase): - """Hyper-V vNUMA test suite. - - This test suite will spawn instances requiring NUMA placement. - """ - - _FEATURE_FLAVOR = {'extra_specs': {'hw:numa_nodes': '1'}} - _BIGGER_FLAVOR = {'ram': 128, 'extra_specs': {'hw:numa_nodes': '1'}} - - # NOTE(claudiub): Hyper-V does not support asymmetric NUMA topologies. - # The resize should fail in this case. - _BAD_FLAVOR = {'ram': 64, 'extra_specs': { - 'hw:numa_nodes': '2', 'hw:numa_mem.0': '64', 'hw:numa_cpus.0': '0'}} - - @testtools.skipUnless(CONF.hyperv.available_numa_nodes > 1, - 'At least 2 NUMA nodes are required.') - @testtools.skipUnless(CONF.compute_feature_enabled.resize, - 'Resize is not available.') - def test_resize_negative(self): - new_flavor = self._create_new_flavor(self._get_flavor_ref(), - self._BAD_FLAVOR) - - # NOTE(claudiub): all NUMA nodes have to be properly defined. - vcpus = [i for i in range(1, int(new_flavor['vcpus']))] - extra_specs = {'hw:numa_mem.1': str(int(new_flavor['ram']) - 64), - 'hw:numa_cpus.1': ','.join(vcpus)} - self.admin_flavors_client.set_flavor_extra_spec( - new_flavor['id'], **extra_specs) - - self._check_resize(new_flavor['id'], expected_fail=True) diff --git a/oswin_tempest_plugin/tests/test_base.py b/oswin_tempest_plugin/tests/test_base.py deleted file mode 100644 index 9eb7657..0000000 --- a/oswin_tempest_plugin/tests/test_base.py +++ /dev/null @@ -1,287 +0,0 @@ -# Copyright 2017 Cloudbase Solutions SRL -# 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 - -from oslo_log import log as logging -from tempest.common import compute -from tempest.common.utils.linux import remote_client -from tempest.common import waiters -from tempest.lib.common.utils import data_utils -from tempest.lib.common.utils import test_utils -from tempest.lib import exceptions -import tempest.scenario.manager - -from oswin_tempest_plugin import config - -CONF = config.CONF -LOG = logging.getLogger(__name__) - - -Server_tuple = collections.namedtuple( - 'Server_tuple', - ['server', 'floating_ip', 'keypair', 'security_groups']) - - -class TestBase(tempest.scenario.manager.ScenarioTest): - """Base class for tests.""" - - credentials = ['primary', 'admin'] - - # Inheriting TestCases should change this version if needed. - _MIN_HYPERV_VERSION = 6002 - - # Inheriting TestCases should change this image ref if needed. - _IMAGE_REF = CONF.compute.image_ref - - # Inheriting TestCases should change this flavor ref if needed. - _FLAVOR_REF = CONF.compute.flavor_ref - - # Inheriting TestCases should change this ssh User if needed. - _IMAGE_SSH_USER = CONF.validation.image_ssh_user - - # suffix to use for the newly created flavors. - _FLAVOR_SUFFIX = '' - - @classmethod - def skip_checks(cls): - super(TestBase, cls).skip_checks() - # check if the configured hypervisor_version is higher than - # the test's required minimum Hyper-V version. - - # TODO(claudiub): instead of expecting a config option specifying - # the hypervisor version, we could check nova's compute nodes for - # their hypervisor versions. - config_vers = CONF.hyperv.hypervisor_version - if config_vers < cls._MIN_HYPERV_VERSION: - msg = ('Configured hypervisor_version (%(config_vers)s) is not ' - 'supported. It must be higher than %(req_vers)s.' % { - 'config_vers': config_vers, - 'req_vers': cls._MIN_HYPERV_VERSION}) - raise cls.skipException(msg) - - @classmethod - def setup_clients(cls): - super(TestBase, cls).setup_clients() - # Compute client - cls.compute_fips_client = ( - cls.os_primary.compute_floating_ips_client) - cls.keypairs_client = cls.os_primary.keypairs_client - cls.servers_client = cls.os_primary.servers_client - cls.admin_servers_client = cls.os_admin.servers_client - cls.admin_flavors_client = cls.os_admin.flavors_client - cls.admin_migrations_client = cls.os_admin.migrations_client - cls.admin_hypervisor_client = cls.os_admin.hypervisor_client - - # Neutron network client - cls.security_groups_client = ( - cls.os_primary.security_groups_client) - cls.security_group_rules_client = ( - cls.os_primary.security_group_rules_client) - - def create_floating_ip(self, server): - """Create a floating IP and associates to a server on Nova""" - - pool_name = CONF.network.floating_network_name - floating_ip = ( - self.compute_fips_client.create_floating_ip(pool=pool_name)) - floating_ip = floating_ip['floating_ip'] - self.addCleanup(test_utils.call_and_ignore_notfound_exc, - self.compute_fips_client.delete_floating_ip, - floating_ip['id']) - self.compute_fips_client.associate_floating_ip_to_server( - floating_ip['ip'], server['id']) - return floating_ip - - def _get_image_ref(self): - return self._IMAGE_REF - - def _flavor_cleanup(self, flavor_id): - try: - self.admin_flavors_client.delete_flavor(flavor_id) - self.admin_flavors_client.wait_for_resource_deletion(flavor_id) - except exceptions.NotFound: - pass - - def _create_new_flavor(self, flavor_ref, flavor_updates): - """Creates a new flavor based on the given flavor and flavor updates. - - :returns: the newly created flavor's ID. - """ - flavor = self.admin_flavors_client.show_flavor(flavor_ref)['flavor'] - - flavor_name = 'test_resize' - if self._FLAVOR_SUFFIX: - flavor_name += '_%s' % self._FLAVOR_SUFFIX - - new_flavor = self.admin_flavors_client.create_flavor( - name=data_utils.rand_name(flavor_name), - ram=flavor['ram'] + flavor_updates.get('ram', 0), - disk=flavor['disk'] + flavor_updates.get('disk', 0), - vcpus=flavor['vcpus'] + flavor_updates.get('vcpus', 0), - )['flavor'] - - self.addCleanup(self._flavor_cleanup, new_flavor['id']) - - # Add flavor extra_specs, if needed. - extra_specs = flavor_updates.get('extra_specs') - if extra_specs: - self.admin_flavors_client.set_flavor_extra_spec( - new_flavor['id'], **extra_specs) - - return new_flavor - - def _get_flavor_ref(self): - return self._FLAVOR_REF - - def _create_server(self, flavor=None): - """Wrapper utility that returns a test server. - - This wrapper utility calls the common create test server and - returns a test server. - """ - clients = self.os_primary - name = data_utils.rand_name(self.__class__.__name__ + "-server") - image_id = self._get_image_ref() - flavor = flavor or self._get_flavor_ref() - keypair = self.create_keypair() - tenant_network = self.get_tenant_network() - security_group = self._create_security_group() - # we need to pass the security group's name to the instance. - sg_group_names = [{'name': security_group['name']}] - - body, _ = compute.create_test_server( - clients, name=name, - flavor=flavor, - image_id=image_id, - key_name=keypair['name'], - tenant_network=tenant_network, - security_groups=sg_group_names, - wait_until='ACTIVE') - - self.addCleanup(waiters.wait_for_server_termination, - self.servers_client, body['id']) - self.addCleanup(test_utils.call_and_ignore_notfound_exc, - self.servers_client.delete_server, body['id']) - server = clients.servers_client.show_server(body['id'])['server'] - - floating_ip = self.create_floating_ip(server) - server_tuple = Server_tuple( - server=server, - keypair=keypair, - floating_ip=floating_ip, - security_groups=[security_group]) - - return server_tuple - - def _get_server_as_admin(self, server): - # only admins have access to certain instance properties. - return self.admin_servers_client.show_server( - server['id'])['server'] - - def _create_security_group(self): - sg_name = data_utils.rand_name(self.__class__.__name__) - sg_desc = sg_name + " description" - secgroup = self.security_groups_client.create_security_group( - name=sg_name, description=sg_desc)['security_group'] - self.addCleanup( - test_utils.call_and_ignore_notfound_exc, - self.security_groups_client.delete_security_group, - secgroup['id']) - - # Add rules to the security group - self._create_loginable_secgroup_rule(secgroup) - return secgroup - - def _create_loginable_secgroup_rule(self, secgroup): - """Create loginable security group rule - - This function will create: - 1. egress and ingress tcp port 22 allow rule in order to allow ssh - access for ipv4. - 3. egress and ingress ipv4 icmp allow rule, in order to allow icmpv4. - """ - - rulesets = [ - # ssh - dict(protocol='tcp', - port_range_min=22, - port_range_max=22), - # ping - dict(protocol='icmp'), - ] - for ruleset in rulesets: - for r_direction in ['ingress', 'egress']: - ruleset['direction'] = r_direction - self._create_security_group_rule( - secgroup, **ruleset) - - def _create_security_group_rule(self, secgroup, **kwargs): - """Create a rule from a dictionary of rule parameters. - - Creates a rule in a secgroup. - - :param secgroup: the security group. - :param kwargs: a dictionary containing rule parameters: - for example, to allow incoming ssh: - rule = { - direction: 'ingress' - protocol:'tcp', - port_range_min: 22, - port_range_max: 22 - } - """ - ruleset = dict(security_group_id=secgroup['id'], - tenant_id=secgroup['tenant_id']) - ruleset.update(kwargs) - - sec_group_rules_client = self.security_group_rules_client - sg_rule = sec_group_rules_client.create_security_group_rule(**ruleset) - sg_rule = sg_rule['security_group_rule'] - - return sg_rule - - def _wait_for_server_status(self, server, status='ACTIVE'): - waiters.wait_for_server_status(self.servers_client, server['id'], - status) - - def _get_server_client(self, server_tuple): - """Get a SSH client to a remote server - - :returns: RemoteClient object - """ - server = server_tuple.server - ip_address = server_tuple.floating_ip['ip'] - private_key = server_tuple.keypair['private_key'] - - # ssh into the VM - username = self._IMAGE_SSH_USER - linux_client = remote_client.RemoteClient( - ip_address, username, pkey=private_key, password=None, - server=server, servers_client=self.servers_client) - linux_client.validate_authentication() - - return linux_client - - def _check_server_connectivity(self, server_tuple): - # if server connectivity works, an SSH client can be opened. - self._get_server_client(server_tuple) - - def _check_scenario(self, server_tuple): - # NOTE(claudiub): This method is to be used when verifying a - # particular scenario. If a scenario test case needs to perform - # different validation steps (e.g.: metrics collection), it should - # overwrite this method. - self._check_server_connectivity(server_tuple) diff --git a/releasenotes/notes/drop-py-2-7-9c98090411bcd207.yaml b/releasenotes/notes/drop-py-2-7-9c98090411bcd207.yaml deleted file mode 100644 index 9297318..0000000 --- a/releasenotes/notes/drop-py-2-7-9c98090411bcd207.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -upgrade: - - | - Python 2.7 support has been dropped. Last release of oswin-tempest-plugin - to support py2.7 is OpenStack Train. The minimum version of Python now - supported by oswin-tempest-plugin is Python 3.5. diff --git a/releasenotes/notes/drop-python-3-6-and-3-7-fbf1c519725da78b.yaml b/releasenotes/notes/drop-python-3-6-and-3-7-fbf1c519725da78b.yaml deleted file mode 100644 index 3d5e4e3..0000000 --- a/releasenotes/notes/drop-python-3-6-and-3-7-fbf1c519725da78b.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -upgrade: - - | - Python 3.6 & 3.7 support has been dropped. The minimum version of Python now - supported is Python 3.8. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index c2c902c..0000000 --- a/requirements.txt +++ /dev/null @@ -1,11 +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!=2.1.0,>=2.0.0 # Apache-2.0 - -oslo.config>=5.1.0 # Apache-2.0 -oslo.log>=3.36.0 # Apache-2.0 -oslo.utils>=3.33.0 # Apache-2.0 -tempest>=17.1.0 # Apache-2.0 -pywinrm>=0.2.2 # MIT diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 520f04a..0000000 --- a/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[metadata] -name = oswin-tempest-plugin -summary = This project contains Tempest tests to cover the os_win project, as well as a plugin to automatically load these tests into Tempest. -description_file = - README.rst -author = Cloudbase Solutions -author_email = info@cloudbasesolutions.com -home_page = https://opendev.org/openstack/oswin-tempest-plugin -python_requires = >=3.8 -classifier = - Environment :: OpenStack - Intended Audience :: Information Technology - Intended Audience :: System Administrators - License :: OSI Approved :: Apache Software License - Operating System :: POSIX :: Linux - Operating System :: Microsoft :: Windows - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.8 - -[files] -packages = - oswin_tempest_plugin - -[entry_points] -tempest.test_plugins = - oswin_tempest_plugin = oswin_tempest_plugin.plugin:OSWinTempestPlugin diff --git a/setup.py b/setup.py deleted file mode 100644 index 566d844..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>=2.0.0'], - pbr=True) diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index c20e8a3..0000000 --- a/test-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. - -hacking>=3.0.1,<3.1.0 # Apache-2.0 - -coverage!=4.4,>=4.0 # Apache-2.0 -python-subunit>=1.0.0 # Apache-2.0/BSD -stestr>=2.0.0 # Apache-2.0 -oslotest>=3.2.0 # Apache-2.0 -testscenarios>=0.4 # Apache-2.0/BSD -testtools>=2.2.0 # MIT - diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 120ec82..0000000 --- a/tox.ini +++ /dev/null @@ -1,43 +0,0 @@ -[tox] -minversion = 3.1.1 -envlist = py3,pypy,pep8 -skipsdist = True -ignore_basepython_conflict = True - -[testenv] -basepython = python3 -usedevelop = True -setenv = - VIRTUAL_ENV={envdir} - PYTHONWARNINGS=default::DeprecationWarning -deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} - -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt -commands = stestr run --slowest {posargs} - -[testenv:pep8] -commands = flake8 {posargs} - -[testenv:venv] -commands = {posargs} - -[testenv:cover] -commands = python setup.py test --coverage --testr-args='{posargs}' - -[testenv:docs] -deps = - -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} - -r{toxinidir}/doc/requirements.txt -commands = sphinx-build -W -b html doc/source doc/build/html - -[testenv:debug] -commands = oslo_debug_helper {posargs} - -[flake8] -# E123, E125 skipped as they are invalid PEP-8. -# W503 line break before binary operator -show-source = True -ignore = E123,E125,W503 -builtins = _ -exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build