From: Maru Newby Date: Sat, 21 Feb 2015 00:15:12 +0000 (+0000) Subject: Add script to copy neutron api tests from tempest X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=30c6f5636517a62e272675c0fcc799c96f2fb2af;p=openstack-build%2Fneutron-build.git Add script to copy neutron api tests from tempest This change adds a script to automate the copying of api tests from tempest in the style of oslo_incubator. The target path will be neutron/tests/tempest and no manual modifications should be made to this path until such time as neutron api test development is frozen in tempest and development can proceed in the neutron tree. Until that occurs, a policy of manual once-daily synchronization is suggested. The target path includes the name 'tempest' as a clear indication that this is not part of neutron, and that once development is allowed to proceed, its contents should be rewritten and removed until there is nothing left. So long as the tests exist in both the tempest and neutron trees, testing effort will be duplicated. The larger goal is to have the tests in question removed from tempest as per the qa guidelines [1], so this should be temporary. 1: https://wiki.openstack.org/wiki/QA/Tempest-test-removal Change-Id: I3cd55983e610a1d61aae565f88fe5017edba1090 --- diff --git a/TESTING.rst b/TESTING.rst index 77b9a5754..873df4e0f 100644 --- a/TESTING.rst +++ b/TESTING.rst @@ -138,6 +138,12 @@ to install and configure all of Neutron's package dependencies. It is not necessary to provide this option if devstack has already been used to deploy Neutron to the target host. +To run the api tests against a live Neutron daemon, deploy tempest and +neutron with devstack and then run the following commands: :: + + export TEMPEST_CONFIG_DIR=/opt/stack/tempest/etc + tox -e api + For more information on the standard Tox-based test infrastructure used by OpenStack and how to do some common test/debugging procedures with Testr, see this wiki page: diff --git a/neutron/tests/api/__init__.py b/neutron/tests/api/__init__.py index e69de29bb..cbfe3d2c4 100644 --- a/neutron/tests/api/__init__.py +++ b/neutron/tests/api/__init__.py @@ -0,0 +1,37 @@ +# 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 unittest + + +# Allow the retargetable and tempest api tests to be executed as part +# of the same job by ensuring that tests from both tests are +# discovered. +# +# TODO(marun) Remove once the tempest tests have been moved to api/ + + +def _discover(loader, path, pattern): + return loader.discover(path, pattern=pattern, top_level_dir=".") + + +def load_tests(_, tests, pattern): + suite = unittest.TestSuite() + suite.addTests(tests) + + loader = unittest.loader.TestLoader() + suite.addTests(_discover(loader, "./neutron/tests/api", pattern)) + suite.addTests(_discover(loader, + "./neutron/tests/tempest/api/network", + pattern)) + + return suite diff --git a/neutron/tests/api/contrib/README.rst b/neutron/tests/api/contrib/README.rst new file mode 100644 index 000000000..79967da77 --- /dev/null +++ b/neutron/tests/api/contrib/README.rst @@ -0,0 +1,5 @@ +This path contains artifacts from tempest that have been modified to +support the execution of api tests from the neutron tree. These +artifacts are intended to be a stop-gap to support test migration, and +it is hoped that changes to tempest and tempest-lib will render it +unnecessary at some point in the future. diff --git a/neutron/tests/api/contrib/__init__.py b/neutron/tests/api/contrib/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/neutron/tests/api/contrib/clients.py b/neutron/tests/api/contrib/clients.py new file mode 100644 index 000000000..3c1681d69 --- /dev/null +++ b/neutron/tests/api/contrib/clients.py @@ -0,0 +1,116 @@ +# 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 neutron.openstack.common import log as logging +from neutron.tests.tempest.common import cred_provider +from neutron.tests.tempest import config +from neutron.tests.tempest import manager +from neutron.tests.tempest.services.identity.v2.json.identity_client import \ + IdentityClientJSON +from neutron.tests.tempest.services.identity.v2.json.token_client import \ + TokenClientJSON +from neutron.tests.tempest.services.identity.v3.json.credentials_client \ + import CredentialsClientJSON +from neutron.tests.tempest.services.identity.v3.json.endpoints_client import \ + EndPointClientJSON +from neutron.tests.tempest.services.identity.v3.json.identity_client import \ + IdentityV3ClientJSON +from neutron.tests.tempest.services.identity.v3.json.policy_client import \ + PolicyClientJSON +from neutron.tests.tempest.services.identity.v3.json.region_client import \ + RegionClientJSON +from neutron.tests.tempest.services.identity.v3.json.service_client import \ + ServiceClientJSON +from neutron.tests.tempest.services.identity.v3.json.token_client import \ + V3TokenClientJSON +from neutron.tests.tempest.services.network.json.network_client import \ + NetworkClientJSON + + +CONF = config.CONF +LOG = logging.getLogger(__name__) + + +class Manager(manager.Manager): + + """ + Top level manager for OpenStack tempest clients + """ + + default_params = { + 'disable_ssl_certificate_validation': + CONF.identity.disable_ssl_certificate_validation, + 'ca_certs': CONF.identity.ca_certificates_file, + 'trace_requests': CONF.debug.trace_requests + } + + # NOTE: Tempest uses timeout values of compute API if project specific + # timeout values don't exist. + default_params_with_timeout_values = { + 'build_interval': CONF.compute.build_interval, + 'build_timeout': CONF.compute.build_timeout + } + default_params_with_timeout_values.update(default_params) + + def __init__(self, credentials=None, service=None): + super(Manager, self).__init__(credentials=credentials) + + self._set_identity_clients() + + self.network_client = NetworkClientJSON( + self.auth_provider, + CONF.network.catalog_type, + CONF.network.region or CONF.identity.region, + endpoint_type=CONF.network.endpoint_type, + build_interval=CONF.network.build_interval, + build_timeout=CONF.network.build_timeout, + **self.default_params) + + def _set_identity_clients(self): + params = { + 'service': CONF.identity.catalog_type, + 'region': CONF.identity.region, + 'endpoint_type': 'adminURL' + } + params.update(self.default_params_with_timeout_values) + + self.identity_client = IdentityClientJSON(self.auth_provider, + **params) + self.identity_v3_client = IdentityV3ClientJSON(self.auth_provider, + **params) + self.endpoints_client = EndPointClientJSON(self.auth_provider, + **params) + self.service_client = ServiceClientJSON(self.auth_provider, **params) + self.policy_client = PolicyClientJSON(self.auth_provider, **params) + self.region_client = RegionClientJSON(self.auth_provider, **params) + self.credentials_client = CredentialsClientJSON(self.auth_provider, + **params) + self.token_client = TokenClientJSON() + if CONF.identity_feature_enabled.api_v3: + self.token_v3_client = V3TokenClientJSON() + + +class AdminManager(Manager): + + """ + Manager object that uses the admin credentials for its + managed client objects + """ + + def __init__(self, service=None): + super(AdminManager, self).__init__( + credentials=cred_provider.get_configured_credentials( + 'identity_admin'), + service=service) diff --git a/neutron/tests/api/test_v2_rest.py b/neutron/tests/api/test_v2_rest.py index a246b200c..90df65cf6 100644 --- a/neutron/tests/api/test_v2_rest.py +++ b/neutron/tests/api/test_v2_rest.py @@ -18,12 +18,11 @@ This module implements BaseNeutronClient for the Tempest rest client and configures the api tests with scenarios targeting the Neutron API. """ -from tempest import test as t_test from tempest_lib import exceptions import testscenarios from neutron.tests.api import base_v2 - +from neutron.tests.tempest import test as t_test # Required to generate tests from scenarios. Not compatible with nose. load_tests = testscenarios.load_tests_apply_scenarios diff --git a/neutron/tests/contrib/post_test_hook.sh b/neutron/tests/contrib/post_test_hook.sh index d5ff19c2e..fc11f6d2b 100644 --- a/neutron/tests/contrib/post_test_hook.sh +++ b/neutron/tests/contrib/post_test_hook.sh @@ -21,39 +21,25 @@ function generate_testr_results { fi } - -function dsvm_functional_prep_func { - : -} - - -function api_prep_func { - sudo chown -R $owner:stack $TEMPEST_DIR - sudo -H -u $owner tox -e $venv --notest - sudo -H -u $owner .tox/$venv/bin/pip install -e $TEMPEST_DIR -} - - if [ "$venv" == "dsvm-functional" ] then owner=stack - prep_func="dsvm_functional_prep_func" + sudo_env= elif [ "$venv" == "api" ] then owner=tempest - prep_func="api_prep_func" + # Configure the api tests to use the tempest.conf set by devstack. + sudo_env="TEMPEST_CONFIG_DIR=$TEMPEST_DIR/etc" fi # Set owner permissions according to job's requirements. cd $NEUTRON_DIR sudo chown -R $owner:stack $NEUTRON_DIR -# Prep the environment according to job's requirements. -$prep_func # Run tests echo "Running neutron $venv test suite" set +e -sudo -H -u $owner tox -e $venv +sudo -H -u $owner $sudo_env tox -e $venv testr_exit_code=$? set -e diff --git a/neutron/tests/tempest/README.rst b/neutron/tests/tempest/README.rst new file mode 100644 index 000000000..bc57df40a --- /dev/null +++ b/neutron/tests/tempest/README.rst @@ -0,0 +1,6 @@ +WARNING +======= + +The files under this path are maintained automatically by the script +tools/copy_api_tests_from_tempest.sh. It's contents should not be +manually modified until further notice. diff --git a/tools/copy_api_tests_from_tempest.sh b/tools/copy_api_tests_from_tempest.sh new file mode 100755 index 000000000..85ba0d479 --- /dev/null +++ b/tools/copy_api_tests_from_tempest.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +# This script is intended to allow repeatable migration of the neutron +# api tests from tempest. The intention is to allow development to +# continue in Tempest while the migration strategy evolves. + +set -e + +if [[ "$#" -ne 1 ]]; then + >&2 echo "Usage: $0 /path/to/tempest +Migrate neutron's api tests from a tempest repo." + exit 1 +fi + +TEMPEST_PATH=${TEMPEST_PATH:-$1} + +if [ ! -f "$TEMPEST_PATH/run_tempest.sh" ]; then + >&2 echo "Unable to find tempest at '$TEMPEST_PATH'. Please verify that the specified path points to a valid tempest repo." + exit 1 +fi + +NEUTRON_PATH=${NEUTRON_PATH:-$(cd $(dirname "$0")/.. && pwd)} +NEUTRON_TEST_PATH=$NEUTRON_PATH/neutron/tests + +function copy_files { + local tempest_dep_paths=( + 'tempest' + 'tempest/api/network' + 'tempest/api/network/admin' + 'tempest/common' + 'tempest/common/generator' + 'tempest/common/utils' + 'tempest/services' + 'tempest/services/identity' + 'tempest/services/identity/v3' + 'tempest/services/identity/v3/json' + 'tempest/services/network' + 'tempest/services/network/json' + ) + for tempest_dep_path in ${tempest_dep_paths[@]}; do + local target_path=$NEUTRON_TEST_PATH/$tempest_dep_path + if [[ ! -d "$target_path" ]]; then + mkdir -p $target_path + fi + cp $TEMPEST_PATH/$tempest_dep_path/*.py $target_path + done + touch $NEUTRON_TEST_PATH/tempest/api/__init__.py + + local paths_to_remove=( + "$NEUTRON_TEST_PATH/tempest/clients.py" + ) + for path_to_remove in ${paths_to_remove[@]}; do + if [ -f "$path_to_remove" ]; then + rm ${path_to_remove} + fi + done +} + +function rewrite_imports { + regexes=( + 's/tempest.common.generator/neutron.tests.tempest.common.generator/' + 's/tempest.test/neutron.tests.tempest.test/' + 's/from tempest.openstack.common import lockutils/from oslo_concurrency import lockutils/' + 's/from tempest.openstack.common import importutils/from oslo_utils import importutils/' + 's/tempest.openstack.common/neutron.openstack.common/' + 's/from tempest(?!_lib) import clients/from neutron.tests.api.contrib import clients/' + 's/from tempest(?!_lib)/from neutron.tests.tempest/' + 's/CONF.lock_path/CONF.oslo_concurrency.lock_path/' + ) + files=$(find $NEUTRON_TEST_PATH/tempest -name '*.py') + for ((i = 0; i < ${#regexes[@]}; i++)); do + perl -p -i -e "${regexes[$i]}" $files + done +} + +copy_files +rewrite_imports diff --git a/tools/misc-sanity-checks.sh b/tools/misc-sanity-checks.sh index 2e3e51934..bc4d2eb01 100644 --- a/tools/misc-sanity-checks.sh +++ b/tools/misc-sanity-checks.sh @@ -32,7 +32,7 @@ check_opinionated_shell () { # If you cannot avoid the use of bash, please change the EXPECTED var below. OBSERVED=$(grep -E '^([[:space:]]*[^#[:space:]]|#!).*bash' \ tox.ini tools/* | wc -l) - EXPECTED=6 + EXPECTED=7 if [ ${EXPECTED} -ne ${OBSERVED} ]; then echo "Bash usage has been detected!" >>$FAILURES fi diff --git a/tox.ini b/tox.ini index 3e03249da..d73e97409 100644 --- a/tox.ini +++ b/tox.ini @@ -84,7 +84,10 @@ commands = sphinx-build -W -b html doc/source doc/build ignore = E125,E126,E128,E129,E265,H305,H404,H405 show-source = true builtins = _ -exclude = ./.*,build,dist,neutron/openstack/common/* +# neutron/tests/tempest needs to be excluded so long as it continues +# to be copied directly from tempest, since tempest and neutron do not +# share a flake8 configuration. +exclude = ./.*,build,dist,neutron/openstack/common/*,neutron/tests/tempest [hacking] import_exceptions = neutron.i18n